Skip to content

Shared Renderer Configuration

This page documents camera, base, ground-plane, and color settings shared by multiple SoRoMoX renderers.

Camera Configuration

CameraConfig

The CameraConfig class provides unified camera configuration across renderers (Matplotlib, Open3D, Viser).

from soromox.rendering import CameraConfig

camera = CameraConfig(
    fov=60.0,                           # Field of view in degrees
    position=(0.6, -0.6, 0.4),          # Camera position (x, y, z)
    look_at=(0.0, 0.0, 0.1),            # Point camera looks at
    up=(0.0, 0.0, 1.0),                 # Camera up vector (default: Z-up)
    distance_factor=2.0,                # Multiplier for auto-positioning
)

renderer.show(q, camera_config=camera)

Parameters

Parameter Type Default Description
fov float 75.0 Field of view in degrees
position tuple None Explicit camera position (x, y, z), None for auto
look_at tuple None Point camera looks at, None for scene center
up tuple (0, 0, 1) Camera up vector
distance_factor float 10.0 Multiplier for auto-positioning distance
position_offset tuple (0.8, -0.8, 0.5) Direction vector for camera placement

Matplotlib applies fov and the viewing direction from position to look_at; its axes limits determine the remaining framing. Open3D and Viser also use the explicit camera distance.

soromox.rendering.camera_config.CameraConfig dataclass

CameraConfig(fov: float = 75.0, position: tuple[float, float, float] | None = None, look_at: tuple[float, float, float] | None = None, up: tuple[float, float, float] = (0.0, 0.0, 1.0), distance_factor: float = 10.0, position_offset: tuple[float, float, float] = (0.8, -0.8, 0.5))

Configuration for camera positioning and view parameters.

This config provides unified camera settings that work across different rendering backends. Settings are interpreted appropriately by each backend.

The camera can be positioned either: 1. Automatically based on scene content (position=None, look_at=None) 2. Explicitly by providing position and look_at coordinates

For automatic positioning, the camera is placed to view the entire scene using the distance_factor and position_offset parameters. Renderers can provide the robot base transform so automatic offsets are interpreted in the base frame instead of fixed world axes.

Attributes:

Name Type Description
fov float

Field of view in degrees (used by 3D renderers)

position tuple[float, float, float] | None

Explicit camera position as (x, y, z) or None for auto

look_at tuple[float, float, float] | None

Point the camera looks at as (x, y, z) or None for auto (scene center)

up tuple[float, float, float]

Camera up vector as (x, y, z), default is world Z-up convention

distance_factor float

Multiplier for scene extent to compute camera distance (only used when position is None)

position_offset tuple[float, float, float]

Direction vector for camera placement relative to center, as (x_factor, y_factor, z_factor) multiplied by computed distance. This is interpreted in the base frame when renderers provide one (only used when position is None)

Example
# Default camera with Z-up, auto-positioned
camera = CameraConfig()

# Custom field of view with an explicit position
camera = CameraConfig(
    fov=60.0,
    position=(0.5, -0.5, 0.3),
    look_at=(0.0, 0.0, 0.1),
)

# Auto-positioned but closer to the scene
camera = CameraConfig(distance_factor=5.0)

compute_auto_position

compute_auto_position(center: ndarray, max_extent: float, reference_transform: ndarray | None = None) -> tuple[ndarray, ndarray]

Compute camera position and look_at from scene bounds.

This method computes automatic camera placement based on the scene's center and extent, using the distance_factor and position_offset.

Parameters:

Name Type Description Default
center ndarray

Scene center point as (3,) array

required
max_extent float

Maximum extent (size) of the scene

required
reference_transform ndarray | None

Optional base transform. When supplied, automatic offsets are rotated by the base orientation. Shape may be planar homogeneous (3, 3) or spatial homogeneous (4, 4).

None

Returns:

Type Description
tuple[ndarray, ndarray]

Tuple of (camera_position, look_at_point) as numpy arrays

compute_up

compute_up() -> ndarray

Compute the camera up vector.

Returns:

Type Description
ndarray

Up vector as a NumPy array with shape (3,).


Robot Base and Ground Plane

All renderers obtain the robot origin and orientation from the model's base_pose and base_transform. This keeps the rendered backbone, base, and reference geometry in the same world frame without a renderer-specific pose override.

Setting Purpose Availability
base_plate_radius_scale Scales the rendered base-plate radius relative to the robot cross section Open3D and Viser
base_plate_thickness Sets the base-plate thickness in meters Open3D and Viser
show_ground_plane Shows or hides the base-aligned reference plane Matplotlib, Open3D, and Viser
ground_plane_size Sets the reference-plane side length in meters; None uses a robot-scaled default Matplotlib, Open3D, and Viser
from soromox.rendering import ViserRenderer

renderer = ViserRenderer(
    robot,
    base_plate_radius_scale=2.0,
    base_plate_thickness=0.06,
    show_ground_plane=True,
    ground_plane_size=0.6,
)

Matplotlib draws a lightweight base marker. Open3D and Viser render base-plate geometry and place the ground plane immediately behind it along the model's base axis. Viser uses its native grid primitive. Specialized Viser renderers, including I-SUPPORT and UMArm, inherit these settings.


Color Configuration

Color Hierarchy

Colors are configured via RendererColorConfig + BackboneColorConfig and resolved using a consistent hierarchy. More specific inputs override less specific ones:

robot_palette → segment_palette → point_palette
robot_colors → segment_colors → point_colors
robot_segment_colors → robot_point_colors

Alpha values in per-robot colors propagate to more specific colors when those omit alpha.

RendererColorConfig

Main color configuration container for all renderers.

from soromox.rendering import ActuatorStyleConfig, BackboneColorConfig, RendererColorConfig

color_config = RendererColorConfig(
    backbone=BackboneColorConfig(
        robot_palette="viridis",
        segment_palette="soromox:ember",
    ),
    base_plate_color=(0.5, 0.5, 0.5),
    ground_plane_color=(0.94, 0.95, 0.96),
    ground_plane_grid_color=(0.72, 0.75, 0.78),
    actuators=ActuatorStyleConfig(
        default_color=(0.8, 0.2, 0.2),
        kind_colors={"tendon": (0.85, 0.2, 0.15)},
        kind_radii={"tendon": 5e-4},
    ),
)

renderer.show(q, color_config=color_config)

soromox.rendering.color_config.RendererColorConfig dataclass

RendererColorConfig(backbone: BackboneColorConfig = BackboneColorConfig(), base_plate_color: tuple[float, float, float] = (0.2, 0.2, 0.2), ground_plane_color: tuple[float, float, float] = (0.94, 0.95, 0.96), ground_plane_grid_color: tuple[float, float, float] = (0.72, 0.75, 0.78), actuators: ActuatorStyleConfig = ActuatorStyleConfig())

Shared renderer colors with sensible defaults.

BackboneColorConfig

Backbone-specific color configuration with palette and explicit color support.

from soromox.rendering import BackboneColorConfig

backbone_config = BackboneColorConfig(
    robot_palette="plasma",                    # Colormap for multiple robots
    segment_palette="soromox:ember",           # Per-segment colors
    robot_colors=[(0.2, 0.6, 0.9, 0.5)],       # Explicit robot colors with alpha
)

soromox.rendering.color_config.BackboneColorConfig dataclass

BackboneColorConfig(segment_palette: ColorSpec = DEFAULT_SEGMENT_PALETTE, robot_palette: ColorSpec = DEFAULT_ROBOT_PALETTE, point_palette: ColorSpec | None = None, robot_colors: ColorSpec | None = None, segment_colors: ColorSpec | None = None, robot_segment_colors: ColorSpec | None = None, point_colors: ColorSpec | None = None, robot_point_colors: ColorSpec | None = None)

Color configuration for the robot backbone.

Hierarchy (low -> high specificity): robot_palette -> segment_palette -> point_palette robot_colors -> segment_colors -> point_colors robot_segment_colors -> robot_point_colors

More specific inputs override less specific ones.


Built-in Palettes and Themes

Available Palettes

SoRoMoX includes publication-friendly color palettes:

Palette Description
soromox:okabe-ito Colorblind-friendly palette
soromox:tol-bright Paul Tol's bright qualitative palette
soromox:tol-muted Paul Tol's muted qualitative palette
soromox:ember Warm gradient (orange to red)
soromox:glacier Cool gradient (blue to cyan)
soromox:slate Neutral gray gradient

You can also use any Matplotlib colormap name (e.g., "viridis", "plasma", "coolwarm").

from soromox.rendering import list_builtin_palettes

print(list_builtin_palettes())

Color Themes

Pre-configured themes for consistent styling:

from soromox.rendering import get_color_theme, list_builtin_themes

# List available themes
print(list_builtin_themes())

# Use a theme
theme = get_color_theme("soromox:paper")
renderer = ViserRenderer(robot, color_config=theme)

Color Shape Reference

When providing explicit colors, use these shapes:

Parameter Shape Description
robot_colors (N, ¾) Per-robot colors (RGB or RGBA)
segment_colors (S, ¾) Per-segment colors
point_colors (P, ¾) Per-backbone-point colors
robot_segment_colors (N, S, ¾) Per-robot, per-segment colors
robot_point_colors (N, P, ¾) Per-robot, per-point colors

Color Legend

For creating legends in plots:

legend = renderer.get_color_legend(num_robots=3, color_config=color_config)
# Returns ColorLegend with robot labels and colors

soromox.rendering.color_config.ColorLegend dataclass

ColorLegend(level: Literal['robot', 'segment', 'point'], colors_rgba: ndarray, labels: list[str])

Lightweight color legend for UI or plots.


Multi-Robot Layouts

Matplotlib, Open3D, and Viser accept batched robot configurations:

  • q with shape (N, DOF) for show() and render_frame();
  • q_ts with shape (N, T, DOF) for sequence rendering or animation.

Use base_offsets to place each robot explicitly or grid_spacing to control automatically generated layouts. Viser additionally supports multi_robot_layout="overlay" to render robots at a common base pose. Per-robot colors and alpha values can distinguish overlaid configurations.

Open3D automatically merges each robot's backbone primitives into one dynamic mesh when an animated scene contains multiple robots. This removes most backend geometry registrations; set merge_backbone_meshes=True to force merging for one robot or False to disable it for profiling or compatibility. Viser always uses its instanced or color-grouped backbone representation because browser scene-handle and message counts dominate that backend. Automatically sized Viser ground planes are centered on the rendered bases and expanded to cover the layout.

renderer.render_sequence(
    ts,
    q_ts_batched,
    multi_robot_layout="overlay",
    color_config=color_config,
)

Recording and Video Encoding

All renderer families accept record_path for sequence output, while their capture mechanisms differ:

  • Matplotlib uses its animation writers and requires FFmpeg for MP4 output.
  • Open3D and Viser use FFmpeg with VideoEncodingConfig.
  • Open3D writes PNG frames when record_path names a directory.
  • Viser can capture synchronized browser snapshots with snapshot_paths.
  • OpenCV uses FFmpeg when available and otherwise falls back to cv2.VideoWriter.
from soromox.rendering import VideoEncodingConfig

renderer.render_sequence(
    ts,
    q_ts,
    record_path="trajectory.mp4",
    video_config=VideoEncodingConfig(crf=18, pix_fmt="yuv420p"),
)

Use record_every_n to subsample captured frames where supported. Recording depends on the backend, so consult the relevant renderer API for capture-only options.

soromox.rendering.video_encoding.VideoEncodingConfig dataclass

VideoEncodingConfig(codec: str = 'libx264', pix_fmt: str = 'yuv444p', preset: str | None = 'veryslow', crf: int | None = 12, tune: str | None = 'animation', profile: str | None = None, bitrate: str | None = None, gop: int | None = None, extra_args: tuple[str, ...] = ())

Configuration for FFmpeg video encoding.

Attributes:

Name Type Description
codec str

Video codec (e.g., "libx264", "libx265")

pix_fmt str

Output pixel format (e.g., "yuv444p", "yuv420p")

preset str | None

Encoding preset (e.g., "veryslow", "slow", "medium", "fast")

crf int | None

Constant Rate Factor (0-51, lower = higher quality)

tune str | None

Tuning preset (e.g., "animation", "film", "grain")

profile str | None

Codec profile (e.g., "high", "baseline")

bitrate str | None

Target bitrate (e.g., "5M", "1000k")

gop int | None

Group of Pictures size (keyframe interval)

extra_args tuple[str, ...]

Additional FFmpeg arguments as tuple of strings