Source code for embodichain.lab.visualization.cfg

# ----------------------------------------------------------------------------
# Copyright (c) 2021-2026 DexForce Technology Co., Ltd.
#
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
# You may obtain a copy of the License at
#
#     http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
# See the License for the specific language governing permissions and
# limitations under the License.
# ----------------------------------------------------------------------------

from __future__ import annotations

from dataclasses import field

from embodichain.utils import configclass

__all__ = ["VisualizationCfg", "ViserServerCfg"]


[docs] @configclass class ViserServerCfg: """Configure the local Viser HTTP/WebSocket server. Args: host: Interface on which Viser listens. Server deployments should inject this value instead of accepting it from an untrusted run request. port: TCP port allocated to the worker. label: Browser application label. verbose: Whether Viser should print server diagnostics. """ host: str = "127.0.0.1" port: int = 8080 label: str = "EmbodiChain" verbose: bool = False def __post_init__(self) -> None: """Validate server settings.""" if not self.host: raise ValueError("host must not be empty.") if not 1 <= self.port <= 65_535: raise ValueError("port must be between 1 and 65535.") if not self.label: raise ValueError("label must not be empty.")
[docs] @configclass class VisualizationCfg: """Configure live scene visualization. Args: backend: Visualization backend name. Supported values are ``"none"`` and ``"viser"``. scene_fps: Maximum scene capture rate. env_ids: Environment indices exposed by the visualizer. ``None`` selects every simulation environment. max_visible_envs: Optional safety limit on the number of selected environments. ``None`` disables the limit. point_cloud_max_points: Maximum number of points retained per point cloud. sensor_image_fps: Maximum camera RGB preview update rate. ``None`` captures once per visualization step instead of using wall-clock rate limiting. soft_body_fps: Maximum soft-body and cloth vertex update rate. allow_commands: Whether simulation-mutating browser commands are allowed. This enables Viser Gizmo dragging and registered articulation joint controls. Keep it disabled for untrusted or publicly reachable browser sessions. viser_server: Viser HTTP/WebSocket server binding settings. """ backend: str = "none" scene_fps: float = 15.0 env_ids: list[int] | None = [0] max_visible_envs: int | None = None point_cloud_max_points: int = 100_000 sensor_image_fps: float | None = 2.0 soft_body_fps: float = 5.0 allow_commands: bool = False viser_server: ViserServerCfg = field(default_factory=ViserServerCfg) def __post_init__(self) -> None: """Validate visualization settings.""" if self.backend not in {"none", "viser"}: raise ValueError( f"Unsupported visualization backend {self.backend!r}; expected 'none' or 'viser'." ) if self.scene_fps <= 0.0: raise ValueError("scene_fps must be greater than zero.") if self.max_visible_envs is not None and self.max_visible_envs <= 0: raise ValueError("max_visible_envs must be greater than zero.") if self.point_cloud_max_points <= 0: raise ValueError("point_cloud_max_points must be greater than zero.") if self.sensor_image_fps is not None and self.sensor_image_fps <= 0.0: raise ValueError("sensor_image_fps must be greater than zero.") if self.soft_body_fps <= 0.0: raise ValueError("soft_body_fps must be greater than zero.") if self.env_ids is not None: if not self.env_ids: raise ValueError("env_ids must contain at least one environment index.") if len(set(self.env_ids)) != len(self.env_ids): raise ValueError("env_ids must not contain duplicates.") if any(env_id < 0 for env_id in self.env_ids): raise ValueError( "env_ids must contain non-negative environment indices." ) if ( self.max_visible_envs is not None and len(self.env_ids) > self.max_visible_envs ): raise ValueError( f"Selected {len(self.env_ids)} environments, exceeding " f"max_visible_envs={self.max_visible_envs}." ) if self.allow_commands and self.backend != "viser": raise ValueError("allow_commands is only supported by the Viser backend.")