Presented by Adam Galloy1, Kayt Frisch PhD1, and Dylan Schmitz2
1Dordt College, 2University of Wisconsin-Madison
Contact: kayt.frisch@dordt.edu
The OpenSim community has developed many models to fit a wide variety of applications. This expansive library of models makes musculoskeletal simulation with OpenSim more acessible, but not all models will be ready for your specific study right away. This page explains the different aspects of a model that may need to be changed before a model is ready for your specific purposes.
Underdefined and Overcomplicated Models
Before running a simulation such as Inverse Kinematics that tracks a subject’s motion and replicates the motion with the OpenSim model, make sure the model is not underdefined. Underdefined models have more degrees of freedom (DOFs) than can be tracked with the number of markers placed on the subject. For example, an upper extremity model may include DOFs for the motion of each finger. However, no markers were placed past the subject’s first knuckle. In this case the model is underdefined since there are more DOFs than the markers can track. DOFs will need to be locked in order for the model to run properly in simulations.
Another case where DOFs may need to be locked for improved results is if a DOF makes the motion too complicated for analysis or if the DOF is highly prone to error and could be making the other DOFs less accurate as a result. In these cases, finding a reasonable position to lock the DOF in could improve simulation results. For details on how to lock or adjust DOFs see the Coordinate Controls and Poses page.
Model Range of Motion
Adjusting the Range of a DOF
Sometimes you may need to adjust the range of motion of a model for your study. For example, a study may call for a more limited range of motion in order to simulate an impairment. A DOF may need to be extended if the model is unable to track a motion because of limits in its range of motion. For example, the 3DGaitModel2392 included with OpenSim has maximum and minimum pelvis rotations of 90 and -90 degrees respectively. This model could not be used to track a person turning around more than 90 degrees.
To adjust the maximum and minimum range of motion of a DOF, first locate the joint that contains the DOF. Continuing with the 3DGaitModel2392’s pelvis rotation as an example, the joint containing the DOF would be the ground_pelivs joint. Once the joint is selected locate the CoordinateSet line in the Property Window and click the … box (circled below).
A CoordinateSet window will now open up. As shown below navigate to the range folder for the desired DOF. In general, follow the path objects->Coordinate->range to find the range folder for the desired DOF. Once the range folder is found adjust the [0] and [1] values to adjust the minimum and maximum range of the DOF respectively (note that angle values must be given in radians). The model may have to be saved and reloaded before the changes are visible.
Adding a New DOF
Another type of adjustment to a model's range of motion is to add a new DOF. An example of a case where this is needed is if a model is fixed to the origin of its coordinate system. Many simulations (especially ones that track subjects) require the model to move freely relative to the model’s ground. 6 DOFs will need to be added to allow this (translations in the x, y, and z directions as well as rotations in the x, y, and z directions).
To add these DOFs locate the body that is connected to the model ground with a joint. For lower body models this body is often the pelvis, and for upper body models it is often the torso. Once the body is located, open the .osim model file in a text editor such as Notepad++. Navigate from OpenSimDocument->Model->BodySet->Objects->Body name = " "->Joint as shown below. Remove any joints between that body and the ground and paste the text from the bottom of the page in between the <Joint> and </Joint> lines (the name of the joint and DOFs can be changed if desired).
Model Marker Set
In order to use motion capture data with a model, a virtual model marker must be attached to the model for every marker used for motion capture. The model markers must have the same name as the experimental markers used for motion capture. OpenSim compares the coordinates of the digital markers on the model to the coordinates of the experimental markers to have the model track the motion of the subject. Because of this direct comparison between the model markers and the experimental markers, the model markers should be placed as close as possible to the same anatomical positions as the experimental markers. Use any pictures of the subject(s) with the full marker set for help placing the markers correctly. In addition to placement position, consider carefully the body on the model that you attach the marker to. For models near joints such as the elbow or shoulder think about how the marker moves with the arm and find the body to attach it to that best mimics this movement. See the Marker Editor page for more information on attaching makers and saving them to a model.
Model Inertial Parameters
Inertial parameters determine how a body in a model responds to forces. Inertial parameters include the mass of the body, its center of mass, and its moments of inertia and products of inertia about each axis. Dynamic analyses such as Inverse Dynamics, Static Optimization, and Forward Dynamics heavily rely on accurate values for the inertial parameters, so it is important that they are set correctly.
Imported models may not already have inertial parameters applied. If the model does not have inertial parameters set for each body, the user will need to set inertial parameters for each body to perform dynamic analyses. Charts published in the literature contain inertial parameters for many different body segments normalized to a subject’s total mass. The Scale Tool automatically scales the inertial parameters of a body, so inertial parameters should be specified based on the generic model’s total mass and body segment sizes, and then when the subject’s mass is entered during the scaling process the individual segments will scale appropriately.
To set the inertial parameters of a body select a body in the navigator window. In the property window the different inertial parameters will appear as shown below. Clicking on a value will allow for editing.
Custom Ground Joint
<CustomJoint name="groundthorax">
<!--Name of the parent body to which this joint connects its owner body.-->
<parent_body>ground</parent_body>
<!--Location of the joint in the parent body specified in the parent reference frame. Default is (0,0,0).-->
<location_in_parent>0 0 0</location_in_parent>
<!--Orientation of the joint in the parent body specified in the parent reference frame. Euler XYZ body-fixed rotation angles are used to express the orientation. Default is (0,0,0).-->
<orientation_in_parent>0 0 0</orientation_in_parent>
<!--Location of the joint in the child body specified in the child reference frame. For SIMM models, this vector is always the zero vector (i.e., the body reference frame coincides with the joint). -->
<location>0 0 0</location>
<!--Orientation of the joint in the owing body specified in the owning body reference frame. Euler XYZ body-fixed rotation angles are used to express the orientation. -->
<orientation>0 0 0</orientation>
<!--Set holding the generalized coordinates (q's) that parmeterize this joint.-->
<CoordinateSet>
<objects>
<Coordinate name="r_x">
<!--Coordinate can describe rotational, translational, or coupled motion. Defaults to rotational.-->
<motion_type>rotational</motion_type>
<!--The value of this coordinate before any value has been set. Rotational coordinate value is in radians and Translational in meters.-->
<default_value>0</default_value>
<!--The speed value of this coordinate before any value has been set. Rotational coordinate value is in rad/s and Translational in m/s.-->
<default_speed_value>0</default_speed_value>
<!--The minimum and maximum values that the coordinate can range between. Rotational coordinate range in radians and Translational in meters.-->
<range>-6.28318531 6.28318531</range>
<!--Flag indicating whether or not the values of the coordinates should be limited to the range, above.-->
<clamped>true</clamped>
<!--Flag indicating whether or not the values of the coordinates should be constrained to the current (e.g. default) value, above.-->
<locked>false</locked>
<!--If specified, the coordinate can be prescribed by a function of time. It can be any OpenSim Function with valid second order derivatives.-->
<prescribed_function />
<!--Flag indicating whether or not the values of the coordinates should be prescribed according to the function above. It is ignored if the no prescribed function is specified.-->
<prescribed>false</prescribed>
</Coordinate>
<Coordinate name="r_y">
<!--Coordinate can describe rotational, translational, or coupled motion. Defaults to rotational.-->
<motion_type>rotational</motion_type>
<!--The value of this coordinate before any value has been set. Rotational coordinate value is in radians and Translational in meters.-->
<default_value>0</default_value>
<!--The speed value of this coordinate before any value has been set. Rotational coordinate value is in rad/s and Translational in m/s.-->
<default_speed_value>0</default_speed_value>
<!--The minimum and maximum values that the coordinate can range between. Rotational coordinate range in radians and Translational in meters.-->
<range>-6.28318531 6.28318531</range>
<!--Flag indicating whether or not the values of the coordinates should be limited to the range, above.-->
<clamped>true</clamped>
<!--Flag indicating whether or not the values of the coordinates should be constrained to the current (e.g. default) value, above.-->
<locked>false</locked>
<!--If specified, the coordinate can be prescribed by a function of time. It can be any OpenSim Function with valid second order derivatives.-->
<prescribed_function />
<!--Flag indicating whether or not the values of the coordinates should be prescribed according to the function above. It is ignored if the no prescribed function is specified.-->
<prescribed>false</prescribed>
</Coordinate>
<Coordinate name="r_z">
<!--Coordinate can describe rotational, translational, or coupled motion. Defaults to rotational.-->
<motion_type>rotational</motion_type>
<!--The value of this coordinate before any value has been set. Rotational coordinate value is in radians and Translational in meters.-->
<default_value>0</default_value>
<!--The speed value of this coordinate before any value has been set. Rotational coordinate value is in rad/s and Translational in m/s.-->
<default_speed_value>0</default_speed_value>
<!--The minimum and maximum values that the coordinate can range between. Rotational coordinate range in radians and Translational in meters.-->
<range>-6.28318531 6.28318531</range>
<!--Flag indicating whether or not the values of the coordinates should be limited to the range, above.-->
<clamped>true</clamped>
<!--Flag indicating whether or not the values of the coordinates should be constrained to the current (e.g. default) value, above.-->
<locked>false</locked>
<!--If specified, the coordinate can be prescribed by a function of time. It can be any OpenSim Function with valid second order derivatives.-->
<prescribed_function />
<!--Flag indicating whether or not the values of the coordinates should be prescribed according to the function above. It is ignored if the no prescribed function is specified.-->
<prescribed>false</prescribed>
</Coordinate>
<Coordinate name="t_x">
<!--Coordinate can describe rotational, translational, or coupled motion. Defaults to rotational.-->
<motion_type>translational</motion_type>
<!--The value of this coordinate before any value has been set. Rotational coordinate value is in radians and Translational in meters.-->
<default_value>0</default_value>
<!--The speed value of this coordinate before any value has been set. Rotational coordinate value is in rad/s and Translational in m/s.-->
<default_speed_value>0</default_speed_value>
<!--The minimum and maximum values that the coordinate can range between. Rotational coordinate range in radians and Translational in meters.-->
<range>-100 100</range>
<!--Flag indicating whether or not the values of the coordinates should be limited to the range, above.-->
<clamped>true</clamped>
<!--Flag indicating whether or not the values of the coordinates should be constrained to the current (e.g. default) value, above.-->
<locked>false</locked>
<!--If specified, the coordinate can be prescribed by a function of time. It can be any OpenSim Function with valid second order derivatives.-->
<prescribed_function />
<!--Flag indicating whether or not the values of the coordinates should be prescribed according to the function above. It is ignored if the no prescribed function is specified.-->
<prescribed>false</prescribed>
</Coordinate>
<Coordinate name="t_y">
<!--Coordinate can describe rotational, translational, or coupled motion. Defaults to rotational.-->
<motion_type>translational</motion_type>
<!--The value of this coordinate before any value has been set. Rotational coordinate value is in radians and Translational in meters.-->
<default_value>0</default_value>
<!--The speed value of this coordinate before any value has been set. Rotational coordinate value is in rad/s and Translational in m/s.-->
<default_speed_value>0</default_speed_value>
<!--The minimum and maximum values that the coordinate can range between. Rotational coordinate range in radians and Translational in meters.-->
<range>-100 100</range>
<!--Flag indicating whether or not the values of the coordinates should be limited to the range, above.-->
<clamped>true</clamped>
<!--Flag indicating whether or not the values of the coordinates should be constrained to the current (e.g. default) value, above.-->
<locked>false</locked>
<!--If specified, the coordinate can be prescribed by a function of time. It can be any OpenSim Function with valid second order derivatives.-->
<prescribed_function />
<!--Flag indicating whether or not the values of the coordinates should be prescribed according to the function above. It is ignored if the no prescribed function is specified.-->
<prescribed>false</prescribed>
</Coordinate>
<Coordinate name="t_z">
<!--Coordinate can describe rotational, translational, or coupled motion. Defaults to rotational.-->
<motion_type>translational</motion_type>
<!--The value of this coordinate before any value has been set. Rotational coordinate value is in radians and Translational in meters.-->
<default_value>0</default_value>
<!--The speed value of this coordinate before any value has been set. Rotational coordinate value is in rad/s and Translational in m/s.-->
<default_speed_value>0</default_speed_value>
<!--The minimum and maximum values that the coordinate can range between. Rotational coordinate range in radians and Translational in meters.-->
<range>-100 100</range>
<!--Flag indicating whether or not the values of the coordinates should be limited to the range, above.-->
<clamped>true</clamped>
<!--Flag indicating whether or not the values of the coordinates should be constrained to the current (e.g. default) value, above.-->
<locked>false</locked>
<!--If specified, the coordinate can be prescribed by a function of time. It can be any OpenSim Function with valid second order derivatives.-->
<prescribed_function />
<!--Flag indicating whether or not the values of the coordinates should be prescribed according to the function above. It is ignored if the no prescribed function is specified.-->
<prescribed>false</prescribed>
</Coordinate>
</objects>
<groups />
</CoordinateSet>
<!--Whether the joint transform defines parent->child or child->parent.-->
<reverse>false</reverse>
<!--Defines how the child body moves with respect to the parent as a function of the generalized coordinates.-->
<SpatialTransform>
<!--3 Axes for rotations are listed first.-->
<TransformAxis name="rotation1">
<!--Names of the coordinates that serve as the independent variables of the transform function.-->
<coordinates>r_x</coordinates>
<!--Rotation or translation axis for the transform.-->
<axis>1 0 0</axis>
<!--Transform function of the generalized coordinates used to represent the amount of transformation along a specified axis.-->
<function>
<LinearFunction>
<coefficients> 1 0</coefficients>
</LinearFunction>
</function>
</TransformAxis>
<TransformAxis name="rotation2">
<!--Names of the coordinates that serve as the independent variables of the transform function.-->
<coordinates>r_y</coordinates>
<!--Rotation or translation axis for the transform.-->
<axis>0 1 0</axis>
<!--Transform function of the generalized coordinates used to represent the amount of transformation along a specified axis.-->
<function>
<LinearFunction>
<coefficients> 1 0</coefficients>
</LinearFunction>
</function>
</TransformAxis>
<TransformAxis name="rotation3">
<!--Names of the coordinates that serve as the independent variables of the transform function.-->
<coordinates>r_z</coordinates>
<!--Rotation or translation axis for the transform.-->
<axis>0 0 1</axis>
<!--Transform function of the generalized coordinates used to represent the amount of transformation along a specified axis.-->
<function>
<LinearFunction>
<coefficients> 1 0</coefficients>
</LinearFunction>
</function>
</TransformAxis>
<!--3 Axes for translations are listed next.-->
<TransformAxis name="translation1">
<!--Names of the coordinates that serve as the independent variables of the transform function.-->
<coordinates>t_x</coordinates>
<!--Rotation or translation axis for the transform.-->
<axis>1 0 0</axis>
<!--Transform function of the generalized coordinates used to represent the amount of transformation along a specified axis.-->
<function>
<LinearFunction>
<coefficients> 1 0</coefficients>
</LinearFunction>
</function>
</TransformAxis>
<TransformAxis name="translation2">
<!--Names of the coordinates that serve as the independent variables of the transform function.-->
<coordinates>t_y</coordinates>
<!--Rotation or translation axis for the transform.-->
<axis>0 1 0</axis>
<!--Transform function of the generalized coordinates used to represent the amount of transformation along a specified axis.-->
<function>
<LinearFunction>
<coefficients> 1 0</coefficients>
</LinearFunction>
</function>
</TransformAxis>
<TransformAxis name="translation3">
<!--Names of the coordinates that serve as the independent variables of the transform function.-->
<coordinates>t_z</coordinates>
<!--Rotation or translation axis for the transform.-->
<axis>0 0 1</axis>
<!--Transform function of the generalized coordinates used to represent the amount of transformation along a specified axis.-->
<function>
<LinearFunction>
<coefficients> 1 0</coefficients>
</LinearFunction>
</function>
</TransformAxis>
</SpatialTransform>
</CustomJoint>