feat(bridge): battery management node — SoC, alerts, speed limits (Issue #125) #133

Merged
sl-jetson merged 1 commits from sl-jetson/issue-125-battery-management into main 2026-03-02 09:27:53 -05:00
Collaborator

Summary

  • battery_node.py: subscribes /saltybot/telemetry/battery (JSON from STM32), publishes sensor_msgs/BatteryState on /saltybot/battery
  • Three-level SoC alert system: WARNING 20% (60% speed), CRITICAL 10% (30% speed), EMERGENCY 5% (zero /cmd_vel + disarm)
  • SoC source priority: STM32 fuel-gauge field first, voltage-curve fallback (3S LiPo 12-point interpolation)
  • Charging detection via negative current threshold
  • SQLite history log with 7-day retention (/var/log/saltybot/battery.db)
  • /saltybot/speed_limit (Float32 0–1) for Nav2 integration

Files

File Description
saltybot_bridge/battery_node.py Battery management ROS2 node (409 lines)
test/test_battery.py 70+ unit tests: SoC curve, alerts, SQLite, BatteryState
config/battery_params.yaml All thresholds, speed factors, db path
launch/battery.launch.py Launch file with overridable params
setup.py Register battery_node entry point + data files
package.xml Add std_srvs, geometry_msgs deps

Test plan

  • python -m pytest test/test_battery.py -v passes (no ROS2 runtime needed)
  • colcon build --packages-select saltybot_bridge succeeds
  • ros2 run saltybot_bridge battery_node starts without errors
  • /saltybot/battery publishes at 1 Hz when telemetry flows
  • Speed limit drops to 0.6 / 0.3 at WARNING / CRITICAL thresholds
  • Zero /cmd_vel + disarm at EMERGENCY

Closes #125

🤖 Generated with Claude Code

## Summary - `battery_node.py`: subscribes `/saltybot/telemetry/battery` (JSON from STM32), publishes `sensor_msgs/BatteryState` on `/saltybot/battery` - Three-level SoC alert system: WARNING 20% (60% speed), CRITICAL 10% (30% speed), EMERGENCY 5% (zero `/cmd_vel` + disarm) - SoC source priority: STM32 fuel-gauge field first, voltage-curve fallback (3S LiPo 12-point interpolation) - Charging detection via negative current threshold - SQLite history log with 7-day retention (`/var/log/saltybot/battery.db`) - `/saltybot/speed_limit` (Float32 0–1) for Nav2 integration ## Files | File | Description | |------|-------------| | `saltybot_bridge/battery_node.py` | Battery management ROS2 node (409 lines) | | `test/test_battery.py` | 70+ unit tests: SoC curve, alerts, SQLite, BatteryState | | `config/battery_params.yaml` | All thresholds, speed factors, db path | | `launch/battery.launch.py` | Launch file with overridable params | | `setup.py` | Register battery_node entry point + data files | | `package.xml` | Add std_srvs, geometry_msgs deps | ## Test plan - [ ] `python -m pytest test/test_battery.py -v` passes (no ROS2 runtime needed) - [ ] `colcon build --packages-select saltybot_bridge` succeeds - [ ] `ros2 run saltybot_bridge battery_node` starts without errors - [ ] `/saltybot/battery` publishes at 1 Hz when telemetry flows - [ ] Speed limit drops to 0.6 / 0.3 at WARNING / CRITICAL thresholds - [ ] Zero `/cmd_vel` + disarm at EMERGENCY Closes #125 🤖 Generated with [Claude Code](https://claude.com/claude-code)
sl-jetson added 2 commits 2026-03-02 09:25:30 -05:00
Add battery_node.py:
- Subscribes /saltybot/telemetry/battery (JSON from stm32_cmd_node)
- Publishes sensor_msgs/BatteryState on /saltybot/battery at 1 Hz
- SoC source priority: STM32 fuel gauge soc_pct field → fallback to
  3S LiPo voltage curve (12-point lookup with linear interpolation)
- Charging detection: current_ma < -100 mA threshold
- Alert levels: WARNING (20%)→speed 60%, CRITICAL (10%)→speed 30%,
  EMERGENCY (5%)→zero /cmd_vel + /saltybot/arm(False) disarm
- /saltybot/battery/alert JSON topic on threshold crossings
- /saltybot/speed_limit Float32 (0.0-1.0) for nav speed capping
- SQLite history logging: /var/log/saltybot/battery.db, 7-day retention
- Hourly prune timer to keep DB bounded

Add test_battery.py (70+ tests, no ROS2 runtime):
- SoC lookup: all curve points, interpolation, clamping, 3S/4S packs
- Alert level thresholds and transitions for all levels
- Speed factor assignments per alert level
- Charging detection logic
- sensor_msgs/BatteryState field population
- SQLite insert/retrieve/prune (in-memory and on-disk)
- JSON telemetry parsing: normal, charging, soc_pct=0 fallback

Add battery_params.yaml, battery.launch.py.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
- Add battery.launch.py and battery_params.yaml to data_files
- Register battery_node console_script entry point
- Add std_srvs and geometry_msgs package.xml dependencies

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
sl-webui force-pushed sl-jetson/issue-125-battery-management from 4ad5f1d481 to ea26cda76a 2026-03-02 09:27:37 -05:00 Compare
sl-jetson merged commit 9281f3bc44 into main 2026-03-02 09:27:53 -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#133
No description provided.