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:
ABCAbstract 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.
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.GeneralGeneral torque actuators
biosym.model.actuators.actuator_models.hill2d.Hill2DHill-type muscle model
biosym.model.actuators.actuator_models.passive_torques.PassiveTorquesPassive torques
- abstractmethod get_actuated_joints()#
Get the list of joints actuated by this actuator model.
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:
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:
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:
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:
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:
- 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)
See also
biosym.model.actuators.actuator_models.general.GeneralGeneral actuator implementation
biosym.model.actuators.actuator_models.general.GeneralMujocoMuJoCo actuator implementation
Actuator Implementations#
- class biosym.model.actuators.actuator_models.general.General(xml_root)#
Bases:
BaseActuatorGeneral 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:
- states#
List of state variable names, formatted as “torque_i” where i is the actuator index.
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
GeneralMujocoMuJoCo-specific general actuator implementation
biosym.model.actuators.actuator_models.hill2d.Hill2DHill-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.
- 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:
- get_n_actuators()#
Get the number of actuators in the model.
- Returns:
Number of actuators defined in this actuator model.
- Return type:
- 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:
- get_n_constraints(*args, **kwargs)#
Get the number of constraints defined by this actuator model.
- Returns:
Number of constraints. Default is 0.
- Return type:
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:
- 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:
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:
- 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:
GeneralGeneral 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
GeneralBase 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.
- 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:
- get_n_actuators()#
Get the number of actuators in the model.
- Returns:
Number of actuators defined in this actuator model.
- Return type:
- 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:
- get_n_constraints(*args, **kwargs)#
Get the number of constraints defined by this actuator model.
- Returns:
Number of constraints. Default is 0.
- Return type:
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:
- 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:
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:
- 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:
BaseActuatorA 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:
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:
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:
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:
BaseActuatorPassive 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:
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:
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:
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.