Prefer a platform-managed workflow where you author actions, observations, and the reward graph in the dashboard and export a ready-to-run
mjlab/skrl task? Use RL Tasks instead. This tutorial is the bring-your-own-stack path.Why reinforcement learning?
Most robot learning on Cyberwave starts with imitation: teleoperate the robot, record demonstrations, and train a VLA policy. That works beautifully when you can show the robot what to do. Reinforcement learning is the tool when you can’t demonstrate the behaviour, or when a demonstration isn’t the point:- No demonstrations available. The motion is too precise, too fast, or too tedious to teleoperate (full-coverage inspection, dynamic balancing, contact-rich insertion).
- You have an objective, not a trajectory. You can score the outcome (keep the part centred, visit every viewpoint, minimise energy) but you don’t know the exact joint path that achieves it. RL discovers the path from the reward.
- You need many, cheap rollouts. RL needs millions of steps. Simulation gives you those for free; the real robot never could.
One scene, everywhere
The environment you build in the editor exports to MuJoCo unchanged. No re-modeling meshes, joints, or cameras by hand.
One SDK, sim to real
The same code drives the simulated twin and the physical robot.
cw.affect("simulation") while you validate, then flip to live.Your stack, your GPU
Train locally with any RL library. Cyberwave never dictates your training loop.
Free rollouts
Millions of MuJoCo steps on a CPU cost nothing and never wear out a motor.
How it works
The pipeline is five steps. You only ever build the scene once, and everything downstream reuses it.1
Set up the environment
Build the robot twin, parts, and sensors once in the editor or over the SDK. Jump to step
2
Export the scene to MuJoCo
One SDK call writes an MJCF scene with meshes, joints, and cameras intact. Jump to step
3
Write and train the RL pipeline locally
Your own Gymnasium env and Stable-Baselines3 loop, millions of steps on CPU. Jump to step
4
Mirror the policy into Cyberwave
Replay the trained policy against the twin with
cw.affect("simulation"). Jump to step5
Deploy to the real robot
Drop the
affect() call. Same script, live hardware. Jump to stepPrerequisites
- Python 3.12 (via conda is easiest, since ML wheels lag the newest system Python)
- A Cyberwave environment with your robot twin (build one in the editor or with the SDK)
- A Cyberwave API key (Profile → API Tokens)
.env file (never commit it):
.env
Step 1: Set up the environment
Build the world your policy will train in: add the robot twin, any parts it interacts with, and the sensors the policy observes (e.g. a wrist camera). Do this in the environment editor or with the SDK:Step 2: Export the scene to MuJoCo
Cyberwave exports your environment as a self-contained MuJoCo scene (anmujoco_scene.xml plus all meshes) that runs on your laptop, cluster, or CI runner. Download the ZIP from the environment export API:
mujoco_scene.xml locally. Sanity-check it before writing any RL code:
See the environment MuJoCo export API for the full set of export endpoints (XML-only, URDF, and universal schema).
Step 3: Write and train the RL pipeline locally
This is your code, running on your machine, and Cyberwave isn’t in the loop yet. The three pieces of any RL task are the reward, the environment, and the training run.1
Define the reward
Turn your objective into a scalar the policy maximises each step. Combine a few dense terms (that guide the arm every step) with a sparse bonus (that rewards the actual goal). For a wrist-camera inspection task:
2
Wrap the scene as a Gymnasium environment
Expose the MuJoCo scene through the standard Validate it with
gym.Env interface so any RL library can train on it.gymnasium.utils.env_checker.check_env before training.3
Train with PPO
Start with a privileged baseline: feed the policy the part’s position from simulation ground truth (a small MLP, no camera) to confirm the task is learnable and your reward is sane. It trains in minutes on a CPU.Once the baseline works, switch to the image policy (
MultiInputPolicy with a CNN) that observes the raw wrist camera. This is the version you can actually deploy, since the real robot has pixels, not ground-truth part positions.Step 4: Mirror the policy into Cyberwave
Your policy runs in MuJoCo, but you want to see it on the Cyberwave twin, in the same 3D viewport you’ll watch the real robot in. Flip the SDK into simulation mode and send each step’s joint targets to the twin:affect("simulation") is active, nothing here touches physical hardware, so it’s safe to run while you iterate. Watch the twin move in the dashboard viewport to confirm the policy behaves the way it did in MuJoCo.
arm.joints.set({...}) publishes joint positions in radians by default (pass degrees=True for degrees). See the Python SDK reference for the full joint API.Step 5: Deploy to the real robot
The payoff: the code that mirrored the policy into simulation is the code that drives the physical robot. Change one line.arm.joints.set({...}) calls now flow through Cyberwave’s live-control path to the real robot (via the Edge Core paired with your twin).
Sim-to-real: closing the observation gap
If your deployable policy reads the wrist camera (the image policy), it transfers directly. The real robot has a real camera, and you read frames back from the twin:External perception
Supply the part’s position from your own perception module (a detector, AprilTags, a depth pipeline) and inject it into the observation each step in place of the sim value.
Student distillation
Train a CNN “student” that takes only the raw camera image + joints and imitates the privileged “teacher”. The student learns to infer the part’s position from pixels, with no external perception needed.
Next steps
RL Tasks (platform-managed)
Author actions, observations, and rewards in the dashboard and export a ready-to-run task.
Uploading policies
Store a trained checkpoint on Cyberwave and serve it as a controller.
Simulation
How MuJoCo, Playground, and
affect() fit together.Python SDK
Full SDK reference: twins, joints, cameras, and more.
Train a VLA
The imitation-learning counterpart to this tutorial.
Connect hardware
Pair the Edge Core so
affect('live') reaches your robot.