Sensor Rig#

MobilityGenSensorRig is a Python Module container that groups all sensors on a robot so that cascade operations — update_state(), enable_rgb_rendering(), state_dict_rgb() — propagate to all sensors automatically without manual loops.

Each sensor is attached as a named attribute on the rig (e.g. rig.front_hawk_left). The sensor name comes from the robot YAML and becomes the key in output data (e.g. "sensor_rig.front_hawk_left.rgb_image").

Currently supported: type: camera — full support via MobilityGenCamera. Logged and skipped: type: lidar, imu, radar.

Sensor attachment#

sensor_prim_path in the YAML is relative to the robot root prim. At build time it is joined with robot_root_path to form an absolute stage path. For cameras, rep.create.render_product(abs_path, resolution) attaches Replicator to the existing UsdGeom.Camera prim. If the prim is missing, the sensor is skipped with a carb.log_error.

Intrinsics (cameras)#

USD is the source of truth. focal_length, aperture, and other optical parameters live in the UsdGeom.Camera prim baked into the robot asset. They are intentionally absent from the YAML — duplicating them would create a divergence risk with no benefit. The YAML only carries sensor_prim_path and pixel resolution.

YAML format#

sensor_rig:
  sensors:
    - name: front_hawk_left
      type: camera
      sensor_prim_path: chassis_link/sensors/front_hawk/left/camera_left
      width_px: 960
      height_px: 600

    - name: front_hawk_right
      type: camera
      sensor_prim_path: chassis_link/sensors/front_hawk/right/camera_right
      width_px: 960
      height_px: 600

    - name: chassis_imu        # unsupported — logged and skipped
      type: imu
      sensor_prim_path: chassis_link/sensors/chassis_imu/Imu_Sensor

Scaffolding the YAML#

scripts/generate_sensor_rigs.py opens a robot USD, discovers all sensor prims, and writes sensor_prim_path entries with # TODO comments on fields requiring human review (name, resolution). Unsupported sensor types are included as comments for inventory. Run once per robot, edit the output, then commit.

BUILD=./_build/linux-x86_64/release
SCRIPT=source/extensions/isaacsim.replicator.mobility_gen.examples/scripts/generate_sensor_rigs.py
DATA=source/extensions/isaacsim.replicator.mobility_gen.examples/isaacsim/replicator/mobility_gen/examples/data/robots

"$BUILD/python.sh" "$SCRIPT" --list "$DATA/carter.yaml"   # inspect only
"$BUILD/python.sh" "$SCRIPT" "$DATA/carter.yaml"          # write in-place

Robot integration#

MobilityGenRobot.__init_subclass__ reads the YAML at class-definition time and stores cls.sensor_configs. build() calls cls.build_sensor_rig(prim_path) after spawning the articulation; build_sensor_rig calls MobilityGenSensorRig.build_mounted. Robots with no sensor_configs (e.g. H1Robot) get sensor_rig = None.

robot = CarterRobot.build("/World/carter")
robot.sensor_rig.enable_rgb_rendering()
robot.sensor_rig.finalize_rendering()   # re-enables Hydra — must be called after all enable_*

# each simulation step
robot.update_state()
images = robot.state_dict_rgb()
# → {"sensor_rig.front_hawk_left.rgb_image": np.ndarray,
#    "sensor_rig.front_hawk_right.rgb_image": np.ndarray}

Footgun: enable_rgb_rendering() disables Hydra texture updates while annotators are attached to avoid OmniGraph crashes on partially-constructed nodes. finalize_rendering() re-enables Hydra. Omitting it causes cameras to silently produce no frames.

Recording and replay#

The UI recording callback writes pose/state only — no sensor readings. Sensor data is generated at replay time by replay_scenario() in build.py, which restores recorded poses to the stage, steps the renderer, and writes annotator outputs. Render modalities (RGB, depth, segmentation, normals) are selected at replay time via ReplayConfig.

Multi-sensor output is automatic: state_dict_rgb() traverses the Module tree recursively, keying each sensor buffer by its full dotted path. The writer uses the key as a folder name; the reader discovers folders via glob. Adding sensors to the YAML requires no changes to writer, reader, or scenario code.