feat: STM32 serial bridge — USB CDC to ROS2 topics #16

Merged
seb merged 1 commits from sl-jetson/stm32-serial-bridge into main 2026-02-28 17:19:25 -05:00
Collaborator

Summary

ROS2 Python package saltybot_bridge that bridges the STM32F722 USB CDC telemetry stream to ROS2 topics for the SLAM/nav stack.

  • Parses actual firmware format (read from src/main.c): {"p","r","e","ig","m","s","y"} — all ×10 integers at 50Hz
  • /saltybot/imu (sensor_msgs/Imu) — pitch/roll/yaw as angular_velocity (rad); orientation_covariance[0]=-1 signals orientation unknown (for robot_localization EKF)
  • /saltybot/balance_state (std_msgs/String) — full PID diagnostics as JSON: pitch, roll, yaw, pid_error, integral, motor_cmd, state label
  • /diagnostics (diagnostic_msgs/DiagnosticArray) — OK=ARMED, WARN=DISARMED, ERROR=TILT_FAULT or IMU fault
  • Auto-reconnects on USB disconnect; logs state transitions (DISARMED → ARMED → TILT_FAULT)
  • launch/bridge.launch.py with serial_port and baud_rate args
  • config/bridge_params.yaml defaults: /dev/ttyACM0 @ 921600 baud

Test plan

  • colcon build --packages-select saltybot_bridge succeeds
  • pytest test/test_parse.py — 8/8 pass (runs without ROS2 runtime)
  • ros2 launch saltybot_bridge bridge.launch.py starts node
  • With STM32 connected: /saltybot/imu publishes at ~50Hz
  • /saltybot/balance_state JSON contains expected fields
  • Unplug USB → node logs reconnect attempt, re-plugging restores stream
  • TILT_FAULT state → /diagnostics shows ERROR level

🤖 Generated with Claude Code

## Summary ROS2 Python package `saltybot_bridge` that bridges the STM32F722 USB CDC telemetry stream to ROS2 topics for the SLAM/nav stack. - **Parses actual firmware format** (read from `src/main.c`): `{"p","r","e","ig","m","s","y"}` — all ×10 integers at 50Hz - **`/saltybot/imu`** (`sensor_msgs/Imu`) — pitch/roll/yaw as `angular_velocity` (rad); `orientation_covariance[0]=-1` signals orientation unknown (for robot_localization EKF) - **`/saltybot/balance_state`** (`std_msgs/String`) — full PID diagnostics as JSON: pitch, roll, yaw, pid_error, integral, motor_cmd, state label - **`/diagnostics`** (`diagnostic_msgs/DiagnosticArray`) — OK=ARMED, WARN=DISARMED, ERROR=TILT_FAULT or IMU fault - Auto-reconnects on USB disconnect; logs state transitions (DISARMED → ARMED → TILT_FAULT) - `launch/bridge.launch.py` with `serial_port` and `baud_rate` args - `config/bridge_params.yaml` defaults: `/dev/ttyACM0` @ 921600 baud ## Test plan - [ ] `colcon build --packages-select saltybot_bridge` succeeds - [ ] `pytest test/test_parse.py` — 8/8 pass (runs without ROS2 runtime) - [ ] `ros2 launch saltybot_bridge bridge.launch.py` starts node - [ ] With STM32 connected: `/saltybot/imu` publishes at ~50Hz - [ ] `/saltybot/balance_state` JSON contains expected fields - [ ] Unplug USB → node logs reconnect attempt, re-plugging restores stream - [ ] TILT_FAULT state → `/diagnostics` shows ERROR level 🤖 Generated with [Claude Code](https://claude.com/claude-code)
sl-jetson added 1 commit 2026-02-28 17:11:23 -05:00
saltybot_bridge ROS2 Python package (ament_python):
- serial_bridge_node.py: reads USB CDC JSON telemetry from STM32F722 at 50Hz
  Parses exact firmware format: {"p","r","e","ig","m","s","y"} (all ×10 ints)
  State enum: 0=DISARMED, 1=ARMED, 2=TILT_FAULT (matched to balance_state_t)
- Publishes sensor_msgs/Imu on /saltybot/imu (pitch/roll/yaw as angular_velocity)
- Publishes std_msgs/String on /saltybot/balance_state (full PID JSON diagnostics)
- Publishes diagnostic_msgs/DiagnosticArray on /diagnostics (OK/WARN/ERROR by state)
- Auto-reconnects on serial disconnect; IMU fault frames → ERROR diagnostic
- launch/bridge.launch.py with serial_port + baud_rate launch args
- config/bridge_params.yaml (921600 baud, /dev/ttyACM0)
- test/test_parse.py: 8 unit tests covering normal, fault, edge cases (all pass)

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

Reviewed, looks good.

Reviewed, looks good.
seb merged commit f2d2df030e into main 2026-02-28 17:19:25 -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#16
No description provided.