Safety Controller#
Isaac ROS Deploy includes a ROS 2 Control plugin named SafetyController.
It sits between an upstream controller and hardware and provides two command
handling mechanisms:
Command blending: Blends commands to gradually enable a policy using
blend_ratio(0.0 to 1.0).Out-of-domain detection: Compares joint-state velocities with configured thresholds and can request an emergency-controller switch.
Warning
The Safety Controller is meant as a useful tool, but it does not qualify as a functional-safety-certified architecture. Do not rely on it as your sole safety mechanism in safety-critical deployments.
Integration with ROS 2 Control#
The safety controller is a ros2_control controller that can be chained
(ChainableControllerInterface). Like any controller in a chain, it takes
reference interfaces as its inputs and exposes command interfaces as its outputs.
This lets it sit in the middle of a controller chain: an upstream controller writes
the safety controller’s reference interfaces, the safety controller post-processes
those values, and it writes the result to the hardware command interfaces.
For the full list of ROS 2 control plugins shipped by Isaac ROS Deploy, refer to the package reference.
Because the safety controller’s purpose is to post-process the commands produced by
an upstream controller, it exposes its reference interfaces with a _raw suffix. The
upstream controller writes its raw, unprocessed command into the *_raw reference
interface, and the safety controller then applies its processing (command blending and
out-of-domain detection) before writing the final hardware command interface.
Because it chains behind any upstream controller, the safety controller works with both LEAPP runtimes:
With the ROS2 Control LEAPP Runtime, chain it directly behind the inference controller:
inference_controller → safety_controller → hardware
With the ROS2 Node LEAPP Runtime, chain it behind a
ForwardJointCommandController. That forwarding controller receives the policy commands over a ROS topic, which the inference graph publishes:inference_graph node → command topic → ForwardJointCommandController → safety_controller → hardware
Command Blending Strategies#
Command blending lets an operator increase the policy command gradually instead of enabling it all at once.
This is especially useful the first time a policy is deployed, when an operator is not yet sure it will behave as expected.
Command blending is controlled by the blend_ratio parameter, which sets how much
the policy commands influence the robot:
At
blend_ratio = 0.0: the policy is completely disabled and inactive. Withinterpolate, each joint targets its configureddefault_positionwhen present, otherwise its measured activation pose.At
blend_ratio = 1.0: the policy is fully activated. Withinterpolate, the target is the policy position command, andno_post_processingpasses the command through.
Two blending strategies are available:
interpolate (default)#
Use this strategy for hardware bring-up and when you need per-joint slew limits.
This strategy performs a velocity-limited slew from a per-joint base pose toward the
blended command. The base pose is the configured default_position when present,
otherwise the measured activation pose. Each cycle the target is
target = base_position + (command - base_position) * blend_ratio
and the integrated reference is moved toward it, capped per joint at max_velocity * dt:
output = reference + clamp(target - reference, -max_velocity * dt, +max_velocity * dt)
At blend_ratio = 0, a joint without default_position holds its activation pose
regardless of what the policy commands. A joint with default_position instead slews from
its current position toward that configured home pose. The per-joint cap is configured via
interpolate_max_velocity (see below). Joints with no configured cap slew without limit.
no_post_processing#
Use this strategy in simulation, or when an independent downstream actuation layer provides the command limits required by the application.
The name refers to the absence of the interpolate strategy’s velocity and slew
post-processing, not to the blend ratio. This strategy still applies blend-ratio
interpolation, so you can ramp a policy in as usual, but it does not limit how fast the
command changes:
output = current + (command - current) * blend_ratio
Velocity-threshold out-of-domain detection, when enabled, still runs before blending.
Out-of-Domain Detection#
Out-of-domain detection triggers a fallback or emergency controller when a configured check fails. It runs before blending. A failed check latches an emergency and requests that the controller manager switch to the configured emergency controller. The failed cycle does not write new commands to hardware.
We currently provide a single out-of-domain detection implementation, based on velocity thresholds.
Velocity Threshold#
This detector triggers when the maximum or mean velocity of the selected joints exceeds a configured threshold. Excluded joints are replaced with zero before both checks:
max_velocity: fails when any joint exceeds this threshold in rad/s.mean_velocity: fails when the mean across all configured joints, with excluded joints zeroed, exceeds this threshold in rad/s.
The detector is enabled only when emergency_controller is nonempty and either velocity
threshold is greater than zero.
Parameter |
Type |
Default |
Description |
|---|---|---|---|
|
|
|
Maximum absolute joint velocity in rad/s. A value less than or equal to zero disables this check. |
|
|
|
Mean absolute joint velocity in rad/s across all configured joints after excluded joints are zeroed. A value less than or equal to zero disables this check. |
|
|
|
Regular expressions that fully match joint names to exclude. Matched joints are set to zero before both velocity checks. |
|
|
|
Controller to activate through |
|
|
|
Timeout, in seconds, supplied to the controller-manager switch request. A zero, negative, or not finite value sends a zero timeout to the service. |
|
|
|
Controllers to deactivate in the emergency switch request. With this list empty, the
request uses |
See the Unitree G1 controller configuration
(controller_manager.yaml)
for an example of this detector. It enables the detector with a 35.0 rad/s maximum threshold
and a 10.0 rad/s mean threshold, excludes hand joints, and switches to freeze_controller:
out_of_domain_detection:
velocity_threshold:
mean_velocity: 10.0
max_velocity: 35.0
excluded_joints:
- "left_hand_.*"
- "right_hand_.*"
emergency_controller: "freeze_controller"
switch_timeout: 2.0
Parameters#
Parameter |
Type |
Default |
Description |
|---|---|---|---|
|
|
|
Blending strategy: |
|
|
|
Blending value (0.0 = policy disabled, 1.0 = policy fully enabled). Dynamically
adjustable via |
|
|
|
Maximum rate of change for |
|
|
|
Per-joint velocity cap in rad/s for the |
|
|
Not configured |
Optional per-joint home pose for |
|
|
|
Default joint stiffness for unclaimed command interfaces. |
|
|
|
Default joint damping for unclaimed command interfaces. |
|
|
|
List of joints to control (required). |