# Tutorial Description¶

The goal of the experiment is to build a model to simulate a simple knee reflex. A knee reflex tries to compensate for a sudden muscle stretch by activating the muscle under stretch appropriately based on its’ muscle stretching speed to compensate the stretch.

To achieve this we will be using the NRP-OpenSim interface. The first step would be to clone the experiment “Opensim Muscle Tutorial - Knee Jerk Experiment”. After cloning click on the experiment and click files to view all the simulation files that we are going to be editing. The file explorer can be used to download and upload all the files.

# Model Creation¶

In order to create a musculoskeletal model in NRP, it involves two stages:

1. Gazebo Modeling : Physical Model

2. Opensim Modeling : Muscle Model

## Gazebo Modeling¶

The model used in this experiment is a simple two link thigh and shank bodies with one rotational degree of freedom to represent the knee joint. The properties of the model are as described below,

 Body Length(m) Mass(kg) Inertia(kg-m2) thigh 0.5 5 1 shank 0.5 5 1

With the properties described in the above table, one can setup up the basic sdf model. In order to attach and make the opensim plugin to work in NRP, the following tag needs to be added in the sdf file. You can download and edit the model.sdf file from the robot folder through the file explorer.

<muscles>model://opensim_knee_jerk_tut/muscles.osim</muscles>

<plugin name="muscle_interface_plugin" filename="libgazebo_ros_muscle_interface.so"></plugin>

The muscles tag points to the location where the description of muscles is setup. More details on writing this file can be found in the following section.

The plugin is needed to link the necessary libraries that interface NRP with Opensim functionality.

## Opensim Modeling¶

The next step is to describe the muscles in the model. This is achieved by writing a *.osim file. This file follows the same syntax as described by the standard opensim osim file description format.

For more details checkout the link <https://simtk-confluence.stanford.edu/display/OpenSim/OpenSim+Models> __ under The Muscle Actuator subheading.

The osim file should contain only the muscles description and the wrapping objects. The bodies/links will be used from the model description defined in sdf file earlier. Hence make sure to use the same names for the bodies in both files

In the current tutorial, a single muscle named vastus is used with the following properties,

 Property Value Units Isometric Force 500 N Optimal Fiber Length 0.19 m Tendon Slack Length 0.19 m Origin [0. 0.25 0.05] m Insertion [0. 0.08 -0.15] m

The above table translated to the osim file looks like,

<Millard2012EquilibriumMuscle name="vastus">
<!--The set of points defining the path of the actuator.-->
<GeometryPath>
<!--The set of points defining the path-->
<PathPointSet>
<objects>
<PathPoint name="origin">
<body>thigh</body>
<!--The fixed location of the path point expressed in its parent frame.-->
<location>0.050000000000000003 0 0</location>
</PathPoint>
<PathPoint name="insertion">
<body>shank</body>
<!--The fixed location of the path point expressed in its parent frame.-->
<location>0.037499999999999999 0.17499999999999999 0</location>
</PathPoint>
</objects>
<groups />
</PathWrap>
</objects>
<groups />
</Appearance>
</GeometryPath>
<!--Maximum isometric force that the fibers can generate-->
<max_isometric_force>500</max_isometric_force>
<!--Optimal length of the muscle fibers-->
<optimal_fiber_length>0.19</optimal_fiber_length>
<!--Resting length of the tendon-->
<tendon_slack_length>0.19</tendon_slack_length>
</Millard2012EquilibriumMuscle>


Note: The above snippet is only an example. Do not copy and paste

The muscles.osim file used for this tutorial also describes a muscle wrapping object. This constraint makes sure that the muscle does not penetrate the bones during the motion of the joint.

# Gazebo-ROS-OpenSim Inerface¶

Once you have setup the models using the above described steps, you should be able to create new experiments with the usual NRP procedure to create a model. Assuming you are familiar with the process, we continue the tutorial.

In order to be able to write controllers and access the muscles in the simulation, there exists a set of muscle topics and messages that can be used.

## Subscribers¶

The states of the muscles initialized and described in the *.osim(muscles.osim) is automatically published on a ros topic with the name  /gazebo_muscle_interface/robot/muscle_states  The above topic uses the ros-msg type MuscleStates which is an array containing MuscleState whose format which looks like,

 Type Name string name float32 force float32 length float32 lengthening_speed geometry_msgs/Vector3[] path_points

## Publishers¶

To control the muscle state, the muscle activation needs to be set by the controller. During initialization every muscle described in the *.osim(muscles.osim) is generated with a individual ros-publisher of the topic,  /gazebo_muscle_interface/robot/MUSCLE_NAME/cmd_activation  The above topic accepts messages of type Float64.

# Reflex-Control¶

Now that the full experimental model is setup, we can develop the controller to simulate the knee reflex.

# Muscle Properties
m_optimal_fiber_length = 0.19
m_max_contraction_velocity = 10.0

# Get muscle state
muscle_states =dict((m.name, m) for m in muscle_states_msg.value.muscles)

# Muscle Lengthening speed
m_speed = muscle_states['vastus'].lengthening_speed

# Maximum muscle speed
m_max_speed = m_optimal_fiber_length*m_max_contraction_velocity

#: Knee jerk reflex control
# Reflex gain
reflex_gain = 2.
m_reflex_activation = min(1., 0.2*reflex_gain*(abs(m_speed) + m_speed)/m_max_speed)

# Send muscle activation
knee_jerk.send_message(m_reflex_activation)