Hill-type Muscle Model#
Two-dimensional Hill-type muscle model for biological force generation.
- 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.