McKibben UMArm¶
The McKibbenActuatedUMArm system models the UMArm as a spatial articulated
chain composed with a direct-pressure ArticulatedMcKibbenActuator. Body dynamics and
actuator geometry have independent immutable parameter objects. Cached robot
parameters are kept outside the Python wheel under assets/robot_parameters/
in the source repository; the convenience factory splits the existing cache
format internally.
ArticulatedMcKibbenActuator is specifically a spatial articulated transmission: its
grouped fixed/moving attachments span two-axis joint pairs and depend on the
host's kinematic frames. It is not installed on PCS or GVS rods. Continuum
models can use threadlike muscle or equivalent pressure-chamber coordinates;
generalizing the full McKibben attachment geometry would require a separate
continuum transmission contract.
The cached MuJoCo scene placement is normalized to the SoRoMoX base convention: the root is placed at the origin and the proximal physical segment points along positive x.
Usage¶
from pathlib import Path
import jax.numpy as jnp
from soromox.systems import McKibbenActuatedUMArm
params_path = Path("assets/robot_parameters/mckibben_umarm/reference_parameters.npz")
robot = McKibbenActuatedUMArm.from_cached_parameters(params_path)
q = jnp.zeros(robot.num_dofs)
p = jnp.zeros(robot.num_actuators)
actuator = robot.actuators[0]
lengths = actuator.effective_lengths(q)
segments = actuator.segments(robot, q)
forces = actuator.axial_forces(q, p)
tau = robot.actuation_force(q, p)
Manual construction keeps body and actuator parameters explicit:
from soromox.actuation import ArticulatedMcKibbenActuator
from soromox.systems import McKibbenActuatedUMArmParams
body_params = McKibbenActuatedUMArmParams.from_cached_npz(params_path)
actuator = ArticulatedMcKibbenActuator.from_cached_npz(params_path)
robot = McKibbenActuatedUMArm(body_params, actuator=actuator)
McKibben actuator coordinates are pressure-normalized volume coordinates,
so pressure is the direct work-conjugate effort. The analytic moment matrix is the transpose of the coordinate Jacobian and retains the cache's group and channel ordering.
For actuator-aware visualization, use UMArmViserRenderer:
from soromox.rendering import UMArmViserRenderer
renderer = UMArmViserRenderer(robot, actuator_color_mode="pressure")
renderer.show(q, actuator_inputs=p)
API Reference¶
soromox.systems.articulated.mckibben_actuated_umarm
¶
McKibben-actuated UMArm articulated system.
This module implements the UMArm body as a SoRoMoX articulated system composed
with :class:soromox.actuation.ArticulatedMcKibbenActuator. The UMArm is a
pneumatically driven rigid-soft hybrid arm introduced by Zuo, Han, Li, Jamal,
and Bruder in "UMArm: Untethered, Modular, Portable, Soft Pneumatic Arm",
arXiv:2505.11476, https://doi.org/10.48550/arXiv.2505.11476.
The body specialization retains UMArm-specific rotor armature and cached-model construction. McKibben geometry, actuator coordinates, moment matrices, axial forces, and rendering geometry live on the installed actuator.
McKibbenActuatedUMArm
¶
McKibbenActuatedUMArm(params: McKibbenActuatedUMArmParams, *, actuator: ArticulatedMcKibbenActuator, passive_elements: PassiveElement | tuple[PassiveElement, ...] | None = (), **kwargs: Any)
Bases: ArticulatedSoftRobot
flowchart TD
soromox.systems.articulated.mckibben_actuated_umarm.McKibbenActuatedUMArm[McKibbenActuatedUMArm]
soromox.systems.articulated.articulated_soft_robot.ArticulatedSoftRobot[ArticulatedSoftRobot]
soromox.systems.soft_robot.SoftRobot[SoftRobot]
soromox.systems.dynamical_system.DynamicalSystem[DynamicalSystem]
soromox.systems.articulated.articulated_soft_robot.ArticulatedSoftRobot --> soromox.systems.articulated.mckibben_actuated_umarm.McKibbenActuatedUMArm
soromox.systems.soft_robot.SoftRobot --> soromox.systems.articulated.articulated_soft_robot.ArticulatedSoftRobot
soromox.systems.dynamical_system.DynamicalSystem --> soromox.systems.soft_robot.SoftRobot
click soromox.systems.articulated.mckibben_actuated_umarm.McKibbenActuatedUMArm href "" "soromox.systems.articulated.mckibben_actuated_umarm.McKibbenActuatedUMArm"
click soromox.systems.articulated.articulated_soft_robot.ArticulatedSoftRobot href "" "soromox.systems.articulated.articulated_soft_robot.ArticulatedSoftRobot"
click soromox.systems.soft_robot.SoftRobot href "" "soromox.systems.soft_robot.SoftRobot"
click soromox.systems.dynamical_system.DynamicalSystem href "" "soromox.systems.dynamical_system.DynamicalSystem"
Spatial UMArm with rigid links and composable McKibben actuation.
The arm is represented as a 12-DOF serial articulated chain, where each
universal joint contributes two one-DOF revolute joints. The required
:class:~soromox.actuation.ArticulatedMcKibbenActuator maps pressure inputs
to generalized joint torques through work-conjugate volume coordinates.
This keeps the UMArm body dynamics separate from the pneumatic transmission
while preserving the original analytic model and channel ordering.
References
Zuo, R., Han, D. H., Li, R., Jamal, S., & Bruder, D. (2025). UMArm: Untethered, Modular, Portable, Soft Pneumatic Arm. arXiv:2505.11476. https://doi.org/10.48550/arXiv.2505.11476
Attributes:
| Name | Type | Description |
|---|---|---|
params |
McKibbenActuatedUMArmParams
|
Typed articulated-body and armature parameters. |
joint_armature |
Array
|
Per-joint rotor armature added to dense inertia and the
articulated-body recursion, shape |
actuators |
tuple[Actuator, ...]
|
One-element tuple containing the installed McKibben actuator. Its parameters own moving/fixed attachment points, effective-length offsets, thread lengths, fiber turns, and joint-pair indices. |
num_segments |
int
|
Number of physical UMArm segments. |
num_mckibben_groups |
int
|
Number of universal-joint actuator groups. |
Initialize a UMArm body with one McKibben actuator.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
params
|
McKibbenActuatedUMArmParams
|
UMArm body dynamics and joint-armature parameters. |
required |
actuator
|
ArticulatedMcKibbenActuator
|
McKibben pressure actuator installed on the body. |
required |
passive_elements
|
PassiveElement | tuple[PassiveElement, ...] | None
|
Optional independent passive mechanics. |
()
|
**kwargs
|
Any
|
Additional arguments forwarded to
:class: |
{}
|
Raises:
| Type | Description |
|---|---|
TypeError
|
If the body or actuator parameter types are invalid. |
tangent_eps
property
¶
Epsilon value for Lie algebra tangent computations.
Returns:
| Name | Type | Description |
|---|---|---|
Array |
Array
|
Epsilon value for Lie algebra tangent computations. |
actuator_input_metadata
property
¶
actuator_input_metadata: tuple[ActuatorMetadata, ...]
Metadata groups in the same order used to concatenate controls.
supports_articulated_tendon_routing
property
¶
The generalized coordinates form a serial articulated joint chain.
base_transform
property
¶
Return the homogeneous transform represented by base_pose.
Planar robots consume [theta, x, y] and return an SE(2) matrix with
shape (3, 3). Spatial robots consume
[qw, qx, qy, qz, x, y, z] and return an SE(3) matrix with shape
(4, 4). Spatial quaternions are scalar-first Hamilton quaternions.
from_cached_parameters
classmethod
¶
from_cached_parameters(path: str | Path, **kwargs: Any) -> McKibbenActuatedUMArm
Build the complete UMArm from an existing cached parameter file.
The cache schema remains unchanged. Body and actuator fields are split into their respective immutable parameter objects during construction.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
path
|
str | Path
|
Path to a UMArm |
required |
**kwargs
|
Any
|
Additional arguments forwarded to the constructor. |
{}
|
Returns:
| Type | Description |
|---|---|
McKibbenActuatedUMArm
|
A UMArm with the cached body and McKibben actuator installed. |
inertia_matrix
¶
Return dense generalized inertia including rotor armature.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
q
|
Array
|
Joint coordinates with shape |
required |
Returns:
| Type | Description |
|---|---|
Array
|
Symmetric inertia matrix with shape |
with_params
¶
with_params(params: McKibbenActuatedUMArmParams) -> McKibbenActuatedUMArm
Replace body and armature parameters while preserving the actuator.
forward_dynamics
¶
Compute state-space forward dynamics.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
t
|
Array
|
Current time, shape |
required |
y
|
Array
|
State vector |
required |
actuation_args
|
tuple | None
|
Optional actuation tuple:
- |
None
|
Returns:
| Type | Description |
|---|---|
Array
|
State derivative |
Raises:
| Type | Description |
|---|---|
ValueError
|
If |
rollout_to
¶
rollout_to(initial_state: SystemState, u: Array | None = None, tau_ext: Array | None = None, environment_model: Callable[[SystemState], tuple[Array | None, Any | None]] | None = None, t1: float | Array = 10.0, solver_dt: float | Array = 0.0001, save_dt: float | Array | None = 0.01, save_ts: Array | None = None, solver: AbstractSolver | None = None, stepsize_controller: AbstractStepSizeController | None = ConstantStepSize(), max_steps: int | None = None) -> SystemState
Roll out the system dynamics in open loop using Diffrax.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
initial_state
|
SystemState
|
Dataclass holding the initial time, system state vector (y), optional actuation (u), and optional control state. |
required |
u
|
Array | None
|
Constant actuation to apply throughout the rollout. If not provided,
falls back to |
None
|
tau_ext
|
Array | None
|
External forces/torques applied to the system (broadcast as constant). |
None
|
environment_model
|
Callable[[SystemState], tuple[Array | None, Any | None]] | None
|
Optional callable that accepts a |
None
|
t1
|
float | Array
|
Final time of the simulation, included in the saved trajectory. |
10.0
|
solver_dt
|
float | Array
|
Time step for the solver. |
0.0001
|
save_dt
|
float | Array | None
|
Time interval at which to save the solution when |
0.01
|
save_ts
|
Array | None
|
Explicit time points to be saved in the output. Must be within
[initial_state.t, t1]. Falls back to |
None
|
solver
|
AbstractSolver | None
|
Solver to use for the ODE integration. |
None
|
stepsize_controller
|
AbstractStepSizeController | None
|
Stepsize controller for the solver. |
ConstantStepSize()
|
max_steps
|
int | None
|
Maximum number of steps for the solver. |
None
|
Returns:
| Type | Description |
|---|---|
SystemState
|
SystemState PyTree containing time samples, system state trajectory, |
SystemState
|
actuation at each saved step, (optionally) the control state |
SystemState
|
trajectory, and (optionally) the environment state trajectory if |
SystemState
|
|
SystemState
|
leading time dimension aligned with |
rollout_closed_loop_to
¶
rollout_closed_loop_to(initial_state: SystemState, controller: Callable[[SystemState], tuple[Array, Any | None]], tau_ext: Array | None = None, environment_model: Callable[[SystemState], tuple[Array | None, Any | None]] | None = None, t1: float | Array = 10.0, solver_dt: float | Array = 0.0001, save_dt: float | Array = 0.01, save_ts: Array | None = None, solver: AbstractSolver | None = None, stepsize_controller: AbstractStepSizeController | None = ConstantStepSize(), max_steps: int | None = None) -> SystemState
Roll out the system dynamics in closed loop using Diffrax.
The provided controller is queried at every integration step with the current
system state (and optional control_state). Its actuation output is added to any
feed-forward actuation contained in initial_state.u.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
initial_state
|
SystemState
|
Dataclass holding the initial time, system state vector (y), optional actuation (u), and optional control state. |
required |
controller
|
Callable[[SystemState], tuple[Array, Any | None]]
|
Callable that accepts a |
required |
tau_ext
|
Array | None
|
External forces/torques applied to the system (broadcast as constant). |
None
|
environment_model
|
Callable[[SystemState], tuple[Array | None, Any | None]] | None
|
Optional callable that accepts a |
None
|
t1
|
float | Array
|
Final time of the simulation, included in the saved trajectory. |
10.0
|
solver_dt
|
float | Array
|
Time step for the solver. |
0.0001
|
save_dt
|
float | Array
|
Time interval at which to save the solution when |
0.01
|
save_ts
|
Array | None
|
Explicit time points to be saved in the output. Must be within
[initial_state.t, t1]. Falls back to |
None
|
solver
|
AbstractSolver | None
|
Solver to use for the ODE integration. |
None
|
stepsize_controller
|
AbstractStepSizeController | None
|
Stepsize controller for the solver. |
ConstantStepSize()
|
max_steps
|
int | None
|
Maximum number of steps for the solver. |
None
|
Returns:
| Type | Description |
|---|---|
SystemState
|
SystemState PyTree containing time samples, system state trajectory, |
SystemState
|
actuation at each saved step, controller state trajectory, and |
SystemState
|
(optionally) the environment state trajectory if |
SystemState
|
|
SystemState
|
leading time dimension aligned with |
rollout_discrete_closed_loop_to
¶
rollout_discrete_closed_loop_to(initial_state: SystemState, controller: Callable[[SystemState], tuple[Array, Any | None]], tau_ext: Array | None = None, environment_model: Callable[[SystemState], tuple[Array | None, Any | None]] | None = None, duration: float = 10.0, solver_dt: float | Array = 0.0001, control_dt: float = 0.01, save_dt: float = 0.01, solver: AbstractSolver | None = None, stepsize_controller: AbstractStepSizeController | None = ConstantStepSize(), max_steps: int | None = None) -> SystemState
Roll out the system in discrete-time closed loop.
The controller is evaluated every control_dt seconds. Between control
evaluations the actuation is held constant and the system is integrated
with Diffrax (equivalent to repeatedly calling rollout_to over each
control interval).
The controller signature mirrors rollout_closed_loop_to. If it returns a
control_state_dot and initial_state.control_state is provided, the
control state is advanced with a forward-Euler step over the control period;
otherwise the control state is held constant between controller calls.
The rollout uses a regular time grid. For static tracing/compilation the
following constraints are enforced:
- duration is an integer multiple of control_dt.
- control_dt is an integer multiple of save_dt.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
initial_state
|
SystemState
|
initial time/state (and optional feedforward actuation/control state). |
required |
controller
|
Callable[[SystemState], tuple[Array, Any | None]]
|
callable returning |
required |
tau_ext
|
Array | None
|
constant external wrench/force applied during the rollout. |
None
|
environment_model
|
Callable[[SystemState], tuple[Array | None, Any | None]] | None
|
Optional callable returning
|
None
|
duration
|
float
|
simulation duration in seconds. |
10.0
|
solver_dt
|
float | Array
|
initial step size for the solver. |
0.0001
|
control_dt
|
float
|
sampling period for the controller. Must be positive. |
0.01
|
save_dt
|
float
|
save interval. Must be positive and evenly divide |
0.01
|
solver
|
AbstractSolver | None
|
Diffrax solver. |
None
|
stepsize_controller
|
AbstractStepSizeController | None
|
Diffrax stepsize controller. |
ConstantStepSize()
|
max_steps
|
int | None
|
maximum solver steps. |
None
|
Returns:
| Type | Description |
|---|---|
SystemState
|
SystemState PyTree containing time samples, system state trajectory, |
SystemState
|
actuation at each saved step, controller state trajectory, and |
SystemState
|
(optionally) the environment state trajectory if |
SystemState
|
|
SystemState
|
leading time dimension aligned with the regular save grid. |
precompute
¶
Optional hook for refreshing state-independent cached quantities.
Subclasses with cached mass, stiffness, damping, basis, or quadrature data can override this method and call it during initialization. Models without such caches can inherit this no-op implementation.
with_actuator_params
¶
with_actuator_params(index: int, params) -> SoftRobot
Return a robot with one actuator's complete parameter object replaced.
update_actuator_params
¶
update_actuator_params(index: int, **updates) -> SoftRobot
Return a robot with selected fields of one actuator's params replaced.
with_passive_element_params
¶
with_passive_element_params(index: int, params) -> SoftRobot
Return a robot with one passive element's complete params replaced.
update_passive_element_params
¶
update_passive_element_params(index: int, **updates) -> SoftRobot
Return a robot with selected passive-element parameter fields replaced.
cross_section_geometry
¶
Return circular cross-section metadata for visualization.
forward_kinematics
¶
Compute the forward kinematics at a point s along the robot.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
q
|
Array
|
Generalized coordinates of shape (num_dofs,). |
required |
s
|
Array
|
Position parameter along the robot structure. The meaning depends on the specific robot type: - For continuum robots (PCS, PlanarPCS): arc-length in [0, L_total] - For articulated robots (Pendulum): can be link index or fraction |
required |
Returns:
| Name | Type | Description |
|---|---|---|
chi |
Array
|
Pose at point s. The shape and meaning depend on the robot type: - For 3D robots (PCS): SE(3) transformation matrix, shape (4, 4) - For planar robots (PlanarPCS, Pendulum): [theta, x, y], shape (3,) |
forward_kinematics_tips
¶
Compute SE(3) frames at all link tips.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
q
|
Array
|
Joint coordinates, shape |
required |
Returns:
| Type | Description |
|---|---|
Array
|
Tip frames, shape |
forward_kinematics_batched
¶
Compute the forward kinematics at multiple points along the robot.
Default implementation uses vmap over forward_kinematics. Subclasses may override this for more efficient batch computation.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
q
|
Array
|
Generalized coordinates of shape (num_dofs,). |
required |
s_ps
|
Array
|
Array of position parameters, shape (N,). |
required |
Returns:
| Name | Type | Description |
|---|---|---|
chi_ps |
Array
|
Poses at all points, shape depends on robot type. |
forward_kinematics_arc_length_derivative
¶
Compute the arc-length derivative of the forward kinematics at s.
The returned tangent has the same shape and representation as
forward_kinematics(q, s).
forward_kinematics_and_arc_length_derivative
¶
Compute forward kinematics and its arc-length derivative at s.
Subclasses can override the protected hook to share intermediate
kinematic quantities between the primal pose and d pose / ds.
jacobian
¶
Compute the Jacobian of the forward kinematics at a point s along the robot.
The Jacobian maps configuration space velocities to operational space (Cartesian/task space) velocities at point s.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
q
|
Array
|
Generalized coordinates of shape (num_dofs,). |
required |
s
|
Array
|
Position parameter along the robot structure. |
required |
Returns:
| Name | Type | Description |
|---|---|---|
J |
Array
|
Jacobian matrix of shape (n_pose_dim, num_dofs), where n_pose_dim depends on the robot type: - For 3D robots (PCS): 6 (angular velocity + linear velocity) - For planar robots (PlanarPCS, Pendulum): 3 (omega_z, v_x, v_y) |
jacobian_tips
¶
Compute spatial Jacobians at all link tips.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
q
|
Array
|
Joint coordinates, shape |
required |
Returns:
| Type | Description |
|---|---|
Array
|
Tip Jacobians, shape |
jacobian_batched
¶
Compute the Jacobian at multiple points along the robot.
Default implementation uses vmap over jacobian. Subclasses may override this for more efficient batch computation.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
q
|
Array
|
Generalized coordinates of shape (num_dofs,). |
required |
s_ps
|
Array
|
Array of position parameters, shape (N,). |
required |
Returns:
| Name | Type | Description |
|---|---|---|
J_ps |
Array
|
Jacobians at all points, shape (N, n_pose_dim, num_dofs). |
jacobian_arc_length_derivative
¶
Compute the arc-length derivative of the Jacobian at s.
The returned derivative has the same shape and frame convention as
jacobian(q, s).
jacobian_and_arc_length_derivative
¶
Compute the Jacobian and its arc-length derivative at s.
Returns:
| Name | Type | Description |
|---|---|---|
J |
Array
|
Jacobian matrix of shape (n_pose_dim, num_dofs). |
Js |
Array
|
Arc-length derivative of the Jacobian with the same shape as |
jacobian_and_time_derivative
¶
Compute the Jacobian and its time derivative at a point s along the robot.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
q
|
Array
|
Generalized coordinates of shape (num_dofs,). |
required |
qd
|
Array
|
Generalized velocities of shape (num_dofs,). |
required |
s
|
Array
|
Position parameter along the robot structure. |
required |
Returns:
| Name | Type | Description |
|---|---|---|
J |
Array
|
Jacobian matrix of shape (n_pose_dim, num_dofs). |
Jd |
Array
|
Time derivative of the Jacobian, shape (n_pose_dim, num_dofs). |
jacobian_and_time_derivative_batched
¶
Compute the Jacobian and its derivative at multiple points along the robot.
Default implementation uses vmap over jacobian_and_time_derivative. Subclasses may override this for more efficient batch computation.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
q
|
Array
|
Generalized coordinates of shape (num_dofs,). |
required |
qd
|
Array
|
Generalized velocities of shape (num_dofs,). |
required |
s_ps
|
Array
|
Array of position parameters, shape (N,). |
required |
Returns:
| Name | Type | Description |
|---|---|---|
J_ps |
Array
|
Jacobians at all points, shape (N, n_pose_dim, num_dofs). |
Jd_ps |
Array
|
Jacobian time derivatives at all points, shape (N, n_pose_dim, num_dofs). |
jacobian_bodyframe
¶
Compute the body-frame Jacobian at a point s along the robot.
The default implementation converts the public inertial-frame Jacobian to the local pose frame using the rotation-only convention used by the dynamics integrands.
jacobian_bodyframe_batched
¶
Compute body-frame Jacobians at multiple points along the robot.
jacobian_and_time_derivative_bodyframe
¶
Compute a body-frame Jacobian and its time derivative at s.
The default differentiates jacobian_bodyframe with respect to the
generalized coordinates.
jacobian_and_time_derivative_bodyframe_batched
¶
jacobian_and_time_derivative_bodyframe_batched(q: Array, qd: Array, s_ps: Array) -> tuple[Array, Array]
Compute body-frame Jacobians and time derivatives at many points.
integration_kinematics
¶
Evaluate poses, body-frame Jacobians, and Jacobian derivatives at interior integration nodes.
The default implementation is intentionally unfused. It samples
integration_points[..., 1:-1] for every segment, maps normalized
nodes to arclength, and calls the public kinematics/Jacobian APIs.
Subclasses can override this method with a fused implementation.
Returns:
| Type | Description |
|---|---|
Array
|
Tuple |
Array
|
|
coriolis_matrix
¶
Compute a Christoffel-consistent dense Coriolis matrix.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
q
|
Array
|
Joint coordinates, shape |
required |
qd
|
Array
|
Joint velocities, shape |
required |
Returns:
| Type | Description |
|---|---|
Array
|
Coriolis matrix, shape |
damping_matrix
¶
Return the viscous joint damping matrix.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
q
|
Array
|
Joint coordinates, shape |
required |
Returns:
| Type | Description |
|---|---|
Array
|
Damping matrix, shape |
stiffness_matrix
¶
Return the linear joint stiffness matrix.
Returns:
| Type | Description |
|---|---|
Array
|
Stiffness matrix, shape |
elastic_force
¶
Compute generalized elastic joint forces.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
q
|
Array
|
Joint coordinates, shape |
required |
Returns:
| Type | Description |
|---|---|
Array
|
Elastic force vector, shape |
gravitational_force
¶
Compute the gravitational force.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
q
|
Array
|
Generalized coordinates of shape (num_dofs,). |
required |
Returns:
| Name | Type | Description |
|---|---|---|
G |
Array
|
Gravitational force of shape (num_dofs,). |
potential_force
¶
Compute the total conservative generalized force.
This is the sum of gravitational and elastic forces.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
q
|
Array
|
Generalized coordinates of shape (num_dofs,). |
required |
Returns:
| Name | Type | Description |
|---|---|---|
tau_pot |
Array
|
Potential force of shape (num_dofs,). |
actuator_coordinates
¶
Return all work-conjugate actuator coordinates in control order.
actuator_velocities
¶
Return all actuator-coordinate velocities in control order.
actuation_matrix
¶
Return the concatenated transmission moment matrix.
actuator_efforts
¶
Map ordered user controls to ordered work-conjugate efforts.
actuation_force
¶
Return generalized actuation force A(q) @ effort.
passive_elastic_force
¶
Return the sum of installed passive conservative forces.
passive_damping_matrix
¶
Return the sum of installed passive damping matrices.
passive_elastic_energy
¶
Return the sum of installed passive elastic energies.
actuator_visual_layers
¶
Return semantic active and passive actuator geometry for renderers.
kinetic_energy
¶
Compute the kinetic energy of the system.
Default implementation: T = 0.5 * qd^T * M(q) * qd
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
q
|
Array
|
Generalized coordinates of shape (num_dofs,). |
required |
qd
|
Array
|
Generalized velocities of shape (num_dofs,). |
required |
Returns:
| Name | Type | Description |
|---|---|---|
T |
Array
|
Kinetic energy (scalar). |
gravitational_energy
¶
Compute the gravitational potential energy of the system.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
q
|
Array
|
Generalized coordinates of shape (num_dofs,). |
required |
Returns:
| Name | Type | Description |
|---|---|---|
U_g |
Array
|
Gravitational potential energy (scalar). |
elastic_energy
¶
Compute the elastic potential energy stored in the system.
Default implementation: U_el = 0.5 * q^T * K * q
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
q
|
Array
|
Generalized coordinates of shape (num_dofs,). |
required |
Returns:
| Name | Type | Description |
|---|---|---|
U_el |
Array
|
Elastic potential energy (scalar). |
potential_energy
¶
Compute the total potential energy of the system.
This is the sum of gravitational and elastic energy.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
q
|
Array
|
Generalized coordinates of shape (num_dofs,). |
required |
Returns:
| Name | Type | Description |
|---|---|---|
U |
Array
|
Total potential energy (scalar). |
total_energy
¶
Compute the total energy of the system.
This is the sum of kinetic and potential energy.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
q
|
Array
|
Generalized coordinates of shape (num_dofs,). |
required |
qd
|
Array
|
Generalized velocities of shape (num_dofs,). |
required |
Returns:
| Name | Type | Description |
|---|---|---|
E |
Array
|
Total energy (scalar). |
dynamics_terms
¶
Return forward-dynamics terms (M, Cqd, G).
Cqd is the convective force vector C(q, qd) @ qd. The default
implementation is intentionally unfused and calls the public matrix and
force APIs separately. Overrides must keep M and Cqd
energy-consistent with inertia_matrix and coriolis_matrix.
classify_segment
¶
Determine which link contains an arc-length position.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
s
|
Array
|
Arc-length position along the serial chain. |
required |
Returns:
| Type | Description |
|---|---|
Array
|
Tuple |
Array
|
arc length within that link. |
forward_kinematics_joints
¶
Compute SE(3) frames at all joint origins.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
q
|
Array
|
Joint coordinates, shape |
required |
Returns:
| Type | Description |
|---|---|
Array
|
Joint frames, shape |
forward_kinematics_coms
¶
Compute SE(3) frames at all link centers of mass.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
q
|
Array
|
Joint coordinates, shape |
required |
Returns:
| Type | Description |
|---|---|
Array
|
COM frames, shape |
jacobian_coms
¶
Compute spatial Jacobians at all link COMs.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
q
|
Array
|
Joint coordinates, shape |
required |
Returns:
| Type | Description |
|---|---|
Array
|
COM Jacobians, shape |
jacobian_joints
¶
Compute spatial Jacobians at all joint origins.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
q
|
Array
|
Joint coordinates, shape |
required |
Returns:
| Type | Description |
|---|---|
Array
|
Joint-origin Jacobians, shape |
jacobian_and_time_derivatives_tips
¶
Compute tip Jacobians and their time derivatives.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
q
|
Array
|
Joint coordinates, shape |
required |
qd
|
Array
|
Joint velocities, shape |
required |
Returns:
| Type | Description |
|---|---|
tuple[Array, Array]
|
Tuple |
update_params
¶
update_params(**updates: Array) -> ArticulatedSoftRobot
Return an updated copy with selected typed parameter fields replaced.
soromox.rendering.umarm.viser_renderer
¶
Viser renderer specialized for the McKibben-actuated UMArm.
UMArmViserRenderer
¶
UMArmViserRenderer(*args, actuator_color_mode: Literal['uniform', 'pressure', 'force'] = 'uniform', actuator_line_width: float | None = None, actuator_radius: float = 0.003, rod_core_radius_scale: float = 0.45, linkage_radius: float = 0.007, end_effector_radius: float = 0.01, end_effector_sphere_radius: float = 0.019, ujoint_disk_thickness: float = 0.01, actuator_disk_thickness: float = 0.01, **kwargs)
Bases: ViserRenderer
flowchart TD
soromox.rendering.umarm.viser_renderer.UMArmViserRenderer[UMArmViserRenderer]
soromox.rendering.viser_renderer.ViserRenderer[ViserRenderer]
soromox.rendering.base.BaseSoftRobotRenderer[BaseSoftRobotRenderer]
soromox.rendering.viser_renderer.ViserRenderer --> soromox.rendering.umarm.viser_renderer.UMArmViserRenderer
soromox.rendering.base.BaseSoftRobotRenderer --> soromox.rendering.viser_renderer.ViserRenderer
click soromox.rendering.umarm.viser_renderer.UMArmViserRenderer href "" "soromox.rendering.umarm.viser_renderer.UMArmViserRenderer"
click soromox.rendering.viser_renderer.ViserRenderer href "" "soromox.rendering.viser_renderer.ViserRenderer"
click soromox.rendering.base.BaseSoftRobotRenderer href "" "soromox.rendering.base.BaseSoftRobotRenderer"
Viser renderer that adds McKibben actuator segments to the UMArm backbone.
show
¶
Display a UMArm frame, optionally coloring actuators by pressure or force.
render_sequence
¶
render_sequence(ts: Array, q_ts: Array, *, pressures: Array | None = None, actuator_color_mode: Literal['uniform', 'pressure', 'force'] | None = None, **kwargs) -> None
Render a UMArm trajectory, including McKibben actuator segments.
start_live_mode
¶
start_live_mode(callback: Callable[[float], ndarray] | None = None, dt: float = 0.033, pressure_callback: Callable[[float], ndarray] | None = None) -> UMArmLiveModeController
Start live visualization mode with UMArm-specific rigid geometry.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
callback
|
Callable[[float], ndarray] | None
|
Optional state provider function |
None
|
dt
|
float
|
Callback-mode update period in seconds. |
0.033
|
pressure_callback
|
Callable[[float], ndarray] | None
|
Optional pressure provider |
None
|
Returns:
| Type | Description |
|---|---|
UMArmLiveModeController
|
Controller for streaming UMArm states into the Viser scene. |
compute_backbone_curve
¶
Compute backbone points from configuration.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
q
|
Array
|
Robot configuration array |
required |
Returns:
| Type | Description |
|---|---|
Array
|
Array of shape (num_points, 3) for 3D or (num_points, 2) for 2D |
compute_backbone_poses
¶
Compute full FK poses at the configured backbone sample points.
compute_actuator_visual_layers
¶
compute_actuator_visual_layers(q: Array, *, actuator_inputs: Array | None = None) -> tuple[ActuatorVisualLayer, ...]
Compute renderer-facing actuator visual layers for one robot.
compute_actuator_visual_layers_batched
¶
compute_actuator_visual_layers_batched(q_batch: Array, base_offsets: Array, *, actuator_inputs: Array | ndarray | None = None) -> tuple[BatchedActuatorVisualLayer, ...]
Compute actuator visual layers for multiple robots with base offsets.
compute_actuator_visual_layers_trajectory
¶
compute_actuator_visual_layers_trajectory(q_ts: Array, base_offsets: Array, *, actuator_inputs: Array | ndarray | None = None) -> tuple[TrajectoryActuatorVisualLayer, ...]
Compute actuator visual layers for (N, T, DOF) trajectories.
render_frame
¶
render_frame(q: Array, *, base_offsets: Array | None = None, color_config: RendererColorConfig | None = None, camera_config: CameraConfig | None = None, render_actuators: bool = True, actuator_inputs: Array | None = None, static_spheres_positions: Array | None = None, static_spheres_radii: Array | None = None, static_spheres_colors: Array | None = None, capture_client_idx: int = 0) -> ndarray
Render single configuration and capture as image.
Note: Requires at least one connected client to capture.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
q
|
Array
|
Robot configuration (DOF,) or batched (N, DOF) |
required |
base_offsets
|
Array | None
|
Base position offsets (N, 3) |
None
|
color_config
|
RendererColorConfig | None
|
Shared renderer color configuration |
None
|
camera_config
|
CameraConfig | None
|
Camera configuration (fov, position, look_at, etc.) |
None
|
render_actuators
|
bool
|
If True, render actuator visual layers. |
True
|
actuator_inputs
|
Array | None
|
Optional actuator inputs for scalar-colored layers. |
None
|
static_spheres_positions
|
Array | None
|
Static sphere positions (M, 3) |
None
|
static_spheres_radii
|
Array | None
|
Static sphere radii (M,) |
None
|
static_spheres_colors
|
Array | None
|
Static sphere colors (M, 3) |
None
|
capture_client_idx
|
int
|
Index of client to capture from |
0
|
Returns:
| Type | Description |
|---|---|
ndarray
|
RGB image as numpy array (height, width, 3), dtype uint8 |
resolve_backbone_colors
¶
resolve_backbone_colors(num_robots: int, *, color_config: RendererColorConfig | None = None, cache: bool = True) -> ResolvedBackboneColors
Resolve backbone colors using the shared config hierarchy.
get_color_legend
¶
get_color_legend(*, num_robots: int = 1, color_config: RendererColorConfig | None = None) -> ColorLegend
Return a lightweight color legend for the current configuration.
compute_backbone_curves_batched
¶
Compute backbone curves for multiple robots with base offsets.
Uses forward_kinematics_batched if available (optimized), otherwise falls back to jax.vmap over compute_backbone_curve.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
q_batch
|
Array
|
Configurations of shape (N, DOF) - batch-first |
required |
base_offsets
|
Array
|
Base position offsets of shape (N, 2) or (N, 3) |
required |
Returns:
| Type | Description |
|---|---|
Array
|
Array of shape (N, num_points, dim) - batch-first |
compute_backbone_curves_and_frames_batched
¶
compute_backbone_curves_and_frames_batched(q_batch: Array, base_offsets: Array) -> tuple[Array, Array]
Compute 3D backbone positions and material frames for multiple robots.
The frame columns are the local material-frame axes in world coordinates. Positional base offsets translate the curves without rotating the frames.
add_gui_plotly
¶
Add a plotly figure to the GUI.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
name
|
str
|
Unique name for the plot |
required |
figure
|
Figure
|
Plotly figure object |
required |
aspect
|
float
|
Aspect ratio (width/height) |
1.0
|
Returns:
| Type | Description |
|---|---|
Any
|
Viser plotly handle |
create_configuration_plot
¶
create_configuration_plot(ts: Array | ndarray, q_ts: Array | ndarray, robot_name: str = 'Robot') -> Figure
Create a plotly figure showing configurations over time.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
ts
|
Array | ndarray
|
Time array (T,) |
required |
q_ts
|
Array | ndarray
|
Configuration array (T, DOF) |
required |
robot_name
|
str
|
Name for the plot title |
'Robot'
|
Returns:
| Type | Description |
|---|---|
Figure
|
Plotly figure |
create_actuator_position_plot
¶
create_actuator_position_plot(ts: Array | ndarray, q_ts: Array | ndarray, robot: SoftRobot, robot_name: str = 'Robot') -> Figure
Create a plotly figure showing actuator coordinates over time.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
ts
|
Array | ndarray
|
Time array (T,) |
required |
q_ts
|
Array | ndarray
|
Configuration array (T, DOF) |
required |
robot
|
SoftRobot
|
Robot instance with an |
required |
robot_name
|
str
|
Name for the plot title |
'Robot'
|
Returns:
| Type | Description |
|---|---|
Figure
|
Plotly figure |
add_dynamic_sphere
¶
add_dynamic_sphere(name: str, position: ndarray, radius: float, color: tuple[float, float, float] = (0.2, 0.2, 0.8), opacity: float = 1.0) -> Any
Add a dynamic sphere to the scene.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
name
|
str
|
Unique identifier for the sphere |
required |
position
|
ndarray
|
Initial position (3,) |
required |
radius
|
float
|
Sphere radius |
required |
color
|
tuple[float, float, float]
|
RGB color (0-1) |
(0.2, 0.2, 0.8)
|
opacity
|
float
|
Opacity (0-1) |
1.0
|
Returns:
| Type | Description |
|---|---|
Any
|
Viser sphere handle |
update_dynamic_sphere
¶
update_dynamic_sphere(name: str, position: ndarray | None = None, radius: float | None = None, color: tuple[float, float, float] | None = None) -> None
Update properties of a dynamic sphere.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
name
|
str
|
Sphere identifier |
required |
position
|
ndarray | None
|
New position (3,) |
None
|
radius
|
float | None
|
New radius |
None
|
color
|
tuple[float, float, float] | None
|
New RGB color |
None
|
remove_dynamic_sphere
¶
Remove a dynamic sphere from the scene.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
name
|
str
|
Sphere identifier |
required |
add_custom_primitive
¶
add_custom_primitive(name: str, primitive_type: Literal['sphere', 'box', 'cylinder', 'mesh'], **kwargs: Any) -> Any
Add a custom primitive to the scene for extensibility.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
name
|
str
|
Unique identifier |
required |
primitive_type
|
Literal['sphere', 'box', 'cylinder', 'mesh']
|
Type of primitive |
required |
**kwargs
|
Any
|
Primitive-specific parameters |
{}
|
Returns:
| Type | Description |
|---|---|
Any
|
Viser scene handle |
render_to_video
¶
render_to_video(ts: Array, q_ts: Array, output_path: str, *, width: int | None = None, height: int | None = None, fps: float | None = None, video_config: VideoEncodingConfig | None = None, camera_position: tuple[float, float, float] | None = None, camera_target: tuple[float, float, float] | None = None, **render_kwargs: Any) -> None
Render sequence directly to video file.
This method renders each frame and writes to video using FFmpeg. Requires at least one connected client for capture.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
ts
|
Array
|
Time stamps |
required |
q_ts
|
Array
|
Configurations |
required |
output_path
|
str
|
Output video path (.mp4, .mov) |
required |
width
|
int | None
|
Frame width (default: self.width) |
None
|
height
|
int | None
|
Frame height (default: self.height) |
None
|
fps
|
float | None
|
Output FPS (if None, derived from ts) |
None
|
video_config
|
VideoEncodingConfig | None
|
FFmpeg settings |
None
|
camera_position
|
tuple[float, float, float] | None
|
Fixed camera position |
None
|
camera_target
|
tuple[float, float, float] | None
|
Camera look-at target |
None
|
**render_kwargs
|
Any
|
Additional render_sequence arguments |
{}
|
UMArmLiveModeController
¶
UMArmLiveModeController(renderer: UMArmViserRenderer, callback: Callable[[float], ndarray] | None = None, dt: float = 0.033, pressure_callback: Callable[[float], ndarray] | None = None)
Bases: LiveModeController
flowchart TD
soromox.rendering.umarm.viser_renderer.UMArmLiveModeController[UMArmLiveModeController]
soromox.rendering.viser_renderer.LiveModeController[LiveModeController]
soromox.rendering.viser_renderer.LiveModeController --> soromox.rendering.umarm.viser_renderer.UMArmLiveModeController
click soromox.rendering.umarm.viser_renderer.UMArmLiveModeController href "" "soromox.rendering.umarm.viser_renderer.UMArmLiveModeController"
click soromox.rendering.viser_renderer.LiveModeController href "" "soromox.rendering.viser_renderer.LiveModeController"
Live-mode controller that updates UMArm rigid geometry from q.
push_state_with_pressures
¶
Push a live UMArm state and actuator pressures.
push_state
¶
Push a new configuration to the renderer.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
q
|
ndarray
|
Configuration array (DOF,) or batched (N, DOF) |
required |
push_state_with_extras
¶
Push state with auxiliary geometry updates.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
q
|
ndarray
|
Configuration array |
required |
dynamic_spheres
|
dict[str, ndarray] | None
|
Dict mapping sphere names to positions |
None
|
from_generator
¶
Consume states from a generator at specified FPS.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
state_generator
|
Generator[ndarray, None, None]
|
Generator yielding configurations |
required |
fps
|
float
|
Target frame rate |
30.0
|
References¶
The UMArm platform was introduced in:
- Zuo, R., Han, D. H., Li, R., Jamal, S., & Bruder, D. (2025). UMArm: Untethered, modular, portable, soft pneumatic arm. arXiv preprint arXiv:2505.11476. https://doi.org/10.48550/arXiv.2505.11476