Arming the drive: a fail-safe by default
The problem: a vehicle that is "on" is not the same as "ready to drive"#
When a remote vehicle boots, a lot has to come up before anyone should be driving it. The LiDAR needs to initialize, the BMS needs to report the battery, the cameras need to stream, the operator needs to be at the terminal and looking at the video feed. Powering the vehicle is a long, mechanical process — you switch on, sensors boot, and only much later do you actually want to move.
Before the arm gate existed, a powered-up vehicle was immediately able to respond to a drive command. That is the wrong default for a machine that can be left running unattended in a battery hall. A stray command from a misconfigured terminal, a misbehaving test script, or an accidental gamepad input could move the vehicle before anyone was ready — or worse, before anyone was watching the camera.
The fix is the same one drones have used for years: an explicit arm state. The drive is disarmed by default, and it stays that way until the operator deliberately enables it. Powering the vehicle and preparing to drive become two separate, deliberate steps.
The state machine#
The arm gate lives in the VCU's shared state (SystemState.driveArmed) and is evaluated once per control-loop cycle. Three states are possible:
- DISARMED — the default at boot. PC, sensors, cameras, CAN and telemetry all run normally, but the drive motors receive zero torque even if a command is present. Steering holds its position; the gimbal stays operable.
- ARMED — the drive is live. The operator reached this state by pressing ARM in the HMI header, and the motors now follow the setpoints.
- FAILSAFE — a watchdog timeout or a latched emergency stop. The drive is released and automatically disarmed.
The important detail is that disarmed is not a fault. It is a deliberate standby: the signal tower does not flash red, and the HMI does not report an error. A vehicle that is simply not armed is not broken — it is waiting.
Arming: a deliberate act#
The ARM button sits in the HMI header next to the emergency-stop controls, so arming is always within reach and always visible. The request travels on the control channel as arm_drive, sent edge-triggered (only when the button changes) so the backend sees an unambiguous arm/disarm edge rather than a stream of identical values.
Two guard rails keep arming safe:
- You cannot arm into a stop. An arm request while a hard failsafe is active is ignored by the vehicle. Arming only succeeds when the system is actually healthy.
- The button follows the vehicle. The HMI reads the confirmed
armedstate back from telemetry, so a backend-side disarm — a watchdog timeout, a latched e-stop — is reflected on the button immediately. The switch cannot lie about the vehicle's real state.
Automatic disarming: the other half of the contract#
Arming is deliberate; disarming is automatic. Any hard failsafe disarms the drive instantly:
- Command watchdog timeout (> 150 ms without a command) — radio loss, terminal crash, cable pulled
- Latched emergency stop — operator intent or a battery fault
After either, the drive stays disarmed until the operator deliberately re-arms. A fresh command never re-arms by itself. This is the same principle as the e-stop latch, applied to the enable side: the vehicle never starts moving again on its own.
The arm gate is evaluated in GetKinematicInput, which now returns three values instead of two — (input, failsafe, driveEnabled) — where driveEnabled = armed && !failsafe gates the drive torque, while failsafe alone continues to drive the debounced report and the signal tower. Separating the two keeps a disarmed standby from being misreported as an error.
Why this belongs in the stop chain#
The arm gate is not a fourth stop mechanism — it is the gate before the stop chain. The three stop mechanisms (emergency-stop latch, worker stale detection, vehicle watchdog) all assume the drive is running and can be stopped. The arm gate answers a different question: should the drive be allowed to run at all, right now, from a cold boot?
For a reconnaissance vehicle the answer is emphatically "no, not until told to". The vehicle's whole purpose is to be deployed, positioned, and then looked at. Most of the time it should be sitting still with its sensors up — and a machine that is sitting still by default, and only moves after a deliberate arm, is a machine that cannot be startled into motion.
Status and next steps#
The arm gate is implemented and tested in the VCU: six new tests cover starting disarmed, arming enabling the motors, failsafe disarming, e-stop disarming, arm requests blocked during a failsafe, and the watchdog interacting with the arm state. All green.
Still on the list: wiring the arm state into the signal tower lamps (a dedicated standby colour), and deciding whether the physical e-stop hardware input should also require re-arming. The design already treats every stop as a re-arm event, so the software side is in place — the remaining questions are about how loudly the vehicle announces its armed/disarmed state, and how the physical world relates to it.
The short version: the drive starts disarmed, arming is a deliberate operator act, and every stop disarms again. A remote vehicle that is on but not armed cannot move — which is exactly what you want from a platform that spends most of its time being looked at.