Actuator Models#

Overview#

Actuator Models for Biomechanical Simulation.

This module provides classes and functions for modeling different types of actuators in biomechanical systems. Actuators represent force/torque generating elements such as muscles, motors, or other active components that can produce motion in the model.

The module includes: - Base actuator classes defining the common interface - Parsers for loading actuator definitions from XML files - Specific actuator model implementations (general, Hill-type muscle, passive torques)

Examples

Load actuators from an XML file:

>>> import biosym.model.actuators.actuator_parser as parser
>>> actuators = parser.get("path/to/actuators.xml")

Access actuator properties:

>>> n_actuators = actuators.get_n_actuators()
>>> actuator_states = actuators.get_n_states()

Base Classes#

class biosym.model.actuators.base_actuator.BaseActuator(xml_root)#

Bases: ABC

Abstract base class for actuator models in biomechanical simulations.

This class defines the interface that all actuator implementations must follow. Actuators represent force/torque generating elements in the biomechanical model, such as muscles, motors, or other active components.

The base class handles common functionality like XML parsing and provides abstract methods that must be implemented by specific actuator types.

Parameters:

xml_root (xml.etree.ElementTree.Element) – Root element of the XML tree containing actuator definitions.

xml_root#

The XML root element containing actuator configuration.

Type:

xml.etree.ElementTree.Element

actuator#

The actuator object instance (implementation-specific).

Type:

object or None

Notes

Subclasses must implement all abstract methods to define the specific behavior of different actuator types (e.g., general torque actuators, Hill-type muscle models, passive torques).

See also

biosym.model.actuators.actuator_models.general.General

General torque actuators

biosym.model.actuators.actuator_models.hill2d.Hill2D

Hill-type muscle model

biosym.model.actuators.actuator_models.passive_torques.PassiveTorques

Passive torques

abstractmethod get_actuated_joints()#

Get the list of joints actuated by this actuator model.

Returns:

Names of joints that are actuated by this actuator model.

Return type:

list of str

Notes

This method must be implemented by all actuator subclasses to specify which joints in the biomechanical model are influenced by the actuators.

abstractmethod get_n_actuators()#

Get the number of actuators in the model.

Returns:

Number of actuators defined in this actuator model.

Return type:

int

Notes

This method must be implemented by all actuator subclasses to specify how many individual actuator elements are present in the model.

get_n_constraints(*args, **kwargs)#

Get the number of constraints defined by this actuator model.

Returns:

Number of constraints. Default is 0.

Return type:

int

Notes

The default implementation returns 0. Actuator subclasses that define constraints (e.g., activation dynamics, force equilibrium) should override this method to return the correct number of constraints.

abstractmethod get_n_states()#

Get the number of states associated with this actuator model.

Returns:

Number of states defined by this actuator model.

Return type:

int

Notes

The default implementation returns 0. Actuator subclasses that define internal states (e.g., muscle activation, fiber length) should override this method to return the correct number of states.

get_nnz()#

Get the number of non-zero entries in the Jacobian of the actuator model.

Returns:

Number of non-zero entries in the Jacobian. Default is 0.

Return type:

int

Notes

The default implementation returns 0. Actuator subclasses that define constraints or dynamics should override this method to return the correct number of non-zero entries in their Jacobian matrices.

process_eom(model)#

Process the equations of motion for the actuator model.

This method is called during the symbolic equation generation phase to integrate actuator dynamics into the overall system equations.

Parameters:

model (biosym.model.model.BiosymModel) – The biomechanical model containing the actuator.

Notes

The default implementation does nothing. Actuator subclasses should override this method if they need to add additional equations of motion, constraints, or symbolic relationships to the model.

Examples of when this is needed: - Muscle activation dynamics - Force-length-velocity relationships - Internal state evolution equations

abstractmethod reset()#

Reset the actuator model to its initial state.

Notes

This method is called at the beginning of simulations to ensure actuators start from a clean state. Implementations should reset any internal state variables, cached values, or dynamic properties.

The exact reset behavior depends on the specific actuator type: - Muscle models may reset activation states - Motor models may reset control states - Passive elements may reset stored energy states

Parser#

Parser for actuator model definitions from XML files.

This module provides functionality to parse XML files containing actuator definitions and instantiate the appropriate actuator model classes.

biosym.model.actuators.actuator_parser.get(file_path, body_weight=None, **kwargs)#

Parse an actuator model file and return the appropriate actuator instance.

This function reads XML files containing actuator definitions and creates the corresponding actuator model objects based on the specified type.

Parameters:
  • file_path (str or xml.etree.ElementTree.Element) – Path to the XML file containing actuator definitions, or an XML Element if the XML has already been parsed.

  • body_weight (float, optional) – Body weight for scaling actuator forces. Currently not used but may be implemented for muscle force scaling in future versions.

Returns:

An instance of the appropriate actuator model class based on the XML type specification.

Return type:

BaseActuator

Raises:

ValueError – If the actuator type specified in the XML is not recognized or supported.

Notes

Supported actuator types: - “actuator” or “general”: General torque actuators - None (MuJoCo format): Motor elements parsed from MuJoCo XML

The function automatically detects the format and actuator type from the XML structure and attributes.

Examples

Load actuators from an XML file:

>>> actuators = get("path/to/actuators.xml")
>>> n_actuators = actuators.get_n_actuators()

Load from an already parsed XML element:

>>> import xml.etree.ElementTree as ET
>>> tree = ET.parse("actuators.xml")
>>> root = tree.getroot()
>>> actuators = get(root)

Actuator Implementations#

class biosym.model.actuators.actuator_models.general.General(xml_root)#

Bases: BaseActuator

General torque actuator model for biomechanical simulations.

This class implements a simple torque actuator model where actuators directly apply torques to joints without complex dynamics. It is suitable for models where actuator dynamics are simplified or when representing idealized motor inputs.

Parameters:

xml_root (xml.etree.ElementTree.Element) – Root element of the XML tree containing actuator definitions. Expected to contain ‘general’ subelements with actuator specifications.

actuators#

Dictionary mapping actuator names to their properties parsed from XML. Each actuator entry contains attributes like name, position, etc.

Type:

dict

n_actuators#

Number of actuators defined in the model.

Type:

int

states#

List of state variable names, formatted as “torque_i” where i is the actuator index.

Type:

list of str

Notes

The general actuator model assumes: - Direct torque application to joints - No actuator dynamics (instantaneous response) - Linear mapping from actuator states to joint torques

XML Format#

The expected XML format for actuator definition:

<actuators type="general">
    <general name="actuator_1" pos="0 0 1"/>
    <general name="actuator_2" pos="1 0 0"/>
</actuators>

Examples

Create actuators from XML:

>>> import xml.etree.ElementTree as ET
>>> root = ET.fromstring(xml_string)
>>> actuators = General(root)
>>> n_act = actuators.get_n_actuators()

See also

GeneralMujoco

MuJoCo-specific general actuator implementation

biosym.model.actuators.actuator_models.hill2d.Hill2D

Hill-type muscle model

forward(states, constants, model)#

Evaluate the actuator model to compute joint torques.

This method maps actuator states (torque commands) to the appropriate joints in the biomechanical model.

Parameters:
  • states (object) – Current state values containing actuator_model attribute with torque values for each actuator.

  • constants (object) – Current constant parameter values (unused for general actuators).

  • model (biosym.model.model.BiosymModel) – The biomechanical model containing joint and force information.

Returns:

Array of joint torques with shape (n_coordinates,). Torques are placed at the indices specified by model.forces[“active_idx”].

Return type:

jax.Array

Notes

The method creates a zero array for all coordinates and fills in the actuator torques at the active joint indices. This ensures proper mapping between actuator outputs and joint inputs.

get_actuated_joints()#

Get the list of joints actuated by this actuator model.

Returns:

List of joint names that are actuated by the defined actuators. If no specific joints are defined, returns an empty list.

Return type:

list of str

get_actuators()#

Get the dictionary of actuator definitions.

Returns:

Dictionary mapping actuator names to their property dictionaries. Each property dictionary contains attributes parsed from the XML.

Return type:

dict

get_n_actuators()#

Get the number of actuators in the model.

Returns:

Number of actuators defined in this actuator model.

Return type:

int

get_n_constants()#

Get the number of constant parameters required by the actuator model.

Returns:

Number of constant parameters. Always 0 for general actuators as they have no internal parameters.

Return type:

int

get_n_constraints(*args, **kwargs)#

Get the number of constraints defined by this actuator model.

Returns:

Number of constraints. Default is 0.

Return type:

int

Notes

The default implementation returns 0. Actuator subclasses that define constraints (e.g., activation dynamics, force equilibrium) should override this method to return the correct number of constraints.

get_n_states()#

Get the number of state variables required by the actuator model.

Returns:

Number of actuator state variables, equal to the number of actuators. Each actuator contributes one torque state variable.

Return type:

int

get_nnz()#

Get the number of non-zero entries in the Jacobian of the actuator model.

Returns:

Number of non-zero entries in the Jacobian. Default is 0.

Return type:

int

Notes

The default implementation returns 0. Actuator subclasses that define constraints or dynamics should override this method to return the correct number of non-zero entries in their Jacobian matrices.

is_torque_actuator()#

Check if this is a torque-based actuator model.

Returns:

True, as general actuators directly apply torques.

Return type:

bool

process_eom(model)#

Process the equations of motion for the actuator model.

This method is called during the symbolic equation generation phase to integrate actuator dynamics into the overall system equations.

Parameters:

model (biosym.model.model.BiosymModel) – The biomechanical model containing the actuator.

Notes

The default implementation does nothing. Actuator subclasses should override this method if they need to add additional equations of motion, constraints, or symbolic relationships to the model.

Examples of when this is needed: - Muscle activation dynamics - Force-length-velocity relationships - Internal state evolution equations

reset()#

Reset the actuator model to its initial state.

Notes

For general actuators, there is no internal state to reset. This method is provided for interface compatibility.

class biosym.model.actuators.actuator_models.general.GeneralMujoco(actuator_list)#

Bases: General

General actuator model specifically for MuJoCo-format XML files.

This class extends the General actuator class to handle actuator definitions in MuJoCo XML format, which uses ‘motor’ elements instead of ‘general’ elements.

Parameters:

actuator_list (list of xml.etree.ElementTree.Element) – List of XML elements representing motor actuators from MuJoCo format.

Notes

MuJoCo format differences: - Uses ‘motor’ elements instead of ‘general’ - May have different attribute naming conventions - Handles MuJoCo-specific actuator properties

See also

General

Base general actuator implementation

forward(states, constants, model)#

Evaluate the actuator model to compute joint torques.

This method maps actuator states (torque commands) to the appropriate joints in the biomechanical model.

Parameters:
  • states (object) – Current state values containing actuator_model attribute with torque values for each actuator.

  • constants (object) – Current constant parameter values (unused for general actuators).

  • model (biosym.model.model.BiosymModel) – The biomechanical model containing joint and force information.

Returns:

Array of joint torques with shape (n_coordinates,). Torques are placed at the indices specified by model.forces[“active_idx”].

Return type:

jax.Array

Notes

The method creates a zero array for all coordinates and fills in the actuator torques at the active joint indices. This ensures proper mapping between actuator outputs and joint inputs.

get_actuated_joints()#

Get the list of joints actuated by this actuator model.

Returns:

List of joint names that are actuated by the defined actuators. If no specific joints are defined, returns an empty list.

Return type:

list of str

get_actuators()#

Get the dictionary of actuator definitions.

Returns:

Dictionary mapping actuator names to their property dictionaries. Each property dictionary contains attributes parsed from the XML.

Return type:

dict

get_n_actuators()#

Get the number of actuators in the model.

Returns:

Number of actuators defined in this actuator model.

Return type:

int

get_n_constants()#

Get the number of constant parameters required by the actuator model.

Returns:

Number of constant parameters. Always 0 for general actuators as they have no internal parameters.

Return type:

int

get_n_constraints(*args, **kwargs)#

Get the number of constraints defined by this actuator model.

Returns:

Number of constraints. Default is 0.

Return type:

int

Notes

The default implementation returns 0. Actuator subclasses that define constraints (e.g., activation dynamics, force equilibrium) should override this method to return the correct number of constraints.

get_n_states()#

Get the number of state variables required by the actuator model.

Returns:

Number of actuator state variables, equal to the number of actuators. Each actuator contributes one torque state variable.

Return type:

int

get_nnz()#

Get the number of non-zero entries in the Jacobian of the actuator model.

Returns:

Number of non-zero entries in the Jacobian. Default is 0.

Return type:

int

Notes

The default implementation returns 0. Actuator subclasses that define constraints or dynamics should override this method to return the correct number of non-zero entries in their Jacobian matrices.

is_torque_actuator()#

Check if this is a torque-based actuator model.

Returns:

True, as general actuators directly apply torques.

Return type:

bool

process_eom(model)#

Process the equations of motion for the actuator model.

This method is called during the symbolic equation generation phase to integrate actuator dynamics into the overall system equations.

Parameters:

model (biosym.model.model.BiosymModel) – The biomechanical model containing the actuator.

Notes

The default implementation does nothing. Actuator subclasses should override this method if they need to add additional equations of motion, constraints, or symbolic relationships to the model.

Examples of when this is needed: - Muscle activation dynamics - Force-length-velocity relationships - Internal state evolution equations

reset()#

Reset the actuator model to its initial state.

Notes

For general actuators, there is no internal state to reset. This method is provided for interface compatibility.

class biosym.model.actuators.actuator_models.hill2d.Hill2d(joints_dict, muscles_dict, defaults)#

Bases: BaseActuator

A reimplementation of the 2D Hill muscle model as in gait2d. This model is purpose-built for 2D models with rotational joints. It is also purpose-built for direct collocation, and needs adjustments to work in a forward simulation setting, and might not perform well in DL scenarios.

Why to not optimize for e as in BioMacSimToolbox: Activating e every 4th node (dt=0.01): c = 0.25 -> a = [0,1,0.66,0.33] - average: 0.5 Activating e every 2nd node (dt=0.01): c = 0.5 -> a = [0.66,1,0.66,1] - average: 0.83 Activating e continuously (dt=0.01), e = 0.5 -> c = 0.25 -> a = 0.5 - average: 0.5 Activating e continuously (dt=0.01), e = 0.707 -> c = 0.5 -> a = 0.707 - average: 0.707 –> Lower than when jittering e Even worse: Activating e every 2nd node (dt=0.02): c = 0.5 -> a = [0, *2, 1.33, *0.67, 0.44,*1.67, 0.89, *1.33, 0.88] - average: 1.02 Activating e strategically 1 (dt=0.02): c = 0.375 -> a = [0, *2, 1.33, 0.87, 0.58, *1.62, 1.07, 0.71, *1.29] - average: 1.05 –> This must be super bad for IPOPT

So i think all we need to account for activation / deactivation dynamics is that the dot{a} is limited by [1/t_act, 1/t_deact]

How to optimize for e then?

Do not: https://www.biorxiv.org/content/10.1101/2025.01.30.635759v1.full.pdf But if you really want to: a[t+1] = e[t] + (a[t] - e[t]) * np.exp(-(e[t]/Tact+(1-e[t])/Tdeact)*t)

Recommendation: Do not optimize for e at all, do not allow a>1, and limit dot{a} as stated here: a[t+1,max] = 1 + ( a[t] - 1 ) * exp(-dt/Tact) # Exponential decay to 1 a[t+1,min] = (a[t]) * exp(-dt/Tdeact) # Exponential decay to 0

So the constraint would be linear violation of this term

constraints(states, constants, model, settings)#
forward(states, constants, model)#
get_actuated_joints()#

Returns the list of actuated joints.

get_actuators()#
get_n_actuators()#

Returns the number of actuators in the model.

get_n_constants()#
get_n_constraints(model, settings)#

Get the number of constraints defined by this actuator model.

Returns:

Number of constraints. Default is 0.

Return type:

int

Notes

The default implementation returns 0. Actuator subclasses that define constraints (e.g., activation dynamics, force equilibrium) should override this method to return the correct number of constraints.

get_n_constraints_per_node()#
get_n_states()#

Get the number of states associated with this actuator model.

Returns:

Number of states defined by this actuator model.

Return type:

int

Notes

The default implementation returns 0. Actuator subclasses that define internal states (e.g., muscle activation, fiber length) should override this method to return the correct number of states.

get_nnz(model, settings)#

Get the number of non-zero entries in the Jacobian of the actuator model.

Returns:

Number of non-zero entries in the Jacobian. Default is 0.

Return type:

int

Notes

The default implementation returns 0. Actuator subclasses that define constraints or dynamics should override this method to return the correct number of non-zero entries in their Jacobian matrices.

jacobian(states, constants, model, settings)#
muscle_equations(states, constants, model)#
plot(states, model, mode, ax, **kwargs)#

Plots the muscles in the model using precomputed EOM muscle geometry. Each muscle is drawn following its anatomically correct path with color indicating activation level: blue (unused) to red (fully activated).

Parameters:
  • states (object or list) – The state(s) of the model containing muscle activations and positions

  • model (object) – The model object containing muscle and body definitions

  • mode (str) – The mode of the plot “init” or “update”

  • ax (matplotlib.axes.Axes) – The axes object to plot on

  • **kwargs (dict) – Additional plotting parameters including: - case : str, “2D” or “3D” (default “3D”) - non_zero_axes : list, required for 2D case - frame : int, required for update mode - plot_objects : tuple, required for update mode

process_eom(model)#

Build the muscle attachment and path computation functions using symbolic variables. This creates fast compiled functions for muscle visualization with proper reference frames.

reset()#

Resets the actuator behaviour.

class biosym.model.actuators.actuator_models.passive_torques.PassiveTorques(joints_dict)#

Bases: BaseActuator

Passive torque actuator model.

forward(states, constants, model)#
get_actuated_joints()#

Returns the list of actuated joints.

get_n_actuators()#

Returns the number of actuators in the model.

get_n_constants()#
get_n_constraints(*args, **kwargs)#

Get the number of constraints defined by this actuator model.

Returns:

Number of constraints. Default is 0.

Return type:

int

Notes

The default implementation returns 0. Actuator subclasses that define constraints (e.g., activation dynamics, force equilibrium) should override this method to return the correct number of constraints.

get_n_states()#

Get the number of states associated with this actuator model.

Returns:

Number of states defined by this actuator model.

Return type:

int

Notes

The default implementation returns 0. Actuator subclasses that define internal states (e.g., muscle activation, fiber length) should override this method to return the correct number of states.

get_nnz()#

Get the number of non-zero entries in the Jacobian of the actuator model.

Returns:

Number of non-zero entries in the Jacobian. Default is 0.

Return type:

int

Notes

The default implementation returns 0. Actuator subclasses that define constraints or dynamics should override this method to return the correct number of non-zero entries in their Jacobian matrices.

process_eom(model)#

Process the equations of motion for the actuator model.

This method is called during the symbolic equation generation phase to integrate actuator dynamics into the overall system equations.

Parameters:

model (biosym.model.model.BiosymModel) – The biomechanical model containing the actuator.

Notes

The default implementation does nothing. Actuator subclasses should override this method if they need to add additional equations of motion, constraints, or symbolic relationships to the model.

Examples of when this is needed: - Muscle activation dynamics - Force-length-velocity relationships - Internal state evolution equations

reset()#

Resets the actuator behaviour.