Modelling#

At a high-level, OPynSim’s modelling API is designed around three classes with distinct roles:

  • opynsim.ModelSpecification: A high-level specification of the model. This is what Python code manipulates before calling opynsim.compile() to yield…

  • opynsim.Model: A compiled read-only physics model, which can create/read/manipulate…

  • opynsim.ModelState: A single state of an opynsim.Model. This can be manipulated with Python code to do something useful with the model.

API Reference#

opynsim.import_osim_file(osim_file_path: str | os.PathLike) opynsim._core.ModelSpecification#

Returns a ModelSpecification imported from an OpenSim (.osim) file on the caller’s filesystem.

Raises:

RuntimeError – If the file cannot be found, read, or is invalid.

opynsim.compile_specification(model_specification: opynsim._core.ModelSpecification) opynsim._core.Model#

Compiles a ModelSpecification into a Model.

The compilation process:

  • Validates the ModelSpecification’s components (properties, subcomponents, and sockets), throwing an exception if the specification is invalid in some way.

  • Assembles a physics system from the validated specification, throwing an exception if the physics system cannot be assembled (e.g. if the contains impossible-to-satisfy joints, or invalid muscle definitions).

Raises:

RuntimeError – If the compilation process failed in some way. It is assumed that the provided ModelSpecification is valid.

class opynsim.Model#

Bases: object

A validated, optimized, compiled, and ready-to-simulate model of a physics system.

A Model can only be created from a ModelSpecification via the compile_specification() function. Therefore, editing a Model requires editing its associated ModelSpecification and recompiling it to create a new Model.

initial_state(self) opynsim._core.ModelState#

Returns a ModelState that represents the initial (default) state of this Model.

The initial state of a Model is dictated by its associated ModelSpecification. For example, if a translational coordinate in the specification had a default_value of 1.0 then that would be written into the ModelState returned by this function.

This function does not guarantee the returned ModelState’s ModelStateStage. Therefore, it’s recommended that callers perform any state modifications they need followed by calling realize() with a ModelStateStage that’s suitable for their desired needs (e.g. user interfaces may need ModelStateStage.REPORT).

realize(self, model_state: opynsim._core.ModelState, model_state_stage: opynsim._core.ModelStateStage) None#

Realizes model_state to the desired model_state_stage, which modifies model_state in-place.

“Realization” of the state involves taking a new set of values from the ModelState and performing computations that those new values enable. Realization is performed in-order one ModelStateStage at time. For example, ModelStateStage.POSITION is realized before ModelStateStage.VELOCITY,then ModelStateStage.DYNAMICS, and so on.

Notes

State realization is a concept that OPynSim inherited from Simbody, which has a much more comprehensive explanation of the realization process in its Simbody Theory Manual. You should read that manual if you want to know more.

set_coordinate_value(self, model_state: std::basic_string_view<char, std: :char_traits<char> >, coordinate_path: opynsim._core.ModelState, value: float) None#

Finds coordinate_path in the model and sets the corresponding state variable in model_state to value.

Changing the value of a coordinate changes model_state’s ModelStateStage to ModelStateStage.POSITION, which means you may need to use Model.realize() to re-realize the state to a later stage if you subsequently intend on doing something else with the model (e.g. for rendering).

class opynsim.ModelSpecification(*args, **kwargs)#

Bases: object

A high-level specification for an opynsim.Model.

A ModelSpecification is what Python code can manipulate, scale, and customize before passing it to opynsim.compile_specification(), which returns a readonly opynsim.Model.

Notes

OPynSim’s API design separates the specification of a model (ModelSpecification) from its validated, assembled, and optimized simulation representation (Model) to ensure that the compilation process (compile_specification()) can freeze and optimize internal datastructures at a single point in the process. This is in contrast to OpenSim, which handles both concerns with a single OpenSim::Model class, which results in edge-cases, such as incorrectly being able to edit a model after a physics system has already been assembled from it.

class opynsim.ModelState#

Bases: object

Represents a single state of a Model.

A ModelState bundles together the state variables, cache variables, and other information necessary to describe a single state of a Model. Model’s can read/manipulate ModelStates in order to opynsim.Model.realize() the state to a later stage (e.g. as part of forward integration) or read outputs values. However, ModelStates may also be created, read, and manipulated by downstream Python code and other utilities in OPynSim.

class opynsim.ModelStateStage(*values)#

Bases: Enum

Represents a stage of state realization (computation).

When calling methods like Model.realize(), a ModelState is realized in-order through each ModelStateStage, starting at the lowest stage and ending at the highest stage.

Each time a ModelState advances through a ModelStateStage, more information is available in the state. For example, after a ModelState is realized to ModelStateStage.POSITION, positional quantities such as the positions of bodies and offset frames are known, and any positional output on the associated Model can then extract that information from the ModelState.

ACCELERATION = 4#
DYNAMICS = 3#
POSITION = 1#
REPORT = 5#
TIME = 0#
VELOCITY = 2#