Back to packages

robonix.primitive.orbbec.gemini330.camera

Orbbec Gemini 330-series RGBD camera driver wrapper — declares RGB + depth + extrinsics contracts.

README

orbbec_camera_rbnx

Robonix package wrapping the Orbbec Gemini 330-series (and other Orbbec) RGBD cameras. Owns the primitive/camera/* namespace. Exposes the camera's RGB + aligned-depth streams under generic contracts so that mapping, scene, and any vision skill can resolve topic names through atlas (no hardcoded /camera/... paths on the consumer side).

Uses the apt-installed ros-humble-orbbec-camera / ros-humble-orbbec-description packages — no source build needed.

Capability surface

Contract Mode Transport Source / handler
robonix/lifecycle/driver rpc gRPC implicit shared Driver(CMD_INIT, config_json) lifecycle
robonix/primitive/camera/rgb topic_out ROS 2 /<cam>/color/image_raw (sensor_msgs/Image)
robonix/primitive/camera/depth topic_out ROS 2 /<cam>/depth/image_raw (sensor_msgs/Image, 16UC1)
robonix/primitive/camera/extrinsics topic_out ROS 2 latched TransformStamped (TODO)
robonix/primitive/camera/snapshot rpc MCP one-shot RGB capture
robonix/primitive/camera/depth_snapshot rpc MCP one-shot depth capture (8-bit JPEG visualization)

Driver-init lifecycle

start.sh only brings up the atlas bridge process. The bridge registers the shared lifecycle Driver automatically; the package manifest must not declare the deprecated camera-specific Driver contract. It then awaits Driver(CMD_INIT, config_json).

When rbnx boot invokes Init it passes the manifest's config: block as JSON. The handler parses config (camera name, model, profiles, depth_registration, IMU on/off), spawns ros2 launch orbbec_camera orbbec_camera.launch.py …, waits for the first frame on the configured RGB topic, declares primitive/camera/{rgb, depth} on atlas, and returns ok. Atlas only ever advertises endpoints we've confirmed are publishing.

Layout

orbbec_camera_rbnx/
├── package_manifest.yaml
├── orbbec_camera/
│   └── main.py                    driver gRPC + lazy Init
├── scripts/
│   ├── build.sh                   rbnx codegen only (no colcon — apt-installed)
│   └── start.sh                   source ROS, exec atlas_bridge
└── .gitignore

Config (passed via Driver(CMD_INIT, config_json))

{
  "camera_name":          "camera",
  "camera_model":         "gemini330_series",
  "color_profile":        "640x480x30",
  "depth_profile":        "640x480x30",
  "depth_registration":   true,
  "enable_color":         true,
  "enable_depth":         true,
  "enable_point_cloud":   false,
  "enable_imu":           false,
  "device_preset":        "",
  "serial_number":        "",
  "usb_port":             "",
  "sentinel_timeout_s":   30.0
}

Leave device_preset empty to use the upstream driver's working Default preset. If set, it must be a named string preset rather than a numeric value.

On robots with more than one Orbbec camera, set either serial_number or usb_port so the driver cannot bind a different camera due to USB enumeration order. usb_port is the stable topology path reported by the Orbbec driver, for example 2-3.

Supported camera_model values (from /opt/ros/humble/share/orbbec_camera/config/): - gemini330_series — default, covers Gemini 335/336/330/335L/336L/330L/335Lg/335Le - gemini2, gemini2L, gemini210 - femto_bolt, femto_mega, femto - astra2, astra - gemini305, gemini345, gemini345_lg, gemini435_le - lidar — Pulsar ME450 / SL450

Build / run standalone

bash scripts/build.sh
bash scripts/start.sh        # registers driver iface, waits for INIT

Prerequisites

sudo apt install ros-humble-orbbec-camera ros-humble-orbbec-description
# Register udev rules (required for USB camera access)
sudo cp /opt/ros/humble/share/orbbec_camera/udev/99-obsensor-libusb.rules /etc/udev/rules.d/
sudo udevadm control --reload-rules && sudo udevadm trigger

License

Apache-2.0 (matches orbbec_camera upstream).