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
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 |
None
|
Returns:
| Type | Description |
|---|---|
tuple[ndarray, ndarray]
|
Tuple of (camera_position, look_at_point) as numpy arrays |
compute_up
¶
Compute the camera up vector.
Returns:
| Type | Description |
|---|---|
ndarray
|
Up vector as a NumPy array with shape |
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").
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
¶
Lightweight color legend for UI or plots.
Multi-Robot Layouts¶
Matplotlib, Open3D, and Viser accept batched robot configurations:
qwith shape(N, DOF)forshow()andrender_frame();q_tswith 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_pathnames 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 |