API  4.5.1
For C++ developers
Simulation Utilities

These are free functions and utility classes in the Simulation library. More...

Functions

OSIMSIMULATION_API SimTK::State OpenSim::simulate (Model &model, const SimTK::State &initialState, double finalTime, bool saveStatesFile=false)
 Simulate a model from an initial state and return the final state. More...
 
OSIMSIMULATION_API void OpenSim::updateStateLabels40 (const Model &model, std::vector< std::string > &labels)
 Update a vector of state labels (in place) to use post-4.0 state paths instead of pre-4.0 state names. More...
 
OSIMSIMULATION_API std::unique_ptr< StorageOpenSim::updatePre40KinematicsStorageFor40MotionType (const Model &pre40Model, const Storage &kinematics)
 Not available through scripting. More...
 
OSIMSIMULATION_API void OpenSim::updatePre40KinematicsFilesFor40MotionType (const Model &model, const std::vector< std::string > &filePaths, std::string suffix="_updated")
 This function can be used to upgrade MOT files generated with versions before 4.0 in which some data columns are associated with coordinates that were incorrectly marked as Rotational (rather than Coupled). More...
 
OSIMSIMULATION_API void OpenSim::updateSocketConnecteesBySearch (Model &model)
 This function attempts to update the connectee path for any Socket anywhere in the model whose connectee path does not point to an existing component. More...
 
OSIMSIMULATION_API std::vector< std::string > OpenSim::createStateVariableNamesInSystemOrder (const Model &model)
 The map provides the index of each state variable in SimTK::State::getY() from its each state variable path string. More...
 
OSIMSIMULATION_API std::vector< std::string > OpenSim::createStateVariableNamesInSystemOrder (const Model &model, std::unordered_map< int, int > &yIndexMap)
 Same as above, but you can obtain a map from the returned state variable names to the index in SimTK::State::getY() that accounts for empty slots in Y. More...
 
OSIMSIMULATION_API std::unordered_map< std::string, int > OpenSim::createSystemYIndexMap (const Model &model)
 The map provides the index of each state variable in SimTK::State::getY() from its state variable path string. More...
 
OSIMSIMULATION_API std::vector< std::string > OpenSim::createControlNamesFromModel (const Model &model, std::vector< int > &modelControlIndices)
 Create a vector of control names based on the actuators in the model for which appliesForce == True. More...
 
OSIMSIMULATION_API std::vector< std::string > OpenSim::createControlNamesFromModel (const Model &model)
 Same as above, but when there is no mapping to the modelControlIndices. More...
 
template<typename T >
std::unordered_set< std::string > OpenSim::createControlNamesForControllerType (const Model &model)
 Create a vector of control names based on the actuators in the model associated with any controller of type T for which appliesForce == True. More...
 
OSIMSIMULATION_API std::unordered_map< std::string, int > OpenSim::createSystemControlIndexMap (const Model &model)
 The map provides the index of each control variable in the SimTK::Vector returned by Model::getControls(), using the control name as the key. More...
 
OSIMSIMULATION_API void OpenSim::checkOrderSystemControls (const Model &model)
 Throws an exception if the order of the controls in the model is not the same as the order of the actuators in the model. More...
 
OSIMSIMULATION_API void OpenSim::checkLabelsMatchModelStates (const Model &model, const std::vector< std::string > &labels)
 Throws an exception if any label in the provided list does not match any state variable names in the model. More...
 
template<typename T >
TimeSeriesTable_< T > OpenSim::analyze (Model model, const TimeSeriesTable &statesTable, const TimeSeriesTable &controlsTable, const std::vector< std::string > &outputPaths, const TimeSeriesTable &discreteVariablesTable={})
 Calculate the requested outputs using the model in the problem and the provided states and controls tables. More...
 
OSIMSIMULATION_API TimeSeriesTableVec3 OpenSim::createSyntheticIMUAccelerationSignals (const Model &model, const TimeSeriesTable &statesTable, const TimeSeriesTable &controlsTable, const std::vector< std::string > &framePaths)
 Calculate "synthetic" acceleration signals equivalent to signals recorded from inertial measurement units (IMUs). More...
 
OSIMSIMULATION_API void OpenSim::appendCoupledCoordinateValues (TimeSeriesTable &table, const Model &model, bool overwriteExistingColumns=true)
 Compute the values of coordinates defined by CoordinateCouplerConstraints in the model and append them to the provided TimeSeriesTable. More...
 
OSIMSIMULATION_API void OpenSim::appendCoordinateValueDerivativesAsSpeeds (TimeSeriesTable &table, const Model &model, bool overwriteExistingColumns=true)
 Compute and append the coordinate speeds in the model by taking the first derivative of the coordinate values in the provided TimeSeriesTable. More...
 

Detailed Description

These are free functions and utility classes in the Simulation library.

Function Documentation

◆ analyze()

template<typename T >
TimeSeriesTable_<T> OpenSim::analyze ( Model  model,
const TimeSeriesTable statesTable,
const TimeSeriesTable controlsTable,
const std::vector< std::string > &  outputPaths,
const TimeSeriesTable discreteVariablesTable = {} 
)

Calculate the requested outputs using the model in the problem and the provided states and controls tables.

The controls table is used to set the model's controls vector. We assume the states and controls tables contain the same time points. The output paths can be regular expressions. For example, ".*activation" gives the activation of all muscles.

The output paths must correspond to outputs that match the type provided in the template argument, otherwise they are not included in the report.

Controls missing from the controls table are given a value of 0.

If you analysis depends on the values of discrete variables in the state, you may provide those values via the optional argument "discreteVariablesTable". This table should contain column labels with the following format: <path_to_component>/<discrete_var_name>. For example, "/forceset/muscle/implicitderiv_normalized_tendon_force".

Note
The provided trajectory is not modified to satisfy kinematic constraints, but SimTK::Motions in the Model (e.g., PositionMotion) are applied. Therefore, this function expects that you've provided a trajectory that already satisfies kinematic constraints. If your provided trajectory does not satisfy kinematic constraints, many outputs will be incorrect. For example, in a model with a patella whose location is determined by a CoordinateCouplerConstraint, the length of a muscle that crosses the patella will be incorrect.
Examples:
exampleHangingMuscle.cpp.

◆ appendCoordinateValueDerivativesAsSpeeds()

OSIMSIMULATION_API void OpenSim::appendCoordinateValueDerivativesAsSpeeds ( TimeSeriesTable table,
const Model model,
bool  overwriteExistingColumns = true 
)

Compute and append the coordinate speeds in the model by taking the first derivative of the coordinate values in the provided TimeSeriesTable.

The table should contain columns with values for valid coordinates in the model. Columns that do not match a coordinate in the model are ignored. The column labels must be the full path to the coordinate values (e.g., /jointset/ground_pelvis/pelvis_tx/value).

Referenced by OpenSim::TabOpAppendCoordinateValueDerivativesAsSpeeds::operate().

◆ appendCoupledCoordinateValues()

OSIMSIMULATION_API void OpenSim::appendCoupledCoordinateValues ( TimeSeriesTable table,
const Model model,
bool  overwriteExistingColumns = true 
)

Compute the values of coordinates defined by CoordinateCouplerConstraints in the model and append them to the provided TimeSeriesTable.

The table should contain columns with values for all the independent coordinates that define the coupled coordinate. The column labels must be the full path to the coordinate values (e.g., /jointset/ground_pelvis/pelvis_tx/value).

Referenced by OpenSim::TabOpAppendCoupledCoordinateValues::operate().

◆ checkLabelsMatchModelStates()

OSIMSIMULATION_API void OpenSim::checkLabelsMatchModelStates ( const Model model,
const std::vector< std::string > &  labels 
)

Throws an exception if any label in the provided list does not match any state variable names in the model.

◆ checkOrderSystemControls()

OSIMSIMULATION_API void OpenSim::checkOrderSystemControls ( const Model model)

Throws an exception if the order of the controls in the model is not the same as the order of the actuators in the model.

◆ createControlNamesForControllerType()

template<typename T >
std::unordered_set<std::string> OpenSim::createControlNamesForControllerType ( const Model model)

Create a vector of control names based on the actuators in the model associated with any controller of type T for which appliesForce == True.

T must either be Controller or any type derived from Controller. For actuators with one control (e.g. ScalarActuator) the control name is simply the actuator name. For actuators with multiple controls, each control name is the actuator name appended by the control index (e.g. "/actuator_0").

References OpenSim::Component::getComponentList().

◆ createControlNamesFromModel() [1/2]

OSIMSIMULATION_API std::vector<std::string> OpenSim::createControlNamesFromModel ( const Model model,
std::vector< int > &  modelControlIndices 
)

Create a vector of control names based on the actuators in the model for which appliesForce == True.

For actuators with one control (e.g. ScalarActuator) the control name is simply the actuator name. For actuators with multiple controls, each control name is the actuator name appended by the control index (e.g. "/actuator_0"); modelControlIndices has length equal to the number of controls associated with actuators that apply a force (appliesForce == True). Its elements are the indices of the controls in the Model::updControls() that are associated with actuators that apply a force.

Referenced by OpenSim::analyzeMocoTrajectory().

◆ createControlNamesFromModel() [2/2]

OSIMSIMULATION_API std::vector<std::string> OpenSim::createControlNamesFromModel ( const Model model)

Same as above, but when there is no mapping to the modelControlIndices.

◆ createStateVariableNamesInSystemOrder() [1/2]

OSIMSIMULATION_API std::vector<std::string> OpenSim::createStateVariableNamesInSystemOrder ( const Model model)

The map provides the index of each state variable in SimTK::State::getY() from its each state variable path string.

Empty slots in Y (e.g., for quaternions) are ignored.

◆ createStateVariableNamesInSystemOrder() [2/2]

OSIMSIMULATION_API std::vector<std::string> OpenSim::createStateVariableNamesInSystemOrder ( const Model model,
std::unordered_map< int, int > &  yIndexMap 
)

Same as above, but you can obtain a map from the returned state variable names to the index in SimTK::State::getY() that accounts for empty slots in Y.

◆ createSyntheticIMUAccelerationSignals()

OSIMSIMULATION_API TimeSeriesTableVec3 OpenSim::createSyntheticIMUAccelerationSignals ( const Model model,
const TimeSeriesTable statesTable,
const TimeSeriesTable controlsTable,
const std::vector< std::string > &  framePaths 
)

Calculate "synthetic" acceleration signals equivalent to signals recorded from inertial measurement units (IMUs).

First, this utility computes the linear acceleration for each frame included in 'framePaths' using Frame's 'linear_acceleration' Output. Then, to mimic acceleration signals measured from IMUs, the model's gravitational acceleration vector is subtracted from the linear accelerations and the resulting accelerations are re-expressed in the bases of the associated Frames.

Note
The linear acceleration Outputs are computed using the analyze() simulation utility, and therefore the 'statesTable' and 'controlsTable' arguments must contain the same time points and we assume that the states obey any kinematic constraints in the Model.
The passed in model must have the correct mass and inertia properties included, since computing accelerations requires realizing to SimTK::Stage::Acceleration which depends on SimTK::Stage::Dynamics.

◆ createSystemControlIndexMap()

OSIMSIMULATION_API std::unordered_map<std::string, int> OpenSim::createSystemControlIndexMap ( const Model model)

The map provides the index of each control variable in the SimTK::Vector returned by Model::getControls(), using the control name as the key.

Exceptions
Exceptionif the order of actuators in the model does not match the order of controls in Model::getControls(). This is an internal error, but you may be able to avoid the error by ensuring all Actuators are in the Model's ForceSet.

◆ createSystemYIndexMap()

OSIMSIMULATION_API std::unordered_map<std::string, int> OpenSim::createSystemYIndexMap ( const Model model)

The map provides the index of each state variable in SimTK::State::getY() from its state variable path string.

◆ simulate()

OSIMSIMULATION_API SimTK::State OpenSim::simulate ( Model model,
const SimTK::State &  initialState,
double  finalTime,
bool  saveStatesFile = false 
)

Simulate a model from an initial state and return the final state.

If the model's useVisualizer flag is true, the user is repeatedly prompted to either begin simulating or quit. The provided state is not updated but the final state is returned at the end of the simulation, when finalTime is reached. Set saveStatesFile=true to save the states to a storage file as: "<model_name>_states.sto".

Examples:
example2DWalking.m.

◆ updatePre40KinematicsFilesFor40MotionType()

OSIMSIMULATION_API void OpenSim::updatePre40KinematicsFilesFor40MotionType ( const Model model,
const std::vector< std::string > &  filePaths,
std::string  suffix = "_updated" 
)

This function can be used to upgrade MOT files generated with versions before 4.0 in which some data columns are associated with coordinates that were incorrectly marked as Rotational (rather than Coupled).

Specific instances of the issue are the patella coordinate in the Rajagopal 2015 and leg6dof9musc models. In these cases, the patella will visualize incorrectly in the GUI when replaying the kinematics from the MOT file, and Static Optimization will yield incorrect results.

The new files are written to the same directories as the original files, but with the provided suffix (before the file extension). To overwrite your original files, set the suffix to an emtpty string.

If the file does not need to be updated, no new file is written.

Conversion of the data only occurs for files in degrees ("inDegrees=yes" in the header).

Do not use this function with MOT files generated by 4.0 or later; doing so will cause your data to be altered incorrectly. We do not detect whether or not your MOT file is pre-4.0.

In OpenSim 4.0, MotionTypes for Coordinates are now determined strictly by the coordinates' owning Joint. In older models, the MotionType, particularly for CustomJoints, were user- specified. That entailed in some cases, incorrectly labeling a Coordinate as being Rotational, for example, when it is in fact Coupled. For the above models, for example, the patella Coordinate had been user-specified to be Rotational, but the angle of the patella about the Z-axis of the patella body, is a spline function (e.g. coupled function) of the patella Coordinate. Thus, the patella Coordinate is not an angle measurement and is not classified as Rotational. Use this utility to remove any unit conversions from Coordinates that were incorrectly labeled as Rotational in the past. For these Coordinates only, the utility will undo the incorrect radians to degrees conversion.

◆ updatePre40KinematicsStorageFor40MotionType()

OSIMSIMULATION_API std::unique_ptr<Storage> OpenSim::updatePre40KinematicsStorageFor40MotionType ( const Model pre40Model,
const Storage kinematics 
)

Not available through scripting.

Returns
nullptr if no update is necessary.

◆ updateSocketConnecteesBySearch()

OSIMSIMULATION_API void OpenSim::updateSocketConnecteesBySearch ( Model model)

This function attempts to update the connectee path for any Socket anywhere in the model whose connectee path does not point to an existing component.

The paths are updated by searching the model for a component with the correct name. For example, a connectee path like ../../some/invalid/path/to/foo will be updated to /bodyset/foo if a Body named foo exists in the Model's BodySet. If a socket specifies a Body foo and more than one Body foo exists in the model, we emit a warning and the socket that specified foo is not altered.

This method is intended for use with models loaded from version-30516 XML files to bring them up to date with the 4.0 interface.

◆ updateStateLabels40()

OSIMSIMULATION_API void OpenSim::updateStateLabels40 ( const Model model,
std::vector< std::string > &  labels 
)

Update a vector of state labels (in place) to use post-4.0 state paths instead of pre-4.0 state names.

For example, this converts labels as follows:

  • pelvis_tilt -> /jointset/ground_pelvis/pelvis_tilt/value
  • pelvis_tilt_u -> /jointset/ground_pelvis/pelvis_tilt/speed
  • soleus.activation -> /forceset/soleus/activation
  • soleus.fiber_length -> /forceset/soleus/fiber_length This can also be used to update the column labels of an Inverse Kinematics Tool solution MOT file so that the data can be used as states. If a label does not identify a state in the model, the column label is not changed.
    Exceptions
    Exceptionif labels are not unique.

Referenced by OpenSim::TabOpUseAbsoluteStateNames::operate().