> ## Documentation Index
> Fetch the complete documentation index at: https://docs.cyberwave.com/llms.txt
> Use this file to discover all available pages before exploring further.

# Drivers

> A Cyberwave driver is a Docker image that interacts with device hardware and the Cyberwave backend.

<Warning>
  **STUB DOCUMENT:** This page is intentionally minimal and will be expanded with deeper technical details in a future update.
</Warning>

A Cyberwave driver is a Docker image that interacts with device hardware and the Cyberwave backend.

## How to use drivers

Register a driver by adding its configuration to a twin's metadata (or the catalog twin's metadata if you control the catalog twin). Use the environment view's **Advanced editing** to edit metadata.

Note: changing a catalog twin's metadata affects all subsequently created digital twins derived from that catalog twin.

Example driver metadata (JSON):

```json theme={null}
{
  "drivers": {
    "default": {
      "docker_image": "cyberwaveos/so101-driver",
      "version": "0.0.1",
      "params": ["--network", "local", "--add-host", "host.docker.internal:host-gateway"]
    }
  }
}
```

### GPU passthrough

Drivers can opt-in to GPU acceleration by setting `"prefer_gpu": true` in their metadata. When the host has the NVIDIA container runtime available **and** configured as the default in `/etc/docker/daemon.json`, Edge Core passes `--gpus` to the driver container.

The optional `"gpu"` field controls which GPUs are exposed:

| `gpu` value    | Docker flag           | Use case                     |
| -------------- | --------------------- | ---------------------------- |
| *(not set)*    | `--gpus all`          | All available GPUs (default) |
| `1`            | `--gpus 1`            | Limit to 1 GPU               |
| `"device=0,2"` | `--gpus "device=0,2"` | Specific GPU devices         |

```json theme={null}
{
  "drivers": {
    "default": {
      "docker_image": "cyberwaveos/go2-ros2-driver:humble",
      "prefer_gpu": true,
      "gpu": "all"
    }
  }
}
```

<Tip>
  On NVIDIA Jetson devices, Edge Core auto-detects the platform and tries a `jetson-` prefixed image tag (e.g. `:humble` → `:jetson-humble`), falling back to the original if unavailable. You can also add a `"linux-aarch64-jetson"` driver key in metadata for explicit Jetson-specific configuration.
</Tip>

### Platform-specific drivers

Use platform keys in `metadata.drivers` to provide platform-specific images or params:

```json theme={null}
{
  "drivers": {
    "default": {
      "docker_image": "cyberwaveos/driver:humble"
    },
    "linux-aarch64-jetson": {
      "docker_image": "cyberwaveos/driver:jetson-humble",
      "prefer_gpu": true
    },
    "darwin-arm64": {
      "docker_image": "cyberwaveos/driver:humble",
      "params": ["--add-host", "host.docker.internal:host-gateway"]
    }
  }
}
```

Edge Core resolves drivers in order: `linux-aarch64-jetson` → `linux-aarch64` → `linux` → `default`.

Manage edge driver containers:

| Subcommand | Description                                              |
| ---------- | -------------------------------------------------------- |
| `list`     | List running driver containers (`--all` includes exited) |
| `start`    | Start a stopped driver container                         |
| `stop`     | Stop a running driver container                          |

## Multi-container drivers

<Warning>
  **STUB DOCUMENT:** This section is intentionally minimal and will be expanded with deeper technical details in a future update.
</Warning>

Some robots require multiple cooperating containers — for example a ROS 2 driver, bridge nodes, Nav2, SLAM, and elevation mapping. Use the `services` array in driver metadata to define a multi-container stack that Edge Core launches automatically.

```json theme={null}
{
  "drivers": {
    "linux-aarch64-jetson": {
      "services": [
        { "image": "cyberwaveos/go2-ros2-driver:jetson-humble", "name": "driver",
          "command": ["ros2", "launch", "cyberwave_go2_driver", "robot_driver.launch.py"] },
        { "image": "cyberwaveos/go2-ros2-driver:jetson-humble", "name": "bridges" },
        { "image": "cyberwaveos/ros2-nav2:jetson-humble", "name": "nav2" },
        { "image": "cyberwaveos/ros2-slam:jetson-humble", "name": "slam" },
        { "image": "cyberwaveos/ros2-elevation-mapping:jetson-humble", "name": "elevation",
          "prefer_gpu": true }
      ],
      "shared_env": { "ROS_DOMAIN_ID": "0", "CYBERWAVE_MAP_DIR": "/data" },
      "shared_params": ["--network", "host", "-v", "/data:/data"]
    },
    "default": {
      "docker_image": "cyberwaveos/go2-ros2-driver",
      "prefer_gpu": true
    }
  }
}
```

Key points:

* `services` present → multi-container mode. `docker_image` present → single-container mode (existing behavior, unchanged).
* Each service requires `image` (Docker image) and `name` (used in the container name suffix).
* Optional per-service fields: `command`, `env`, `params`, `prefer_gpu`, `gpu`.
* `shared_env` and `shared_params` apply to all services. Per-service `env` overrides shared values.
* Container naming: `cyberwave-driver-{twin_uuid[:8]}-{service_name}`.
* Edge Core injects standard env vars (`CYBERWAVE_API_KEY`, MQTT, Zenoh, etc.) into every service automatically.

## Data bus

Drivers publish sensor data (frames, depth, joint states) to the **edge data bus** — a Zenoh-backed publish/subscribe system that lets worker containers consume data with zero network overhead (shared memory). See [Writing compatible drivers](/edge/drivers/writing-compatible-drivers) for the channel naming convention and wire format.

## macOS hardware bridge (stub)

When Edge Core runs on macOS, Linux `--device` mappings in Docker params cannot
directly expose host camera/serial hardware to driver containers. Use a host
bridge process and forward into Docker via `host.docker.internal`.

* Optional host hook env var:
  * `CYBERWAVE_MACOS_DEVICE_BRIDGE_COMMAND`
* Command template variables:
  * `{host_device}`, `{container_device}`, `{twin_uuid}`, `{container_name}`, `{config_dir}`
* Bridge command can return a resolved source (`resolved_device=...` or JSON) so
  Edge Core can inject `CYBERWAVE_METADATA_VIDEO_DEVICE` automatically.
* Optional macOS behavior:
  * `CYBERWAVE_MACOS_STRIP_VIDEO_DEVICE_PARAMS=true` removes Linux-only
    `--device /dev/video*` mappings before container start when a non-`/dev`
    source is resolved.
* For camera twins, Edge Core can derive default macOS camera bridge candidates
  even without explicit `--device` params, enabling minimal default driver
  metadata to work.
* Use platform-specific driver keys in `metadata.drivers` (for example
  `darwin-arm64`, `darwin`, `macos`) to provide macOS-specific params while
  keeping `default` for Linux.
