Skip to content

I-Support

3D pneumatically actuated soft robot based on the I-Support platform.

Overview

ISupport is a specialized PCS implementation for 3D pneumatic soft robots. Its pressure chambers use the common threadlike-actuation model: each physical chamber is represented by a straight, segment-local equivalent path through the deformable pneumatic section.

  • 3 chambers per segment: Radially arranged pneumatic chambers
  • Pressure-based control: Direct pressure input for actuation
  • I-Support platform: Specific configuration for the I-Support robot

I-SUPPORT pneumatic soft robot rendered with its specialized Viser geometry

I-SUPPORT Viser rendering with corrugated pneumatic chambers, spacers, and rigid interfaces.

Specialized Viser Rendering

Use ISupportViserRenderer to display the physical chamber layout instead of the generic swept backbone. The renderer follows the model's chamber radii, radial distances, angle offsets, pneumatic-segment grouping, and rigid connector topology. It adds corrugated chamber surfaces, six translucent spacers per pneumatic segment, and the base, intermediate, and tip interfaces.

from soromox.rendering import ISupportViserRenderer, ISupportVisualConfig

renderer = ISupportViserRenderer(
    robot,
    visual_config=ISupportVisualConfig(),
    num_points=50,
)
renderer.show(q)

ISupportVisualConfig exposes spacer thickness, chamber ellipticity, bellows pitch and amplitude, mesh resolution, colors, and spacer opacity. Rigid segments and pneumatic-section spacers use their modeled radii; no visual-only connector slots are added.

Pass chamber pressures in pascals to color each chamber with the sequential Matplotlib Blues colormap. The default scale spans 0–300 kPa and omits the palest 15% of the colormap so unpressurized chambers remain visible. Values outside the configured scale are clamped. Pressure channels use segment-major order: all chamber azimuth indices of the first pneumatic segment, followed by those of the second segment, and so on.

The pressure_range configuration is expressed in pascals, matching the model and pressure input API. Conversion to kPa happens only for sidebar and label presentation.

pressures = jnp.array([2.0e4, 0.0, 0.0])
renderer.show(q, pressures=pressures)

Interactive views color the chambers whenever pressures are supplied. Pressure text starts hidden and can be enabled with the Show pressure labels sidebar checkbox. Labels use one-based model terminology and display values in kPa, for example Segment 1 · Chamber 1 and 20.0 kPa. A captured frame has no interactive sidebar, so render_frame(q, pressures=pressures) includes both the colors and labels automatically. Omitting pressures retains the original uniform chamber appearance and renders no pressure text.

For trajectories, pressures may be a constant (num_actuators,) vector, a (T, num_actuators) time series, or a batched (N, T, num_actuators) time series:

renderer.render_sequence(ts, q_ts, pressures=pressure_ts)

The live controller accepts synchronized updates through push_state_with_pressures(q, pressures), a separate pressure_callback, or a state callback that returns (q, pressures).

Model Quick Start

import jax.numpy as jnp
from soromox.systems import ISupport, ISupportParams, ISupportStructure

params = ISupportParams(
    # Physical order: rigid base, pneumatic section, rigid tip.
    length=jnp.array([0.01, 0.18, 0.01]),
    radius=jnp.array([0.03, 35.6e-3, 0.025]),
    density=jnp.array([1210.0, 1104.0, 1210.0]),
    young_modulus=jnp.array([2.0e9, 1.6464e6, 2.0e9]),
    shear_modulus=jnp.array([0.8e9, 0.5488e6, 0.8e9]),
    material_damping_coefficient=1.96e3,
    reference_strain=jnp.tile(
        jnp.array([0.0, 0.0, 0.0, 1.0, 0.0, 0.0]), 3
    ),
    chamber_inner_radius=jnp.array([6.39e-3]),
    chamber_outer_radius=jnp.array([7.79e-3]),
    chamber_distance=jnp.array([20e-3]),
    chamber_azimuth_angles=(2.0 * jnp.pi * jnp.arange(3) / 3)[None, :],
)
robot = ISupport(
    params,
    structure=ISupportStructure(
        num_gauss_points=3,
        rigid_segment_selector=(True, False, True),
    ),
)

q = jnp.zeros(robot.num_dofs)

# Pressure actuation (3 chambers per pneumatic segment)
u = jnp.array([2.0e4, 0.0, 0.0])

# Forward kinematics
g_tip = robot.forward_kinematics(q, s=jnp.sum(robot.L))

Key Features

Chamber Configuration

The I-Support robot uses 3 pneumatic chambers per segment, arranged radially at 120-degree intervals. This configuration enables:

chamber_azimuth_angles has shape (num_pneumatic_segments, num_chambers_per_segment). Azimuth is a right-handed rotation about local +X, measured in radians from local +Y toward local +Z, so a chamber center is [0, d*cos(phi), d*sin(phi)]. Entry j is pressure channel j; the model does not sort or generate angles. Each row may be rotated, wrapped, and listed in any channel order, but its wrapped circular gaps must be uniformly 2*pi/num_chambers_per_segment (within rtol=1e-6, atol=1e-8). Asymmetric layouts are currently rejected because the passive cross-section model assumes rotational symmetry.

If chamber_azimuth_angles is omitted, ISupport supplies the canonical three-chamber layout [0, 2*pi/3, 4*pi/3], or [0°, 120°, 240°], for every pneumatic segment. Pass an explicit array whenever physical pressure-channel order differs from that default.

  • Bending in any direction
  • Extension/compression along the backbone
  • Complex 3D deformations

Actuation Mapping

Pressure remains the user control and is measured in pascals. The work coordinate of chamber k is the equivalent chamber volume

V_k(q) = A_eff,k * length_k(q),

so the pressure actuation matrix is

A(q) = (dV/dq)^T = (d length/dq)^T diag(A_eff).

This is the same distributed virtual-path model introduced in PR #116, now expressed through ThreadlikeActuator.pressure_chambers(...). It is configuration-dependent and integrates the path contribution along every PCS child belonging to the physical pneumatic section. A chamber never crosses a rigid connector or contributes to another pneumatic section.

chamber_effective_pressure_area has one entry per physical pneumatic section and is shared by its pressure channels. If omitted, the model uses the annular area

A_eff = pi * (chamber_outer_radius**2 - chamber_inner_radius**2).

The pressure-conjugate coordinates, velocities, efforts, moment matrix, and generalized force use the shared actuation interface:

volumes = robot.actuator_coordinates(q)
volume_rates = robot.actuator_velocities(q, qd)
pressure_efforts = robot.actuator_efforts(q, pressures, qd=qd)
A = robot.actuation_matrix(q)
tau = robot.actuation_force(q, pressures, qd=qd)

For the current DirectEffort model, pressure_efforts == pressures. The effective area is part of the transmission coordinate and moment matrix rather than a separate pressure-to-force conversion API.

I-SUPPORT's specialized renderer continues to draw the detailed bellows and accepts actuator_inputs= (with pressures= as a mutually exclusive alias). The internal equivalent paths are not drawn as generic pneumatic tubes.

API Reference

soromox.systems.pcs.isupport.ISupport

ISupport(params: ISupportParams, structure: ISupportStructure | None = None, **kwargs: Any)

Bases: PCS


              flowchart TD
              soromox.systems.pcs.isupport.ISupport[ISupport]
              soromox.systems.pcs.pcs.PCS[PCS]
              soromox.systems.soft_robot.SoftRobot[SoftRobot]
              soromox.systems.dynamical_system.DynamicalSystem[DynamicalSystem]

                              soromox.systems.pcs.pcs.PCS --> soromox.systems.pcs.isupport.ISupport
                                soromox.systems.soft_robot.SoftRobot --> soromox.systems.pcs.pcs.PCS
                                soromox.systems.dynamical_system.DynamicalSystem --> soromox.systems.soft_robot.SoftRobot
                




              click soromox.systems.pcs.isupport.ISupport href "" "soromox.systems.pcs.isupport.ISupport"
              click soromox.systems.pcs.pcs.PCS href "" "soromox.systems.pcs.pcs.PCS"
              click soromox.systems.soft_robot.SoftRobot href "" "soromox.systems.soft_robot.SoftRobot"
              click soromox.systems.dynamical_system.DynamicalSystem href "" "soromox.systems.dynamical_system.DynamicalSystem"
            

A kinematic and dynamic model for the (AM) I-Support robot based on the Piecewise Constant Strain shape parametrization.

Attributes:

Name Type Description
num_segments int

Number of segments (constant strain sections) along the robot.

num_actuators int

Number of actuators (control inputs) for the robot.

g0 Array

Initial pose of the robot base as an SE(3) transformation matrix.

g Array

Gravitational acceleration vector (embedded in a 6D vector). [0, 0, 0, g_x, g_y, g_z]

length Array

Length of each segment [m], cached as L.

radius Array

Radius of each segment [m], cached as r.

young_modulus Array

Elastic modulus of each segment [Pa], cached as E.

shear_modulus Array

Shear modulus of each segment [Pa], cached as G.

density Array

Density of each segment [kg/m^3], cached as rho.

damping_matrix Array

Resolved damping matrix of the flattened strain coordinates, cached as D_full. It can be supplied directly or derived from a material damping coefficient in Pa*s. Matrix-entry units depend on the associated generalized strain coordinates.

num_active_strains Array

Number of active strain components (based on strain_selector).

num_strains int

Total number of strain components (6 * num_segments).

B_xi Array

Basis matrix for projecting active strains (6 * num_segments, num_active_strains).

xi_ref Array

Reference strain (reference configuration) of the robot.

num_gauss_points int

Requested nonzero Gauss-Legendre quadrature nodes.

num_integration_points int

Stored integration nodes, including zero-weight endpoints.

integration_points, integration_weights

Quadrature nodes and weights.

chamber_inner_radius integration_weights

Inner radius of each segment's actuator [m], cached as r_chamber_in.

chamber_outer_radius integration_weights

Outer radius of each segment's actuator [m], cached as r_chamber_out.

chamber_distance integration_weights

Radial distance of the center of the actuators from the centerline of the backbone [m], cached as d_chamber.

chamber_azimuth_angles Array

Explicit chamber azimuths [rad], right-handed about local +X from +Y toward +Z. The second axis is pressure-channel order.

References

Arleo, L., Stano, G., Percoco, G., & Cianchetti, M. (2021). I-support soft arm for assistance tasks: a new manufacturing approach based on 3D printing and characterization. Progress in Additive Manufacturing, 6(2), 243-256. https://doi.org/10.1007/s40964-020-00158-y

Alessi, C., Falotico, E., & Lucantonio, A. (2023). Ablation study of a dynamic model for a 3D-printed pneumatic soft robotic arm. IEEE Access, 11, 37840-37853. https://doi.org/10.1109/ACCESS.2023.3266282

Alessi, C., Bianchi, D., Stano, G., Cianchetti, M., & Falotico, E. (2024). Pushing with soft robotic arms via deep reinforcement learning. Advanced Intelligent Systems, 6(8), 2300899. https://doi.org/10.1002/aisy.202300899

Initialize the ISupport class

Parameters:

Name Type Description Default
params ISupportParams

Dynamic I-SUPPORT parameters.

required
structure ISupportStructure | None

Static I-SUPPORT layout. If omitted, physical segments alternate rigid and pneumatic from index zero, and each pneumatic segment is represented by one PCS segment.

None
**kwargs Any

Additional keyword arguments.

{}

tangent_eps property

tangent_eps: Array

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.

length property

length: Array

Total backbone length of the robot (scalar).

segment_length property

segment_length: Array

Per-segment backbone lengths.

is_planar property

is_planar: bool

PCS is a spatial (3D) model.

supports_articulated_tendon_routing property

supports_articulated_tendon_routing: bool

Whether joint indices describe a serial articulated routing topology.

base_transform property

base_transform: Array

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.

with_params

with_params(params: ISupportParams) -> ISupport

Return an updated copy with a full pneumatic-segment parameter object.

update_params

update_params(**updates: Array) -> ISupport

Return an updated copy with selected pneumatic parameter fields replaced.

chamber_azimuths

chamber_azimuths(pneumatic_segment_idx: Array) -> Array

Return one azimuth per chamber in pressure-channel order.

This concise accessor name is distinct from the parameter field chamber_azimuth_angles. The returned array has shape (num_chambers_per_segment,) and is not sorted or normalized.

Parameters:

Name Type Description Default
pneumatic_segment_idx Array

Index of the physical pneumatic segment.

required

Returns:

Type Description
Array

Chamber azimuth angles in radians, indexed exactly like the

Array

segment's pressure inputs.

local_chamber_offsets

local_chamber_offsets(pneumatic_segment_idx: Array) -> Array

Return vectors from the local backbone centerline to chamber centers.

The result has shape (num_chambers_per_segment, 3) and follows pressure-channel order. Each row is expressed in the pneumatic segment's local frame as [0, d*cos(phi), d*sin(phi)]; it is an offset vector, not an absolute chamber-center position.

Parameters:

Name Type Description Default
pneumatic_segment_idx Array

Index of the physical pneumatic segment.

required

Returns:

Type Description
Array

Local chamber-center offset vectors in meters.

actuator_visual_layers

actuator_visual_layers(q: Array, s_points: Array, *, actuator_inputs: Array | None = None) -> tuple

Keep equivalent chamber-center paths out of generic renderers.

forward_dynamics

forward_dynamics(t: Array, y: Array, actuation_args: tuple | None = None) -> Array

Forward dynamics function.

Parameters:

Name Type Description Default
t Array

Current time.

required
y Array

State vector containing configuration and velocity. Shape is (2 * num_strains,).

required
actuation_args tuple

Additional arguments for the actuation mapping function. Default is None.

None

Returns:

Name Type Description
yd Array

Time derivative of the state vector.

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 initial_state.u, then zeros.

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 SystemState and returns (tau_environment, environment_state_dot). The returned generalized torques are added to tau_ext during integration.

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 save_ts is not provided.

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 save_dt if None.

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

initial_state.environment_state was provided. Each leaf has a

SystemState

leading time dimension aligned with save_ts.

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 SystemState and returns a tuple (u_control, control_state_dot). u_control is added to the base actuation from the initial state.

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 SystemState and returns (tau_environment, environment_state_dot). The returned generalized torques are added to tau_ext during integration.

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 save_ts is not provided.

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 save_dt if None.

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

initial_state.environment_state was provided. Each leaf has a

SystemState

leading time dimension aligned with save_ts.

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 (u_control, control_state_dot).

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 (tau_environment, environment_state_dot). The returned generalized torques are added to tau_ext during integration.

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 control_dt.

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

initial_state.environment_state was provided. Each leaf has a

SystemState

leading time dimension aligned with the regular save grid.

precompute

precompute() -> None

Refresh state-independent matrices cached by the model.

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

cross_section_geometry(q: Array, s: Array) -> tuple[Array, Array]

Return the assumed solid circular cross-section and segment radius.

forward_kinematics

forward_kinematics(q: Array, s: Array) -> Array

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

forward_kinematics_tips(q: Array) -> Array

Compute the forward kinematics of the robot at all segment tips.

Parameters:

Name Type Description Default
q Array

generalized coordinates of shape (num_active_strains,).

required

Returns:

Name Type Description
g_tips Array

forward kinematics of the robot at all segment tips, shape (num_segments, 4, 4) : g_tip_i = [[ R, p], [0, 0, 0, 1]] where R is the rotation matrix and p is the position vector.

forward_kinematics_batched

forward_kinematics_batched(q: Array, s_ps: Array) -> Array

Compute the forward kinematics of the robot at a batch of points s_ps along the robot.

Parameters:

Name Type Description Default
q Array

generalized coordinates of shape (num_active_strains,).

required
s_ps Array

point coordinates along the robot in the interval [0, L] of shape (N,).

required

Returns:

Name Type Description
g_ps Array

forward kinematics of the robot at all points s_ps, shape (N, 4, 4) : g_si = [[ R, p], [0, 0, 0, 1]] where R is the rotation matrix and p is the position vector.

forward_kinematics_arc_length_derivative

forward_kinematics_arc_length_derivative(q: Array, s: Array) -> Array

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

forward_kinematics_and_arc_length_derivative(q: Array, s: Array) -> tuple[Array, Array]

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

jacobian(q: Array, s: Array) -> Array

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

jacobian_tips(q: Array) -> Array

Compute inertial-frame Jacobians at all segment tips.

Parameters:

Name Type Description Default
q Array

generalized coordinates of shape (num_active_strains,).

required

Returns:

Name Type Description
J_tips Array

inertial-frame Jacobians at each segment tip, shape (num_segments, 6, num_active_strains).

jacobian_batched

jacobian_batched(q: Array, s_ps: Array) -> Array

Compute inertial-frame Jacobians at multiple arc-length positions.

jacobian_arc_length_derivative

jacobian_arc_length_derivative(q: Array, s: Array) -> Array

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

jacobian_and_arc_length_derivative(q: Array, s: Array) -> tuple[Array, Array]

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 J.

jacobian_and_time_derivative

jacobian_and_time_derivative(q: Array, qd: Array, s: Array) -> tuple[Array, Array]

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

jacobian_and_time_derivative_batched(q: Array, qd: Array, s_ps: Array) -> tuple[Array, Array]

Compute inertial-frame Jacobians and time derivatives at multiple arc-length positions.

jacobian_bodyframe

jacobian_bodyframe(q: Array, s: Array) -> Array

Compute the Jacobian of the forward kinematics at a point s along the robot in the body frame.

Parameters:

Name Type Description Default
q Array

generalized coordinates of shape (num_active_strains,).

required
s Array

point coordinate along the robot in the interval [0, L].

required

Returns:

Name Type Description
J_local Array

Jacobian of the forward kinematics at point s in the body frame, shape (6, num_active_strains)

jacobian_bodyframe_batched

jacobian_bodyframe_batched(q: Array, s_ps: Array) -> Array

Compute the Jacobian of the forward kinematics at a batch of points s_ps along the robot in the body frame.

Parameters:

Name Type Description Default
q Array

generalized coordinates of shape (num_active_strains,).

required
s_ps Array

point coordinates along the robot in the interval [0, L] of shape (N,).

required

Returns:

Name Type Description
J_local_ps Array

Jacobians evaluated at all points, shape (N, 6, num_active_strains)

jacobian_and_time_derivative_bodyframe

jacobian_and_time_derivative_bodyframe(q: Array, qd: Array, s: Array) -> tuple[Array, Array]

Compute the Jacobian and its time-derivative for the forward kinematics at a point s along the robot in the body frame.

Parameters:

Name Type Description Default
q Array

generalized coordinates of shape (num_active_strains,).

required
qd Array

time-derivative of the generalized coordinates of shape (num_active_strains,).

required
s Array

point coordinate along the robot in the interval [0, L].

required

Returns:

Name Type Description
J_local Array

Jacobian of the forward kinematics at point s in the body frame, shape (6, num_active_strains)

Jd_local Array

Time-derivative of the Jacobian at point s in the body frame, shape (6, num_active_strains)

jacobian_and_time_derivative_bodyframe_batched

jacobian_and_time_derivative_bodyframe_batched(q: Array, qd: Array, s_ps: Array) -> tuple[Array, Array]

Compute the Jacobian and its time-derivative for the forward kinematics at a batch of points s_ps along the robot in the body frame.

Parameters:

Name Type Description Default
q Array

generalized coordinates of shape (num_active_strains,).

required
qd Array

time-derivative of the generalized coordinates of shape (num_active_strains,).

required
s_ps Array

point coordinates along the robot in the interval [0, L] of shape (N,).

required

Returns:

Name Type Description
J_local_ps Array

Jacobians evaluated at all points, shape (N, 6, num_active_strains)

Jd_local_ps Array

Time-derivative of the Jacobians, shape (N, 6, num_active_strains)

integration_kinematics

integration_kinematics(q: Array, qd: Array) -> tuple[Array, Array, Array]

Return integration-point kinematics in active generalized coordinates.

The stored quadrature grid includes zero-weight endpoint nodes; this method ignores those endpoints and evaluates only the nonzero-weight interior quadrature nodes. The coordinates are generalized coordinates for active strain components only.

Parameters:

Name Type Description Default
q Array

Active generalized coordinates, shape (self.num_dofs,).

required
qd Array

Active generalized velocities, shape (self.num_dofs,).

required

Returns:

Type Description
Array

Tuple (g_ps, J_ps, Jd_ps). g_ps contains SE(3) poses with

Array

shape (self.num_segments, self.num_gauss_points, 4, 4).

Array

J_ps contains body-frame Jacobians in active generalized

tuple[Array, Array, Array]

coordinates with shape

tuple[Array, Array, Array]

(self.num_segments, self.num_gauss_points, 6, self.num_dofs).

tuple[Array, Array, Array]

Jd_ps contains their time derivatives with the same shape as

tuple[Array, Array, Array]

J_ps.

inertia_matrix

inertia_matrix(q: Array) -> Array

Compute the inertia matrix of the robot.

Parameters:

Name Type Description Default
q Array

generalized coordinates of shape (num_active_strains,).

required

Returns:

Name Type Description
B Array

Inertia matrix of shape (num_active_strains, num_active_strains).

coriolis_matrix

coriolis_matrix(q: Array, qd: Array) -> Array

Compute the Coriolis matrix of the robot.

Parameters:

Name Type Description Default
q Array

generalized coordinates of shape (num_active_strains,).

required
qd Array

time-derivative of the generalized coordinates of shape (num_active_strains,).

required

Returns:

Name Type Description
C Array

Coriolis matrix of shape (num_active_strains, num_active_strains).

damping_matrix

damping_matrix(q: Array) -> Array

Compute the damping matrix of the robot.

Parameters:

Name Type Description Default
q Array

generalized coordinates of shape (num_active_strains,).

required

Returns:

Name Type Description
D Array

Damping matrix of shape (num_active_strains, num_active_strains).

stiffness_matrix

stiffness_matrix() -> Array

Compute the stiffness matrix of the robot.

Returns:

Name Type Description
K Array

Stiffness matrix of shape (num_active_strains, num_active_strains).

elastic_force

elastic_force(q: Array) -> Array

Compute the elastic forces of the robot.

Parameters:

Name Type Description Default
q Array

generalized coordinates of shape (num_active_strains,).

required

Returns:

Name Type Description
tau_el Array

Elastic force of shape (num_active_strains,).

gravitational_force

gravitational_force(q: Array) -> Array

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

potential_force(q: Array) -> Array

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

actuator_coordinates(q: Array) -> Array

Return all work-conjugate actuator coordinates in control order.

actuator_velocities

actuator_velocities(q: Array, qd: Array) -> Array

Return all actuator-coordinate velocities in control order.

actuation_matrix

actuation_matrix(q: Array) -> Array

Return the concatenated transmission moment matrix.

actuator_efforts

actuator_efforts(q: Array, u: Array, qd: Array | None = None) -> Array

Map ordered user controls to ordered work-conjugate efforts.

actuation_force

actuation_force(q: Array, u: Array, qd: Array | None = None) -> Array

Return generalized actuation force A(q) @ effort.

passive_elastic_force

passive_elastic_force(q: Array) -> Array

Return the sum of installed passive conservative forces.

passive_damping_matrix

passive_damping_matrix(q: Array) -> Array

Return the sum of installed passive damping matrices.

passive_elastic_energy

passive_elastic_energy(q: Array) -> Array

Return the sum of installed passive elastic energies.

kinetic_energy

kinetic_energy(q: Array, qd: Array) -> Array

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

gravitational_energy(q: Array) -> Array

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

elastic_energy(q: Array) -> Array

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

potential_energy(q: Array) -> Array

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

total_energy(q: Array, qd: Array) -> Array

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

dynamics_terms(q: Array, qd: Array) -> tuple[Array, Array, Array]

Assemble forward-dynamics terms in active generalized coordinates.

The coordinates and returned generalized forces correspond only to the active strain components selected by the strain basis.

Parameters:

Name Type Description Default
q Array

Active generalized coordinates, shape (self.num_dofs,).

required
qd Array

Active generalized velocities, shape (self.num_dofs,).

required

Returns:

Type Description
Array

Tuple (B, Cqd, G). B is the active-coordinate inertia

Array

matrix with shape (self.num_dofs, self.num_dofs). Cqd is

Array

the active Coriolis/centrifugal force vector with shape

tuple[Array, Array, Array]

(self.num_dofs,). G is the active generalized gravity

tuple[Array, Array, Array]

vector with shape (self.num_dofs,).

classify_segment

classify_segment(s: Array) -> tuple[Array, Array]

Classify the point along the robot to the corresponding segment.

Parameters:

Name Type Description Default
s Array

point coordinate along the robot in the interval [0, L].

required

Returns:

Name Type Description
segment_idx Array

index of the segment where the point is located

s_segment Array

point coordinate along the segment in the interval [0, l_segment]

strain

strain(q: Array) -> Array

Compute the strain vector from the generalized coordinates.

Components use the rod material frame, whose local x-axis is the longitudinal backbone direction.

Parameters:

Name Type Description Default
q Array

generalized coordinates of shape (num_active_strains,).

required

Returns:

Name Type Description
xi Array

strain vector of shape (num_active_strains,)

inverse_kinematics

inverse_kinematics(g_tips: Array) -> Array

Recover generalized coordinates from the absolute tip poses of each segment.

The routine converts each tip pose into a body-relative transform, extracts the corresponding twist via the SE(3) logarithmic map, and normalises by segment length to obtain the constant strain representation used by the PCS model.

Parameters:

Name Type Description Default
g_tips Array

homogeneous tip transforms of shape (num_segments, 4, 4).

required

Returns:

Name Type Description
q Array

generalized coordinates q of shape (num_active_strains,).

jacobian_and_arc_length_derivative_bodyframe

jacobian_and_arc_length_derivative_bodyframe(q: Array, s: Array) -> tuple[Array, Array]

Compute the body-frame Jacobian and its arc-length derivative at s.

jacobian_arc_length_derivative_bodyframe

jacobian_arc_length_derivative_bodyframe(q: Array, s: Array) -> Array

Compute the arc-length derivative of the body-frame Jacobian at s.

jacobian_inertialframe

jacobian_inertialframe(q: Array, s: Array) -> Array

Compute the Jacobian of the forward kinematics at a point s along the robot in the inertial frame.

Parameters:

Name Type Description Default
q Array

generalized coordinates of shape (num_active_strains,).

required
s Array

point coordinate along the robot in the interval [0, L].

required

Returns:

Name Type Description
J_global Array

Jacobian of the forward kinematics at point s in the inertial frame, shape (6, num_active_strains)

jacobian_and_arc_length_derivative_inertialframe

jacobian_and_arc_length_derivative_inertialframe(q: Array, s: Array) -> tuple[Array, Array]

Compute the inertial-frame Jacobian and its arc-length derivative at s.

jacobian_arc_length_derivative_inertialframe

jacobian_arc_length_derivative_inertialframe(q: Array, s: Array) -> Array

Compute the arc-length derivative of the inertial-frame Jacobian at s.

jacobian_inertialframe_batched

jacobian_inertialframe_batched(q: Array, s_ps: Array) -> Array

Compute the Jacobian of the forward kinematics at a batch of points s_ps along the robot in the inertial frame. Args: q (Array): generalized coordinates of shape (num_active_strains,). s_ps (Array): point coordinates along the robot in the interval [0, L] of shape (N,).

Returns:

Name Type Description
J_global_ps Array

Jacobians evaluated at all points, shape (N, 6, num_active_strains)

jacobian_and_time_derivative_inertialframe

jacobian_and_time_derivative_inertialframe(q: Array, qd: Array, s: Array) -> tuple[Array, Array]

Compute the Jacobian and its time-derivative for the forward kinematics at a point s along the robot in the inertial frame.

Parameters:

Name Type Description Default
q Array

generalized coordinates of shape (num_active_strains,).

required
qd Array

time-derivative of the generalized coordinates of shape (num_active_strains,).

required
s Array

point coordinate along the robot in the interval [0, L].

required

Returns:

Name Type Description
J_global Array

Jacobian of the forward kinematics at point s in the inertial frame, shape (6, num_active_strains)

Jd_global Array

Time-derivative of the Jacobian at point s in the inertial frame, shape (6, num_active_strains)

jacobian_and_time_derivative_inertialframe_batched

jacobian_and_time_derivative_inertialframe_batched(q: Array, qd: Array, s_ps: Array) -> tuple[Array, Array]

Compute the Jacobian and its time-derivative for the forward kinematics at a batch of points s_ps along the robot in the inertial frame.

Parameters:

Name Type Description Default
q Array

generalized coordinates of shape (num_active_strains,).

required
qd Array

time-derivative of the generalized coordinates of shape (num_active_strains,).

required
s_ps Array

point coordinates along the robot in the interval [0, L] of shape (N,).

required

Returns:

Name Type Description
J_global_ps Array

Jacobians evaluated at all points, shape (N, 6, num_active_strains)

Jd_global_ps Array

Time-derivative of the Jacobians, shape (N, 6, num_active_strains)

References

Key literature on the I-SUPPORT platform and its dynamic modeling:

  • Arleo, L., Stano, G., Percoco, G., & Cianchetti, M. (2021). I-support soft arm for assistance tasks: a new manufacturing approach based on 3D printing and characterization. Progress in Additive Manufacturing, 6(2), 243–256. https://doi.org/10.1007/s40964-020-00158-y
  • Alessi, C., Falotico, E., & Lucantonio, A. (2023). Ablation study of a dynamic model for a 3D-printed pneumatic soft robotic arm. IEEE Access, 11, 37840–37853. https://doi.org/10.1109/ACCESS.2023.3266282
  • Alessi, C., Bianchi, D., Stano, G., Cianchetti, M., & Falotico, E. (2024). Pushing with soft robotic arms via deep reinforcement learning. Advanced Intelligent Systems, 6(8), 2300899. https://doi.org/10.1002/aisy.202300899