Skip to main content

Docker Images

The full robot stack is published as four images on Docker Hub, each available in three tags (jazzy, humble, jetson-humble): The jetson-humble driver image ships with optimized defaults for constrained hardware.

Quick Start

When connected to the Cyberwave platform, the edge-core service automatically pulls and starts all required containers based on the asset metadata configured for your twin. For local development with Docker Compose, see the driver README.

ROS 2 Topics

The driver publishes standard ROS 2 topics that any ROS 2 node can consume independently: All robot-specific topics are namespaced as twin_<your-twin-uuid> by default.

Key Environment Variables

Obstacle Avoidance

When GO2_OBSTACLE_AVOIDANCE=true (the default), velocity commands are routed through the Go2’s firmware obstacle avoidance pipeline instead of the standard Sport API. The firmware fuses ultrasonic and LiDAR sensors to detect obstacles and will override velocity commands to prevent collisions. On startup the driver sends SwitchSet and UseRemoteCommandFromApi to the robot so the firmware accepts velocity commands from the ROS 2 stack rather than only the physical remote controller.
Onboard obstacle avoidance operates independently from Nav2’s path planner. The firmware may intervene — slowing down or stopping the robot — even when Nav2 considers the path clear. This can cause Nav2 goals to take longer or be aborted if the firmware repeatedly blocks planned motion. If you need full control over obstacle handling through Nav2’s costmaps and local planner, set GO2_OBSTACLE_AVOIDANCE=false.
To disable:

Obstacle Avoidance & Teleoperation

There are two layers of obstacle avoidance on the Go2:
  1. Onboard — the robot’s built-in ultrasonic + LiDAR avoidance at the firmware level.
  2. Driver-level — path planning avoidance through costmaps constructed in real time by the navigation stack.
When GO2_OBSTACLE_AVOIDANCE=true (configurable in the twin metadata; enabled by default), the driver activates both layers for autonomous navigation.
Recommended teleoperation during mapping:
  • Cyberwave keyboard controller — obstacle avoidance is active (onboard + driver-level). This is the recommended way to drive the robot while building a map of your environment.
  • Unitree physical remote — always retains onboard obstacle avoidance regardless of driver configuration.
Both options are safe for teleoperation during mapping.
Bluetooth gamepad obstacle avoidance now depends on the active controller policy:
  • Local Bluetooth controller (local): obstacle avoidance stays on the robot-side local controller path.
  • Keyboard teleop and autonomous navigation: the driver switches to the autonomy/remote-command path, and the gamepad does not keep independent obstacle avoidance.

AES-128 Key (firmware ≥ 1.1.15)

Go2 firmware 1.1.15+ uses a per-device AES-128 key (data2=3 protocol) to encrypt the WebRTC LAN handshake. Without this key, both the driver node and native video node will fail to connect. Fetch the key using the unitree_webrtc_connect CLI (requires the Unitree account used in the Unitree Go/Explore mobile app):
Set the 32-hex-char key in your env file or Edge Core shared_env:
Older firmware (below 1.1.15) uses a static key built into the driver and does not require this variable. If GO2_AES_128_KEY is unset and the robot returns data2=3, the driver will log a clear error with instructions.

Robot IP discovery

The driver validates that the Go2 is reachable before starting any ROS 2 node, so you get a fast failure instead of a silent WebRTC hang. Resolution order:
  1. ROBOT_IP (from env or Edge Core metadata) — probed via TCP on port 9991.
  2. If unreachable (or unset), each address in ROBOT_IP_FALLBACKS is tried.
  3. First address that responds is used for the entire stack.
  4. If nothing responds, the container exits with an error and pushes a robot_unreachable alert to Cyberwave (if SDK credentials are available).
The default fallback list covers the two most common Go2 network configurations: Custom networks: If your Go2 is on a different subnet (e.g. behind a router), override the fallback list:
You can set both ROBOT_IP (preferred address) and ROBOT_IP_FALLBACKS (safety net). If the preferred IP is unreachable, the driver automatically falls through to the fallback list.
The probe uses a TCP socket connect on port 9991 (Go2 WebRTC signaling) with a 2-second timeout per address. No WebRTC handshake is attempted. Simulation launches skip the check entirely.

Config Profiles

Set CONFIG_PROFILE=jetson or use the jetson-humble Docker image which sets this automatically.

Edge Core metadata

When using Cyberwave Edge Core for managed deployment, the driver stack is configured through twin/asset metadata. Edge Core reads this metadata, pulls images, and injects environment variables automatically.

Multi-container configuration

The Go2 ROS 2 stack runs as multiple cooperating containers. Define the stack in metadata.drivers using the services array:
To add a service (e.g. elevation mapping), append to the services array. To set the robot IP or fallback list, add them to shared_env:
See Drivers overview for the full metadata schema and Writing compatible drivers for the edge_configs per-device pattern.

Stream Recording

The Go2 driver streams video to the Cyberwave media service via WebRTC. Each stream can request server-side recording (producing MP4 artifacts for later replay). Default behavior (no env vars set):
  • camera_bridge — records by default (true).
  • occupancy_grid_bridge, local_costmap_bridge, global_costmap_bridge — do not record by default.
Resolution order per bridge:
  1. CYBERWAVE_ENABLE_RECORDING — if set, overrides everything.
  2. Per-bridge env var (e.g. CYBERWAVE_ENABLE_RECORDING_PREVIEW) — overrides the built-in default.
  3. Built-in default.
Recording is handled by the media service SFU, not on the edge device. Enabling recording adds negligible load to the robot’s hardware.

Jetson Performance Tuning

Running the full Go2 stack on a Jetson Orin Nano (or similar constrained hardware) requires tuning runtime rates and encoder settings. Add these to your .env file or Edge Core shared_env:
These values are tuned for a Jetson Orin Nano running the full stack (driver + Nav2 + SLAM). If your board has more headroom (e.g. Orin NX) or less (e.g. other services running), you can adjust camera and pointcloud rates accordingly.

NVIDIA Container Toolkit (Jetson / GPU)

GPU-accelerated containers (simulation, video decode, elevation mapping) require the NVIDIA Container Toolkit. This is especially important on Jetson (L4T / JetPack) where the toolkit must be installed and the runtime registered with Docker.
On Jetson, set the NVIDIA runtime as the default so all containers get GPU access automatically:
If nvidia-container-toolkit is already installed but containers cannot access the GPU, re-run the nvidia-ctk runtime configure step, ensure daemon.json has the nvidia runtime, and restart Docker.