Teleoperation is the one modality where a bad operator breaks hardware. ClutchCall therefore does not let an operator onto a live robot class until the safety core itself has signed off on them. The training screen is that exam: the operator drives a simulated edge through the real safety core, and the core grades the run. Passing every drill in a skill/level curriculum makes a certification claimable. The certification is what the dispatcher checks before it hands that operator a live session on that robot class.

The drill rig: safety core against a sim edge

A drill run builds the same rig as the cockpit. The only additions are the scenario target overlay and the live scorer. The safety core running in the browser is the same WASM build that runs on a live link, so the state machine the operator is graded against is bit-identical to the one that governs real hardware. States surface as BOOT, SAFE, ARMED, DIVERGED, and PROTECTIVE_STOP. The run loop ticks every 40 ms:
  1. Integrate the joystick velocities into the commanded target pose — 55 °/s per axis, clamped to ±165° per joint.
  2. op.step(target) then edge.step().
  3. Read op.view() for the ghost pose, divergence, robot state, and fault.
  4. Push that sample into the scorer with dt = 0.04.
Aborting, resetting, switching drills, or leaving the screen tears the rig down: the interval is cleared, and both the operator and the sim edge are closed.

Anatomy of a scenario

A scenario is a plain object. These are the fields the drill screen reads: Pose error shown in the HUD is the max-norm:
The progress meter is labelled reach-and-hold — reaching tolerance is not the end of the drill, holding there for holdS is. Two scenario fields make a drill hard. Both are visible to the operator as warning chips before they start. Link quality configures the loopback transport: A poor link adds delay and loss on top of a 40 ms control period, which puts the watchdog at risk. The operator has to drive in a way that tolerates the link, not just a way that reaches the pose. Obstruction fires once, the first tick where elapsed time reaches obstacleAtS. It calls edge.setTracking(0.5) — the simulated arm’s tracking collapses, so it stalls behind the commanded ghost. Divergence then grows for as long as the operator keeps pushing. The correct response is to ease off; the wrong response trips the core.

How the scorer grades a run

Each tick the scorer receives the ghost pose, the divergence in degrees, the robot state, and the fault, along with the 40 ms delta. From that stream it maintains three live values that the HUD renders:
  • progress — reach-and-hold completion, 0 to 1.
  • elapsedS — run time, checked against timeLimitS.
  • faultEvents — the count of safety-core trips: watchdog, divergence, and E-STOP.
When the run terminates the scorer exposes a result, the rig is torn down, and the result panel renders. A drill passes only on a clean run: the pose reached and held, and zero safety-core trips. The core is the examiner — there is no way to argue with it, and there is no partial credit for a run that tripped it.

The score breakdown

The result carries a score out of 100 and a four-part breakdown: The panel headline reflects one of three outcomes:

Driving the twin

Two on-screen joysticks, or a gamepad if one is connected: Stick deflection is a velocity, not a position: it is integrated into the commanded pose at 55 °/s per tick and clamped to ±165°. Releasing the stick holds the current commanded pose, which is what lets an operator settle inside tolerance for the hold window. Aborting or resetting zeroes all six velocities.

Curriculum and certification

A curriculum is the set of drills for one skill + level pair. The screen loads it on mount and whenever the selected drill changes:
The curriculum card lists every drill in the set, ticks the ones whose id is in passedIds, tags drills that have a poor link or an obstruction as hard, and lets the operator jump straight to any of them. The loop is:
  1. Operator passes a drill.
  2. The screen calls api.recordPass(scenario.id) and reloads the curriculum.
  3. When every drill in the set has been passed, the reloaded curriculum comes back with complete: true and a curriculum complete — cert available chip appears.
  4. The operator claims it: api.grantCert(scenario.skill, scenario.level).
Until the curriculum is complete, a passing run shows progress toward the certification (passedIds.length of drills.length) rather than a claim button. A single passed drill is never a certification.

How a certification gates dispatch

The certification is keyed by skill and level, which is how it maps onto a robot class. Once granted, the automatic call distributor’s claim_lowest_rtt path is permitted to dispatch that operator to sessions on that robot class. An operator without the certification for a class is not a dispatch candidate for it. This is why the drill rig runs the production safety core rather than a lookalike: the certification asserts that this operator drove that class to a target pose without tripping the exact state machine that will be watching them on live hardware.