stub: The RL Composer’s Sensors subsection lets you opt schema-defined cameras into the mjlabSceneCfg.sensorstuple and author MuJoCo contact sensors. Each entry lives on a singleRLTaskSceneEntityrow and is persisted as a JSON object on the entity’ssensorsfield. The backend aggregates every entity’ssensorslist when it regeneratesscene_cfg.py, so a contact sensor on therobotentity referencing thecubeentity ends up as oneContactSensorCfgin the SceneCfg with bothContactMatchblocks pointed at the right entities.
Supported sensor types
stub:
- Camera (RGB / depth) — schema-derived. One UI card per physical device, even when the schema lists separate
color_camera+depth_cameraentries: Cyberwave groups them by the stripped parent-link key so a single Orbbec Gemini surfaces one logical entry withRGBandDepthtoggles. The composer readsTwin.universal_schema.sensorsfor the host twin and every twin docked to it.- Contact — user-authored. Each row maps directly to one
mjlab.sensor.ContactSensorCfg(primary=ContactMatch(...), secondary=ContactMatch(...) | None, ...). The primary side defaults to the host entity; the secondary side picks any sibling RL task scene entity by name (or stays empty for an “any-contact” detector).
Persisted JSON shape
stub: TheRLTaskSceneEntity.sensorsfield stores one of two row shapes. Camera (one row per logical device):Contact:
Codegen mapping
stub:scene_codegen.pywalks every entity’ssensorslist and emits oneContactSensorCfgper contact-sensor row intoSceneCfg.sensors=(...). Camera sensors are not emitted asCameraSensorCfgentries inSceneCfg.sensors; instead, the packager preserves camera metadata (MJCF camera name, width, height, data_types) inscene_bindings.CAMERA_SENSORS. At runtime,env_cfg.pywires each camera observation term viastandard_camera_resolver(camera_sensors=bindings.CAMERA_SENSORS, ...)fromtask_export.standard_resolvers, which routes depth terms tomdp.observations.DepthCameraObservationCfgand RGB terms tomdp.observations.ColorCameraObservationCfg. The merged MJCF prefixes every camera body with<entity>/<source_twin_hex>__<bind_mjcf_camera>, so a camera bound to a docked twin stays addressable inside the host entity’s subtree. When no entity carries any sensor the codegen falls back to the no-op defaultsensors=()and drops themjlab.sensorimport.
Docked-twin caveat (contact subtrees)
stub: When a host twin has docked twins (e.g. a wrist camera attached to a robot arm), the merged MJCF prefixes every docked body with<source_twin_hex>__. A contact sensor withmode="subtree"on the host entity therefore also matches bodies inside docked subtrees unless you exclude them explicitly. The composer surfaces an amber warning under each docked twin with a one-click “Add to exclude” button that injects the suggested regex (^<hex_prefix>__.*$) into the primaryexcludelist.
SDK
stub: The Python SDK exposesmake_camera_sensor(...)andmake_contact_sensor(...)convenience builders alongside a newsensors=keyword onassign_articulation_entity/assign_rigid_entity. Seecyberwave-sdks/cyberwave-python/cyberwave/rl_tasks.pyfor the full signatures.