The topics covered in this section include:
Table of Contents |
---|
You can also find more information in the /wiki/spaces/OpenSim/pages/53084243.
Overview
An OpenSim model represents the neuromuscular and musculoskeletal dynamics of a human or animal that is of interest to study within a computer simulation. The OpenSim model is made up of components corresponding to parts of the physical system that combine to generate or describe movement. These parts are: reference frames, bodies, joints, constraints, forces, contact geometry, markers and controllers.
In OpenSim, a model's skeletal system is represented by rigid bodies interconnected by joints. Joints define how a body two bodies (e.g., bone segment), termed parent and child bodies, can move with respect to its parent body. In OpenSim, each body has a parent and is connected to its parent via a joint. one another. Constraints can also be applied to limit the motion of bodies.
...
An OpenSim Model File (arm26.osim). The file below was opened in the XML editor Notepad++, which provides the color syntax highlighting. The sections have been collapsed to highlight the model components. Clicking on the + icon to the left of a section would expand it, displaying the relevant tags for that section.
Info |
---|
Use the OpenSim GUI's XML Browser, under Help to find the XML mark-up for any OpenSim model component described below. |
...
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
...
A body is a moving reference frame (Bo) in which its center-of-mass and inertia are defined, and the location of a joint frame (B) fixed to the body can be specified. Similarly, the joint frame (P) in the parent body frame (Po) can also be specified. Flexibility in specifying the joint is achieved by permitting joint frames that are not coincident with the body frame. In 4.0, this flexibility was enhanced via the introduction of the Frame class hierarchy. There are three main types of Frames: Ground (each model starts with a ground frame), Body, and PhysicalOffsetFrame. All three of these frames are called PhysicalFrames because they either are a rigid body or are fixed to a rigid body. In OpenSim 4.0, a joint connects two PhysicalFrames (parent and child). One can use PhysicalOffsetFrames to specify a constant transform between a joint frame and the body frame.
As an example, the body r_humerus contains the joint r_shoulder. The figure below shows an example from Arm26 defining the r_shoulder joint. Note the key tags, such as <socket_parent_frame>, <socket_child_frame>, <Coordinate>, <translation>, and <orientation>. Note the use of an intermediate PhysicalOffsetFrame for the joint's parent frame.
...
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:
...
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 angle 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> |
...
Code Block | ||||
---|---|---|---|---|
| ||||
<!--Apply a force at a point in the direction specified in the body frame --> <PointActuator name="FY_residual"> <!--Name of Body to which this actuator is applied.--> <body> pelvis </body> <!--Location of application point; in body frame unless point_is_global=true--> <point> 0 0 0</point> <!--Interpret point in Ground frame if true; otherwise, body frame.--> <point_is_global> false </point_is_global> <!--Force application direction; in body frame unless force_is_global=true.--> <direction> 1 0 0</direction> <!--Interpret direction in Ground frame if true; otherwise, body frame.--> <force_is_global> true </force_is_global> <!--The maximum force produced by this actuator when fully activated.--> <optimal_force> 8.0 </optimal_force> </PointActuator> <!--Apply an equal and opposite torque on two bodies about the axis defined in the the first body --> <TorqueActuator name="MZ_residual"> <optimal_force> 1000.0 </optimal_force> <bodyA> ground </bodyA> <axis> 0.000 0.000 -1.000 </axis> <bodyB> pelvis </bodyB> </TorqueActuator > <!--Apply a generalized force along (force) or about (torque) the axis of a generalized coordinate. Positive force increases the coordinate --> <CoordinateActuator name="knee_reserve"> <optimal_force> 300.0 </optimal_force> <coordinate> knee_angle_r </coordinate> </CoordinateActuator> |
The Muscle Actuator
There are several muscle models in OpenSim. All muscles include a set of muscle points where the muscle is connected to bones (bodies) and provide utilities for calculating muscle-actuator lengths and velocities. Internally muscle models may differ in the number and types of parameters. Muscles typically include muscle activation and contraction dynamics and their own states (for example activation and muscle fiber length). The control values are typically bounded excitations (ranging from 0 to 1) which lead to a change in activation and then force. Below is an example of a muscle model, as described by Thelen (2003), from an OpenSim model.
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> |
...