Skip to content

Renderer API

API reference for SoRoMoX visualization and rendering backends.

Start with the Rendering overview to compare output and choose a backend. Camera, color, base, ground-plane, multi-robot, and recording options are documented under Shared Configuration.

Shared Renderer Contract

All renderers inherit from BaseSoftRobotRenderer, which provides cached forward kinematics, backbone sampling, color resolution, and a common interface for individual and batched robot configurations.

BaseSoftRobotRenderer (abstract base)
├── MatplotlibRenderer         # Generic 2D and 3D plots
├── Open3DRenderer             # Interactive 3D visualization
├── ViserRenderer              # Browser-based interactive 3D visualization
├── OpenCVPlanarRenderer       # Fast planar rendering
└── OpenCVPlanarHSARenderer    # Planar HSA-specific rendering
API Shared behavior Availability
BaseSoftRobotRenderer Backbone sampling, cached forward kinematics, batched layouts, color resolution, and the common rendering interface All renderers
Robot base The robot's base_pose and base_transform place and orient the rendered robot in the world frame All renderers
Base plate base_plate_radius_scale and base_plate_thickness configure the base geometry Open3D and Viser; Matplotlib draws a lightweight base marker
Ground plane show_ground_plane and ground_plane_size configure a base-aligned reference plane; its colors come from RendererColorConfig Matplotlib, Open3D, and Viser

Actuator and Helper Geometry

If a robot exposes actuator_visual_layers(q, s_points, *, actuator_inputs=None), the renderers can display its semantic actuator geometry when render_actuators=True. The hook returns one or more ActuatorVisualLayer objects with points shaped (num_actuators_in_layer, num_points, dim).

For batches and trajectories, robots may additionally provide actuator_visual_layers_batched(...) or actuator_visual_layers_trajectory(...). The base renderer uses these hooks when available and otherwise falls back to the single-configuration hook.

Open3D and Viser also accept helper spheres through static_spheres_positions, static_spheres_radii, and static_spheres_colors. Their sequence renderers additionally support the corresponding dynamic_spheres_* arguments.

Base Class

soromox.rendering.base.BaseSoftRobotRenderer

BaseSoftRobotRenderer(robot: SoftRobot, width: int = 800, height: int = 600, num_points: int = 50, background_color: tuple[float, float, float] = (1.0, 1.0, 1.0), color_config: RendererColorConfig | None = None, show_ground_plane: bool = False, ground_plane_size: float | None = None)

Bases: ABC


              flowchart TD
              soromox.rendering.base.BaseSoftRobotRenderer[BaseSoftRobotRenderer]

              

              click soromox.rendering.base.BaseSoftRobotRenderer href "" "soromox.rendering.base.BaseSoftRobotRenderer"
            

Abstract base class for soft robot visualization backends.

Provides cached forward kinematics and a common interface for rendering soft robots across different backends (Matplotlib, Open3D, OpenCV).

Subclasses must implement
  • render_frame: Render single configuration to RGB image array
  • render_sequence: Render animated sequence
  • show: Display a single frame interactively
Subclasses may override
  • is_3d: Default uses robot.is_planar
  • _extract_positions: Extract xyz/xy from FK poses

Attributes:

Name Type Description
robot SoftRobot

SoftRobot system object with forward_kinematics method

width

Image width in pixels

height

Image height in pixels

num_points

Number of points for discretizing backbone curve

background_color

RGB tuple for background color (0-1 range)

color_config

Shared color configuration for renderers

L_max

Total length of the robot backbone

base_pose

Robot base pose coordinates. Planar robots use [theta, x, y]; spatial robots use scalar-first quaternion pose [qw, qx, qy, qz, x, y, z].

base_transform

Homogeneous base transform. Shape (3, 3) for planar robots and (4, 4) for spatial robots.

show_ground_plane

Whether supported backends render a ground reference

ground_plane_size

Optional ground-plane side length in meters

Initialize the renderer with a robot and visualization parameters.

Parameters:

Name Type Description Default
robot SoftRobot

Robot system with forward_kinematics method and length property

required
width int

Image width in pixels

800
height int

Image height in pixels

600
num_points int

Number of points for backbone curve discretization

50
background_color tuple[float, float, float]

RGB background color tuple (values 0-1)

(1.0, 1.0, 1.0)
color_config RendererColorConfig | None

Shared renderer color configuration

None
show_ground_plane bool

Whether supported backends render a ground reference

False
ground_plane_size float | None

Optional ground-plane side length in meters

None

is_planar property

is_planar: bool

Return True for planar (SE(2)) robots.

is_3d property

is_3d: bool

Return True for 3D rendering, False for planar rendering.

compute_backbone_curve

compute_backbone_curve(q: Array) -> Array

Compute backbone points from configuration.

Parameters:

Name Type Description Default
q Array

Robot configuration array

required

Returns:

Type Description
Array

Array of shape (num_points, 3) for 3D or (num_points, 2) for 2D

compute_backbone_poses

compute_backbone_poses(q: Array) -> Array

Compute full FK poses at the configured backbone sample points.

compute_actuator_visual_layers

compute_actuator_visual_layers(q: Array, *, actuator_inputs: Array | None = None) -> tuple[ActuatorVisualLayer, ...]

Compute renderer-facing actuator visual layers for one robot.

compute_actuator_visual_layers_batched

compute_actuator_visual_layers_batched(q_batch: Array, base_offsets: Array, *, actuator_inputs: Array | ndarray | None = None) -> tuple[BatchedActuatorVisualLayer, ...]

Compute actuator visual layers for multiple robots with base offsets.

compute_actuator_visual_layers_trajectory

compute_actuator_visual_layers_trajectory(q_ts: Array, base_offsets: Array, *, actuator_inputs: Array | ndarray | None = None) -> tuple[TrajectoryActuatorVisualLayer, ...]

Compute actuator visual layers for (N, T, DOF) trajectories.

render_frame abstractmethod

render_frame(q: Array) -> ndarray

Render single configuration to RGB image array.

Parameters:

Name Type Description Default
q Array

Robot configuration array

required

Returns:

Type Description
ndarray

RGB image as numpy array of shape (height, width, 3), dtype uint8

render_sequence abstractmethod

render_sequence(ts: Array, q_ts: Array, playback_speed: float = 1.0, record_path: str | None = None, **kwargs: Any) -> None

Render animated sequence to video file.

Default implementation uses animate_cv2. Subclasses can override for native playback (e.g., Open3D interactive viewer).

Parameters:

Name Type Description Default
ts Array

Time stamps array of shape (T,)

required
q_ts Array

Configurations array of shape (T, DOF)

required
playback_speed float

Speed up factor for the video (playback)

1.0
record_path str | None

Path to save video file (required for default impl)

None

show abstractmethod

show(q: Array, **kwargs) -> None

Display single frame interactively (blocking).

Default implementation uses matplotlib. Subclasses can override for native viewers (e.g., Open3D window).

Parameters:

Name Type Description Default
q Array

Robot configuration array

required

resolve_backbone_colors

resolve_backbone_colors(num_robots: int, *, color_config: RendererColorConfig | None = None, cache: bool = True) -> ResolvedBackboneColors

Resolve backbone colors using the shared config hierarchy.

get_color_legend

get_color_legend(*, num_robots: int = 1, color_config: RendererColorConfig | None = None) -> ColorLegend

Return a lightweight color legend for the current configuration.

clear_color_cache

clear_color_cache() -> None

Clear cached color resolutions.

compute_backbone_curves_batched

compute_backbone_curves_batched(q_batch: Array, base_offsets: Array) -> Array

Compute backbone curves for multiple robots with base offsets.

Uses forward_kinematics_batched if available (optimized), otherwise falls back to jax.vmap over compute_backbone_curve.

Parameters:

Name Type Description Default
q_batch Array

Configurations of shape (N, DOF) - batch-first

required
base_offsets Array

Base position offsets of shape (N, 2) or (N, 3)

required

Returns:

Type Description
Array

Array of shape (N, num_points, dim) - batch-first

compute_backbone_curves_and_frames_batched

compute_backbone_curves_and_frames_batched(q_batch: Array, base_offsets: Array) -> tuple[Array, Array]

Compute 3D backbone positions and material frames for multiple robots.

The frame columns are the local material-frame axes in world coordinates. Positional base offsets translate the curves without rotating the frames.

Matplotlib Renderer

MatplotlibRenderer provides static figures, notebook-friendly inspection, slider-based playback, and ordinary animations for planar and spatial robots. Spatial configurations use a 3D axes view controlled by CameraConfig.

soromox.rendering.matplotlib_renderer.MatplotlibRenderer

MatplotlibRenderer(robot: SoftRobot, width: int = 800, height: int = 600, num_points: int = 50, background_color: tuple[float, float, float] = (1.0, 1.0, 1.0), color_config: RendererColorConfig | None = None, show_ground_plane: bool = True, ground_plane_size: float | None = None, line_width: float = 4.0, grid_spacing: tuple[float, float] = (0.3, 0.3), base_offsets: Array | None = None, actuator_line_width: float = 2.0)

Bases: BaseSoftRobotRenderer


              flowchart TD
              soromox.rendering.matplotlib_renderer.MatplotlibRenderer[MatplotlibRenderer]
              soromox.rendering.base.BaseSoftRobotRenderer[BaseSoftRobotRenderer]

                              soromox.rendering.base.BaseSoftRobotRenderer --> soromox.rendering.matplotlib_renderer.MatplotlibRenderer
                


              click soromox.rendering.matplotlib_renderer.MatplotlibRenderer href "" "soromox.rendering.matplotlib_renderer.MatplotlibRenderer"
              click soromox.rendering.base.BaseSoftRobotRenderer href "" "soromox.rendering.base.BaseSoftRobotRenderer"
            

Matplotlib visualization for any continuum soft robot.

Supports both 2D (planar) and 3D robots, with FuncAnimation and slider modes. The dimensionality is auto-detected from the robot's forward kinematics output.

Example
renderer = MatplotlibRenderer(robot)
renderer.show(q)
renderer.animate(ts, q_ts, mode="slider")

Initialize Matplotlib renderer.

Parameters:

Name Type Description Default
robot SoftRobot

Robot system with forward_kinematics method

required
width int

Figure width in pixels

800
height int

Figure height in pixels

600
num_points int

Number of points for backbone discretization

50
background_color tuple[float, float, float]

RGB background color (0-1 range)

(1.0, 1.0, 1.0)
color_config RendererColorConfig | None

Shared renderer color configuration

None
show_ground_plane bool

Whether to draw a reference plane through the base

True
ground_plane_size float | None

Optional side length of the reference plane in meters

None
line_width float

Width of backbone line

4.0
grid_spacing tuple[float, float]

(x, y) spacing for batched layouts

(0.3, 0.3)
base_offsets Array | None

Optional explicit base offsets for batched layouts

None
actuator_line_width float

Line width for actuator polylines

2.0

is_planar property

is_planar: bool

Return True for planar (SE(2)) robots.

is_3d property

is_3d: bool

Return True for 3D rendering, False for planar rendering.

render_frame

render_frame(q: Array, *, base_offsets: Array | None = None, color_config: RendererColorConfig | None = None, camera_config: CameraConfig | None = None, render_actuators: bool = True, actuator_inputs: Array | None = None) -> ndarray

Render configuration(s) to an RGB image array.

Parameters:

Name Type Description Default
q Array

Robot configuration array. Shape (DOF,) for a single robot or (N, DOF) for batched rendering.

required
base_offsets Array | None

Optional explicit base offsets of shape (N, 2) or (N, 3) for batched layouts. When provided for a single robot, accepts (dim,) or (1, dim).

None
color_config RendererColorConfig | None

Shared renderer color configuration.

None
camera_config CameraConfig | None

Camera configuration. Matplotlib uses its field of view and the direction from position to look-at for 3D plots.

None
render_actuators bool

Whether to render actuator visual layers if available.

True
actuator_inputs Array | None

Optional actuator inputs for scalar-colored layers.

None

Returns:

Name Type Description
img ndarray

RGB image of shape (height, width, 3), dtype uint8.

show

show(q: Array, *, base_offsets: Array | None = None, color_config: RendererColorConfig | None = None, camera_config: CameraConfig | None = None, render_actuators: bool = True, actuator_inputs: Array | None = None) -> None

Display a single frame interactively (supports batched inputs).

Parameters:

Name Type Description Default
q Array

Robot configuration array. Shape (DOF,) or (N, DOF).

required
base_offsets Array | None

Optional explicit base offsets for batched layouts (N, ⅔) or (1, dim) for single robot.

None
color_config RendererColorConfig | None

Shared renderer color configuration.

None
camera_config CameraConfig | None

Camera configuration. Matplotlib uses its field of view and the direction from position to look-at for 3D plots.

None
render_actuators bool

Whether to render actuator visual layers if available.

True
actuator_inputs Array | None

Optional actuator inputs for scalar-colored layers.

None

Returns:

Type Description
None

None

animate

animate(ts: Array, q_ts: Array, interval: int = 50, mode: str = 'slider', show: bool = True, playback_speed: float = 1.0, record_path: str | None = None, base_offsets: Array | None = None, color_config: RendererColorConfig | None = None, camera_config: CameraConfig | None = None, render_actuators: bool = True, actuator_inputs: Array | None = None) -> AnimateReturn

Interactive matplotlib animation with slider or auto-play.

Parameters:

Name Type Description Default
ts Array

Time stamps array of shape (T,)

required
q_ts Array

Configurations array of shape (T, DOF) or (N, T, DOF)

required
interval int

Frame interval in ms (for animation mode)

50
mode str

"slider" for manual scrubbing, "animation" for auto-play

'slider'
show bool

Whether to call plt.show()

True
playback_speed float

Multiplier for playback speed (>1 = faster)

1.0
record_path str | None

Optional path to save animation (mp4/gif depending on writer)

None
base_offsets Array | None

Optional explicit base offsets for batched layouts

None
color_config RendererColorConfig | None

Shared renderer color configuration.

None
camera_config CameraConfig | None

Camera configuration. Matplotlib uses its field of view and the direction from position to look-at for 3D plots.

None
render_actuators bool

Whether to render actuator visual layers if available

True
actuator_inputs Array | None

Optional actuator inputs for scalar-colored layers.

None

Returns:

Type Description
AnimateReturn

HTML object for Jupyter display (animation mode only)

render_sequence

render_sequence(ts: Array, q_ts: Array, *, interval: int = 50, record_path: str | None = None, playback_speed: float = 1.0, camera_config: CameraConfig | None = None, color_config: RendererColorConfig | None = None, render_actuators: bool = True, actuator_inputs: Array | None = None, show: bool = False) -> None

Render an animated sequence (optionally saving to disk).

This reuses the animation code path with mode='animation'.

Parameters:

Name Type Description Default
ts Array

Time stamps array of shape (T,)

required
q_ts Array

Configurations array of shape (T, DOF) or (N, T, DOF)

required
interval int

Frame interval in ms

50
record_path str | None

Optional path to save animation

None
playback_speed float

Multiplier for playback speed

1.0
camera_config CameraConfig | None

Camera configuration. Matplotlib uses its field of view and the direction from position to look-at for 3D plots.

None
color_config RendererColorConfig | None

Shared renderer color configuration.

None
render_actuators bool

Whether to render actuator visual layers if available

True
actuator_inputs Array | None

Optional actuator inputs for scalar-colored layers.

None
show bool

Whether to display the animation

False

compute_backbone_curve

compute_backbone_curve(q: Array) -> Array

Compute backbone points from configuration.

Parameters:

Name Type Description Default
q Array

Robot configuration array

required

Returns:

Type Description
Array

Array of shape (num_points, 3) for 3D or (num_points, 2) for 2D

compute_backbone_poses

compute_backbone_poses(q: Array) -> Array

Compute full FK poses at the configured backbone sample points.

compute_actuator_visual_layers

compute_actuator_visual_layers(q: Array, *, actuator_inputs: Array | None = None) -> tuple[ActuatorVisualLayer, ...]

Compute renderer-facing actuator visual layers for one robot.

compute_actuator_visual_layers_batched

compute_actuator_visual_layers_batched(q_batch: Array, base_offsets: Array, *, actuator_inputs: Array | ndarray | None = None) -> tuple[BatchedActuatorVisualLayer, ...]

Compute actuator visual layers for multiple robots with base offsets.

compute_actuator_visual_layers_trajectory

compute_actuator_visual_layers_trajectory(q_ts: Array, base_offsets: Array, *, actuator_inputs: Array | ndarray | None = None) -> tuple[TrajectoryActuatorVisualLayer, ...]

Compute actuator visual layers for (N, T, DOF) trajectories.

resolve_backbone_colors

resolve_backbone_colors(num_robots: int, *, color_config: RendererColorConfig | None = None, cache: bool = True) -> ResolvedBackboneColors

Resolve backbone colors using the shared config hierarchy.

get_color_legend

get_color_legend(*, num_robots: int = 1, color_config: RendererColorConfig | None = None) -> ColorLegend

Return a lightweight color legend for the current configuration.

clear_color_cache

clear_color_cache() -> None

Clear cached color resolutions.

compute_backbone_curves_batched

compute_backbone_curves_batched(q_batch: Array, base_offsets: Array) -> Array

Compute backbone curves for multiple robots with base offsets.

Uses forward_kinematics_batched if available (optimized), otherwise falls back to jax.vmap over compute_backbone_curve.

Parameters:

Name Type Description Default
q_batch Array

Configurations of shape (N, DOF) - batch-first

required
base_offsets Array

Base position offsets of shape (N, 2) or (N, 3)

required

Returns:

Type Description
Array

Array of shape (N, num_points, dim) - batch-first

compute_backbone_curves_and_frames_batched

compute_backbone_curves_and_frames_batched(q_batch: Array, base_offsets: Array) -> tuple[Array, Array]

Compute 3D backbone positions and material frames for multiple robots.

The frame columns are the local material-frame axes in world coordinates. Positional base offsets translate the curves without rotating the frames.

Open3D Renderer

Open3DRenderer provides interactive spatial visualization with mesh geometry, camera controls, playback, screenshots, and offline frame or video capture. Open3D currently requires Python 3.12 or earlier because Python 3.13 wheels are not yet available.

Set backbone_style="discrete" for per-point spheres or "swept" for cylinders, boxes, or ellipses generated from the robot cross section. Multi-robot sequence scenes automatically merge each robot's backbone primitives to reduce Open3D registrations; merge_backbone_meshes can force or disable this behavior when measuring a particular workload.

Keyboard Controls

Key Action
Space Play or pause
/ Step to the next or previous frame
H Go to the first frame
S Save a snapshot
R Reset the camera
C Capture camera parameters
L Load camera parameters
V Print camera parameters
Q / Esc Quit

soromox.rendering.open3d_renderer.Open3DRenderer

Open3DRenderer(robot: SoftRobot, width: int = 1920, height: int = 1200, num_points: int = 80, background_color: tuple[float, float, float] = (1.0, 1.0, 1.0), color_config: RendererColorConfig | None = None, backbone_style: str = 'swept', recompute_normals: bool = True, tube_resolution: int = 20, sphere_resolution: int = 32, base_plate_radius_scale: float = 2.0, base_plate_thickness: float = 0.06, show_ground_plane: bool = True, ground_plane_size: float | None = None, grid_spacing: tuple[float, float] = (0.5, 0.5), base_offsets: Array | None = None, actuator_line_width: float = 2.0, camera_margin_ratio: float = 0.05, merge_backbone_meshes: bool | None = None)

Bases: BaseSoftRobotRenderer


              flowchart TD
              soromox.rendering.open3d_renderer.Open3DRenderer[Open3DRenderer]
              soromox.rendering.base.BaseSoftRobotRenderer[BaseSoftRobotRenderer]

                              soromox.rendering.base.BaseSoftRobotRenderer --> soromox.rendering.open3d_renderer.Open3DRenderer
                


              click soromox.rendering.open3d_renderer.Open3DRenderer href "" "soromox.rendering.open3d_renderer.Open3DRenderer"
              click soromox.rendering.base.BaseSoftRobotRenderer href "" "soromox.rendering.base.BaseSoftRobotRenderer"
            

Open3D visualization for any continuum soft robot.

Provides interactive 3D visualization with spheres for backbone, optional actuator rendering, and keyboard controls.

Example
renderer = Open3DRenderer(robot)
renderer.show(q)
renderer.render_sequence(ts, q_ts, playback_speed=1.0)

Initialize Open3D renderer.

Parameters:

Name Type Description Default
robot SoftRobot

Robot system with forward_kinematics method

required
width int

Window width in pixels

1920
height int

Window height in pixels

1200
num_points int

Number of points for backbone discretization

80
background_color tuple[float, float, float]

RGB background color (0-1 range)

(1.0, 1.0, 1.0)
color_config RendererColorConfig | None

Shared renderer color configuration

None
backbone_style str

"swept" (material-frame surface) or "discrete" (markers)

'swept'
recompute_normals bool

Whether to recompute vertex normals per segment update

True
tube_resolution int

Radial resolution for tube segments

20
sphere_resolution int

Resolution for backbone spheres

32
base_plate_radius_scale float

Multiplier applied to the maximum cross-section radius to size the base plate

2.0
base_plate_thickness float

Absolute thickness of the base plate geometry

0.06
show_ground_plane bool

Whether to render a base-aligned ground plane

True
ground_plane_size float | None

Optional side length of the ground plane in meters

None
grid_spacing tuple[float, float]

(x, y) spacing between robot bases for batched rendering

(0.5, 0.5)
base_offsets Array | None

Explicit base offsets of shape (N, 2) or (N, 3) for batched rendering

None
actuator_line_width float

Width of actuator lines

2.0
camera_margin_ratio float

Margin ratio for camera bounding box

0.05
merge_backbone_meshes bool | None

Whether to merge each robot's backbone primitives into one dynamic mesh. None selects merging automatically for multi-robot scenes while retaining the lower per-frame update cost of unmerged single-robot scenes.

None

is_3d property

is_3d: bool

Whether this renderer operates in 3D space.

Returns:

Name Type Description
is_3d bool

Always True for the Open3D renderer.

is_planar property

is_planar: bool

Return True for planar (SE(2)) robots.

render_frame

render_frame(q: Array, *, base_offsets: Array | None = None, color_config: RendererColorConfig | None = None, camera_config: CameraConfig | None = None, render_actuators: bool = True, actuator_inputs: Array | None = None, static_spheres_positions: Array | None = None, static_spheres_radii: Array | None = None, static_spheres_colors: Array | None = None, dynamic_spheres_positions: Array | None = None, dynamic_spheres_radii: Array | None = None, dynamics_spheres_colors: Array | None = None) -> ndarray

Render a single configuration headlessly and return an RGB array.

Parameters:

Name Type Description Default
q Array

Robot configuration of shape (DOF,) or batched (N, DOF).

required
base_offsets Array | None

Optional base offsets of shape (N, ⅔) for batched layouts.

None
color_config RendererColorConfig | None

Optional shared renderer color configuration.

None
camera_config CameraConfig | None

Camera configuration (fov, position, look_at, etc.)

None
render_actuators bool

Whether to render actuator visual layers if available.

True
actuator_inputs Array | None

Optional actuator inputs for scalar-colored layers.

None
static_spheres_positions Array | None

Optional static sphere centers, shape (M, 3).

None
static_spheres_radii Array | None

Optional static sphere radii, length M.

None
static_spheres_colors Array | None

Optional static sphere colors, shape (M, ¾).

None
dynamic_spheres_positions Array | None

Optional dynamic sphere trajectories, shape (K, T, 3).

None
dynamic_spheres_radii Array | None

Optional dynamic sphere radii, length K.

None
dynamics_spheres_colors Array | None

Optional dynamic sphere colors, shape (K, ¾).

None

Returns:

Name Type Description
img ndarray

Rendered RGB image of shape (height, width, 3), dtype uint8.

show

show(q: Array, *, base_offsets: Array | None = None, color_config: RendererColorConfig | None = None, camera_config: CameraConfig | None = None, render_actuators: bool = True, actuator_inputs: Array | None = None, static_spheres_positions: Array | None = None, static_spheres_radii: Array | None = None, static_spheres_colors: Array | None = None, dynamic_spheres_positions: Array | None = None, dynamic_spheres_radii: Array | None = None, dynamics_spheres_colors: Array | None = None) -> None

Display a single frame interactively with full geometry options.

Parameters:

Name Type Description Default
q Array

Robot configuration of shape (DOF,) or batched (N, DOF).

required
base_offsets Array | None

Optional base offsets of shape (N, ⅔) for batched layouts.

None
color_config RendererColorConfig | None

Optional shared renderer color configuration.

None
camera_config CameraConfig | None

Camera configuration (fov, position, look_at, etc.)

None
render_actuators bool

Whether to render actuator visual layers if available.

True
actuator_inputs Array | None

Optional actuator inputs for scalar-colored layers.

None
static_spheres_positions Array | None

Optional static sphere centers, shape (M, 3).

None
static_spheres_radii Array | None

Optional static sphere radii, length M.

None
static_spheres_colors Array | None

Optional static sphere colors, shape (M, ¾).

None
dynamic_spheres_positions Array | None

Optional dynamic sphere trajectories, shape (K, T, 3).

None
dynamic_spheres_radii Array | None

Optional dynamic sphere radii, length K.

None
dynamics_spheres_colors Array | None

Optional dynamic sphere colors, shape (K, ¾).

None

Returns:

Type Description
None

None

render_sequence

render_sequence(ts: Array, q_ts: Array, *, playback_speed: float = 1.0, autoplay: bool = True, loop: bool = False, record_path: str | None = None, record_every_n: int = 1, record_prefix: str = 'frame_', video_config: VideoEncodingConfig | None = None, close_when_recording_done: bool = False, camera_config: CameraConfig | None = None, base_offsets: Array | None = None, color_config: RendererColorConfig | None = None, render_actuators: bool = True, actuator_inputs: Array | None = None, static_spheres_positions: Array | None = None, static_spheres_radii: Array | None = None, static_spheres_colors: Array | None = None, dynamic_spheres_positions: Array | None = None, dynamic_spheres_radii: Array | None = None, dynamics_spheres_colors: Array | None = None, window_name: str = 'Robot Animation (Open3D)') -> None

Render an animated trajectory interactively or headlessly.

Parameters:

Name Type Description Default
ts Array

Time stamps of shape (T,).

required
q_ts Array

Configurations of shape (T, DOF) or batched (N, T, DOF).

required
playback_speed float

Playback speed multiplier (>0).

1.0
autoplay bool

Start playback immediately. If False, wait for space bar to play.

True
loop bool

Whether to loop the animation when it reaches the end.

False
record_path str | None

Optional path to save frames or video (extension determines mode).

None
record_every_n int

Save every n-th frame when recording images.

1
record_prefix str

Filename prefix for recorded frames.

'frame_'
video_config VideoEncodingConfig | None

Optional ffmpeg encoding configuration for video output.

None
close_when_recording_done bool

Close the viewer after the final recorded frame.

False
camera_config CameraConfig | None

Camera configuration (fov, position, look_at, etc.). Note: For interactive viewing, user can adjust camera with mouse.

None
base_offsets Array | None

Optional base offsets of shape (N, ⅔) for batched layouts.

None
color_config RendererColorConfig | None

Optional shared renderer color configuration.

None
render_actuators bool

Whether to render actuator visual layers if available.

True
actuator_inputs Array | None

Optional actuator inputs for scalar-colored layers.

None
static_spheres_positions Array | None

Optional static sphere centers, shape (M, 3).

None
static_spheres_radii Array | None

Optional static sphere radii, length M.

None
static_spheres_colors Array | None

Optional static sphere colors, shape (M, ¾).

None
dynamic_spheres_positions Array | None

Optional dynamic sphere trajectories, shape (K, T, 3).

None
dynamic_spheres_radii Array | None

Optional dynamic sphere radii, length K.

None
dynamics_spheres_colors Array | None

Optional dynamic sphere colors, shape (K, ¾).

None
window_name str

Title for the viewer window.

'Robot Animation (Open3D)'

Returns:

Type Description
None

None

compute_backbone_curve

compute_backbone_curve(q: Array) -> Array

Compute backbone points from configuration.

Parameters:

Name Type Description Default
q Array

Robot configuration array

required

Returns:

Type Description
Array

Array of shape (num_points, 3) for 3D or (num_points, 2) for 2D

compute_backbone_poses

compute_backbone_poses(q: Array) -> Array

Compute full FK poses at the configured backbone sample points.

compute_actuator_visual_layers

compute_actuator_visual_layers(q: Array, *, actuator_inputs: Array | None = None) -> tuple[ActuatorVisualLayer, ...]

Compute renderer-facing actuator visual layers for one robot.

compute_actuator_visual_layers_batched

compute_actuator_visual_layers_batched(q_batch: Array, base_offsets: Array, *, actuator_inputs: Array | ndarray | None = None) -> tuple[BatchedActuatorVisualLayer, ...]

Compute actuator visual layers for multiple robots with base offsets.

compute_actuator_visual_layers_trajectory

compute_actuator_visual_layers_trajectory(q_ts: Array, base_offsets: Array, *, actuator_inputs: Array | ndarray | None = None) -> tuple[TrajectoryActuatorVisualLayer, ...]

Compute actuator visual layers for (N, T, DOF) trajectories.

resolve_backbone_colors

resolve_backbone_colors(num_robots: int, *, color_config: RendererColorConfig | None = None, cache: bool = True) -> ResolvedBackboneColors

Resolve backbone colors using the shared config hierarchy.

get_color_legend

get_color_legend(*, num_robots: int = 1, color_config: RendererColorConfig | None = None) -> ColorLegend

Return a lightweight color legend for the current configuration.

clear_color_cache

clear_color_cache() -> None

Clear cached color resolutions.

compute_backbone_curves_batched

compute_backbone_curves_batched(q_batch: Array, base_offsets: Array) -> Array

Compute backbone curves for multiple robots with base offsets.

Uses forward_kinematics_batched if available (optimized), otherwise falls back to jax.vmap over compute_backbone_curve.

Parameters:

Name Type Description Default
q_batch Array

Configurations of shape (N, DOF) - batch-first

required
base_offsets Array

Base position offsets of shape (N, 2) or (N, 3)

required

Returns:

Type Description
Array

Array of shape (N, num_points, dim) - batch-first

compute_backbone_curves_and_frames_batched

compute_backbone_curves_and_frames_batched(q_batch: Array, base_offsets: Array) -> tuple[Array, Array]

Compute 3D backbone positions and material frames for multiple robots.

The frame columns are the local material-frame axes in world coordinates. Positional base offsets translate the curves without rotating the frames.

References

Zhou, Q. Y., Park, J., & Koltun, V. (2018). Open3D: A modern library for 3D data processing. arXiv preprint arXiv:1801.09847.

Open3D documentation

Viser Renderer

ViserRenderer provides browser-based spatial visualization with live state streaming, playback controls, multi-robot scenes, lighting, helper geometry, plot panels, and synchronized video or snapshot capture. As with Open3D, backbone_style selects discrete or swept robot geometry.

GUI Plots and Live Mode

ViserRenderer.render_sequence() can add Plotly panels with:

  • plot_configurations=True
  • plot_actuator_positions=True
  • custom_plots={"My Plot": (figure, aspect)}

Plot panels require Plotly and a single trajectory with shape (T, DOF). Live visualization is available through start_live_mode(), either with a callback that supplies states or by pushing states to the returned controller.

Visual Quality

Viser exposes backend-specific controls for:

  • lighting through enable_default_lights, directional-light, and ambient-light parameters;
  • materials through material, flat_shading, and wireframe;
  • mesh quality through sphere_resolution and cylinder_sections;
  • shadows through cast_shadows, backbone_cast_shadow, and sphere_cast_shadow.

soromox.rendering.viser_renderer.ViserRenderer

ViserRenderer(robot: SoftRobot, width: int = 1920, height: int = 1200, num_points: int = 80, background_color: tuple[float, float, float] = (1.0, 1.0, 1.0), color_config: RendererColorConfig | None = None, host: str = '0.0.0.0', port: int = 8080, backbone_style: Literal['discrete', 'swept'] = 'swept', sphere_resolution: int = 3, cylinder_sections: int = 48, grid_spacing: tuple[float, float] = (0.5, 0.5), base_offsets: Array | None = None, base_plate_radius_scale: float = 2.0, base_plate_thickness: float = 0.06, show_ground_plane: bool = True, ground_plane_size: float | None = None, actuator_line_width: float = 3.0, camera_fov: float = 75.0, enable_default_lights: bool = True, add_directional_light: bool = True, directional_light_intensity: float = 0.8, directional_light_direction: tuple[float, float, float] = (-0.5, -1.0, -0.5), directional_light_color: tuple[int, int, int] = (255, 255, 255), add_ambient_light: bool = True, ambient_light_intensity: float = 0.4, ambient_light_color: tuple[int, int, int] = (255, 255, 255), cast_shadows: bool = True, material: Literal['standard', 'toon3', 'toon5'] = 'standard', flat_shading: bool = False, wireframe: bool = False, backbone_cast_shadow: bool = True, sphere_cast_shadow: bool = True, auto_start: bool = True, open_browser: bool = True)

Bases: BaseSoftRobotRenderer


              flowchart TD
              soromox.rendering.viser_renderer.ViserRenderer[ViserRenderer]
              soromox.rendering.base.BaseSoftRobotRenderer[BaseSoftRobotRenderer]

                              soromox.rendering.base.BaseSoftRobotRenderer --> soromox.rendering.viser_renderer.ViserRenderer
                


              click soromox.rendering.viser_renderer.ViserRenderer href "" "soromox.rendering.viser_renderer.ViserRenderer"
              click soromox.rendering.base.BaseSoftRobotRenderer href "" "soromox.rendering.base.BaseSoftRobotRenderer"
            

Viser-based web visualization for soft robots.

Provides interactive 3D visualization accessible via web browser with: - Real-time animation playback with GUI controls - Live mode for streaming robot states - Multiple robot overlay - Dynamic spheres for setpoints/obstacles - Embedded plot panels - Video export via FFmpeg

Example
renderer = ViserRenderer(robot, port=8080)
renderer.show(q)
renderer.render_sequence(ts, q_ts, playback_speed=1.0, loop=True)

Initialize Viser renderer.

Parameters:

Name Type Description Default
robot SoftRobot

SoftRobot system with forward_kinematics method

required
width int

Default render width in pixels

1920
height int

Default render height in pixels

1200
num_points int

Number of points for backbone curve discretization

80
background_color tuple[float, float, float]

RGB background color (0-1 range)

(1.0, 1.0, 1.0)
color_config RendererColorConfig | None

Shared renderer color configuration

None
host str

Server bind address (0.0.0.0 for all interfaces)

'0.0.0.0'
port int

Server port number

8080
backbone_style Literal['discrete', 'swept']

"swept" (material-frame surface) or "discrete" (spheres)

'swept'
sphere_resolution int

Icosphere subdivision level (1=low, 2=medium, 3=good, 4=high)

3
cylinder_sections int

Number of cylinder cross-section segments (higher=smoother)

48
grid_spacing tuple[float, float]

(x, y) spacing for multi-robot grid layout

(0.5, 0.5)
base_offsets Array | None

Explicit base position offsets (N, 3)

None
base_plate_radius_scale float

Base plate radius relative to robot radius

2.0
base_plate_thickness float

Base plate thickness in meters

0.06
show_ground_plane bool

Whether to add Viser's native ground grid

True
ground_plane_size float | None

Optional side length of the ground grid in meters

None
actuator_line_width float

Line width for actuator visualization

3.0
camera_fov float

Camera field of view in degrees

75.0
enable_default_lights bool

Enable Viser's default lighting

True
add_directional_light bool

Add custom directional light

True
directional_light_intensity float

Directional light intensity (0-1+)

0.8
directional_light_direction tuple[float, float, float]

Directional light direction vector (x, y, z)

(-0.5, -1.0, -0.5)
directional_light_color tuple[int, int, int]

Directional light RGB color (0-255)

(255, 255, 255)
add_ambient_light bool

Add custom ambient light

True
ambient_light_intensity float

Ambient light intensity (0-1+)

0.4
ambient_light_color tuple[int, int, int]

Ambient light RGB color (0-255)

(255, 255, 255)
cast_shadows bool

Enable shadow casting for default lights

True
material Literal['standard', 'toon3', 'toon5']

Material type ("standard", "toon3", "toon5")

'standard'
flat_shading bool

Use flat shading instead of smooth

False
wireframe bool

Render geometry as wireframe

False
backbone_cast_shadow bool

Enable shadow casting for backbone geometry

True
sphere_cast_shadow bool

Enable shadow casting for sphere geometry

True
auto_start bool

Start server immediately

True
open_browser bool

Open browser automatically when show() is called

True

is_3d property

is_3d: bool

Always True for Viser (3D only).

server property

server: ViserServer

Access underlying Viser server.

url property

url: str

URL to access the visualization.

is_planar property

is_planar: bool

Return True for planar (SE(2)) robots.

start

start() -> None

Start the Viser server.

stop

stop() -> None

Stop the Viser server.

render_frame

render_frame(q: Array, *, base_offsets: Array | None = None, color_config: RendererColorConfig | None = None, camera_config: CameraConfig | None = None, render_actuators: bool = True, actuator_inputs: Array | None = None, static_spheres_positions: Array | None = None, static_spheres_radii: Array | None = None, static_spheres_colors: Array | None = None, capture_client_idx: int = 0) -> ndarray

Render single configuration and capture as image.

Note: Requires at least one connected client to capture.

Parameters:

Name Type Description Default
q Array

Robot configuration (DOF,) or batched (N, DOF)

required
base_offsets Array | None

Base position offsets (N, 3)

None
color_config RendererColorConfig | None

Shared renderer color configuration

None
camera_config CameraConfig | None

Camera configuration (fov, position, look_at, etc.)

None
render_actuators bool

If True, render actuator visual layers.

True
actuator_inputs Array | None

Optional actuator inputs for scalar-colored layers.

None
static_spheres_positions Array | None

Static sphere positions (M, 3)

None
static_spheres_radii Array | None

Static sphere radii (M,)

None
static_spheres_colors Array | None

Static sphere colors (M, 3)

None
capture_client_idx int

Index of client to capture from

0

Returns:

Type Description
ndarray

RGB image as numpy array (height, width, 3), dtype uint8

show

show(q: Array, *, base_offsets: Array | None = None, color_config: RendererColorConfig | None = None, camera_config: CameraConfig | None = None, render_actuators: bool = True, actuator_inputs: Array | None = None, static_spheres_positions: Array | None = None, static_spheres_radii: Array | None = None, static_spheres_colors: Array | None = None, blocking: bool = True) -> None

Display single frame interactively.

Opens browser automatically and optionally blocks.

Parameters:

Name Type Description Default
q Array

Robot configuration (DOF,) or batched (N, DOF)

required
base_offsets Array | None

Base position offsets (N, 3)

None
color_config RendererColorConfig | None

Shared renderer color configuration

None
camera_config CameraConfig | None

Camera configuration (fov, position, look_at, etc.)

None
render_actuators bool

If True, render actuator visual layers.

True
actuator_inputs Array | None

Optional actuator inputs for scalar-colored layers.

None
static_spheres_positions Array | None

Static sphere positions (M, 3)

None
static_spheres_radii Array | None

Static sphere radii (M,)

None
static_spheres_colors Array | None

Static sphere colors (M, 3)

None
blocking bool

If True, block until user closes browser

True

render_sequence

render_sequence(ts: Array, q_ts: Array, *, playback_speed: float = 1.0, autoplay: bool = True, loop: bool = False, record_path: str | None = None, snapshot_paths: Mapping[int, str | Path] | None = None, record_every_n: int = 1, stop_when_recording_done: bool = False, record_client_timeout: float = 10.0, record_frame_timeout: float = 10.0, video_config: VideoEncodingConfig | None = None, camera_config: CameraConfig | None = None, base_offsets: Array | None = None, color_config: RendererColorConfig | None = None, render_actuators: bool = True, actuator_inputs: Array | None = None, multi_robot_layout: Literal['grid', 'overlay'] = 'grid', static_spheres_positions: Array | None = None, static_spheres_radii: Array | None = None, static_spheres_colors: Array | None = None, dynamic_spheres_positions: Array | None = None, dynamic_spheres_radii: Array | None = None, dynamic_spheres_colors: Array | None = None, blocking: bool = True, plot_configurations: bool = False, plot_actuator_positions: bool = False, custom_plots: dict[str, tuple] | None = None, robot_name: str = 'Robot') -> None

Render animated trajectory with full visualization options.

Parameters:

Name Type Description Default
ts Array

Time stamps (T,)

required
q_ts Array

Configurations (T, DOF) or batched (N, T, DOF)

required
playback_speed float

Speed multiplier

1.0
autoplay bool

Start playing immediately

True
loop bool

Loop animation

False
record_path str | None

Path to save video (mp4, mov)

None
snapshot_paths Mapping[int, str | Path] | None

Mapping from zero-based frame indices to PNG paths. Requested snapshots use the same synchronized browser render as video.

None
record_every_n int

Record every N frames

1
stop_when_recording_done bool

If True, return after recording one non-looping pass through the sequence.

False
record_client_timeout float

Seconds to wait for a browser client before video recording fails.

10.0
record_frame_timeout float

Seconds to wait for each browser render before video recording fails.

10.0
video_config VideoEncodingConfig | None

FFmpeg encoding settings

None
camera_config CameraConfig | None

Camera configuration (fov, position, look_at, etc.)

None
base_offsets Array | None

Base position offsets (N, ⅔)

None
color_config RendererColorConfig | None

Shared renderer color configuration

None
render_actuators bool

If True, render actuator visual layers.

True
actuator_inputs Array | None

Optional actuator inputs for scalar-colored layers.

None
multi_robot_layout Literal['grid', 'overlay']

"grid" for side-by-side, "overlay" for same position

'grid'
static_spheres_positions Array | None

Static sphere positions

None
static_spheres_radii Array | None

Static sphere radii

None
static_spheres_colors Array | None

Static sphere colors

None
dynamic_spheres_positions Array | None

Time-varying sphere positions

None
dynamic_spheres_radii Array | None

Time-varying sphere radii

None
dynamic_spheres_colors Array | None

Time-varying sphere colors

None
blocking bool

If True, block until viewer closes

True
plot_configurations bool

If True, add configuration vs time plot to GUI

False
plot_actuator_positions bool

If True, add actuator coordinate plot to GUI

False
custom_plots dict[str, tuple] | None

Dictionary mapping plot names to (figure, aspect) tuples for custom plotly figures to add to the GUI

None
robot_name str

Name for plot titles

'Robot'

add_gui_plotly

add_gui_plotly(name: str, figure: Figure, aspect: float = 1.0) -> Any

Add a plotly figure to the GUI.

Parameters:

Name Type Description Default
name str

Unique name for the plot

required
figure Figure

Plotly figure object

required
aspect float

Aspect ratio (width/height)

1.0

Returns:

Type Description
Any

Viser plotly handle

create_configuration_plot

create_configuration_plot(ts: Array | ndarray, q_ts: Array | ndarray, robot_name: str = 'Robot') -> Figure

Create a plotly figure showing configurations over time.

Parameters:

Name Type Description Default
ts Array | ndarray

Time array (T,)

required
q_ts Array | ndarray

Configuration array (T, DOF)

required
robot_name str

Name for the plot title

'Robot'

Returns:

Type Description
Figure

Plotly figure

create_actuator_position_plot

create_actuator_position_plot(ts: Array | ndarray, q_ts: Array | ndarray, robot: SoftRobot, robot_name: str = 'Robot') -> Figure

Create a plotly figure showing actuator coordinates over time.

Parameters:

Name Type Description Default
ts Array | ndarray

Time array (T,)

required
q_ts Array | ndarray

Configuration array (T, DOF)

required
robot SoftRobot

Robot instance with an actuator_coordinates method

required
robot_name str

Name for the plot title

'Robot'

Returns:

Type Description
Figure

Plotly figure

start_live_mode

start_live_mode(callback: Callable[[float], ndarray] | None = None, dt: float = 0.033) -> LiveModeController

Start live visualization mode.

Two usage patterns:

Callback mode (renderer pulls):

def get_state(t):
    return compute_robot_state(t)

controller = renderer.start_live_mode(callback=get_state)

Stream mode (user pushes):

controller = renderer.start_live_mode()
for q in simulation_loop():
    controller.push_state(q)

Parameters:

Name Type Description Default
callback Callable[[float], ndarray] | None

Optional state provider function (time) -> q

None
dt float

Time step for callback mode in seconds

0.033

Returns:

Type Description
LiveModeController

LiveModeController for managing the live session

add_dynamic_sphere

add_dynamic_sphere(name: str, position: ndarray, radius: float, color: tuple[float, float, float] = (0.2, 0.2, 0.8), opacity: float = 1.0) -> Any

Add a dynamic sphere to the scene.

Parameters:

Name Type Description Default
name str

Unique identifier for the sphere

required
position ndarray

Initial position (3,)

required
radius float

Sphere radius

required
color tuple[float, float, float]

RGB color (0-1)

(0.2, 0.2, 0.8)
opacity float

Opacity (0-1)

1.0

Returns:

Type Description
Any

Viser sphere handle

update_dynamic_sphere

update_dynamic_sphere(name: str, position: ndarray | None = None, radius: float | None = None, color: tuple[float, float, float] | None = None) -> None

Update properties of a dynamic sphere.

Parameters:

Name Type Description Default
name str

Sphere identifier

required
position ndarray | None

New position (3,)

None
radius float | None

New radius

None
color tuple[float, float, float] | None

New RGB color

None

remove_dynamic_sphere

remove_dynamic_sphere(name: str) -> None

Remove a dynamic sphere from the scene.

Parameters:

Name Type Description Default
name str

Sphere identifier

required

add_custom_primitive

add_custom_primitive(name: str, primitive_type: Literal['sphere', 'box', 'cylinder', 'mesh'], **kwargs: Any) -> Any

Add a custom primitive to the scene for extensibility.

Parameters:

Name Type Description Default
name str

Unique identifier

required
primitive_type Literal['sphere', 'box', 'cylinder', 'mesh']

Type of primitive

required
**kwargs Any

Primitive-specific parameters

{}

Returns:

Type Description
Any

Viser scene handle

render_to_video

render_to_video(ts: Array, q_ts: Array, output_path: str, *, width: int | None = None, height: int | None = None, fps: float | None = None, video_config: VideoEncodingConfig | None = None, camera_position: tuple[float, float, float] | None = None, camera_target: tuple[float, float, float] | None = None, **render_kwargs: Any) -> None

Render sequence directly to video file.

This method renders each frame and writes to video using FFmpeg. Requires at least one connected client for capture.

Parameters:

Name Type Description Default
ts Array

Time stamps

required
q_ts Array

Configurations

required
output_path str

Output video path (.mp4, .mov)

required
width int | None

Frame width (default: self.width)

None
height int | None

Frame height (default: self.height)

None
fps float | None

Output FPS (if None, derived from ts)

None
video_config VideoEncodingConfig | None

FFmpeg settings

None
camera_position tuple[float, float, float] | None

Fixed camera position

None
camera_target tuple[float, float, float] | None

Camera look-at target

None
**render_kwargs Any

Additional render_sequence arguments

{}

compute_backbone_curve

compute_backbone_curve(q: Array) -> Array

Compute backbone points from configuration.

Parameters:

Name Type Description Default
q Array

Robot configuration array

required

Returns:

Type Description
Array

Array of shape (num_points, 3) for 3D or (num_points, 2) for 2D

compute_backbone_poses

compute_backbone_poses(q: Array) -> Array

Compute full FK poses at the configured backbone sample points.

compute_actuator_visual_layers

compute_actuator_visual_layers(q: Array, *, actuator_inputs: Array | None = None) -> tuple[ActuatorVisualLayer, ...]

Compute renderer-facing actuator visual layers for one robot.

compute_actuator_visual_layers_batched

compute_actuator_visual_layers_batched(q_batch: Array, base_offsets: Array, *, actuator_inputs: Array | ndarray | None = None) -> tuple[BatchedActuatorVisualLayer, ...]

Compute actuator visual layers for multiple robots with base offsets.

compute_actuator_visual_layers_trajectory

compute_actuator_visual_layers_trajectory(q_ts: Array, base_offsets: Array, *, actuator_inputs: Array | ndarray | None = None) -> tuple[TrajectoryActuatorVisualLayer, ...]

Compute actuator visual layers for (N, T, DOF) trajectories.

resolve_backbone_colors

resolve_backbone_colors(num_robots: int, *, color_config: RendererColorConfig | None = None, cache: bool = True) -> ResolvedBackboneColors

Resolve backbone colors using the shared config hierarchy.

get_color_legend

get_color_legend(*, num_robots: int = 1, color_config: RendererColorConfig | None = None) -> ColorLegend

Return a lightweight color legend for the current configuration.

clear_color_cache

clear_color_cache() -> None

Clear cached color resolutions.

compute_backbone_curves_batched

compute_backbone_curves_batched(q_batch: Array, base_offsets: Array) -> Array

Compute backbone curves for multiple robots with base offsets.

Uses forward_kinematics_batched if available (optimized), otherwise falls back to jax.vmap over compute_backbone_curve.

Parameters:

Name Type Description Default
q_batch Array

Configurations of shape (N, DOF) - batch-first

required
base_offsets Array

Base position offsets of shape (N, 2) or (N, 3)

required

Returns:

Type Description
Array

Array of shape (N, num_points, dim) - batch-first

compute_backbone_curves_and_frames_batched

compute_backbone_curves_and_frames_batched(q_batch: Array, base_offsets: Array) -> tuple[Array, Array]

Compute 3D backbone positions and material frames for multiple robots.

The frame columns are the local material-frame axes in world coordinates. Positional base offsets translate the curves without rotating the frames.

References

Yi, B., Kim, C. M., Kerr, J., Wu, G., Feng, R., Zhang, A., Kulhanek, J., Choi, H., Ma, Y., Tancik, M., & Kanazawa, A. (2025). Viser: Imperative, Web-based 3D Visualization in Python. arXiv preprint arXiv:2507.22885.

OpenCV Planar Renderer

OpenCVPlanarRenderer provides lightweight single-frame rendering and fast video export for planar robots.

soromox.rendering.opencv_planar_renderer.OpenCVPlanarRenderer

OpenCVPlanarRenderer(robot: SoftRobot, width: int = 700, height: int = 700, num_points: int = 50, background_color: tuple[float, float, float] = (1.0, 1.0, 1.0), base_color: tuple[int, int, int] = (0, 255, 0), backbone_color: tuple[int, int, int] = (0, 0, 0), backbone_thickness: int | None = None, actuator_color: tuple[int, int, int] = (40, 40, 230), actuator_thickness: int = 2, base_radius_scale: float = 2.0, length_scale: float = 2.0, origin_uv: tuple[int, int] | None = None)

Bases: BaseOpenCVRenderer


              flowchart TD
              soromox.rendering.opencv_planar_renderer.OpenCVPlanarRenderer[OpenCVPlanarRenderer]
              soromox.rendering.opencv_base.BaseOpenCVRenderer[BaseOpenCVRenderer]
              soromox.rendering.base.BaseSoftRobotRenderer[BaseSoftRobotRenderer]

                              soromox.rendering.opencv_base.BaseOpenCVRenderer --> soromox.rendering.opencv_planar_renderer.OpenCVPlanarRenderer
                                soromox.rendering.base.BaseSoftRobotRenderer --> soromox.rendering.opencv_base.BaseOpenCVRenderer
                



              click soromox.rendering.opencv_planar_renderer.OpenCVPlanarRenderer href "" "soromox.rendering.opencv_planar_renderer.OpenCVPlanarRenderer"
              click soromox.rendering.opencv_base.BaseOpenCVRenderer href "" "soromox.rendering.opencv_base.BaseOpenCVRenderer"
              click soromox.rendering.base.BaseSoftRobotRenderer href "" "soromox.rendering.base.BaseSoftRobotRenderer"
            

OpenCV visualization for planar soft robots.

Renders the backbone curve with optional segment-aware thickness when per-segment radii are available.

Example
renderer = OpenCVPlanarRenderer(robot)
image = renderer.render_frame(q)
renderer.show(q)

Initialize OpenCV renderer for planar robots.

Parameters:

Name Type Description Default
robot SoftRobot

Planar robot instance

required
width int

Image width in pixels

700
height int

Image height in pixels

700
num_points int

Number of points for curve discretization

50
background_color tuple[float, float, float]

RGB background color (0-1 range)

(1.0, 1.0, 1.0)
base_color tuple[int, int, int]

BGR color for base marker

(0, 255, 0)
backbone_color tuple[int, int, int]

BGR color for backbone

(0, 0, 0)
backbone_thickness int | None

Line thickness for backbone (None = auto)

None
actuator_color tuple[int, int, int]

BGR color for actuator visual layers

(40, 40, 230)
actuator_thickness int

Line thickness for actuator visual layers

2
base_radius_scale float

Multiplier applied to the cross-section span for the base marker

2.0
length_scale float

Scale factor for robot in image (robot occupies height/length_scale)

2.0
origin_uv tuple[int, int] | None

Pixel coordinates of world origin (None = center of image)

None

is_3d property

is_3d: bool

Planar robots are 2D.

is_planar property

is_planar: bool

Return True for planar (SE(2)) robots.

render_frame

render_frame(q: Array, *, base_offsets: Array | None = None, render_actuators: bool = True, actuator_inputs: Array | None = None) -> ndarray

Render single configuration to BGR image array.

Parameters:

Name Type Description Default
q Array

Robot configuration array of shape (DOF,) for a single robot.

required
base_offsets Array | None

Optional positional offset with shape (2,) or (3,). The z component is ignored for this planar renderer.

None
render_actuators bool

Whether to render actuator visual layers if available.

True
actuator_inputs Array | None

Optional actuator inputs for scalar-colored layers.

None

Returns:

Name Type Description
img ndarray

BGR image of shape (height, width, 3), dtype uint8.

show

show(q: Array, *, base_offsets: Array | None = None, render_actuators: bool = True, actuator_inputs: Array | None = None) -> None

Display single frame in OpenCV window.

Parameters:

Name Type Description Default
q Array

Robot configuration array of shape (DOF,).

required
base_offsets Array | None

Optional positional offset with shape (2,) or (3,).

None
render_actuators bool

Whether to render actuator visual layers if available.

True
actuator_inputs Array | None

Optional actuator inputs for scalar-colored layers.

None

compute_backbone_curve

compute_backbone_curve(q: Array) -> Array

Compute backbone points from configuration.

Parameters:

Name Type Description Default
q Array

Robot configuration array

required

Returns:

Type Description
Array

Array of shape (num_points, 3) for 3D or (num_points, 2) for 2D

compute_backbone_poses

compute_backbone_poses(q: Array) -> Array

Compute full FK poses at the configured backbone sample points.

compute_actuator_visual_layers

compute_actuator_visual_layers(q: Array, *, actuator_inputs: Array | None = None) -> tuple[ActuatorVisualLayer, ...]

Compute renderer-facing actuator visual layers for one robot.

compute_actuator_visual_layers_batched

compute_actuator_visual_layers_batched(q_batch: Array, base_offsets: Array, *, actuator_inputs: Array | ndarray | None = None) -> tuple[BatchedActuatorVisualLayer, ...]

Compute actuator visual layers for multiple robots with base offsets.

compute_actuator_visual_layers_trajectory

compute_actuator_visual_layers_trajectory(q_ts: Array, base_offsets: Array, *, actuator_inputs: Array | ndarray | None = None) -> tuple[TrajectoryActuatorVisualLayer, ...]

Compute actuator visual layers for (N, T, DOF) trajectories.

render_sequence

render_sequence(ts: Array, q_ts: Array, playback_speed: float = 1.0, record_path: str | None = None, video_config: VideoEncodingConfig | None = None) -> None

Render animated sequence to video file using ffmpeg.

Falls back to OpenCV VideoWriter if ffmpeg is unavailable.

Parameters:

Name Type Description Default
ts Array

Time stamps of shape (T,)

required
q_ts Array

Configurations of shape (T, DOF)

required
playback_speed float

Playback speed multiplier (>0)

1.0
record_path str | None

Path to save video file

None
video_config VideoEncodingConfig | None

Optional ffmpeg encoding configuration

None

resolve_backbone_colors

resolve_backbone_colors(num_robots: int, *, color_config: RendererColorConfig | None = None, cache: bool = True) -> ResolvedBackboneColors

Resolve backbone colors using the shared config hierarchy.

get_color_legend

get_color_legend(*, num_robots: int = 1, color_config: RendererColorConfig | None = None) -> ColorLegend

Return a lightweight color legend for the current configuration.

clear_color_cache

clear_color_cache() -> None

Clear cached color resolutions.

compute_backbone_curves_batched

compute_backbone_curves_batched(q_batch: Array, base_offsets: Array) -> Array

Compute backbone curves for multiple robots with base offsets.

Uses forward_kinematics_batched if available (optimized), otherwise falls back to jax.vmap over compute_backbone_curve.

Parameters:

Name Type Description Default
q_batch Array

Configurations of shape (N, DOF) - batch-first

required
base_offsets Array

Base position offsets of shape (N, 2) or (N, 3)

required

Returns:

Type Description
Array

Array of shape (N, num_points, dim) - batch-first

compute_backbone_curves_and_frames_batched

compute_backbone_curves_and_frames_batched(q_batch: Array, base_offsets: Array) -> tuple[Array, Array]

Compute 3D backbone positions and material frames for multiple robots.

The frame columns are the local material-frame axes in world coordinates. Positional base offsets translate the curves without rotating the frames.

OpenCV Planar HSA Renderer

OpenCVPlanarHSARenderer extends the planar OpenCV backend with HSA-specific geometry. Its system-level usage is documented with the Planar HSA model.

soromox.rendering.planar_hsa.opencv_renderer.OpenCVPlanarHSARenderer

OpenCVPlanarHSARenderer(robot: PlanarHSA, width: int = 700, height: int = 700, num_points: int = 50, background_color: tuple[float, float, float] = (1.0, 1.0, 1.0), base_color: tuple[int, int, int] = (0, 0, 0), backbone_color: tuple[int, int, int] = (255, 0, 0), rod_color: tuple[int, int, int] = (0, 255, 0), platform_color: tuple[int, int, int] = (0, 0, 255), backbone_thickness: int = 5, rod_thickness: int = 10)

Bases: BaseOpenCVRenderer


              flowchart TD
              soromox.rendering.planar_hsa.opencv_renderer.OpenCVPlanarHSARenderer[OpenCVPlanarHSARenderer]
              soromox.rendering.opencv_base.BaseOpenCVRenderer[BaseOpenCVRenderer]
              soromox.rendering.base.BaseSoftRobotRenderer[BaseSoftRobotRenderer]

                              soromox.rendering.opencv_base.BaseOpenCVRenderer --> soromox.rendering.planar_hsa.opencv_renderer.OpenCVPlanarHSARenderer
                                soromox.rendering.base.BaseSoftRobotRenderer --> soromox.rendering.opencv_base.BaseOpenCVRenderer
                



              click soromox.rendering.planar_hsa.opencv_renderer.OpenCVPlanarHSARenderer href "" "soromox.rendering.planar_hsa.opencv_renderer.OpenCVPlanarHSARenderer"
              click soromox.rendering.opencv_base.BaseOpenCVRenderer href "" "soromox.rendering.opencv_base.BaseOpenCVRenderer"
              click soromox.rendering.base.BaseSoftRobotRenderer href "" "soromox.rendering.base.BaseSoftRobotRenderer"
            

OpenCV visualization for Planar HSA robots.

Renders the virtual backbone, rods, and platforms with custom colors. This is a specialized renderer that uses HSA-specific forward kinematics.

Example
renderer = OpenCVPlanarHSARenderer(robot)
image = renderer.render_frame(q)
renderer.show(q)

Initialize OpenCV renderer for Planar HSA.

Parameters:

Name Type Description Default
robot PlanarHSA

PlanarHSA robot instance

required
width int

Image width in pixels

700
height int

Image height in pixels

700
num_points int

Number of points for curve discretization

50
background_color tuple[float, float, float]

RGB background color (0-1 range)

(1.0, 1.0, 1.0)
base_color tuple[int, int, int]

BGR color for base rectangle

(0, 0, 0)
backbone_color tuple[int, int, int]

BGR color for virtual backbone

(255, 0, 0)
rod_color tuple[int, int, int]

BGR color for rods

(0, 255, 0)
platform_color tuple[int, int, int]

BGR color for platforms

(0, 0, 255)
backbone_thickness int

Line thickness for backbone

5
rod_thickness int

Line thickness for rods

10

is_3d property

is_3d: bool

Planar HSA is 2D.

is_planar property

is_planar: bool

Return True for planar (SE(2)) robots.

render_frame

render_frame(q: Array, *, base_offsets: Array | None = None) -> ndarray

Render single configuration to BGR image array.

Parameters:

Name Type Description Default
q Array

Robot configuration array

required
base_offsets Array | None

Optional positional offset with shape (2,) or (3,). The z component is ignored for this planar renderer.

None

Returns:

Type Description
ndarray

BGR image as numpy array of shape (height, width, 3), dtype uint8

show

show(q: Array, *, base_offsets: Array | None = None) -> None

Display single frame in OpenCV window.

Parameters:

Name Type Description Default
q Array

Robot configuration

required
base_offsets Array | None

Optional positional offset with shape (2,) or (3,).

None

compute_backbone_curve

compute_backbone_curve(q: Array) -> Array

Compute backbone points from configuration.

Parameters:

Name Type Description Default
q Array

Robot configuration array

required

Returns:

Type Description
Array

Array of shape (num_points, 3) for 3D or (num_points, 2) for 2D

compute_backbone_poses

compute_backbone_poses(q: Array) -> Array

Compute full FK poses at the configured backbone sample points.

compute_actuator_visual_layers

compute_actuator_visual_layers(q: Array, *, actuator_inputs: Array | None = None) -> tuple[ActuatorVisualLayer, ...]

Compute renderer-facing actuator visual layers for one robot.

compute_actuator_visual_layers_batched

compute_actuator_visual_layers_batched(q_batch: Array, base_offsets: Array, *, actuator_inputs: Array | ndarray | None = None) -> tuple[BatchedActuatorVisualLayer, ...]

Compute actuator visual layers for multiple robots with base offsets.

compute_actuator_visual_layers_trajectory

compute_actuator_visual_layers_trajectory(q_ts: Array, base_offsets: Array, *, actuator_inputs: Array | ndarray | None = None) -> tuple[TrajectoryActuatorVisualLayer, ...]

Compute actuator visual layers for (N, T, DOF) trajectories.

render_sequence

render_sequence(ts: Array, q_ts: Array, playback_speed: float = 1.0, record_path: str | None = None, video_config: VideoEncodingConfig | None = None) -> None

Render animated sequence to video file using ffmpeg.

Falls back to OpenCV VideoWriter if ffmpeg is unavailable.

Parameters:

Name Type Description Default
ts Array

Time stamps of shape (T,)

required
q_ts Array

Configurations of shape (T, DOF)

required
playback_speed float

Playback speed multiplier (>0)

1.0
record_path str | None

Path to save video file

None
video_config VideoEncodingConfig | None

Optional ffmpeg encoding configuration

None

resolve_backbone_colors

resolve_backbone_colors(num_robots: int, *, color_config: RendererColorConfig | None = None, cache: bool = True) -> ResolvedBackboneColors

Resolve backbone colors using the shared config hierarchy.

get_color_legend

get_color_legend(*, num_robots: int = 1, color_config: RendererColorConfig | None = None) -> ColorLegend

Return a lightweight color legend for the current configuration.

clear_color_cache

clear_color_cache() -> None

Clear cached color resolutions.

compute_backbone_curves_batched

compute_backbone_curves_batched(q_batch: Array, base_offsets: Array) -> Array

Compute backbone curves for multiple robots with base offsets.

Uses forward_kinematics_batched if available (optimized), otherwise falls back to jax.vmap over compute_backbone_curve.

Parameters:

Name Type Description Default
q_batch Array

Configurations of shape (N, DOF) - batch-first

required
base_offsets Array

Base position offsets of shape (N, 2) or (N, 3)

required

Returns:

Type Description
Array

Array of shape (N, num_points, dim) - batch-first

compute_backbone_curves_and_frames_batched

compute_backbone_curves_and_frames_batched(q_batch: Array, base_offsets: Array) -> tuple[Array, Array]

Compute 3D backbone positions and material frames for multiple robots.

The frame columns are the local material-frame axes in world coordinates. Positional base offsets translate the curves without rotating the frames.