saltylab-firmware/AUTONOMOUS_ARMING.md
sl-firmware e4116dffc0 feat: Remove ELRS arm requirement for autonomous operation (Issue #512)
Enable Jetson autonomous arming while keeping RC as optional override.

Changes:
- RC kill switch (CH5 OFF) now triggers emergency stop instead of disarm
  → Allows Jetson-armed robots to remain armed when RC disconnects
  → Maintains kill switch safety for emergency situations

- RC disarm only triggers on explicit CH5 falling edge (RC still alive)
  → RC disconnect doesn't disarm Jetson-controlled missions
  → RC failsafe timer (500ms) handles signal loss separately

- Jetson arming via CDC 'A' command works independently of RC state
  → Robots can operate fully autonomous without RC transmitter
  → Heartbeat timeout (500ms) prevents runaway if Jetson crashes

Safety maintained:
- Arming hold timer: 500ms (prevents accidental arm)
- Tilt limit: ±10° level required
- IMU calibration: Required before any arm attempt
- Remote E-stop: Blocks all arming
- RC failsafe: 500ms signal loss = disarm
- Jetson timeout: 500ms heartbeat = zero motors

Command protocol (unchanged):
- Jetson: A=arm, D=disarm, E=estop, Z=clear estop
- RC: CH5 switch (optional override)
- Heartbeat: H command every ≤500ms
- Drive: C<speed>,<steer> every ≤200ms

See AUTONOMOUS_ARMING.md for complete protocol and testing checklist.

Co-Authored-By: Claude Haiku 4.5 <noreply@anthropic.com>
2026-03-06 11:45:12 -05:00

4.8 KiB

Autonomous Arming (Issue #512)

Overview

The robot can now be armed and operated autonomously from the Jetson without requiring an RC transmitter. The RC receiver (ELRS) is now optional and serves as an override/kill-switch rather than a requirement.

Arming Sources

Jetson Autonomous Arming

  • Command: A\n (single byte 'A' followed by newline)
  • Sent via USB CDC to the STM32 firmware
  • Robot arms after ARMING_HOLD_MS (~500ms) safety hold period
  • Works even when RC is not connected or not armed

RC Arming (Optional Override)

  • Command: CH5 switch on ELRS transmitter
  • When RC is connected and armed, robot can be armed via RC
  • RC and Jetson can both request arming independently

Safety Features

Maintained from Original Design

  1. Arming Hold Timer — 500ms hold before motors enable (prevents accidental arming)
  2. Tilt Safety — Robot must be within ±10° level to arm
  3. IMU Calibration — Gyro must be calibrated before arming
  4. Remote E-Stop Overridesafety_remote_estop_active() blocks all arming

New for Autonomous Operation

  1. RC Kill Switch (CH5 OFF when RC connected)

    • Triggers emergency stop (motor cutoff) instead of disarm
    • Allows Jetson-armed robots to remain armed when RC disconnects
    • Maintains safety of kill switch for emergency situations
  2. RC Failsafe

    • If RC signal is lost after being established, robot disarms (500ms timeout)
    • Prevents runaway if RC connection drops during flight
    • USB-only mode (no RC ever connected) is unaffected
  3. Jetson Timeout (200ms heartbeat)

    • Jetson must send heartbeat (H command) every 500ms
    • Prevents autonomous runaway if Jetson crashes/loses connection
    • Handled by jetson_cmd_is_active() checks

Command Protocol

From Jetson to STM32 (USB CDC)

A           — Request arm (triggers safety hold, then motors enable)
D           — Request disarm (immediate motor stop)
E           — Emergency stop (immediate motor cutoff, latched)
Z           — Clear emergency stop latch
H           — Heartbeat (refresh timeout timer, every 500ms)
C<spd>,<str> — Drive command: speed, steer (also refreshes heartbeat)

From STM32 to Jetson (USB CDC)

Motor commands are gated by bal.state == BALANCE_ARMED:

  • When ARMED: Motor commands sent every 20ms (50 Hz)
  • When DISARMED: Zero sent every 20ms (prevents ESC timeout)

Arming State Machine

DISARMED
  ↓
  +-- Jetson sends 'A' OR RC CH5 rises (with conditions met)
      ↓
      safety_arm_start() called
      (arm hold timer starts)
      ↓
      Wait ARMING_HOLD_MS
      ↓
      safety_arm_ready() returns true
      ↓
      balance_arm() called
      ARMED ← (motors now respond to commands)

ARMED
  ↓
  +-- Jetson sends 'D' → balance_disarm()
  +-- RC CH5 falls AND RC still alive → balance_disarm()
  +-- RC signal lost (failsafe) → balance_disarm()
  +-- Tilt fault detected → immediate motor stop
  +-- RC kill switch (CH5 OFF) → emergency stop (not disarm)

RC Override Priority

When RC is connected and active:

  • Steer channel: Blended with Jetson via mode_manager (per active mode)
  • Kill switch: RC CH5 OFF triggers emergency stop (overrides everything)
  • Failsafe: RC signal loss triggers disarm (prevents runaway)

When RC is disconnected:

  • Robot operates under Jetson commands alone
  • Emergency stop remains available via 'E' command from Jetson
  • No automatic mode change; mission continues autonomously

Testing Checklist

  • Jetson can arm robot without RC (send 'A' command)
  • Robot motors respond to Jetson drive commands when armed
  • Robot disarms on Jetson 'D' command
  • RC kill switch (CH5 OFF) triggers emergency stop without disarming
  • Robot can be re-armed after RC kill switch via Jetson 'A' command
  • RC failsafe still works (500ms signal loss = disarm)
  • Jetson heartbeat timeout works (500ms without H/C = motors zero)
  • Tilt fault still triggers immediate stop
  • IMU calibration required before arm
  • Arming hold timer (500ms) enforced

Migration from RC-Only

Old Workflow (ELRS-Required)

  1. Power on robot
  2. Arm via RC CH5
  3. Send speed/steer commands via RC
  4. Disarm via RC CH5

New Workflow (Autonomous)

  1. Power on robot
  2. Send heartbeat 'H' every 500ms from Jetson
  3. When ready to move, send 'A' command (wait 500ms)
  4. Send drive commands 'C,' every ≤200ms
  5. When done, send 'D' command to disarm

New Workflow (RC + Autonomous Mixed)

  1. Power on robot, bring up RC
  2. Jetson sends heartbeat 'H'
  3. Arm via RC CH5 OR Jetson 'A' (both valid)
  4. Control via RC sticks OR Jetson drive commands (blended)
  5. Emergency kill: RC CH5 OFF (emergency stop) OR Jetson 'E'
  6. Disarm: RC CH5 OFF then ON, OR Jetson 'D'

References

  • Issue #512: Remove ELRS arm requirement
  • Files: /src/main.c (arming logic), /lib/USB_CDC/src/usbd_cdc_if.c (CDC commands)