The topics covered in this section include:
...
Code Block | ||||
---|---|---|---|---|
| ||||
<Body name="r_humerus"> <attached_geometry>...</attached_geometry> <WrapObjectSet>...</WrapObjectSet> <mass>1.8645719999999999</mass> <mass_center>0 -0.18049599999999999 0</mass_center> <inertia>0.01481 0.0045510000000000004 0.013193 0 0 0</inertia> </Body> |
Every model comes with a Ground body, which exists as a property of a Model, not in the BodySet.
Geometry
...
q are the joint coordinates, and x are the spatial coordinates for the rotations (x1, x2, x3) and translations (x4, x5, x6) along user-defined axes that specify a spatial transform (X) according to functions fi. The behavior of a CustomJoint is specified by its SpatialTransform. A SpatialTransform is comprised of 6 TransformAxis tags (3 rotations and 3 translations) that define the spatial position of B in P as a function of coordinates. Each transform axis enables a function of joint coordinates to operate about or along its axis. The function of q is used to determine the displacement for that axis. The order of the spatial transform is fixed with rotations first followed by translations. Subsequently, coupled motion (i.e., describing motion of two degrees of freedom as a function of one coordinate) is easily handled. The example below (from the gait2354.osim model) describes coupled motion of the knee, with both tibial translation and knee flexion described as a function of knee angle:
Spatial transform of a custom joint that implements a translating knee joint
Code Block | ||||
---|---|---|---|---|
| ||||
<SpatialTransform name=""> <!--3 Axes for rotations are listed first.--> <TransformAxis name="rotation1"> <function> <LinearFunction name=""> <coefficients> 1.00000000 0.0000000 </coefficients> </LinearFunction> </function> <coordinates> knee_angle_r </coordinates> <axis> 0.00000000 0.00000000 1.00000000 </axis> <TransformAxis> <TransformAxis name="rotation2"> <function> <Constant name=""> <value> 0.00000000 </value> </Constant> </function> <coordinates> </coordinates> <axis> 0.00000000 1.00000000 0.00000000 </axis> </TransformAxis> <TransformAxis name="rotation3"> ... <!--3 Axes for translations are listed next.--> <TransformAxis name="translation1"> <function> <NaturalCubicSpline name=""> ... </function> <coordinates> knee_angle_r </coordinates> <axis> 1.00000000 0.00000000 0.00000000 </axis> </TransformAxis> <TransformAxis name="translation2"> <function> <NaturalCubicSpline name=""> ... </function> <coordinates> knee_angle_r </coordinates> <axis> 0.00000000 1.00000000 0.00000000 </axis> </TransformAxis> <TransformAxis name="translation3"> ... </SpatialTransform> |
...
OpenSim currently supports three types of built-in constraints: PointConstraint, WeldConstraint, and CoordinateCouplerConstraint. A point constraint fixes a point defined with respect to two bodies (i.e., no relative translations). A weld constraint fixes the relative location and orientation of two bodies (i.e., no translations or rotations). A coordinate coupler relates the generalized coordinate of a given joint (the dependent coordinate) to any other coordinates in the model (independent coordinates). The user must supply a function that returns a dependent value based on independent values. The following example implements coordinate coupler constraint for the motion of the patella as a function of the knee ankle and also welds the foot to ground.Example of constraints in OpenSim:
Code Block | ||||
---|---|---|---|---|
| ||||
<!--Constraints in the model.--> <ConstraintSet name=""> <objects> <!-- Constrain the translation of the patella in the x-direction as a function of the knee_angle --> <CoordinateCouplerConstraint name="pat_tx_r"> <isEnforced> true </isEnforced> <coupled_coordinates_function> <SimmSpline name=""> <x> -2.09439510 -1.39626340 -1.04719755 -0.69813170 -0.34906585 -0.17453293 ... </x> <y> 0.01710145 0.03202815 0.03766273 0.04250649 0.04636173 0.04784451 ... </y> </SimmSpline> </coupled_coordinates_function> <!-- coordinates involved in the constraint must be defined by joints in this model --> <independent_coordinate_names> knee_angle_r </independent_coordinate_names> <dependent_coordinate_name> pat_tx_r </dependent_coordinate_name> </CoordinateCouplerConstraint> <!-- Constrain the translation of the patella in the y-direction as a function of the knee_angle --> <CoordinateCouplerConstraint name="pat_ty_r"> ... <!-- Constrain the rotation of the patella as a function of the knee_angle --> <CoordinateCouplerConstraint name="pat_angle_r"> ... <!-- Constrain a foot to the floor with a weld. A weld specifies a location and orientation of two frames on separate bodies that must remain spatially coincident and aligned. --> <WeldConstraint name="weld"> <isEnforced>true</isEnforced> <socket_frame1> /bodyset/foot_r </socket_frame1> <socket_frame2> /ground </socket_frame2> </WeldConstraint> </objects> <groups/> </ConstraintSet> |
...
In addition to the muscle properties, we need to define its geometry. In this example, a geometry path is defined for the muscle using a set of path points.Sample muscle actuator from a model’s ForceSet:
Code Block | ||||
---|---|---|---|---|
| ||||
<Thelen2003Muscle name="BICshort"> <appliesForce>true</appliesForce> <!--The set of points defining the path of the actuator.--> <GeometryPath> <!--The set of points defining the path--> <PathPointSet> <objects> <PathPoint name="BICshort-P1"> <socket_parent_frame>/bodyset/base</socket_parent_frame> <!--The fixed location of the path point expressed in its parent frame.--> <location>0.0046750000000000003 -0.01231 0.13475000000000001</location> </PathPoint> <PathPoint name="BICshort-P2"> <socket_parent_frame>/bodyset/base</socket_parent_frame> <!--The fixed location of the path point expressed in its parent frame.--> <location>-0.0070749999999999997 -0.040039999999999999 0.14507</location> </PathPoint> ... </PathPointSet> <!--The wrap objects that are associated with this path--> <PathWrapSet>...</PathWrapSet> <!--Default appearance attributes for this GeometryPath--> <Appearance> <!--The color, (red, green, blue), [0, 1], used to display the geometry. --> <color>0.80000000000000004 0.10000000000000001 0.10000000000000001</color> </Appearance> </GeometryPath> <!--Maximum isometric force that the fibers can generate--> <max_isometric_force>435.56</max_isometric_force> <!--Optimal length of the muscle fibers--> <optimal_fiber_length>0.1321</optimal_fiber_length> <!--Resting length of the tendon--> <tendon_slack_length>0.1923</tendon_slack_length> <!--Angle between tendon and fibers at optimal fiber length expressed in radians--> <pennation_angle_at_optimal>0</pennation_angle_at_optimal> <!--Maximum contraction velocity of the fibers, in optimal fiberlengths/second--> <max_contraction_velocity>10</max_contraction_velocity> <!--tendon strain at maximum isometric muscle force--> <FmaxTendonStrain>0.033000000000000002</FmaxTendonStrain> <!--passive muscle strain at maximum isometric muscle force--> <FmaxMuscleStrain>0.59999999999999998</FmaxMuscleStrain> <!--shape factor for Gaussian active muscle force-length relationship--> <KshapeActive>0.5</KshapeActive> <!--exponential shape factor for passive force-length relationship--> <KshapePassive>4</KshapePassive> <!--force-velocity shape factor--> <Af>0.29999999999999999</Af> <!--maximum normalized lengthening force--> <Flen>1.8</Flen> <!--Activation time constant, in seconds--> <activation_time_constant>0.01</activation_time_constant> <!--Deactivation time constant, in seconds--> <deactivation_time_constant>0.040000000000000001</deactivation_time_constant> </Thelen2003Muscle> |
...