Skip to main content

What is an online controller?

An online controller is a controller policy that runs in its own controller-host cloud node — separate from the simulation. The controller host communicates with a plant (the cyberwave-sim physics worker or a live robot) over MQTT and WebRTC. The plant only steps physics and publishes state; it never runs the controller logic in its own loop. This split is the defining property of online controllers: the control loop and the physics loop live in different processes, connected by a wire. Because that wire is the same whether the plant is a simulator or a real robot, an online controller can target either with no code changes.
Cyberwave supports basic mjlab today — online controllers run against both basic MuJoCo and vectorized mjlab backends over the same wire. We’re planning to release a richer Cyberwave mjlab extension with useful helpers in the future.

Online controller types

Three policy types run on the online-controller host path:

Code

A custom Python controller you write — a control() function or a stateful controller class — optionally carrying named model weights.

Random

A random policy, optionally shaped by weights. Useful for smoke-testing a plant or establishing a baseline.

RL Task

A trained RL checkpoint exported from an RL Task, evaluated closed-loop against the plant.
Other controller policies — teleop, navigation, motion, and mlmodel/vla — do not use the online-controller host path. They run on their own command-triggered or cloud inference paths.

How controllers are routed

Routing is decided by the explicit policy type plus a structured controller family — never by keyword or name matching. When you start a run, the backend resolves the assigned policy and dispatches it to the matching controller host.

Runtime interfaces

Each online controller interacts with its plant through a sim-shaped interface, so your controller code reads state and writes commands without knowing whether the plant is simulated or live.
  • code and code + weights controllers see a MuJoCo-shaped sim view — a familiar sim.data / sim.model surface for reading joint state and writing controls.
  • rltask (RL) policies use a SimulationLike interface — the same observation/action contract an RL policy expects during training.
Keep these as conceptual contracts: your controller reads observations and writes actions each step; the host handles transport to and from the plant.

Authoring code controllers

Code controllers support two authoring modes.

Function mode (default)

Define a control function. The host calls it each control step.
  • sim — the MuJoCo-shaped sim view (read state, write ctrl).
  • sim_time — current simulation time in seconds.
  • artifacts — a dict of named weights/files (present only for code + weights controllers).

Class mode (entrypoint_type="class")

For stateful controllers that load weights once and keep state across steps, use class mode. The host instantiates the class once, then calls it each step.
Set entrypoint_type="class" on the policy to opt into class mode. Use it whenever your controller needs to load model weights or maintain internal state between steps.

Named artifacts and weights

A code + weights controller attaches one or more named binary files — typically .pt, .onnx, or .safetensors. Each artifact carries: The artifacts reach your code differently per authoring mode:
  • Function mode — delivered as the third positional argument, the artifacts dict.
  • Class mode — delivered to __init__ as the artifacts argument, so you can load them once.
Class mode plus named artifacts is the canonical pattern for a trained policy: load the primary checkpoint in __init__, then run inference each step in __call__.

CPU vs GPU compute

Controller policies that carry a modelmlmodel/vla, random, or code-with-weights — accept an inference device. This choice selects where the controller host runs inference and is independent of the simulation’s physics device. Key rules:
  • cpu is the default. It runs on an inexpensive CPU host.
  • The saved device is just the default. You can override it per-run at deploy time without changing the saved policy.
  • device is rejected for policies that carry no model — for example a plain code controller or a teleop policy. Those have nothing to run inference on.
The device choice is purely about controller inference. It does not affect which device the plant uses to step physics.

Live mode

Because the controller host talks to its plant purely over MQTT and WebRTC, the same code, random, or rltask controller can target a live robot plant instead of cyberwave-sim — with no controller code changes. The controller reads state and writes commands exactly as it does in simulation; only the plant on the other end of the wire changes.

Simulation backends

Online controllers run against two simulation backends over the same wire:
  • Basic MuJoCo — a single MjModel / MjData plant.
  • Vectorized mjlab — a manager-based, GPU-capable plant.
Your controller does not need to know which backend the plant uses; the runtime interface is the same.

Quick example

Create a code controller policy, then run it against a twin.
1

Create the controller policy

Create a code policy with your control function (or class).
2

Run it on a twin

Execute the policy against a robot twin. The backend dispatches the controller to its host, which drives the plant.
3

Stop the run

Stop a single policy run, or stop every online controller in an environment at once.
A minimal code controller body:

Deploy a trained RL policy

An rltask controller is created by publishing a trained checkpoint, then assigned to a twin like any other controller. Using the OpenArm pick-up policy from the RL task walkthrough:
Then start a simulation from the environment’s Simulate tab in the dashboard — the backend resolves the assigned policy and dispatches it to its controller host automatically. See Uploading Policies for how the checkpoint and controller are produced.

API reference

Where to go next

RL Tasks

Train and export RL policies to run as rltask online controllers.

Uploading Policies

Bring your own code and weights as a controller policy.

Simulation

How the simulation plant steps physics and publishes state.