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 RendererConfig, GeometryConfig, ISupportViserRenderer, ISupportVisualConfig

renderer = ISupportViserRenderer(
    robot,
    visual_config=ISupportVisualConfig(),
    config=RendererConfig(geometry=GeometryConfig(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, LinkSpec, PCS

reference = [0.0, 0.0, 0.0, 1.0, 0.0, 0.0]
links = [
    # Physical order: rigid base, pneumatic section, rigid tip.
    LinkSpec.circular(
        length=length,
        radius=radius,
        density=density,
        young_modulus=young,
        shear_modulus=shear,
        material_damping_coefficient=1.96e3,
        reference_strain=reference,
    )
    for length, radius, density, young, shear in zip(
        [0.01, 0.18, 0.01],
        [0.03, 35.6e-3, 0.025],
        [1210.0, 1104.0, 1210.0],
        [2.0e9, 1.6464e6, 2.0e9],
        [0.8e9, 0.5488e6, 0.8e9],
    )
]
params = ISupportParams(
    link=PCS.params_from_links(links).link,
    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_coordinates)

# 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 an I-SUPPORT model from typed parameters.

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 forwarded to :class:PCS.

{}

Raises:

Type Description
TypeError

If params or structure has the wrong type.

ValueError

If the physical layout, chamber geometry, expanded PCS parameters, or an inherited constructor option is invalid.

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.

num_base_coordinates property

num_base_coordinates: int

Return the configuration-storage dimension of the base.

Returns:

Type Description
int

Zero for fixed robots, three for planar floating robots, and seven

int

for spatial floating robots.

num_base_velocities property

num_base_velocities: int

Return the generalized-velocity dimension of the base.

Returns:

Type Description
int

Zero for fixed robots, three for planar floating robots, and six

int

for spatial floating robots.

num_coordinates property

num_coordinates: int

Return the total configuration dimension.

Returns:

Type Description
int

nq, including runtime base coordinates when enabled.

num_velocities property

num_velocities: int

Return the total generalized-velocity dimension.

Returns:

Type Description
int

nv, including runtime base velocities when enabled.

num_auxiliary_states property

num_auxiliary_states: int

Return the number of trailing first-order auxiliary states.

Returns:

Type Description
int

The hysteresis-state dimension, or zero for systems without

int

auxiliary dynamics.

state_size property

state_size: int

Return the flattened first-order state dimension.

Returns:

Type Description
int

num_coordinates + num_velocities + num_auxiliary_states.

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

Return the per-segment backbone lengths.

Returns:

Type Description
Array

Array with shape (num_segments,).

is_planar property

is_planar: bool

Return whether the system is planar.

Returns:

Type Description
bool

Always False because spatial PCS uses SE(3) kinematics.

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 of the fixed/internal base pose.

Planar robots consume [theta, x, y] and return an SE(2) matrix with shape (3, 3). Spatial robots consume [qx, qy, qz, qw, x, y, z] and return an SE(3) matrix with shape (4, 4). Spatial quaternions are scalar-last Hamilton quaternions.

with_params

with_params(params: ISupportParams) -> ISupport

Return a copy using complete physical-segment parameters.

The physical I-SUPPORT layout is expanded back into PCS segments, and inherited geometry, dynamics, and actuation caches are refreshed.

Parameters:

Name Type Description Default
params ISupportParams

Complete replacement :class:ISupportParams compatible with the model's static physical layout and chamber count.

required

Returns:

Type Description
ISupport

A new I-SUPPORT model containing the replacements. The original

ISupport

model is unchanged.

Raises:

Type Description
TypeError

If params is not an :class:ISupportParams.

ValueError

If validation fails or the replacement changes a static layout choice such as the number of chambers.

update_params

update_params(**updates: Array) -> ISupport

Return a copy with selected physical parameter fields replaced.

Parameters:

Name Type Description Default
**updates Array

Fields of :class:ISupportParams to replace, including inherited PCS fields and pneumatic chamber fields.

{}

Returns:

Type Description
ISupport

A new validated I-SUPPORT model with refreshed PCS and actuator

ISupport

caches.

Raises:

Type Description
KeyError

If an update names an unknown parameter field.

TypeError

If a replacement has an invalid type.

ValueError

If the resulting parameters are invalid or incompatible with the static physical layout.

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

Return generic actuator layers for rendering.

I-SUPPORT's chamber-center paths represent equivalent pressure-volume coordinates rather than physical tendons, so generic renderers should not draw them.

Parameters:

Name Type Description Default
q Array

Generalized coordinates accepted by the common rendering API.

required
s_points Array

Backbone sampling coordinates accepted by the common rendering API.

required
actuator_inputs Array | None

Optional actuator inputs accepted by the common rendering API.

None

Returns:

Type Description
tuple

An empty tuple.

forward_dynamics

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

Compute the time derivative of a spatial PCS state.

Parameters:

Name Type Description Default
t Array

Current integration time. PCS dynamics are autonomous, so the value is accepted for solver compatibility but is not otherwise used.

required
y Array

State [q, v, auxiliary] with shape (state_size,).

required
actuation_args tuple | None

Optional tuple containing the actuation input u and, optionally, an external generalized force tau_ext. A one-element tuple is interpreted as (u,) and a two-element tuple as (u, tau_ext). Missing values default to zero.

None
backend ExecutionBackend | None

Optional execution-backend override for the inertia, Coriolis, and gravity terms. None uses :attr:backend.

None

Returns:

Type Description
Array

State derivative [qd, qdd] with the same shape as y.

Raises:

Type Description
ValueError

If actuation_args does not contain one or two elements.

project_state

project_state(y: Array) -> Array

Project a state onto the robot's configuration manifold.

Fixed and planar systems return the original state without additional array operations. Spatial floating systems normalize the leading scalar-last quaternion while preserving velocity and auxiliary state.

Parameters:

Name Type Description Default
y Array

State with trailing dimension state_size.

required

Returns:

Type Description
Array

State with a unit floating-base quaternion when applicable.

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 | Sequence[float] | 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 | Sequence[float] | 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 | None = 0.01, save_ts: Array | Sequence[float] | 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 | None

Time interval at which to save the solution when save_ts is not provided.

0.01
save_ts Array | Sequence[float] | 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.

pack_configuration

pack_configuration(q_internal: Array, *, base_pose: Array | None = None) -> Array

Pack internal coordinates and a runtime base pose.

Parameters:

Name Type Description Default
q_internal Array

Internal coordinates with trailing dimension num_internal_dofs.

required
base_pose Array | None

Required runtime pose for floating robots. Fixed robots reject this argument.

None

Returns:

Type Description
Array

Total configuration with trailing dimension num_coordinates.

Raises:

Type Description
ValueError

If a required base pose is missing, a fixed robot is given a runtime pose, or a trailing dimension is invalid.

split_configuration

split_configuration(q: Array) -> tuple[Array | None, Array]

Split total configuration into base and internal coordinates.

Parameters:

Name Type Description Default
q Array

Configuration with trailing dimension num_coordinates.

required

Returns:

Type Description
tuple[Array | None, Array]

(q_base, q_internal). q_base is None for fixed robots.

pack_velocity

pack_velocity(qd_internal: Array, *, base_velocity: Array | None = None) -> Array

Pack internal and floating-base generalized velocities.

Parameters:

Name Type Description Default
qd_internal Array

Internal generalized velocity with trailing dimension num_internal_dofs.

required
base_velocity Array | None

Optional world-frame base velocity. Omission uses zero for floating robots; fixed robots reject this argument.

None

Returns:

Type Description
Array

Total generalized velocity with trailing dimension

Array

num_velocities.

Raises:

Type Description
ValueError

If a fixed robot is given a base velocity or a trailing dimension is invalid.

split_velocity

split_velocity(v: Array) -> tuple[Array | None, Array]

Split total velocity into base and internal components.

Parameters:

Name Type Description Default
v Array

Generalized velocity with trailing dimension num_velocities.

required

Returns:

Type Description
tuple[Array | None, Array]

(v_base, qd_internal). v_base is None for fixed robots.

pack_state

pack_state(q: Array, v: Array, auxiliary_state: Array | None = None) -> Array

Pack configuration, velocity, and optional auxiliary state.

Parameters:

Name Type Description Default
q Array

Configuration with trailing dimension num_coordinates.

required
v Array

Velocity with trailing dimension num_velocities.

required
auxiliary_state Array | None

Optional state with trailing dimension num_auxiliary_states. Omission uses zeros.

None

Returns:

Type Description
Array

State [q, v, auxiliary] with broadcast leading axes and trailing

Array

dimension state_size.

split_state

split_state(y: Array) -> tuple[Array, Array, Array]

Split a state with unequal configuration and velocity dimensions.

Parameters:

Name Type Description Default
y Array

State with trailing dimension state_size.

required

Returns:

Type Description
tuple[Array, Array, Array]

(q, v, auxiliary_state) with preserved leading axes.

normalize_configuration

normalize_configuration(q: Array) -> Array

Normalize a floating spatial quaternion without changing hemisphere.

Parameters:

Name Type Description Default
q Array

Configuration with trailing dimension num_coordinates.

required

Returns:

Type Description
Array

The unchanged input for fixed or planar robots, or a configuration

Array

whose leading scalar-last quaternion has unit norm.

Raises:

Type Description
ValueError

If a concrete spatial quaternion is zero or non-finite.

configuration_derivative

configuration_derivative(q: Array, v: Array) -> Array

Map generalized velocity to the derivative of stored coordinates.

Parameters:

Name Type Description Default
q Array

Configuration with trailing dimension num_coordinates.

required
v Array

Velocity with trailing dimension num_velocities.

required

Returns:

Type Description
Array

qdot with trailing dimension num_coordinates. Spatial base

Array

angular velocity is world-frame and left-multiplies the quaternion.

retract_configuration

retract_configuration(q: Array, delta_v: Array) -> Array

Retract a velocity-space increment onto configuration space.

Parameters:

Name Type Description Default
q Array

Configuration with trailing dimension num_coordinates.

required
delta_v Array

Tangent increment with trailing dimension num_velocities.

required

Returns:

Type Description
Array

Updated configuration. Spatial rotation increments left-multiply

Array

the scalar-last quaternion and the result is normalized.

base_transform_from_configuration

base_transform_from_configuration(q: Array) -> Array

Convert the runtime or fixed base pose to homogeneous transforms.

Parameters:

Name Type Description Default
q Array

Total configuration for floating robots or internal configuration for fixed robots.

required

Returns:

Type Description
Array

A planar (..., 3, 3) or spatial (..., 4, 4) transform.

with_fixed_base_pose

with_fixed_base_pose(pose: Array) -> Self

Return a fixed robot with a different mounting pose.

Parameters:

Name Type Description Default
pose Array

Planar pose with shape (3,) or spatial scalar-last quaternion pose with shape (7,).

required

Returns:

Type Description
Self

A functionally updated robot with mounting-dependent caches refreshed.

Raises:

Type Description
ValueError

If the robot is floating or the pose is invalid.

precompute

precompute() -> None

Refresh state-independent matrices cached by the model.

Returns:

Type Description
None

None. Material unit-response operators and the segment, full,

None

and active-coordinate matrices are replaced in place.

with_actuator_params

with_actuator_params(index: int, params) -> Self

Return a robot with one actuator's complete parameter object replaced.

update_actuator_params

update_actuator_params(index: int, **updates: Any) -> Self

Return a robot with selected fields of one actuator's params replaced.

with_passive_element_params

with_passive_element_params(index: int, params) -> Self

Return a robot with one passive element's complete params replaced.

update_passive_element_params

update_passive_element_params(index: int, **updates: Any) -> Self

Return a robot with selected passive-element parameter fields replaced.

cross_section_geometry

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

Evaluate the circular cross-section at a backbone coordinate.

Parameters:

Name Type Description Default
q Array

Generalized coordinates. PCS cross-section geometry is configuration-independent, but q is accepted for the common continuum-robot interface.

required
s Array

Scalar global backbone coordinate.

required

Returns:

Type Description
Array

A tuple containing the circular :class:CrossSectionGeometry tag

Array

and a one-element array holding the selected segment radius.

Raises:

Type Description
ValueError

If s cannot be assigned to a segment.

forward_kinematics

forward_kinematics(q: Array, s: Array, *, backend: ExecutionBackend | None = None) -> Array

Compute an SE(3) pose at one curvilinear abscissa.

Parameters:

Name Type Description Default
q Array

Active generalized strains with shape (D,).

required
s Array

Scalar curvilinear abscissa.

required
backend ExecutionBackend | None

Optional execution override. None uses the model's configured backend.

None

Returns:

Type Description
Array

Homogeneous transform with shape (4, 4).

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_abscissa_batched

forward_kinematics_abscissa_batched(q: Array, s_ps: Array, *, backend: ExecutionBackend | None = None) -> Array

Compute SE(3) poses at a batch of curvilinear abscissae.

Parameters:

Name Type Description Default
q Array

Active generalized strains with shape (D,).

required
s_ps Array

Curvilinear abscissae with shape (N,).

required
backend ExecutionBackend | None

Optional execution override. None uses the model's configured backend.

None

Returns:

Type Description
Array

Homogeneous transforms with shape (N, 4, 4).

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_coordinates,).

required
s Array

Position parameter along the robot structure.

required

Returns:

Name Type Description
J Array

Jacobian matrix of shape (n_pose_dim, num_velocities), 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_abscissa_batched

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

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

Parameters:

Name Type Description Default
q Array

Active generalized strains with shape (num_active_strains,).

required
s_ps Array

Backbone coordinates with shape (num_points,).

required

Returns:

Type Description
Array

Inertial-frame Jacobians with shape

Array

(num_points, 6, num_active_strains).

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_velocities).

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_coordinates,).

required
qd Array

Generalized velocities of shape (num_velocities,).

required
s Array

Position parameter along the robot structure.

required

Returns:

Name Type Description
J Array

Jacobian matrix of shape (n_pose_dim, num_velocities).

Jd Array

Time derivative of the Jacobian, shape (n_pose_dim, num_velocities).

jacobian_and_time_derivative_abscissa_batched

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

Compute batched inertial Jacobians and their time derivatives.

Parameters:

Name Type Description Default
q Array

Active generalized strains with shape (num_active_strains,).

required
qd Array

Active generalized strain rates with shape (num_active_strains,).

required
s_ps Array

Backbone coordinates with shape (num_points,).

required

Returns:

Type Description
Array

A tuple (J, J_dot) whose arrays both have shape

Array

(num_points, 6, num_active_strains).

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_abscissa_batched

jacobian_bodyframe_abscissa_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_abscissa_batched

jacobian_and_time_derivative_bodyframe_abscissa_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_internal_dofs,).

required
qd Array

Active generalized velocities, shape (self.num_internal_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_internal_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_coordinates,).

required

Returns:

Name Type Description
G Array

Gravitational force of shape (num_velocities,).

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_coordinates,).

required

Returns:

Name Type Description
tau_pot Array

Potential force of shape (num_velocities,).

actuator_coordinates

actuator_coordinates(q: Array) -> Array

Return the installed transmissions' work-conjugate coordinates.

Coordinates are concatenated in actuator and channel order, matching the columns of :meth:actuation_matrix and the entries returned by :meth:actuator_efforts. Their physical units may differ between actuator families, such as length for tendons or volume for pressure actuation.

Parameters:

Name Type Description Default
q Array

Generalized coordinates of shape (num_coordinates,).

required

Returns:

Name Type Description
y_a Array

Actuator coordinates of shape (num_actuators,). An unactuated robot returns an empty array.

actuator_velocities

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

Return the installed transmissions' coordinate velocities.

Velocities are concatenated in actuator and channel order and satisfy yd_a = A(q).T @ qd, where A(q) is the concatenated actuator transmission matrix.

Parameters:

Name Type Description Default
q Array

Generalized coordinates of shape (num_coordinates,).

required
qd Array

Generalized velocities of shape (num_velocities,).

required

Returns:

Name Type Description
yd_a Array

Actuator-coordinate velocities of shape (num_actuators,). An unactuated robot returns an empty array.

actuation_matrix

actuation_matrix(q: Array, *, backend: ExecutionBackend | None = None) -> Array

Return the actuator matrix through the selected execution backend.

actuator_efforts

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

Map user controls to work-conjugate actuator efforts.

Controls and returned efforts follow the order of the installed actuators. Effort models evaluate the actuator coordinates or velocities only when those quantities are required. If an effort model requires velocity and qd is omitted, zero generalized velocity is used.

Parameters:

Name Type Description Default
q Array

Generalized coordinates of shape (num_coordinates,).

required
u Array

Actuator controls of shape (num_actuators,).

required
qd Array | None

Optional generalized velocities of shape (num_velocities,).

None
actuation_matrix Array | None

Optional precomputed actuator transmission matrix with shape (num_velocities, num_actuators). It is reused for velocity-dependent effort laws.

None

Returns:

Name Type Description
e Array

Work-conjugate actuator efforts of shape (num_actuators,).

Raises:

Type Description
ValueError

If u or actuation_matrix has an incompatible shape.

actuation_force

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

Return generalized actuator force through the selected backend.

passive_elastic_force

passive_elastic_force(q: Array) -> Array

Return the installed passive elements' elastic generalized force.

This method sums only composable passive-element contributions. System implementations add the result to their intrinsic body elasticity when evaluating :meth:elastic_force.

Parameters:

Name Type Description Default
q Array

Generalized coordinates of shape (num_coordinates,).

required

Returns:

Name Type Description
tau_passive Array

Passive elastic generalized force of shape (num_velocities,). A robot without passive elements returns zeros.

passive_damping_matrix

passive_damping_matrix(q: Array) -> Array

Return the installed passive elements' generalized damping matrix.

This method sums only composable passive-element contributions. System implementations add the result to their intrinsic body damping when evaluating :meth:damping_matrix.

Parameters:

Name Type Description Default
q Array

Generalized coordinates of shape (num_coordinates,).

required

Returns:

Name Type Description
D_passive Array

Passive damping matrix of shape (num_velocities, num_velocities). A robot without passive elements returns zeros.

passive_elastic_energy

passive_elastic_energy(q: Array) -> Array

Return the installed passive elements' stored elastic energy.

This method sums only composable passive-element contributions. System implementations add the result to their intrinsic body strain energy when evaluating elastic or potential energy.

Parameters:

Name Type Description Default
q Array

Generalized coordinates of shape (num_coordinates,).

required

Returns:

Name Type Description
U_passive Array

Scalar passive elastic energy. A robot without passive elements returns zero.

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_coordinates,).

required
qd Array

Generalized velocities of shape (num_velocities,).

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_coordinates,).

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_coordinates,).

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_coordinates,).

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_coordinates,).

required
qd Array

Generalized velocities of shape (num_velocities,).

required

Returns:

Name Type Description
E Array

Total energy (scalar).

dynamics_terms

dynamics_terms(q: Array, qd: Array, *, backend: ExecutionBackend | None = None) -> tuple[Array, Array, Array]

Assemble spatial PCS dynamics terms for one or many environments.

backend=None uses the model's configured :attr:backend. Warp is selected for forward-only GPU execution with any positive quadrature count; CPU execution and all forward- or reverse-mode differentiation use the JAX implementation. Applying :func:jax.vmap to scalar calls invokes one batch-shaped Warp pipeline rather than mapping independent batch-one launches.

The Warp implementation uses FP64 local constant-strain operators and one persistent cooperative chain block per environment. Its generated source is independent of the batch size and segment count. Install the optional dependency with pip install soromox[warp] before explicitly requesting it.

Parameters:

Name Type Description Default
q Array

Active generalized coordinates with shape (num_dofs,) or (batch_size, num_dofs).

required
qd Array

Active generalized velocities with the same shape as q.

required
backend ExecutionBackend | None

Optional per-call override: "auto", "jax", or "warp". None uses :attr:backend.

None

Returns:

Type Description
Array

Tuple (B, Cqd, G) with the same optional leading batch dimension

Array

as the inputs. B is the active inertia matrix, Cqd is the

Array

Coriolis/centrifugal force action, and G is generalized gravity.

Raises:

Type Description
ValueError

If the backend or input shapes are invalid, or a Warp batch is empty.

TypeError

If Warp is selected for non-FP64 states.

ImportError

If Warp is selected but warp-lang is unavailable.

params_from_links(links: list[LinkSpec] | tuple[LinkSpec, ...], *, gravity: Array | None = None) -> PCSParams

Build spatial PCS parameters from shared link specifications.

Parameters:

Name Type Description Default
links list[LinkSpec] | tuple[LinkSpec, ...]

Non-empty sequence of constant, circular link specifications. Each reference strain must have shape (6,).

required
gravity Array | None

Optional world-frame gravity vector with shape (3,).

None

Returns:

Name Type Description
Validated PCSParams

class:PCSParams with canonical per-link stiffness and

PCSParams

damping arrays of shape (num_links, 6, 6).

Raises:

Type Description
ValueError

If no links are supplied; a link is not constant and circular; a reference strain has the wrong shape; a material source is incomplete; or an explicit matrix is not (6, 6).

from_links(links: list[LinkSpec] | tuple[LinkSpec, ...], *, structure: PCSStructure | None = None, gravity: Array | None = None, base_pose: Array | None = None, **kwargs: Any) -> PCS

Construct a spatial PCS model from shared link specifications.

Parameters:

Name Type Description Default
links list[LinkSpec] | tuple[LinkSpec, ...]

Non-empty sequence of constant, circular link specifications.

required
structure PCSStructure | None

Optional static PCS quadrature, strain-selection, and rotational-scaling configuration. Defaults to :class:PCSStructure.

None
gravity Array | None

Optional world-frame gravity vector with shape (3,).

None
base_pose Array | None

Optional base translation and unit quaternion with shape (7,).

None
**kwargs Any

Additional keyword arguments forwarded to the PCS constructor, such as actuators or passive elements.

{}

Returns:

Type Description
PCS

A fully initialized spatial PCS model.

Raises:

Type Description
TypeError

If a structure or constructor argument has an invalid type.

ValueError

If a link specification, static structure, parameter array, or attached component is invalid.

update_link_params(**updates: Any) -> PCS

Return a copy with selected continuum-link fields replaced.

Parameters:

Name Type Description Default
**updates Any

Fields of :class:ContinuumLinkParams to replace, such as length, density, reference_strain, cross_section, stiffness, or damping.

{}

Returns:

Type Description
PCS

A new validated PCS model with refreshed dependent caches.

Raises:

Type Description
TypeError

If an unknown link field is supplied.

ValueError

If a replacement is invalid or changes the static segment or strain layout.

link_matrices_from_material(material: IsotropicMaterialParams) -> tuple[Array, Array]

Map isotropic material variables to canonical PCS link matrices.

Parameters:

Name Type Description Default
material IsotropicMaterialParams

Scalar or per-segment Young's modulus, either shear modulus or Poisson's ratio, and optional material damping coefficient. Scalars are broadcast over all segments.

required

Returns:

Type Description
Array

A tuple (stiffness, damping) whose arrays both have shape

Array

(num_segments, 6, 6).

Raises:

Type Description
ValueError

If a material field is not scalar or does not have shape (num_segments,).

with_isotropic_material

with_isotropic_material(material: IsotropicMaterialParams) -> Self

Return a copy whose link matrices are built from isotropic material.

The supplied material PyTree remains caller-owned and is not stored on the model.

Parameters:

Name Type Description Default
material IsotropicMaterialParams

Scalar or per-segment isotropic material variables.

required

Returns:

Type Description
Self

A new PCS model containing the generated canonical link stiffness

Self

and damping matrices.

Raises:

Type Description
ValueError

If a material field cannot be broadcast to one value per segment.

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 a body-frame Jacobian and its arc-length derivative.

Parameters:

Name Type Description Default
q Array

Active generalized strains with shape (num_active_strains,).

required
s Array

Scalar global backbone coordinate.

required

Returns:

Type Description
Array

A tuple (J, J_s) containing the body-frame Jacobian and its

Array

derivative with respect to global arc length. Both arrays have

tuple[Array, Array]

shape (6, num_active_strains).

jacobian_arc_length_derivative_bodyframe

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

Compute the body-frame Jacobian derivative with respect to arc length.

Parameters:

Name Type Description Default
q Array

Active generalized strains with shape (num_active_strains,).

required
s Array

Scalar global backbone coordinate.

required

Returns:

Type Description
Array

Arc-length derivative with shape

Array

(6, num_active_strains).

jacobian_inertialframe

jacobian_inertialframe(q: Array, s: Array, *, backend: ExecutionBackend | None = None) -> Array

Compute an inertial Jacobian at one curvilinear abscissa.

Parameters:

Name Type Description Default
q Array

Active generalized strains with shape (D,).

required
s Array

Scalar curvilinear abscissa.

required
backend ExecutionBackend | None

Optional execution override. None uses the model's configured backend.

None

Returns:

Type Description
Array

Inertial Jacobian with shape (6, D).

jacobian_inertialframe_abscissa_batched

jacobian_inertialframe_abscissa_batched(q: Array, s_ps: Array, *, backend: ExecutionBackend | None = None) -> Array

Compute inertial Jacobians at a batch of curvilinear abscissae.

Parameters:

Name Type Description Default
q Array

Active generalized strains with shape (D,).

required
s_ps Array

Curvilinear abscissae with shape (N,).

required
backend ExecutionBackend | None

Optional execution override. None uses the model's configured backend.

None

Returns:

Type Description
Array

Inertial-frame Jacobians with shape (N, 6, D).

forward_kinematics_and_jacobian_inertialframe

forward_kinematics_and_jacobian_inertialframe(q: Array, s: Array, *, backend: ExecutionBackend | None = None) -> tuple[Array, Array]

Compute an SE(3) pose and inertial Jacobian in one traversal.

Parameters:

Name Type Description Default
q Array

Active generalized strains with shape (D,).

required
s Array

Scalar curvilinear abscissa.

required
backend ExecutionBackend | None

Optional execution override. None uses the model's configured backend.

None

Returns:

Type Description
Array

A pose with shape (4, 4) and an inertial Jacobian with shape

Array

(6, D).

forward_kinematics_and_jacobian_inertialframe_abscissa_batched

forward_kinematics_and_jacobian_inertialframe_abscissa_batched(q: Array, s_ps: Array, *, backend: ExecutionBackend | None = None) -> tuple[Array, Array]

Compute fused poses and Jacobians for an abscissa batch.

Parameters:

Name Type Description Default
q Array

Active generalized strains with shape (D,).

required
s_ps Array

Curvilinear abscissae with shape (N,).

required
backend ExecutionBackend | None

Optional execution override. None uses the model's configured backend.

None

Returns:

Type Description
Array

Poses with shape (N, 4, 4) and inertial Jacobians with shape

Array

(N, 6, D).

jacobian_and_arc_length_derivative_inertialframe

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

Compute an inertial-frame Jacobian and its arc-length derivative.

Parameters:

Name Type Description Default
q Array

Active generalized strains with shape (num_active_strains,).

required
s Array

Scalar global backbone coordinate.

required

Returns:

Type Description
Array

A tuple (J, J_s) containing the inertial-frame Jacobian and its

Array

derivative with respect to global arc length. Both arrays have

tuple[Array, Array]

shape (6, num_active_strains).

jacobian_arc_length_derivative_inertialframe

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

Compute the inertial Jacobian derivative with respect to arc length.

Parameters:

Name Type Description Default
q Array

Active generalized strains with shape (num_active_strains,).

required
s Array

Scalar global backbone coordinate.

required

Returns:

Type Description
Array

Arc-length derivative with shape

Array

(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_abscissa_batched

jacobian_and_time_derivative_inertialframe_abscissa_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