Skip to content

Actuation-Space Controllers

The coordinates used here are supplied by the common actuation model, including signed/scaled threadlike coordinates rather than raw tendon lengths.

Actuation-space controllers operate in a transformed coordinate system where the actuation matrix becomes a simple identity structure. This formulation, developed by Pustina et al. (2024) and further elaborated in Pustina (2025), provides a clean separation between actuated and unactuated dynamics, making it particularly well-suited for underactuated soft robots.

Overview

The key insight of actuation-space control is to transform the robot dynamics into a collocated form (also called input-decoupled form), where the actuation matrix becomes:

\[ A_y = \begin{bmatrix} I_{n_a} \\ 0_{n_u \times n_a} \end{bmatrix} \]

where:

  • \(n_a\) is the number of actuators
  • \(n_u = n - n_a\) is the number of unactuated degrees of freedom

In this representation:

  • The first \(n_a\) rows (actuated coordinates) are directly controlled via an identity actuation matrix
  • The remaining \(n_u\) rows (unactuated coordinates) receive no direct actuation—they evolve according to dynamic coupling only

Benefits of Actuation-Space Formulation

Key Advantages

  1. Natural handling of underactuation: Clean separation between actuated and unactuated dynamics without needing pseudo-inverses
  2. No actuation matrix inversion in the control law: Control inputs directly map to actuator forces without requiring \(A(q)^{-1}\) or \(A(q)^{\dagger}\) in the control law
  3. Simplified stability analysis: Standard Lyapunov-based arguments can be applied directly to the actuated subsystem
  4. Handles configuration-dependent actuation: Works seamlessly with non-constant, non-diagonal, and non-square actuation matrices as long as mapping from configuration- to actuation-space exists (i.e., integrability condition from (Pustina et al., 2024) is satisfied)

Controller Summary

Controller Type Model-Based Term Description
PIDController Tracker None Pure PID control in actuation space
FeedforwardCompensationTracker Tracker Full dynamics at \(q_\mathrm{des}\) Open-loop feedforward + feedback
MixedStateFeedbackTracker Tracker Mixed state evaluation Hybrid feedforward strategy
GravityCancellationRegulator Regulator \(G_y(q) + \tau_{\mathrm{el},y}(q_\mathrm{des})\) Real-time gravity compensation
PotentialCancellationRegulator Regulator \(G_y(q) + \tau_{\mathrm{el},y}(q)\) Full potential cancellation
PotentialCompensationRegulator Regulator \(G_y(q_\mathrm{des}) + \tau_{\mathrm{el},y}(q_\mathrm{des})\) Potential shaping

Zero Dynamics and Stability

Zero Dynamics Assumption

In any underactuated control setting—regardless of whether the controller operates in configuration space, operational space, or actuation space—a key assumption is that the zero dynamics (the dynamics of unactuated coordinates when actuated coordinates are perfectly controlled) are stable or at least bounded.

Why emphasized here?

While the zero dynamics stability assumption applies universally to all underactuated systems, we emphasize it in the actuation-space context because actuation-space controllers are particularly well-suited for underactuated robots. The clean separation between actuated and unactuated dynamics in this formulation makes the role of zero dynamics especially transparent.

For soft robots, this assumption is often satisfied because:

  • Elastic forces provide natural restoring behavior
  • Damping forces dissipate energy from unactuated modes
  • Gravitational potential often has stabilizing effects

However, if the zero dynamics are unstable, trajectory tracking may fail despite perfect tracking on the actuated coordinates. This limitation is fundamental to underactuation and cannot be overcome by any control strategy—whether in configuration space, operational space, or actuation space.


Reference Trajectory Feasibility

In underactuated settings (\(n_u > 0\)), the reference trajectory cannot be arbitrarily specified:

Regulation (Setpoint Control)

For setpoint regulation, the unactuated coordinates of the setpoint must be statically feasible—there must exist an equilibrium of the system at the desired configuration. Otherwise, the system cannot remain at rest at the setpoint, even with perfect control of the actuated coordinates.

Trajectory Tracking

For trajectory tracking, the unactuated coordinates of the reference trajectory must be dynamically feasible—the trajectory must be consistent with the system's equations of motion. In other words, the reference must correspond to a valid solution of the zero dynamics.

Practical Recommendation

For underactuated systems, setpoint regulation is generally more robust than trajectory tracking since it only requires static feasibility of the unactuated coordinates.


Base Class

All actuation-space controllers inherit from ActuationSpaceBaseController:

soromox.control.actuation_space.ActuationSpaceBaseController

Bases: BaseController, ABC


              flowchart TD
              soromox.control.actuation_space.ActuationSpaceBaseController[ActuationSpaceBaseController]
              soromox.control.base_controller.BaseController[BaseController]

                              soromox.control.base_controller.BaseController --> soromox.control.actuation_space.ActuationSpaceBaseController
                


              click soromox.control.actuation_space.ActuationSpaceBaseController href "" "soromox.control.actuation_space.ActuationSpaceBaseController"
              click soromox.control.base_controller.BaseController href "" "soromox.control.base_controller.BaseController"
            

Abstract base class for actuation-space controllers.

Actuation-space control, as developed in the fundamental work by Pustina et al. (2024) and Pustina (2025), represents the robot dynamics in a collocated form (also called input-decoupled form), where the actuation matrix becomes a simple identity structure:

A_y = [[I_{n_a}], [0_{n_u, n_a}]]

where n_a is the number of actuators and n_u = n - n_a is the number of unactuated degrees of freedom. In this form:

  • The first n_a/num_actuators rows (actuated coordinates) are directly actuated via an identity actuation matrix, meaning actuator inputs directly map to generalized forces on these coordinates.
  • The remaining n_u (i.e., num_dofs - num_actuators) rows (unactuated coordinates) receive no direct actuation input—they are driven only by dynamic coupling.
Benefits of Actuation-Space Formulation
  1. Natural handling of actuation coupling and underactuation: For robots with full (i.e., non-diagonal) and on-square actuation matrices A(q), the actuation-space formulation provides a clean separation between the actuated and unactuated dynamics.

  2. Simplified stability/convergence proofs: Control design and stability analysis become significantly easier when the actuation structure is diagonal. Standard Lyapunov-based arguments can be applied directly to the actuated subsystem without needing to account for the structure of A(q).

Zero Dynamics and Stability

In any underactuated control setting—regardless of whether the controller operates in configuration space, operational space, or actuation space—a key assumption is that the zero dynamics (i.e., the dynamics of the unactuated coordinates when the actuated coordinates are perfectly controlled) are stable or at least bounded.

We emphasize this assumption here because actuation-space controllers are particularly well-suited for underactuated robots, and the clean separation between actuated and unactuated dynamics in this formulation makes the role of zero dynamics especially transparent.

This assumption is often satisfied for soft robots because:

  • Elastic and damping forces provide natural stabilization of the unactuated modes
  • The internal dynamics of soft materials tend to be dissipative
  • Gravitational potential energy often has stabilizing effects

When designing controllers, keep in mind: - Controllers typically only directly control the first n_a (actuated) coordinates - The unactuated coordinates evolve according to the zero dynamics - If the zero dynamics are unstable, trajectory tracking may fail despite perfect tracking on the actuated coordinates - This limitation is fundamental to underactuation and cannot be overcome by any control strategy—whether in configuration space, operational space, or actuation space

Feasibility of Reference Trajectories in Underactuated Settings

In underactuated settings (n_u > 0), the reference trajectory for the unactuated coordinates cannot be arbitrarily specified. The unactuated coordinates are not directly controlled and evolve according to the system's internal dynamics.

  • Regulation (setpoint control): The unactuated coordinates of the setpoint must be statically feasible, meaning there must exist an equilibrium of the system at the desired configuration. Otherwise, the system cannot remain at rest at the setpoint, even with perfect control of the actuated coordinates.

  • Tracking (trajectory following): The unactuated coordinates of the reference trajectory must be at least dynamically feasible, meaning the trajectory must be consistent with the system's equations of motion. In other words, the reference must correspond to a valid solution of the zero dynamics.

If these feasibility conditions are not satisfied, the controller will be unable to achieve the desired behavior, regardless of control gains or design.

Reference Trajectory Conversion

This base class provides a convert_reference_trajectory_to_actuation_space method that transforms a configuration-space reference trajectory to actuation space using the coordinate transformations provided by ActuationSpaceDynamics. This ensures that: - Position setpoints are mapped through the (generally nonlinear) actuated coordinate map for the actuated coordinates - Velocity and acceleration references are properly transformed using the Jacobian and its time derivatives

Attributes:

Name Type Description
robot SoftRobot

The soft robot system to be controlled (set to actuation_space_dynamics.robot).

reference_trajectory ReferenceTrajectory

The desired trajectory in actuation space.

reference_trajectory_config_space ReferenceTrajectory | None

The original configuration-space trajectory, or None if trajectory was provided directly in actuation space. This is needed for model-based control terms that evaluate dynamics at q_des, since the inverse mapping from actuation space y back to configuration space q is generally nonlinear and not trivially invertible.

actuation_space_dynamics ActuationSpaceDynamics

The ActuationSpaceDynamics instance that provides coordinate transformations between configuration and actuation space.

References

Pustina, P., Della Santina, C., Boyer, F., De Luca, A., & Renda, F. (2024). Input decoupling of lagrangian systems via coordinate transformation: General characterization and its application to soft robotics. IEEE Transactions on Robotics, 40, 2098-2110.

Pustina, P. (2025). Analysis and control of the underactuation in continuum soft robots: a kinematic independent approach. PhD Thesis, Sapienza University of Rome.

__call__ abstractmethod

__call__(system_state: SystemState) -> tuple[Array, Any | None]

Compute the control action given the current system state.

This method is called at each control step to compute the actuation input based on the current state and the reference trajectory.

Implementations should be JAX-compatible (jittable) for use with the rollout methods in DynamicalSystem. Avoid Python control flow that depends on array values; use jax.lax primitives instead.

Parameters:

Name Type Description Default
system_state SystemState

The current state of the system, containing: - t (Array): Current simulation time - y (Array): Robot state vector (typically, configuration and velocity) - u (Optional[Array]): Previous actuation input (optional) - control_state (Optional[Any]): Internal controller state (optional) - environment_state (Optional[Any]): Environment state (optional)

required

Returns:

Name Type Description
u_control Array

The control input to apply, shape (num_actuators,).

control_state_dot Optional[Any]

Time derivative of the internal controller state as a PyTree (e.g., integrator error for integral control), or None if the controller is stateless.


Trajectory Trackers

Trajectory trackers are designed for dynamic trajectory tracking where the reference includes position, velocity, and acceleration profiles.

PIDController

Basic PID controller in actuation space without model-based feedforward. By working in actuation space, there is no need to invert the actuation matrix—the control input is directly the actuator force/torque.

The control law is:

\[ \tau = K_p e_a + K_i \int e_a \, dt + K_d \dot{e}_a \]

where \(e_a = y_{a,\mathrm{des}} - y_a\) is the error in the actuated coordinates (first \(n_a\) entries of the actuation-space coordinates).

Direct Actuation

Unlike configuration-space controllers that require \(\tau = A(q)^{-1} \cdot (\text{control law})\), the actuation-space PID output \(\tau\) is directly the actuator input without any matrix inversion.

soromox.control.actuation_space.PIDController

PIDController(actuation_space_dynamics: ActuationSpaceDynamics, reference_trajectory: ReferenceTrajectory, pid_control: PIDControl, reference_in_configuration_space: bool = True)

Bases: ActuationSpaceBaseController, ClosedFormModelBasedController


              flowchart TD
              soromox.control.actuation_space.PIDController[PIDController]
              soromox.control.actuation_space.base_controller.ActuationSpaceBaseController[ActuationSpaceBaseController]
              soromox.control.closed_form_model_based_controller.ClosedFormModelBasedController[ClosedFormModelBasedController]
              soromox.control.base_controller.BaseController[BaseController]

                              soromox.control.actuation_space.base_controller.ActuationSpaceBaseController --> soromox.control.actuation_space.PIDController
                                soromox.control.base_controller.BaseController --> soromox.control.actuation_space.base_controller.ActuationSpaceBaseController
                

                soromox.control.closed_form_model_based_controller.ClosedFormModelBasedController --> soromox.control.actuation_space.PIDController
                                soromox.control.base_controller.BaseController --> soromox.control.closed_form_model_based_controller.ClosedFormModelBasedController
                



              click soromox.control.actuation_space.PIDController href "" "soromox.control.actuation_space.PIDController"
              click soromox.control.actuation_space.base_controller.ActuationSpaceBaseController href "" "soromox.control.actuation_space.base_controller.ActuationSpaceBaseController"
              click soromox.control.closed_form_model_based_controller.ClosedFormModelBasedController href "" "soromox.control.closed_form_model_based_controller.ClosedFormModelBasedController"
              click soromox.control.base_controller.BaseController href "" "soromox.control.base_controller.BaseController"
            

PID controller in actuation space for soft robots.

This controller implements PID control in the robot's actuation space, computing control inputs based on tracking errors in the actuated coordinates only. By working in actuation space, the controller benefits from the collocated form where the actuation matrix is an identity (for the actuated coordinates).

Key Features
  1. Direct control of actuated coordinates: The PID operates only on the first n_a (actuated) coordinates in actuation space. These coordinates directly correspond to actuator inputs via the identity actuation structure.

  2. No actuation matrix inversion: Unlike configuration-space controllers, there is no need to invert or pseudo-invert the actuation matrix A(q) in the control law. The control input tau is directly the actuator force/torque.

  3. Automatic reference trajectory conversion: If a configuration-space reference trajectory is provided, it is automatically converted to actuation space using the coordinate transformations.

Control Law

The control law is:

tau = Kp @ e_a + Ki @ integral_error_a + Kd @ ed_a
where
  • e_a = y_a_des - y_a is the actuated coordinate error (shape: n_a)
  • ed_a = yd_a_des - yd_a is the actuated velocity error (shape: n_a)
  • integral_error_a = integral of sat(e_a) over time
  • sat() is an optional saturation function for anti-windup
  • tau is the actuator input (shape: n_a)

The subscript "_a" denotes the actuated portion (first n_a entries) of the actuation-space coordinates.

Zero Dynamics Assumption

In any underactuated control setting—regardless of whether the controller operates in configuration space, operational space, or actuation space—a key assumption is that the zero dynamics (dynamics of unactuated coordinates when actuated coordinates are perfectly tracked) are stable. We emphasize this here because actuation-space controllers are particularly well-suited for underactuated robots. For soft robots with elastic restoring forces and damping, this assumption is typically satisfied. If the zero dynamics are unstable, the unactuated coordinates may diverge even with perfect tracking on the actuated coordinates.

Usage

The controller can be initialized with either:

  1. A configuration-space reference trajectory (will be automatically converted)
  2. An actuation-space reference trajectory (used directly)

Set reference_in_configuration_space=True (default) if providing a configuration-space trajectory, or False if providing an actuation-space trajectory directly.

Attributes:

Name Type Description
robot

The soft robot system to be controlled.

reference_trajectory

The desired trajectory in actuation space.

reference_trajectory_config_space

The original configuration-space trajectory, or None if trajectory was provided in actuation space. Used by subclasses for model-based control terms that need to evaluate dynamics at q_des.

actuation_space_dynamics

The ActuationSpaceDynamics instance for coordinate transformations.

pid_control PIDControl

The PIDControl instance containing gains and saturation. Note: Gains should be sized for the actuated coordinates (n_a).

Initialize the actuation-space PID controller.

Parameters:

Name Type Description Default
actuation_space_dynamics ActuationSpaceDynamics

The ActuationSpaceDynamics instance that provides coordinate transformations and contains the robot.

required
reference_trajectory ReferenceTrajectory

The desired trajectory to track. If reference_in_configuration_space=True, this should be a configuration-space trajectory which will be converted to actuation space. Otherwise, it should already be in actuation space.

required
pid_control PIDControl

A PIDControl instance containing the control gains (Kp, Ki, Kd) and optional saturation function. The gains should be sized for the actuated coordinates (n_a x n_a or n_a).

required
reference_in_configuration_space bool

If True (default), the reference trajectory is in configuration space and will be converted to actuation space. If False, the reference trajectory is already in actuation space.

True
Note

When reference_in_configuration_space=True, the original configuration- space trajectory is stored in reference_trajectory_config_space for use by model-based controllers that need to evaluate dynamics at q_des. This is necessary because the mapping from actuation space y back to configuration space q is generally nonlinear and not trivially invertible (e.g., for PCS with configuration-dependent tendon routing).

__call__
__call__(system_state: SystemState) -> tuple[Array, Any | None]

Compute the combined control action.

Combines the model-based feedforward term and the error-based feedback term by summing both the control inputs and the control state derivatives.

Parameters:

Name Type Description Default
system_state SystemState

The current state of the system.

required

Returns:

Name Type Description
u_control Array

Combined control input, shape (num_actuators,).

control_state_dot Optional[Any]

Combined time derivative of the internal controller state, or None if both terms are stateless.

model_based_term
model_based_term(system_state: SystemState) -> tuple[Array, Any | None]

Compute the model-based feedforward control term.

This term typically computes the control input required to achieve the desired trajectory based on the system dynamics model (e.g., inverse dynamics, gravity compensation).

The default implementation returns zero control input. Subclasses can override this method to provide model-based feedforward control.

Parameters:

Name Type Description Default
system_state SystemState

The current state of the system.

required

Returns:

Name Type Description
u_model Array

Model-based control input, shape (num_actuators,).

control_state_dot Optional[Any]

Time derivative of the internal controller state contributed by this term, or None.

error_based_feedback_term
error_based_feedback_term(system_state: SystemState) -> tuple[Array, PIDControllerState | None]

Compute the PID feedback control term in actuation space.

This method computes the PID control action based on the tracking error in the actuated coordinates only (first n_a coordinates in actuation space).

Parameters:

Name Type Description Default
system_state SystemState

The current state of the system, containing: - t: Current simulation time - y: Robot state vector [q, qd] (configuration and velocity) - control_state: PIDControllerState containing integral error of shape (n_a,), or None if not using integral control.

required

Returns:

Name Type Description
tau Array

The actuator control input, shape (num_actuators,).

control_state_dot PIDControllerState | None

Time derivative of the PIDControllerState, or None if no control state is being tracked.

update_gains
update_gains(gains: dict[str, Array]) -> PIDController

This function updates the gains of the PID controller.

Parameters:

Name Type Description Default
gains dict[str, Array]

proportional, integral, and derivative gains

required

Returns:

Name Type Description
updated_self PIDController

self object with updated gains


FeedforwardCompensationTracker

Feedforward compensation evaluates the complete inverse dynamics at the desired configuration in actuation space. This provides open-loop feedforward plus feedback correction.

The control law is:

\[ \tau_\mathrm{model} = M_y(q_\mathrm{des}) \ddot{y}_\mathrm{des} + \eta_y(q_\mathrm{des}, \dot{q}_\mathrm{des}) \dot{y}_\mathrm{des} + G_y(q_\mathrm{des}) + \tau_{\mathrm{el},y}(q_\mathrm{des}) + D_y(q_\mathrm{des}) \dot{y}_\mathrm{des} \]
\[ \tau = \tau_\mathrm{model}[:n_a] + \tau_\mathrm{feedback} \]

where \([:n_a]\) denotes extracting only the first \(n_a\) (actuated) rows.

Underactuation

In underactuated settings, trajectory tracking is an open research problem. The reference trajectory for unactuated coordinates must be dynamically feasible. The controller will emit a warning when used with underactuated systems.

soromox.control.actuation_space.FeedforwardCompensationTracker

FeedforwardCompensationTracker(actuation_space_dynamics: ActuationSpaceDynamics, reference_trajectory: ReferenceTrajectory, pid_control: PIDControl, reference_in_configuration_space: bool = True)

Bases: PIDController


              flowchart TD
              soromox.control.actuation_space.FeedforwardCompensationTracker[FeedforwardCompensationTracker]
              soromox.control.actuation_space.pid_controller.PIDController[PIDController]
              soromox.control.actuation_space.base_controller.ActuationSpaceBaseController[ActuationSpaceBaseController]
              soromox.control.closed_form_model_based_controller.ClosedFormModelBasedController[ClosedFormModelBasedController]
              soromox.control.base_controller.BaseController[BaseController]

                              soromox.control.actuation_space.pid_controller.PIDController --> soromox.control.actuation_space.FeedforwardCompensationTracker
                                soromox.control.actuation_space.base_controller.ActuationSpaceBaseController --> soromox.control.actuation_space.pid_controller.PIDController
                                soromox.control.base_controller.BaseController --> soromox.control.actuation_space.base_controller.ActuationSpaceBaseController
                

                soromox.control.closed_form_model_based_controller.ClosedFormModelBasedController --> soromox.control.actuation_space.pid_controller.PIDController
                                soromox.control.base_controller.BaseController --> soromox.control.closed_form_model_based_controller.ClosedFormModelBasedController
                




              click soromox.control.actuation_space.FeedforwardCompensationTracker href "" "soromox.control.actuation_space.FeedforwardCompensationTracker"
              click soromox.control.actuation_space.pid_controller.PIDController href "" "soromox.control.actuation_space.pid_controller.PIDController"
              click soromox.control.actuation_space.base_controller.ActuationSpaceBaseController href "" "soromox.control.actuation_space.base_controller.ActuationSpaceBaseController"
              click soromox.control.closed_form_model_based_controller.ClosedFormModelBasedController href "" "soromox.control.closed_form_model_based_controller.ClosedFormModelBasedController"
              click soromox.control.base_controller.BaseController href "" "soromox.control.base_controller.BaseController"
            

Feedforward compensation trajectory tracker in actuation space for soft robots.

This controller extends the actuation-space PIDController by adding a model-based feedforward term that evaluates the complete inverse dynamics at the desired configuration. It computes the inertial forces, Coriolis forces, gravitational forces, elastic forces, and damping forces all evaluated at the desired configuration q_des, then transforms them to actuation space.

By working in actuation space, this controller benefits from the collocated form where the actuation matrix becomes an identity for the actuated coordinates. The model-based term is computed by: 1. Evaluating the actuation-space dynamics at q_des (from the configuration-space reference trajectory) 2. Using the actuation-space velocities yd_des and accelerations ydd_des 3. Extracting only the first n_a (actuated) rows for the control input

Important

This controller requires the reference trajectory to be provided in configuration space (reference_in_configuration_space=True). The configuration-space trajectory is needed to evaluate dynamics at q_des, since the inverse mapping from actuation space y back to configuration space q is generally nonlinear and not trivially invertible.

Control Law

The control law is:

tau_model_y = M_y(q_des) @ ydd_des + eta_y(q_des, qd_des) @ yd_des
              + G_y(q_des) + tau_el_y(q_des) + D_y(q_des) @ yd_des

tau = tau_model_y[:n_a] + tau_feedback
where
  • M_y is the actuation-space inertia matrix evaluated at q_des
  • eta_y is the actuation-space Coriolis matrix evaluated at (q_des, qd_des)
  • G_y is the actuation-space gravitational force evaluated at q_des
  • tau_el_y is the actuation-space elastic force evaluated at q_des
  • D_y is the actuation-space damping matrix evaluated at q_des
  • yd_des, ydd_des are the desired velocity and acceleration in actuation space
  • n_a is the number of actuators
  • tau is the actuator input (shape: n_a)
  • tau_feedback is the PID feedback term from the parent class

Only the first n_a rows of the actuation-space forces contribute to the control input, corresponding to the actuated coordinates.

Underactuation Warning

In underactuated settings (n_u > 0), trajectory tracking is an open research problem. The unactuated coordinates evolve according to the zero dynamics and cannot be independently controlled. The reference trajectory for the unactuated coordinates must be dynamically feasible, meaning it must correspond to a valid solution of the system's equations of motion. If the reference trajectory is not feasible, tracking performance may be significantly degraded.

Attributes:

Name Type Description
robot

The soft robot system to be controlled.

reference_trajectory

The desired trajectory in actuation space.

reference_trajectory_config_space

The original configuration-space trajectory (required for evaluating dynamics at q_des).

actuation_space_dynamics

The ActuationSpaceDynamics instance for coordinate transformations.

pid_control PIDControl

The PIDControl instance containing gains and saturation.

References

Della Santina, C., Duriez, C., & Rus, D. (2023). Model-based control of soft robots: A survey of the state of the art and open challenges. IEEE Control Systems Magazine, 43(3), 30-65.

Pustina, P. (2025). Analysis and control of the underactuation in continuum soft robots: a kinematic independent approach. PhD Thesis, Sapienza University of Rome.

Stölzle, M. (2025). Safe yet Precise Soft Robots: Incorporating Physics into Learned Models for Control. Dissertation, Delft University of Technology. https://doi.org/10.4233/uuid:24c1f667-8fd6-431a-bb78-11d22f8cb3da

Initialize the actuation-space feedforward compensation trajectory tracker.

Parameters:

Name Type Description Default
actuation_space_dynamics ActuationSpaceDynamics

The ActuationSpaceDynamics instance that provides coordinate transformations and contains the robot.

required
reference_trajectory ReferenceTrajectory

The desired trajectory to track. Must be in configuration space (set reference_in_configuration_space=True). The configuration-space trajectory is required to evaluate dynamics at q_des.

required
pid_control PIDControl

A PIDControl instance containing the control gains (Kp, Ki, Kd) and optional saturation function. The gains should be sized for the actuated coordinates (n_a x n_a or n_a).

required
reference_in_configuration_space bool

Must be True for this controller. The configuration-space trajectory is required to evaluate dynamics at the desired configuration q_des.

True

Raises:

Type Description
ValueError

If reference_in_configuration_space=False. This controller requires the configuration-space trajectory to evaluate dynamics.

__call__
__call__(system_state: SystemState) -> tuple[Array, Any | None]

Compute the combined control action.

Combines the model-based feedforward term and the error-based feedback term by summing both the control inputs and the control state derivatives.

Parameters:

Name Type Description Default
system_state SystemState

The current state of the system.

required

Returns:

Name Type Description
u_control Array

Combined control input, shape (num_actuators,).

control_state_dot Optional[Any]

Combined time derivative of the internal controller state, or None if both terms are stateless.

error_based_feedback_term
error_based_feedback_term(system_state: SystemState) -> tuple[Array, PIDControllerState | None]

Compute the PID feedback control term in actuation space.

This method computes the PID control action based on the tracking error in the actuated coordinates only (first n_a coordinates in actuation space).

Parameters:

Name Type Description Default
system_state SystemState

The current state of the system, containing: - t: Current simulation time - y: Robot state vector [q, qd] (configuration and velocity) - control_state: PIDControllerState containing integral error of shape (n_a,), or None if not using integral control.

required

Returns:

Name Type Description
tau Array

The actuator control input, shape (num_actuators,).

control_state_dot PIDControllerState | None

Time derivative of the PIDControllerState, or None if no control state is being tracked.

update_gains
update_gains(gains: dict[str, Array]) -> PIDController

This function updates the gains of the PID controller.

Parameters:

Name Type Description Default
gains dict[str, Array]

proportional, integral, and derivative gains

required

Returns:

Name Type Description
updated_self PIDController

self object with updated gains

model_based_term
model_based_term(system_state: SystemState) -> tuple[Array, Any | None]

Compute the model-based feedforward control term in actuation space.

This method computes the control input required to track the desired trajectory by evaluating the complete inverse dynamics at the desired configuration q_des. Only the first n_a (actuated) rows of the actuation- space forces contribute to the output.

Parameters:

Name Type Description Default
system_state SystemState

The current state of the system, containing: - t: Current simulation time - y: Robot state vector [q, qd] (configuration and velocity)

required

Returns:

Name Type Description
tau_model Array

The model-based control input, shape (num_actuators,).

control_state_dot Any | None

None (this term is stateless).


MixedStateFeedbackTracker

Mixed state feedback uses a hybrid evaluation strategy: dynamical matrices (inertia, Coriolis, gravitational, damping) are evaluated at the current state, while the desired velocities and accelerations are used for computing forces. Elastic forces are evaluated at the desired configuration.

The control law is:

\[ \tau_\mathrm{model} = M_y(q) \ddot{y}_\mathrm{des} + \eta_y(q, \dot{q}) \dot{y}_\mathrm{des} + G_y(q) + \tau_{\mathrm{el},y}(q_\mathrm{des}) + D_y(q) \dot{y}_\mathrm{des} \]
\[ \tau = \tau_\mathrm{model}[:n_a] + \tau_\mathrm{feedback} \]

This approach often provides better control performance than pure feedforward compensation since it uses the actual state for configuration-dependent matrices.

Coriolis Matrix Requirements

For theoretical stability guarantees, the Coriolis matrix \(C(q, \dot{q})\) must be derived using Christoffel symbols of the first kind, ensuring that \(N = \dot{M} - 2C\) is skew-symmetric.

soromox.control.actuation_space.MixedStateFeedbackTracker

MixedStateFeedbackTracker(actuation_space_dynamics: ActuationSpaceDynamics, reference_trajectory: ReferenceTrajectory, pid_control: PIDControl, reference_in_configuration_space: bool = True)

Bases: PIDController


              flowchart TD
              soromox.control.actuation_space.MixedStateFeedbackTracker[MixedStateFeedbackTracker]
              soromox.control.actuation_space.pid_controller.PIDController[PIDController]
              soromox.control.actuation_space.base_controller.ActuationSpaceBaseController[ActuationSpaceBaseController]
              soromox.control.closed_form_model_based_controller.ClosedFormModelBasedController[ClosedFormModelBasedController]
              soromox.control.base_controller.BaseController[BaseController]

                              soromox.control.actuation_space.pid_controller.PIDController --> soromox.control.actuation_space.MixedStateFeedbackTracker
                                soromox.control.actuation_space.base_controller.ActuationSpaceBaseController --> soromox.control.actuation_space.pid_controller.PIDController
                                soromox.control.base_controller.BaseController --> soromox.control.actuation_space.base_controller.ActuationSpaceBaseController
                

                soromox.control.closed_form_model_based_controller.ClosedFormModelBasedController --> soromox.control.actuation_space.pid_controller.PIDController
                                soromox.control.base_controller.BaseController --> soromox.control.closed_form_model_based_controller.ClosedFormModelBasedController
                




              click soromox.control.actuation_space.MixedStateFeedbackTracker href "" "soromox.control.actuation_space.MixedStateFeedbackTracker"
              click soromox.control.actuation_space.pid_controller.PIDController href "" "soromox.control.actuation_space.pid_controller.PIDController"
              click soromox.control.actuation_space.base_controller.ActuationSpaceBaseController href "" "soromox.control.actuation_space.base_controller.ActuationSpaceBaseController"
              click soromox.control.closed_form_model_based_controller.ClosedFormModelBasedController href "" "soromox.control.closed_form_model_based_controller.ClosedFormModelBasedController"
              click soromox.control.base_controller.BaseController href "" "soromox.control.base_controller.BaseController"
            

Mixed state feedback trajectory tracker in actuation space for soft robots.

This controller extends the actuation-space PIDController by adding a model-based feedforward term that uses a hybrid evaluation strategy in actuation space: the dynamical matrices (inertia, Coriolis, gravitational, damping) are evaluated at the current state, while the desired acceleration and velocity are used for computing the inertial, Coriolis, and damping forces. Only the elastic forces are evaluated at the desired configuration.

This mixed strategy often provides better control performance with good model knowledge compared to pure feedforward compensation since it uses the actual state for the configuration-dependent matrices while still providing feedforward action through the desired velocities and accelerations.

Important

This controller requires the reference trajectory to be provided in configuration space (reference_in_configuration_space=True). The configuration-space trajectory is needed to evaluate elastic forces at q_des, since the inverse mapping from actuation space y back to configuration space q is generally nonlinear and not trivially invertible.

Control Law

The control law is:

tau_model_y = M_y(q) @ ydd_des + eta_y(q, qd) @ yd_des
              + G_y(q) + tau_el_y(q_des) + D_y(q) @ yd_des

tau = tau_model_y[:n_a] + tau_feedback
where
  • M_y(q) is the actuation-space inertia matrix at current configuration
  • eta_y(q, qd) is the actuation-space Coriolis matrix at current state
  • G_y(q) is the actuation-space gravitational force at current configuration
  • tau_el_y(q_des) is the actuation-space elastic force at desired configuration
  • D_y(q) is the actuation-space damping matrix at current configuration
  • yd_des, ydd_des are the desired velocity and acceleration in actuation space
  • n_a is the number of actuators
  • tau is the actuator input (shape: n_a)
  • tau_feedback is the PID feedback term from the parent class

Only the first n_a rows of the actuation-space forces contribute to the control input, corresponding to the actuated coordinates.

Underactuation Warning

In underactuated settings (n_u > 0), trajectory tracking is an open research problem. The unactuated coordinates evolve according to the zero dynamics and cannot be independently controlled. The reference trajectory for the unactuated coordinates must be dynamically feasible, meaning it must correspond to a valid solution of the system's equations of motion. If the reference trajectory is not feasible, tracking performance may be significantly degraded.

Coriolis Matrix Warning

For the theoretical stability guarantees to hold, the Coriolis matrix must be derived using the Christoffel symbols of the first kind, ensuring that the matrix N = dM/dt - 2*C is skew-symmetric. This property is essential for passivity-based stability proofs.

Attributes:

Name Type Description
robot

The soft robot system to be controlled.

reference_trajectory

The desired trajectory in actuation space.

reference_trajectory_config_space

The original configuration-space trajectory (required for evaluating elastic forces at q_des).

actuation_space_dynamics

The ActuationSpaceDynamics instance for coordinate transformations.

pid_control PIDControl

The PIDControl instance containing gains and saturation.

References

Kelly, R., & Carelli, R. (1996). A class of nonlinear PD-type controllers for robot manipulators. Journal of Robotic Systems, 13(12), 793-802.

Della Santina, C., Katzschmann, R. K., Bicchi, A., & Rus, D. (2020). Model-based dynamic feedback control of a planar soft robot: trajectory tracking and interaction with the environment. The International Journal of Robotics Research, 39.

Pustina, P. (2025). Analysis and control of the underactuation in continuum soft robots: a kinematic independent approach. PhD Thesis, Sapienza University of Rome.

Stölzle, M. (2025). Safe yet Precise Soft Robots: Incorporating Physics into Learned Models for Control. Dissertation, Delft University of Technology. https://doi.org/10.4233/uuid:24c1f667-8fd6-431a-bb78-11d22f8cb3da

Initialize the actuation-space mixed state feedback trajectory tracker.

Parameters:

Name Type Description Default
actuation_space_dynamics ActuationSpaceDynamics

The ActuationSpaceDynamics instance that provides coordinate transformations and contains the robot.

required
reference_trajectory ReferenceTrajectory

The desired trajectory to track. Must be in configuration space (set reference_in_configuration_space=True). The configuration-space trajectory is required to evaluate elastic forces at q_des.

required
pid_control PIDControl

A PIDControl instance containing the control gains (Kp, Ki, Kd) and optional saturation function. The gains should be sized for the actuated coordinates (n_a x n_a or n_a).

required
reference_in_configuration_space bool

Must be True for this controller. The configuration-space trajectory is required to evaluate elastic forces at the desired configuration q_des.

True

Raises:

Type Description
ValueError

If reference_in_configuration_space=False. This controller requires the configuration-space trajectory to evaluate elastic forces.

__call__
__call__(system_state: SystemState) -> tuple[Array, Any | None]

Compute the combined control action.

Combines the model-based feedforward term and the error-based feedback term by summing both the control inputs and the control state derivatives.

Parameters:

Name Type Description Default
system_state SystemState

The current state of the system.

required

Returns:

Name Type Description
u_control Array

Combined control input, shape (num_actuators,).

control_state_dot Optional[Any]

Combined time derivative of the internal controller state, or None if both terms are stateless.

error_based_feedback_term
error_based_feedback_term(system_state: SystemState) -> tuple[Array, PIDControllerState | None]

Compute the PID feedback control term in actuation space.

This method computes the PID control action based on the tracking error in the actuated coordinates only (first n_a coordinates in actuation space).

Parameters:

Name Type Description Default
system_state SystemState

The current state of the system, containing: - t: Current simulation time - y: Robot state vector [q, qd] (configuration and velocity) - control_state: PIDControllerState containing integral error of shape (n_a,), or None if not using integral control.

required

Returns:

Name Type Description
tau Array

The actuator control input, shape (num_actuators,).

control_state_dot PIDControllerState | None

Time derivative of the PIDControllerState, or None if no control state is being tracked.

update_gains
update_gains(gains: dict[str, Array]) -> PIDController

This function updates the gains of the PID controller.

Parameters:

Name Type Description Default
gains dict[str, Array]

proportional, integral, and derivative gains

required

Returns:

Name Type Description
updated_self PIDController

self object with updated gains

model_based_term
model_based_term(system_state: SystemState) -> tuple[Array, Any | None]

Compute the model-based feedforward control term for trajectory tracking.

This method computes the control input using a mixed evaluation strategy in actuation space: - Dynamical matrices (M_y, eta_y, G_y, D_y) are evaluated at current state - The desired acceleration and velocity are used for inertial/Coriolis/damping forces - Elastic forces are evaluated at the desired configuration q_des

Parameters:

Name Type Description Default
system_state SystemState

The current state of the system, containing: - t: Current simulation time - y: Robot state vector [q, qd] (configuration and velocity)

required

Returns:

Name Type Description
tau_model Array

The model-based control input, shape (num_actuators,).

control_state_dot Any | None

None (this term is stateless).


Setpoint Regulators

Setpoint regulators are specialized for regulation tasks (constant setpoints) or quasi-static trajectories. They do not consider inertial, Coriolis, or damping forces.

GravityCancellationRegulator

Gravity cancellation evaluates gravity at the current configuration (for real-time compensation) and elastic forces at the desired configuration (to set the equilibrium), all in actuation space.

The control law is:

\[ \tau_\mathrm{model} = G_y(q) + \tau_{\mathrm{el},y}(q_\mathrm{des}) \]
\[ \tau = \tau_\mathrm{model}[:n_a] + \tau_\mathrm{feedback} \]

soromox.control.actuation_space.GravityCancellationRegulator

GravityCancellationRegulator(actuation_space_dynamics: ActuationSpaceDynamics, reference_trajectory: ReferenceTrajectory, pid_control: PIDControl, reference_in_configuration_space: bool = True)

Bases: PIDController


              flowchart TD
              soromox.control.actuation_space.GravityCancellationRegulator[GravityCancellationRegulator]
              soromox.control.actuation_space.pid_controller.PIDController[PIDController]
              soromox.control.actuation_space.base_controller.ActuationSpaceBaseController[ActuationSpaceBaseController]
              soromox.control.closed_form_model_based_controller.ClosedFormModelBasedController[ClosedFormModelBasedController]
              soromox.control.base_controller.BaseController[BaseController]

                              soromox.control.actuation_space.pid_controller.PIDController --> soromox.control.actuation_space.GravityCancellationRegulator
                                soromox.control.actuation_space.base_controller.ActuationSpaceBaseController --> soromox.control.actuation_space.pid_controller.PIDController
                                soromox.control.base_controller.BaseController --> soromox.control.actuation_space.base_controller.ActuationSpaceBaseController
                

                soromox.control.closed_form_model_based_controller.ClosedFormModelBasedController --> soromox.control.actuation_space.pid_controller.PIDController
                                soromox.control.base_controller.BaseController --> soromox.control.closed_form_model_based_controller.ClosedFormModelBasedController
                




              click soromox.control.actuation_space.GravityCancellationRegulator href "" "soromox.control.actuation_space.GravityCancellationRegulator"
              click soromox.control.actuation_space.pid_controller.PIDController href "" "soromox.control.actuation_space.pid_controller.PIDController"
              click soromox.control.actuation_space.base_controller.ActuationSpaceBaseController href "" "soromox.control.actuation_space.base_controller.ActuationSpaceBaseController"
              click soromox.control.closed_form_model_based_controller.ClosedFormModelBasedController href "" "soromox.control.closed_form_model_based_controller.ClosedFormModelBasedController"
              click soromox.control.base_controller.BaseController href "" "soromox.control.base_controller.BaseController"
            

Gravity cancellation regulator in actuation space for soft robots.

This controller extends the actuation-space PIDController by adding a model-based feedforward term that compensates for the gravitational forces at the current configuration and elastic forces at the desired configuration, all evaluated in actuation space.

By working in actuation space, this controller benefits from the collocated form where the actuation matrix becomes an identity for the actuated coordinates. The model-based term is computed by: 1. Evaluating the gravitational force at the current configuration q 2. Evaluating the elastic force at the desired configuration q_des 3. Transforming to actuation space and extracting the first n_a rows

Note

This regulator is specialized for setpoint regulation or quasi-static trajectories as it does not consider the dynamical (e.g., inertial, Coriolis, damping, etc.) forces of the soft robot.

Important

This controller requires the reference trajectory to be provided in configuration space (reference_in_configuration_space=True). The configuration-space trajectory is needed to evaluate elastic forces at q_des, since the inverse mapping from actuation space y back to configuration space q is generally nonlinear and not trivially invertible.

Control Law

The control law is:

tau_model_y = G_y(q) + tau_el_y(q_des)

tau = tau_model_y[:n_a] + tau_feedback
where
  • G_y(q) is the actuation-space gravitational force at current configuration
  • tau_el_y(q_des) is the actuation-space elastic force at desired configuration
  • n_a is the number of actuators
  • tau is the actuator input (shape: n_a)
  • tau_feedback is the PID feedback term from the parent class

Only the first n_a rows of the actuation-space forces contribute to the control input, corresponding to the actuated coordinates.

Attributes:

Name Type Description
robot

The soft robot system to be controlled.

reference_trajectory

The desired trajectory in actuation space.

reference_trajectory_config_space

The original configuration-space trajectory (required for evaluating elastic forces at q_des).

actuation_space_dynamics

The ActuationSpaceDynamics instance for coordinate transformations.

pid_control PIDControl

The PIDControl instance containing gains and saturation.

References

Della Santina, C., Katzschmann, R. K., Bicchi, A., & Rus, D. (2020). Model-based dynamic feedback control of a planar soft robot: trajectory tracking and interaction with the environment. The International Journal of Robotics Research, 39.

Pustina, P. (2025). Analysis and control of the underactuation in continuum soft robots: a kinematic independent approach. PhD Thesis, Sapienza University of Rome.

Stölzle, M. (2025). Safe yet Precise Soft Robots: Incorporating Physics into Learned Models for Control. Dissertation, Delft University of Technology. https://doi.org/10.4233/uuid:24c1f667-8fd6-431a-bb78-11d22f8cb3da

Initialize the actuation-space gravity cancellation regulator.

Parameters:

Name Type Description Default
actuation_space_dynamics ActuationSpaceDynamics

The ActuationSpaceDynamics instance that provides coordinate transformations and contains the robot.

required
reference_trajectory ReferenceTrajectory

The desired trajectory to track. Must be in configuration space (set reference_in_configuration_space=True). The configuration-space trajectory is required to evaluate elastic forces at q_des.

required
pid_control PIDControl

A PIDControl instance containing the control gains (Kp, Ki, Kd) and optional saturation function. The gains should be sized for the actuated coordinates (n_a x n_a or n_a).

required
reference_in_configuration_space bool

Must be True for this controller. The configuration-space trajectory is required to evaluate elastic forces at the desired configuration q_des.

True

Raises:

Type Description
ValueError

If reference_in_configuration_space=False. This controller requires the configuration-space trajectory to evaluate elastic forces.

__call__
__call__(system_state: SystemState) -> tuple[Array, Any | None]

Compute the combined control action.

Combines the model-based feedforward term and the error-based feedback term by summing both the control inputs and the control state derivatives.

Parameters:

Name Type Description Default
system_state SystemState

The current state of the system.

required

Returns:

Name Type Description
u_control Array

Combined control input, shape (num_actuators,).

control_state_dot Optional[Any]

Combined time derivative of the internal controller state, or None if both terms are stateless.

error_based_feedback_term
error_based_feedback_term(system_state: SystemState) -> tuple[Array, PIDControllerState | None]

Compute the PID feedback control term in actuation space.

This method computes the PID control action based on the tracking error in the actuated coordinates only (first n_a coordinates in actuation space).

Parameters:

Name Type Description Default
system_state SystemState

The current state of the system, containing: - t: Current simulation time - y: Robot state vector [q, qd] (configuration and velocity) - control_state: PIDControllerState containing integral error of shape (n_a,), or None if not using integral control.

required

Returns:

Name Type Description
tau Array

The actuator control input, shape (num_actuators,).

control_state_dot PIDControllerState | None

Time derivative of the PIDControllerState, or None if no control state is being tracked.

update_gains
update_gains(gains: dict[str, Array]) -> PIDController

This function updates the gains of the PID controller.

Parameters:

Name Type Description Default
gains dict[str, Array]

proportional, integral, and derivative gains

required

Returns:

Name Type Description
updated_self PIDController

self object with updated gains

model_based_term
model_based_term(system_state: SystemState) -> tuple[Array, Any | None]

Compute the model-based feedforward control term for gravity cancellation.

This method computes the control input required to compensate for the gravitational forces at the current configuration and elastic forces at the desired configuration, all in actuation space. Only the first n_a (actuated) rows of the actuation-space forces contribute to the output.

Parameters:

Name Type Description Default
system_state SystemState

The current state of the system, containing: - t: Current simulation time - y: Robot state vector [q, qd] (configuration and velocity)

required

Returns:

Name Type Description
tau_model Array

The model-based control input, shape (num_actuators,).

control_state_dot Any | None

None (this term is stateless).


PotentialCancellationRegulator

Potential cancellation evaluates both gravitational and elastic forces at the current configuration, providing real-time cancellation of all potential energy forces.

This is closely related to the PD+ controller in rigid robotics, which was shown to be globally asymptotically stable by Paden & Panja (1988) and Kelly & Carelli (1996).

The control law is:

\[ \tau_\mathrm{model} = G_y(q) + \tau_{\mathrm{el},y}(q) \]
\[ \tau = \tau_\mathrm{model}[:n_a] + \tau_\mathrm{feedback} \]

soromox.control.actuation_space.PotentialCancellationRegulator

PotentialCancellationRegulator(actuation_space_dynamics: ActuationSpaceDynamics, reference_trajectory: ReferenceTrajectory, pid_control: PIDControl, reference_in_configuration_space: bool = True)

Bases: PIDController


              flowchart TD
              soromox.control.actuation_space.PotentialCancellationRegulator[PotentialCancellationRegulator]
              soromox.control.actuation_space.pid_controller.PIDController[PIDController]
              soromox.control.actuation_space.base_controller.ActuationSpaceBaseController[ActuationSpaceBaseController]
              soromox.control.closed_form_model_based_controller.ClosedFormModelBasedController[ClosedFormModelBasedController]
              soromox.control.base_controller.BaseController[BaseController]

                              soromox.control.actuation_space.pid_controller.PIDController --> soromox.control.actuation_space.PotentialCancellationRegulator
                                soromox.control.actuation_space.base_controller.ActuationSpaceBaseController --> soromox.control.actuation_space.pid_controller.PIDController
                                soromox.control.base_controller.BaseController --> soromox.control.actuation_space.base_controller.ActuationSpaceBaseController
                

                soromox.control.closed_form_model_based_controller.ClosedFormModelBasedController --> soromox.control.actuation_space.pid_controller.PIDController
                                soromox.control.base_controller.BaseController --> soromox.control.closed_form_model_based_controller.ClosedFormModelBasedController
                




              click soromox.control.actuation_space.PotentialCancellationRegulator href "" "soromox.control.actuation_space.PotentialCancellationRegulator"
              click soromox.control.actuation_space.pid_controller.PIDController href "" "soromox.control.actuation_space.pid_controller.PIDController"
              click soromox.control.actuation_space.base_controller.ActuationSpaceBaseController href "" "soromox.control.actuation_space.base_controller.ActuationSpaceBaseController"
              click soromox.control.closed_form_model_based_controller.ClosedFormModelBasedController href "" "soromox.control.closed_form_model_based_controller.ClosedFormModelBasedController"
              click soromox.control.base_controller.BaseController href "" "soromox.control.base_controller.BaseController"
            

Potential cancellation regulator in actuation space for soft robots.

This controller extends the actuation-space PIDController by adding a model-based feedforward term that cancels the gravitational and elastic forces at the current configuration, all evaluated in actuation space. This provides real-time cancellation of potential energy forces.

This regulator is closely related to PD+ regulators in rigid robotics, which augment PD feedback with gravity compensation evaluated at the current configuration. The PD+ approach was shown to be globally asymptotically stable for rigid robot manipulators by Paden & Panja (1988) and Kelly & Carelli (1996).

Note

This regulator is specialized for setpoint regulation or quasi-static trajectories as it does not consider the dynamical (e.g., inertial, Coriolis, damping, etc.) forces of the soft robot.

Control Law

The control law is:

tau_model_y = G_y(y) + tau_el_y(y)

tau = tau_model_y[:n_a] + tau_feedback
where
  • G_y(y) is the actuation-space gravitational force at current configuration
  • tau_el_y(y) is the actuation-space elastic force at current configuration
  • n_a is the number of actuators
  • tau is the actuator input (shape: n_a)
  • tau_feedback is the PID feedback term from the parent class

Only the first n_a rows of the actuation-space forces contribute to the control input, corresponding to the actuated coordinates.

Attributes:

Name Type Description
robot

The soft robot system to be controlled.

reference_trajectory

The desired trajectory in actuation space.

actuation_space_dynamics

The ActuationSpaceDynamics instance for coordinate transformations.

pid_control PIDControl

The PIDControl instance containing gains and saturation.

References

Paden, B., & Panja, R. (1988). Globally asymptotically stable 'PD+' controller for robot manipulators. International Journal of Control, 47(6), 1697-1712.

Kelly, R., & Carelli, R. (1996). A class of nonlinear PD-type controllers for robot manipulators. Journal of Robotic Systems, 13(12), 793-802.

Pustina, P. (2025). Analysis and control of the underactuation in continuum soft robots: a kinematic independent approach. PhD Thesis, Sapienza University of Rome.

Stölzle, M. (2025). Safe yet Precise Soft Robots: Incorporating Physics into Learned Models for Control. Dissertation, Delft University of Technology. https://doi.org/10.4233/uuid:24c1f667-8fd6-431a-bb78-11d22f8cb3da

Initialize the actuation-space potential cancellation regulator.

Parameters:

Name Type Description Default
actuation_space_dynamics ActuationSpaceDynamics

The ActuationSpaceDynamics instance that provides coordinate transformations and contains the robot.

required
reference_trajectory ReferenceTrajectory

The desired trajectory to track. If reference_in_configuration_space=True, this should be a configuration-space trajectory which will be converted to actuation space. Otherwise, it should already be in actuation space.

required
pid_control PIDControl

A PIDControl instance containing the control gains (Kp, Ki, Kd) and optional saturation function. The gains should be sized for the actuated coordinates (n_a x n_a or n_a).

required
reference_in_configuration_space bool

If True (default), the reference trajectory is in configuration space and will be converted to actuation space. If False, the reference trajectory is already in actuation space.

True
__call__
__call__(system_state: SystemState) -> tuple[Array, Any | None]

Compute the combined control action.

Combines the model-based feedforward term and the error-based feedback term by summing both the control inputs and the control state derivatives.

Parameters:

Name Type Description Default
system_state SystemState

The current state of the system.

required

Returns:

Name Type Description
u_control Array

Combined control input, shape (num_actuators,).

control_state_dot Optional[Any]

Combined time derivative of the internal controller state, or None if both terms are stateless.

error_based_feedback_term
error_based_feedback_term(system_state: SystemState) -> tuple[Array, PIDControllerState | None]

Compute the PID feedback control term in actuation space.

This method computes the PID control action based on the tracking error in the actuated coordinates only (first n_a coordinates in actuation space).

Parameters:

Name Type Description Default
system_state SystemState

The current state of the system, containing: - t: Current simulation time - y: Robot state vector [q, qd] (configuration and velocity) - control_state: PIDControllerState containing integral error of shape (n_a,), or None if not using integral control.

required

Returns:

Name Type Description
tau Array

The actuator control input, shape (num_actuators,).

control_state_dot PIDControllerState | None

Time derivative of the PIDControllerState, or None if no control state is being tracked.

update_gains
update_gains(gains: dict[str, Array]) -> PIDController

This function updates the gains of the PID controller.

Parameters:

Name Type Description Default
gains dict[str, Array]

proportional, integral, and derivative gains

required

Returns:

Name Type Description
updated_self PIDController

self object with updated gains

model_based_term
model_based_term(system_state: SystemState) -> tuple[Array, Any | None]

Compute the model-based feedforward control term for potential cancellation.

This method computes the control input required to compensate for the gravitational and elastic forces at the current configuration, all in actuation space. Only the first n_a (actuated) rows of the actuation-space forces contribute to the output.

Parameters:

Name Type Description Default
system_state SystemState

The current state of the system, containing: - t: Current simulation time - y: Robot state vector [q, qd] (configuration and velocity)

required

Returns:

Name Type Description
tau_model Array

The model-based control input, shape (num_actuators,).

control_state_dot Any | None

None (this term is stateless).


PotentialCompensationRegulator

Potential compensation (or "potential shaping") evaluates both forces at the desired configuration, effectively reshaping the potential energy landscape to have a minimum at the setpoint.

The control law is:

\[ \tau_\mathrm{model} = G_y(q_\mathrm{des}) + \tau_{\mathrm{el},y}(q_\mathrm{des}) \]
\[ \tau = \tau_\mathrm{model}[:n_a] + \tau_\mathrm{feedback} \]

soromox.control.actuation_space.PotentialCompensationRegulator

PotentialCompensationRegulator(actuation_space_dynamics: ActuationSpaceDynamics, reference_trajectory: ReferenceTrajectory, pid_control: PIDControl, reference_in_configuration_space: bool = True)

Bases: PIDController


              flowchart TD
              soromox.control.actuation_space.PotentialCompensationRegulator[PotentialCompensationRegulator]
              soromox.control.actuation_space.pid_controller.PIDController[PIDController]
              soromox.control.actuation_space.base_controller.ActuationSpaceBaseController[ActuationSpaceBaseController]
              soromox.control.closed_form_model_based_controller.ClosedFormModelBasedController[ClosedFormModelBasedController]
              soromox.control.base_controller.BaseController[BaseController]

                              soromox.control.actuation_space.pid_controller.PIDController --> soromox.control.actuation_space.PotentialCompensationRegulator
                                soromox.control.actuation_space.base_controller.ActuationSpaceBaseController --> soromox.control.actuation_space.pid_controller.PIDController
                                soromox.control.base_controller.BaseController --> soromox.control.actuation_space.base_controller.ActuationSpaceBaseController
                

                soromox.control.closed_form_model_based_controller.ClosedFormModelBasedController --> soromox.control.actuation_space.pid_controller.PIDController
                                soromox.control.base_controller.BaseController --> soromox.control.closed_form_model_based_controller.ClosedFormModelBasedController
                




              click soromox.control.actuation_space.PotentialCompensationRegulator href "" "soromox.control.actuation_space.PotentialCompensationRegulator"
              click soromox.control.actuation_space.pid_controller.PIDController href "" "soromox.control.actuation_space.pid_controller.PIDController"
              click soromox.control.actuation_space.base_controller.ActuationSpaceBaseController href "" "soromox.control.actuation_space.base_controller.ActuationSpaceBaseController"
              click soromox.control.closed_form_model_based_controller.ClosedFormModelBasedController href "" "soromox.control.closed_form_model_based_controller.ClosedFormModelBasedController"
              click soromox.control.base_controller.BaseController href "" "soromox.control.base_controller.BaseController"
            

Potential compensation regulator in actuation space for soft robots.

This controller extends the actuation-space PIDController by adding a model-based feedforward term that compensates for the gravitational and elastic forces at the desired configuration, all evaluated in actuation space. This is known as "potential shaping" as it effectively reshapes the potential energy landscape of the system to have a minimum at the desired configuration.

Note

This regulator is specialized for setpoint regulation or quasi-static trajectories as it does not consider the dynamical (e.g., inertial, Coriolis, damping, etc.) forces of the soft robot.

Important

This controller requires the reference trajectory to be provided in configuration space (reference_in_configuration_space=True). The configuration-space trajectory is needed to evaluate forces at q_des, since the inverse mapping from actuation space y back to configuration space q is generally nonlinear and not trivially invertible.

Control Law

The control law is:

tau_model_y = G_y(q_des) + tau_el_y(q_des)

tau = tau_model_y[:n_a] + tau_feedback
where
  • G_y(q_des) is the actuation-space gravitational force at desired configuration
  • tau_el_y(q_des) is the actuation-space elastic force at desired configuration
  • n_a is the number of actuators
  • tau is the actuator input (shape: n_a)
  • tau_feedback is the PID feedback term from the parent class

Only the first n_a rows of the actuation-space forces contribute to the control input, corresponding to the actuated coordinates.

Attributes:

Name Type Description
robot

The soft robot system to be controlled.

reference_trajectory

The desired trajectory in actuation space.

reference_trajectory_config_space

The original configuration-space trajectory (required for evaluating forces at q_des).

actuation_space_dynamics

The ActuationSpaceDynamics instance for coordinate transformations.

pid_control PIDControl

The PIDControl instance containing gains and saturation.

References

Kelly, R., & Salgado, R. (1994). PD control with computed feedforward of robot manipulators: A design procedure. IEEE Transactions on Robotics and Automation, 10(4), 566-571.

Borja, P., Della Santina, C., & Albu-Schäffer, A. (2022). Energy-shaping control of soft continuum manipulators with in-plane disturbances. The International Journal of Robotics Research, 41(1), 62-81.

Pustina, P. (2025). Analysis and control of the underactuation in continuum soft robots: a kinematic independent approach. PhD Thesis, Sapienza University of Rome.

Stölzle, M. (2025). Safe yet Precise Soft Robots: Incorporating Physics into Learned Models for Control. Dissertation, Delft University of Technology. https://doi.org/10.4233/uuid:24c1f667-8fd6-431a-bb78-11d22f8cb3da

Initialize the actuation-space potential compensation regulator.

Parameters:

Name Type Description Default
actuation_space_dynamics ActuationSpaceDynamics

The ActuationSpaceDynamics instance that provides coordinate transformations and contains the robot.

required
reference_trajectory ReferenceTrajectory

The desired trajectory to track. Must be in configuration space (set reference_in_configuration_space=True). The configuration-space trajectory is required to evaluate forces at q_des.

required
pid_control PIDControl

A PIDControl instance containing the control gains (Kp, Ki, Kd) and optional saturation function. The gains should be sized for the actuated coordinates (n_a x n_a or n_a).

required
reference_in_configuration_space bool

Must be True for this controller. The configuration-space trajectory is required to evaluate forces at the desired configuration q_des.

True

Raises:

Type Description
ValueError

If reference_in_configuration_space=False. This controller requires the configuration-space trajectory to evaluate forces.

__call__
__call__(system_state: SystemState) -> tuple[Array, Any | None]

Compute the combined control action.

Combines the model-based feedforward term and the error-based feedback term by summing both the control inputs and the control state derivatives.

Parameters:

Name Type Description Default
system_state SystemState

The current state of the system.

required

Returns:

Name Type Description
u_control Array

Combined control input, shape (num_actuators,).

control_state_dot Optional[Any]

Combined time derivative of the internal controller state, or None if both terms are stateless.

error_based_feedback_term
error_based_feedback_term(system_state: SystemState) -> tuple[Array, PIDControllerState | None]

Compute the PID feedback control term in actuation space.

This method computes the PID control action based on the tracking error in the actuated coordinates only (first n_a coordinates in actuation space).

Parameters:

Name Type Description Default
system_state SystemState

The current state of the system, containing: - t: Current simulation time - y: Robot state vector [q, qd] (configuration and velocity) - control_state: PIDControllerState containing integral error of shape (n_a,), or None if not using integral control.

required

Returns:

Name Type Description
tau Array

The actuator control input, shape (num_actuators,).

control_state_dot PIDControllerState | None

Time derivative of the PIDControllerState, or None if no control state is being tracked.

update_gains
update_gains(gains: dict[str, Array]) -> PIDController

This function updates the gains of the PID controller.

Parameters:

Name Type Description Default
gains dict[str, Array]

proportional, integral, and derivative gains

required

Returns:

Name Type Description
updated_self PIDController

self object with updated gains

model_based_term
model_based_term(system_state: SystemState) -> tuple[Array, Any | None]

Compute the model-based feedforward control term for potential compensation.

This method computes the control input required to compensate for the gravitational and elastic forces at the desired configuration, all in actuation space. Only the first n_a (actuated) rows of the actuation-space forces contribute to the output.

Parameters:

Name Type Description Default
system_state SystemState

The current state of the system, containing: - t: Current simulation time - y: Robot state vector [q, qd] (configuration and velocity)

required

Returns:

Name Type Description
tau_model Array

The model-based control input, shape (num_actuators,).

control_state_dot Any | None

None (this term is stateless).


Usage Example

import jax.numpy as jnp
from soromox.control import ReferenceTrajectory
from soromox.control.actuation_space import (
    PIDController,
    MixedStateFeedbackTracker,
    GravityCancellationRegulator,
)
from soromox.control import PIDControl
from soromox.coordinate_transformations import ActuationSpaceDynamics

# Assume `robot` is a soft robot system with independent actuator coordinates,
# for example `PlanarPCS(..., actuators=ThreadlikeActuator.tendons(routing))`.

# Create actuation-space dynamics
asd = ActuationSpaceDynamics(robot=robot)

# Define reference trajectory in configuration space
ts = jnp.linspace(0, 10, 1000)
q_des_ts = jnp.zeros((len(ts), robot.num_dofs))
# ... fill in desired trajectory ...

ref_traj = ReferenceTrajectory(ts=ts, x_des_ts=q_des_ts)

# Create PID control gains (sized for actuated coordinates)
pid = PIDControl(
    Kp=jnp.ones(robot.num_actuators) * 100.0,
    Ki=jnp.ones(robot.num_actuators) * 10.0,
    Kd=jnp.ones(robot.num_actuators) * 20.0,
)

# Option 1: Pure PID in actuation space
controller_pid = PIDController(
    actuation_space_dynamics=asd,
    reference_trajectory=ref_traj,
    pid_control=pid,
    reference_in_configuration_space=True,  # Trajectory is in config space
)

# Option 2: Gravity cancellation regulator (for setpoint regulation)
controller_regulator = GravityCancellationRegulator(
    actuation_space_dynamics=asd,
    reference_trajectory=ref_traj,
    pid_control=pid,
    reference_in_configuration_space=True,
)

# Option 3: Mixed state feedback tracker (for trajectory tracking)
controller_tracker = MixedStateFeedbackTracker(
    actuation_space_dynamics=asd,
    reference_trajectory=ref_traj,
    pid_control=pid,
    reference_in_configuration_space=True,
)

References

The actuation-space control formulation was developed in the following foundational works:

  • Pustina, P., Della Santina, C., Boyer, F., De Luca, A., & Renda, F. (2024). Input decoupling of Lagrangian systems via coordinate transformation: General characterization and its application to soft robotics. IEEE Transactions on Robotics, 40, 2098-2110.

  • Pustina, P. (2025). Analysis and control of the underactuation in continuum soft robots: a kinematic independent approach. PhD Thesis, Sapienza University of Rome.

For related soft robot control approaches:

  • Della Santina, C., Katzschmann, R. K., Bicchi, A., & Rus, D. (2020). Model-based dynamic feedback control of a planar soft robot: trajectory tracking and interaction with the environment. The International Journal of Robotics Research, 39(4-5), 490-513.

  • Della Santina, C., Duriez, C., & Rus, D. (2023). Model-based control of soft robots: A survey of the state of the art and open challenges. IEEE Control Systems Magazine, 43(3), 30-65.

For stability analysis of PD-type controllers:

  • Paden, B., & Panja, R. (1988). Globally asymptotically stable 'PD+' controller for robot manipulators. International Journal of Control, 47(6), 1697-1712.

  • Kelly, R., & Carelli, R. (1996). A class of nonlinear PD-type controllers for robot manipulators. Journal of Robotic Systems, 13(12), 793-802.