saltylab-firmware/AUTONOMOUS_ARMING.md
sl-firmware fa75c442a7 feat: remove all STM32/Mamba/BlackPill references — ESP32-S3 only
Archive STM32 firmware to legacy/stm32/:
- src/, include/, lib/USB_CDC/, platformio.ini, test stubs, flash_firmware.py
- test/test_battery_adc.c, test_hw_button.c, test_pid_schedule.c, test_vesc_can.c, test_can_watchdog.c
- USB_CDC_BUG.md

Rename: stm32_protocol → esp32_protocol, mamba_protocol → balance_protocol,
  stm32_cmd_node → esp32_cmd_node, stm32_cmd_params → esp32_cmd_params,
  stm32_cmd.launch.py → esp32_cmd.launch.py,
  test_stm32_protocol → test_esp32_protocol, test_stm32_cmd_node → test_esp32_cmd_node

Content cleanup across all files:
- Mamba F722S → ESP32-S3 BALANCE
- BlackPill → ESP32-S3 IO
- STM32F722/F7xx → ESP32-S3
- stm32Mode/Version/Port → esp32Mode/Version/Port
- STM32 State/Mode labels → ESP32 State/Mode
- Jetson Nano → Jetson Orin Nano Super
- /dev/stm32 → /dev/esp32
- stm32_bridge → esp32_bridge
- STM32 HAL → ESP-IDF

docs/SALTYLAB.md:
- Update "Drone FC Details" to describe ESP32-S3 BALANCE board (Waveshare ESP32-S3 Touch LCD 1.28)
- Replace verbose "Self-Balancing Control" STM32 section with brief note pointing to SAUL-TEE-SYSTEM-REFERENCE.md

TEAM.md: Update Embedded Firmware Engineer role to ESP32-S3 / ESP-IDF

No new functionality — cleanup only.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-04-04 09:00:38 -04:00

5.3 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) <<<<<<< HEAD
  • Sent via USB CDC to the ESP32 BALANCE firmware =======
  • Sent via USB Serial (CH343) to the ESP32-S3 firmware

291dd68 (feat: remove all STM32/Mamba/BlackPill references — ESP32-S3 only)

  • 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

<<<<<<< HEAD

From Jetson to ESP32 BALANCE (USB CDC)

=======

From Jetson to ESP32-S3 (USB Serial (CH343))

291dd68 (feat: remove all STM32/Mamba/BlackPill references — ESP32-S3 only)

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)

<<<<<<< HEAD

From ESP32 BALANCE to Jetson (USB CDC)

=======

From ESP32-S3 to Jetson (USB Serial (CH343))

291dd68 (feat: remove all STM32/Mamba/BlackPill references — ESP32-S3 only) 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)