feat: motor driver layer — differential drive, steer ramp, estop #19

Merged
seb merged 1 commits from sl-controls/motor-driver into main 2026-02-28 17:19:42 -05:00
Collaborator

Summary

Adds motor_driver.c/h as a layer between the balance PID and the raw hoverboard UART driver.

  • Differential drive mixing: balance_cmd → speed channel, steer_cmd → steer channel (ready for RC/autonomous yaw input)
  • Steer-only ramping: ramps steer at MOTOR_STEER_RAMP_RATE (20 counts/ms) to prevent yaw torque disturbing balance. Balance PID output is not ramped — it keeps full immediate authority.
  • Headroom clamping: reduces steer so |speed|+|steer| <= MOTOR_CMD_MAX, ensuring ESC never clips the balance command
  • Emergency stop: latches on BALANCE_TILT_FAULT, clears on BALANCE_DISARMED; zero-send stays in the 50Hz ESC tick to avoid flooding UART at 1kHz
  • main.c: replaces bare hoverboard_send() calls with motor_driver_update()
  • config.h: adds MOTOR_CMD_MAX=1000, MOTOR_STEER_RAMP_RATE=20

Test plan

  • Build passes (no new warnings)
  • Disarmed: ESC receives 0,0 at 50Hz — no timeout
  • Armed: speed tracks bal.motor_cmd, steer ramps from 0 when steer_cmd applied
  • Tilt fault: estop latches, both channels zero
  • Re-disarm: estop clears, ready to re-arm
  • Headroom: with speed=900, steer clamped to ≤100

🤖 Generated with Claude Code

## Summary Adds `motor_driver.c/h` as a layer between the balance PID and the raw hoverboard UART driver. - **Differential drive mixing**: `balance_cmd` → speed channel, `steer_cmd` → steer channel (ready for RC/autonomous yaw input) - **Steer-only ramping**: ramps steer at `MOTOR_STEER_RAMP_RATE` (20 counts/ms) to prevent yaw torque disturbing balance. Balance PID output is **not** ramped — it keeps full immediate authority. - **Headroom clamping**: reduces steer so `|speed|+|steer| <= MOTOR_CMD_MAX`, ensuring ESC never clips the balance command - **Emergency stop**: latches on `BALANCE_TILT_FAULT`, clears on `BALANCE_DISARMED`; zero-send stays in the 50Hz ESC tick to avoid flooding UART at 1kHz - `main.c`: replaces bare `hoverboard_send()` calls with `motor_driver_update()` - `config.h`: adds `MOTOR_CMD_MAX=1000`, `MOTOR_STEER_RAMP_RATE=20` ## Test plan - [ ] Build passes (no new warnings) - [ ] Disarmed: ESC receives 0,0 at 50Hz — no timeout - [ ] Armed: speed tracks `bal.motor_cmd`, steer ramps from 0 when steer_cmd applied - [ ] Tilt fault: estop latches, both channels zero - [ ] Re-disarm: estop clears, ready to re-arm - [ ] Headroom: with speed=900, steer clamped to ≤100 🤖 Generated with [Claude Code](https://claude.com/claude-code)
sl-controls added 1 commit 2026-02-28 17:15:57 -05:00
Adds motor_driver.c/h between the balance PID and the raw
hoverboard UART driver:

- Differential drive: balance_cmd → speed, steer_cmd → steer
- Steer-only ramping at MOTOR_STEER_RAMP_RATE (balance PID keeps
  full immediate authority — no ramp on speed channel)
- Headroom clamp: reduces steer so |speed|+|steer|<=MOTOR_CMD_MAX
  ensuring ESC never clips the balance command
- Emergency stop: latches on TILT_FAULT, clears on BALANCE_DISARMED;
  send path stays in 50Hz ESC tick to avoid flooding UART

main.c: replace bare hoverboard_send() with motor_driver_update();
config.h: MOTOR_CMD_MAX=1000, MOTOR_STEER_RAMP_RATE=20 counts/ms

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
seb approved these changes 2026-02-28 17:19:26 -05:00
seb left a comment
Owner

Reviewed, looks good.

Reviewed, looks good.
seb merged commit fb3c8c863a into main 2026-02-28 17:19:42 -05:00
Sign in to join this conversation.
No Reviewers
No Label
2 Participants
Notifications
Due Date
No due date set.
Dependencies

No dependencies set.

Reference: seb/saltylab-firmware#19
No description provided.