Skip to main content
This page is for hardware makers and for teams with custom hardware. When you finish, anyone with access to your asset can spawn a twin of your robot, simulate it, drive the real machine from the browser or the SDK, record data, and put a trained policy in control. That holds whether the hardware is on the same desk or on the other side of the world. At a glance: stages 0–10 · advanced · you need a URDF (or MJCF) with meshes, a Linux edge device, Docker, and a working driver or vendor SDK for your robot.

Support levels

Pick a target level before you start. Each level builds on the one before it and has a test you can run yourself. Time budget. These are planning ranges for a team that already has a clean URDF and a working ROS 2 driver: L0 in about an hour, L2 in 1–2 days, L3 in 3–5 days, L4 in 1–2 weeks. Without a ROS 2 driver, add the time it takes you to write one against your vendor SDK.

The config files, and who reads them

Four files come up when you integrate a robot. They do different jobs.
Two corrections to older pages. The image that runs for your robot is set in the asset’s metadata.drivers, not in a cyberwave.yml driver: block. The method that registers a driver interface is twin.driver.set_schema(...). twin.commands only invokes and lists commands.
Where each is documented: Drivers (metadata.drivers) · Writing compatible drivers (cw-driver.yml) · BaseROS2Driver (combined manifest) · cyberwave.yml.

Stages

1

0. Plan

Artifact: a one-paragraph plan: target level, who maintains the driver (you, Cyberwave, or the community), and whether the driver is open or closed source.Decide early whether the asset will be private to your workspace, shared with your organization, or public. Start private and change it later. For closed-source drivers, see Licensing your driver.Done when: the target level is written down and you know who owns the driver image.
2

1. Describe the robot

Artifact: a ZIP with one main .urdf (or .xacro) and every mesh and texture it references, using relative paths that match the ZIP layout. Include inertials and joint limits now; L1 needs them.Validate locally before you upload. The same parser library the platform uses is on PyPI. It has a Python API, not a CLI:
The parser tolerates common URDF quirks (a missing type on a joint, say) and records each one in parse_context. Anything under errors means something in your file was discarded. Starting from MuJoCo? cyberwave_robot_format.mjcf.MJCFParser parses MJCF the same way.Done when: validate() returns no issues and parse_context["errors"] is empty.
3

2. Create the asset

Artifact: a private asset in your workspace, with a slug such as acme/catalog/my-arm.Upload from the dashboard (Create an asset) or with POST /api/v1/assets/create-with-urdf (API upload). ZIPs up to 512 MB are accepted.Then run the L0 test in the free Playground:
Done when: every joint moves the right link in the right direction and stops at its limits. You are at L0.
4

3. Declare capabilities and sensors

Artifact: the asset’s universal schema, with correct extensions.cyberwave.capabilities and a sensors list.Capabilities decide which UI panels and SDK classes your twin gets. can_actuate enables joint control and the re-calibrate action, can_locomote enables Missions, can_grip and has_joints enable the controller UI, and a non-empty sensors list enables sensor windows. The full table is in the feature-to-capability matrix.Fix them on the asset page’s onboarding checklist, in the JSON editor (Editing a universal schema), or from the SDK:
For each sensor, set its id, type (rgb, depth, lidar_3d, imu, …), mount offset, and, for cameras, width, height and FOV. The declared resolution must match the frames your driver actually publishes. If the aspect ratio differs, the object_pose workflow node refuses to deproject (aspect_mismatch). Mimic joints are covered in Mimic joints.Done when: the twin shows the panels you expect (joint sliders, gripper, sensor windows) and nothing else.
5

4. Make it simulate

Artifact: physics on the asset and MuJoCo enabled under Simulator compatibility.Set world physics with cw.assets.set_physics(asset.uuid, timestep=0.002, ...) (physics reference). Enable MuJoCo on the asset. New twins inherit it; existing twins keep their own setting. MuJoCo won’t start if any twin in the environment isn’t marked compatible. In the environment editor, Simulation readiness → Prepare simulation lists missing data and proposes fixes (Simulator compatibility).cw.affect("simulation") starts a MuJoCo instance, which is billable (credits).Done when: MuJoCo starts with your twin and it holds a commanded pose. You are at L1.
6

5. Write the driver

Artifact: a driver process that bridges your hardware to the twin.If your robot already has a ROS 2 driver, subclass BaseROS2Driver and forward topics with from_ros. You don’t write MQTT code or message conversion:
Run it with CYBERWAVE_API_KEY and CYBERWAVE_TWIN_UUID set (Edge Core injects both in production). CW_ROS2_AUTO_ACTIVATE=true is recommended during development. The SDK stamps source_type=edge on everything from_ros publishes. If you write listeners, never act on inbound edge* messages; that’s your own feedback (source-type convention).For arms and grippers, compose the driver mixins rather than writing joint-command plumbing yourself. No ROS? Subclass BaseDriver and call your vendor SDK. Full reference: BaseROS2Driver.Done when: the twin mirrors the robot in Live mode. You are at L2.
7

6. Declare the interface

Artifact: a cw-driver.yml (or, for ROS 2, the exported manifest.yaml) that lists only the topics and commands your driver handles.By default the driver registers its own interface when it starts (auto_register_interface = True calls twin.driver.set_schema(...)). To register it without running the driver, or from CI:
For ROS 2 drivers, export the combined manifest at build time with python main.py write-manifest. set_schema compiles the file on the platform (POST /api/v1/twins/{uuid}/driver-schema), writes metadata.mqtt, and re-binds twin.commands.<name>. Details: Writing compatible drivers.Done when: the teleop overlay and get_supported_commands() list exactly the commands your driver implements.
8

7. Package and bind

Artifact: a Docker image, pushed to a registry, and bound to the asset in metadata.drivers.Build for every edge platform you support. Push to Docker Hub or to the Cyberwave registry registry.cyberwave.com (Enterprise; authenticate with docker login registry.cyberwave.com using your API key, see Docker registry). Version tags are immutable there.Bind the image to the asset. Edge Core reads this block and starts one container per linked twin:
Edge Core uses the most specific key for the host (for example linux-aarch64-jetson or darwin-arm64) and falls back to default. On a Jetson with no Jetson key, it tries a jetson--prefixed tag first. Use services instead of docker_image for multi-container stacks (driver + Nav2 + SLAM), and pass env vars as -e KEY=value pairs in params. Reference: Drivers.Set it on the asset from the SDK (read, merge, write), or edit a twin’s metadata in the environment editor under Advanced editing. Changing the asset affects twins created afterwards.
Done when: on a clean device, sudo cyberwave pair followed by selecting your twin pulls the image, the container starts, and the twin goes online. Watch it with cyberwave edge status and cyberwave edge logs -f.
9

8. Safety and operations

Artifact: a driver that fails loudly and stops safely.
  • Exit non-zero when required hardware is missing, so Edge Core raises driver_start_failure and applies its restart policy. run_driver_main exits with code 1 when the driver raises.
  • Stop on silence. If commands stop arriving mid-teleop, bring the robot to a safe state. Zenoh command channels support watchdog_ms with an on_command_timeout hook. For MQTT, implement the timeout in your driver.
  • Raise alerts operators can see: create_twin_alert(...) or AlertManager from the SDK (Alerts).
  • Calibration: a twin with can_actuate shows a Re-calibrate driver action in Live mode. Test it against your robot, and document any vendor calibration steps on the asset.
Done when: you cut the edge device’s network during teleop, the robot stops safely, and an alert appears on the twin. You are at L3.
10

9. Learn

Artifact: a kit (robot + camera), a recorded dataset, and a policy running as the twin’s controller.Dock your cameras to the robot as child twins with an asset kit. Edge Core passes child camera twins to the parent driver in CYBERWAVE_CHILD_TWIN_UUIDS. Then record teleop episodes, export them (LeRobot is one of the export formats), fine-tune a VLA, and assign it with twin.policy.assign(...). Worked example: SO-101 teleop dataset → Train a VLA.Done when: a policy trained on your robot’s data drives the robot. You are at L4.
11

10. Publish

Artifact: a public asset (and kit) with a clear description, bill of materials and troubleshooting notes.Switch the asset’s visibility to Public when it’s ready. Public assets are visible to anyone on the platform. To be listed with a support level, or for closed-source driver distribution, contact Cyberwave or email info@cyberwave.com with your target level and the pass-test results.Done when: the asset is public and you’ve sent your level evidence to Cyberwave.

Checklist

Copy this into your tracker.

Next steps

Bring your own hardware

End-to-end tutorial for a first custom device.

Writing compatible drivers

Container contract, cw-driver.yml, MQTT catalog and sensor output.

UR Sim with a ROS 2 driver

A working BaseROS2Driver against a simulated UR arm.

Supported hardware

Robots that already have a driver.