8d67d06857
feat: Integration test suite (Issue #504 )
...
Add comprehensive integration testing for complete ROS2 system stack:
Integration Tests (test_integration_full_stack.py):
- Verifies all ROS2 nodes launch successfully
- Checks critical topics are published (sensors, nav, control)
- Validates system component health and stability
- Tests launch file validity and configuration
- Covers indoor/outdoor/follow modes
Launch Testing (test_launch_full_stack.py):
- Validates launch file syntax and configuration
- Verifies all required packages are installed
- Checks launch sequence timing
- Validates conditional logic for optional components
Test Coverage:
✓ SLAM/RTAB-Map (indoor mode)
✓ Nav2 navigation stack
✓ Perception (YOLOv8n person detection)
✓ Control (cmd_vel bridge, STM32 bridge)
✓ Audio pipeline and monitoring
✓ Sensors (LIDAR, RealSense, UWB, CSI cameras)
✓ Battery and temperature monitoring
✓ Autonomous docking behavior
✓ TF2 tree and odometry
Usage:
pytest test/test_integration_full_stack.py -v
pytest test/test_launch_full_stack.py -v
Documentation:
See test/README_INTEGRATION_TESTS.md for detailed information.
Co-Authored-By: Claude Haiku 4.5 <noreply@anthropic.com>
2026-03-06 16:42:31 -05:00
e5329391bc
feat: Add parameter profile YAML files for Nav2 (Issue #506 )
...
- profile_indoor.yaml: Conservative settings (0.4 m/s, 0.35m inflation)
- profile_outdoor.yaml: Moderate settings (0.8 m/s, 0.3m inflation)
- profile_demo.yaml: Agile settings (0.6 m/s, 0.32m inflation)
Each profile customizes velocity limits, costmap inflation, and obstacle detection.
2026-03-06 16:42:31 -05:00
5d17b6c501
feat: Issue #506 — Update nav2.launch.py for profile support
...
Add profile argument to nav2.launch.py to accept launch profile parameter
and log profile selection for debugging/monitoring.
Changes:
- Add profile_arg declaration with choices (indoor/outdoor/demo)
- Add profile substitution and log output
- Update docstring with profile documentation
Co-Authored-By: Claude Haiku 4.5 <noreply@anthropic.com>
2026-03-06 16:42:31 -05:00
b5acb32ee6
feat: Issue #506 — Update full_stack.launch.py for profile support
...
Add profile argument and documentation to full_stack.launch.py for
Issue #506 launch parameter profiles. Updated to support:
- profile:=indoor (conservative)
- profile:=outdoor (moderate)
- profile:=demo (agile with tricks/social features)
Changes:
- Add profile_arg declaration
- Add profile substitution handle
- Update docstring with profile examples
- Ready for profile-based Nav2 parameter overrides
Co-Authored-By: Claude Haiku 4.5 <noreply@anthropic.com>
2026-03-06 16:42:31 -05:00
bbfcd2a9d1
feat: Issue #506 — Launch parameter profiles (indoor/outdoor/demo)
...
Implement profile-based parameter overrides for Nav2, costmap, and behavior
server configurations. Profiles predefine parameter sets for different
deployment scenarios.
New files:
- config/profiles/indoor.yaml: Conservative (0.2 m/s, tight geofence, no GPS)
- config/profiles/outdoor.yaml: Moderate (0.5 m/s, wide geofence, GPS-enabled)
- config/profiles/demo.yaml: Agile (0.3 m/s, tricks/social features enabled)
- saltybot_bringup/profile_loader.py: YAML loader and parameter merger utility
Supports: ros2 launch saltybot_bringup full_stack.launch.py profile:=<profile>
Co-Authored-By: Claude Haiku 4.5 <noreply@anthropic.com>
2026-03-06 16:42:31 -05:00
5add2cab51
Merge remote-tracking branch 'origin/sl-mechanical/issue-505-charging-dock'
...
# Conflicts:
# phone/INSTALL_MOTOR_TEST.md
# phone/MOTOR_TEST_JOYSTICK.md
# phone/motor_test_joystick.py
2026-03-06 14:59:59 -05:00
892d0a2089
Merge remote-tracking branch 'origin/sl-android/issue-513-phone-joystick'
...
# Conflicts:
# phone/MOTOR_TEST_JOYSTICK.md
# phone/motor_test_joystick.py
2026-03-06 14:00:21 -05:00
678fd221f5
Merge pull request 'feat: Remove ELRS arm requirement (Issue #512 )' ( #514 ) from sl-firmware/issue-512-autonomous-arming into main
2026-03-06 12:52:05 -05:00
sl-android
f49e84b8bb
feat: Phone-based motor test joystick app (Issue #513 )
...
Implements terminal-based curses UI for interactive bench testing of SaltyBot motors via Termux.
Features:
- Interactive keyboard-based joystick (W/A/S/D or arrow keys)
- Conservative velocity defaults: 0.1 m/s linear, 0.3 rad/s angular
- Real-time velocity feedback with bar graphs
- Spacebar e-stop (instantly zeros velocity)
- 500ms timeout safety (sends zero velocity if idle)
- Dual backend: ROS2 (/cmd_vel) or WebSocket
- Graceful fallback if ROS2 unavailable
Safety Features:
- Conservative defaults (0.1/0.3 m/s)
- E-stop button (spacebar)
- 500ms timeout (sends zero if idle)
- Input clamping and exponential decay
- Status/warning displays
Files:
- motor_test_joystick.py: Main application
- MOTOR_TEST_JOYSTICK.md: User documentation
- INSTALL_MOTOR_TEST.md: Installation guide
Co-Authored-By: Claude Haiku 4.5 <noreply@anthropic.com>
2026-03-06 11:47:15 -05:00
48e9af60a9
feat: Remove ELRS arm requirement for autonomous operation (Issue #512 )
...
Enable Jetson autonomous arming while keeping RC as optional override.
Key Changes:
=============
1. RC Kill Switch (CH5 OFF) → Emergency Stop (not disarm)
- Motors cutoff immediately on kill switch
- Robot remains armed (allows re-arm without re-initializing)
- Maintains kill switch safety for emergency situations
2. RC Disarm Only on Explicit CH5 Falling Edge (while RC alive)
- RC disconnect doesn't disarm Jetson-controlled missions
- RC failsafe timer (500ms) still handles signal loss
3. Jetson Autonomous Arming (via CDC 'A' command)
- Works independently of RC state
- Requires: calibrated IMU, robot level (±10°), no estop active
- Uses same 500ms arm-hold safety as RC
4. All Safety Preserved
- Arming hold timer: 500ms
- Tilt limit: ±10° level
- IMU calibration required
- Remote E-stop override
- RC failsafe: 500ms signal loss = disarm
- Jetson timeout: 500ms heartbeat = zero motors
Command Protocol (CDC):
A = arm (Jetson)
D = disarm (Jetson)
E/Z = estop / clear estop
H = heartbeat (keep-alive)
C<spd>,<str> = drive command
Behavior Matrix:
RC disconnected → Jetson-armed stays armed, normal operation
RC connected + armed → Both Jetson and RC can arm, blended control
RC kill switch (CH5) → Emergency stop + can re-arm via Jetson 'A'
RC signal lost → Disarm after 500ms (failsafe)
See AUTONOMOUS_ARMING.md for complete protocol and testing checklist.
Co-Authored-By: Claude Haiku 4.5 <noreply@anthropic.com>
2026-03-06 11:46:03 -05:00
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
b0c2b5564d
feat: Add Issue #505 CAD - 24V Charging Dock OpenSCAD Models
...
CAD implementation files for Issue #505 (24V charging dock upgrade):
- charging_dock_505.scad: Main dock assembly
* Base plate: 340×320×12 mm (enlarged for 240W PSU)
* Back wall: 250×85×10 mm (pogo pin housing, LED bezel recess)
* V-guide rails: 100mm deep, self-centering funnel (print 2×)
* ArUco marker frame: ID 42 (DICT_4X4_250), 15cm mast
* PSU bracket: Sized for Mean Well IRM-240-24 (210×108×56 mm)
* LED bezel: 4× status indicators (SEARCHING/ALIGNED/CHARGING/FULL)
- charging_dock_receiver_505.scad: Robot-side receiver variants
* Lab receiver: Stem collar mount (SaltyLab)
* Rover receiver: Deck flange mount (SaltyRover)
* Tank receiver: Skid plate mount + extended nose (SaltyTank)
* Common contact geometry: 20mm CL-to-CL brass pads, V-nose guide
* Wire bore: 3mm (supports 12 AWG charging wires)
Key changes from Issue #159 (5V):
- PSU dimensions: 63×45×28 mm → 210×108×56 mm
- Base/bracket enlarged accordingly
- ArUco ID: 0 → 42
- Contact geometry unchanged (compatible with Issue #159 receivers)
- Pogo pins, V-guides, LED circuit identical
Files ready for:
- STL export via OpenSCAD render commands
- 3D printing (PETG recommended)
- Assembly integration with docking node (#489 )
Co-Authored-By: Claude Haiku 4.5 <noreply@anthropic.com>
2026-03-06 11:44:28 -05:00
1f4929b68c
Merge remote-tracking branch 'origin/sl-jetson/issue-477-urdf'
...
# Conflicts:
# jetson/config/RECOVERY_BEHAVIORS.md
2026-03-06 11:43:31 -05:00
d97fa5fab0
Merge remote-tracking branch 'origin/sl-webui/issue-482-behavior-tree'
...
# Conflicts:
# jetson/ros2_ws/src/saltybot_bringup/behavior_trees/autonomous_coordinator.xml
# jetson/ros2_ws/src/saltybot_bringup/launch/autonomous_mode.launch.py
2026-03-06 11:43:26 -05:00
a3d3ea1471
Merge remote-tracking branch 'origin/sl-perception/issue-478-costmaps'
...
# Conflicts:
# jetson/ros2_ws/src/saltybot_bringup/config/nav2_params.yaml
2026-03-06 11:43:11 -05:00
e1248f92b9
Merge pull request 'feat: Face display animations on STM32 LCD (Issue #507 )' ( #508 ) from sl-android/issue-507-face-animations into main
2026-03-06 10:57:28 -05:00
6f3dd46285
feat: Add Issue #503 - Audio pipeline with Jabra SPEAK 810
...
Implement full audio pipeline with:
- Jabra SPEAK 810 USB audio I/O (mic + speaker)
- openwakeword 'Hey Salty' wake word detection
- whisper.cpp GPU-accelerated STT (small/base/medium/large models)
- piper TTS synthesis and playback
- Audio state machine: listening → processing → speaking
- MQTT status and state reporting
- Real-time latency metrics tracking
ROS2 Topics Published:
- /saltybot/speech/transcribed_text: STT output for voice router
- /saltybot/audio/state: Current audio state
- /saltybot/audio/status: JSON metrics with latencies
MQTT Topics:
- saltybot/audio/state: Current state (listening/processing/speaking)
- saltybot/audio/status: Complete status JSON
Configuration parameters in yaml:
- device_name: Jabra device pattern
- wake_word_threshold: 0.5 (tunable)
- whisper_model: small/base/medium/large
- mqtt_enabled: true/false with broker config
Co-Authored-By: Claude Haiku 4.5 <noreply@anthropic.com>
2026-03-06 10:30:58 -05:00
5cea0812d5
feat: Add Issue #505 - 24V Charging Dock Hardware Design
...
- Design specification: 24V DC power delivery (upgraded from 5V Issue #159 )
- ArUco marker ID 42 (15cm frame) for precision alignment
- Spring-loaded contact pads with V-channel guide rails
- Comprehensive BOM for 24V PSU, wiring, LED status circuit
- Compatible with docking node #489 (ROS2 integration)
- 3D-printable PETG frame (base, back wall, guide rails, brackets)
- Electrical: 240W Mean Well IRM-240-24 PSU, 20A current capacity
- Safety: Fused output, varistor protection, soft-start capable
- Integration: MQTT status reporting, GPIO LED control (Jetson Orin NX)
Files:
- ISSUE_505_CHARGING_DOCK_24V_DESIGN.md: Complete design spec (mechanical, electrical, assembly)
- charging_dock_505_BOM.csv: Procurement list with sourcing info
Next: CAD implementation (charging_dock_505.scad, receiver variant)
Co-Authored-By: Claude Haiku 4.5 <noreply@anthropic.com>
2026-03-06 10:30:44 -05:00
sl-android
49628bcc61
feat: Add Issue #507 - Face display animations on STM32 LCD
...
Implements expressive face animations with 5 core emotions (happy/sad/curious/angry/sleeping) and smooth transitions on small LCD displays.
Features:
- State machine with smooth 0.5s emotion transitions (ease-in-out cubic easing)
- Automatic idle blinking (4-6s intervals, 100-150ms duration per blink)
- UART command interface via USART3 @ 115200 (text-based protocol)
- 30Hz target refresh rate via systick integration
- Low-level LCD abstraction supporting monochrome and RGB565
- Rendering primitives: pixel, line (Bresenham), circle (midpoint), filled rect
Architecture:
- face_lcd.h/c: Hardware-agnostic framebuffer & display driver
- face_animation.h/c: Emotion state machine & parameterized face rendering
- face_uart.h/c: UART command parser (HAPPY/SAD/CURIOUS/ANGRY/SLEEP/NEUTRAL/BLINK/STATUS)
- Unit tests (14 test cases): emotion transitions, blinking, rendering, all emotions
Integration:
- main.c: Added includes, initialization (servo_init), systick tick, main loop processing
- Pending: LCD hardware initialization (SPI/I2C config, display controller setup)
Files: 9 new (headers, source, tests, docs), 1 modified (main.c)
Lines: ~1450 total (345 headers, 650 source, 350 tests, 900 docs)
Co-Authored-By: Claude Haiku 4.5 <noreply@anthropic.com>
2026-03-06 10:27:36 -05:00
80ee9ece87
Merge pull request 'feat: Voice command router (Issue #491 )' ( #499 ) from sl-webui/issue-491-voice-router into main
2026-03-05 19:25:32 -05:00
Sebastien Vayrette
868b453777
fix: resolve merge conflicts for voice router PR #499 (keep both docking + mission logging)
2026-03-05 19:25:23 -05:00
83e3033abe
Merge pull request 'feat: OTA firmware update (Issue #492 )' ( #500 ) from sl-jetson/issue-492-ota-update into main
2026-03-05 17:24:58 -05:00
5f6a13ccca
Merge pull request 'feat: Multi-sensor fusion (Issue #490 )' ( #498 ) from sl-perception/issue-490-sensor-fusion into main
2026-03-05 17:24:03 -05:00
4dc18201aa
Merge pull request 'feat: Docking station behavior (Issue #489 )' ( #497 ) from sl-controls/issue-489-docking into main
2026-03-05 17:16:37 -05:00
2dd03a245d
Merge pull request 'feat: ROS2 bag recording for mission logging (Issue #488 )' ( #496 ) from sl-firmware/issue-488-bag-recording into main
2026-03-05 17:16:22 -05:00
340248a0d2
feat: Add docking state publisher and update configuration (Issue #489 )
...
- Add /saltybot/docking_state publisher (std_msgs/String) for monitoring
- Update docking_params.yaml battery_low_pct: 15% → 20%
- Add Issue #475 references for conservative servo speeds
Co-Authored-By: Claude Haiku 4.5 <noreply@anthropic.com>
2026-03-05 17:08:48 -05:00
7a4930e8d2
feat: ROS2 bag recording for mission logging (Issue #488 )
...
Implement automatic mission logging with bag recorder:
- Auto-records to ~/.saltybot-data/bags/ with 30min rotation
- Records mission-critical topics: /scan, /cmd_vel, /odom, /tf, /camera/color/image_raw/compressed, /saltybot/diagnostics
- MCAP format (preferred) with fallback to sqlite3 with zstd compression
- Services: /saltybot/save_bag, /saltybot/start_recording, /saltybot/stop_recording
- FIFO 20GB disk limit with automatic cleanup of oldest bags
- Auto-starts on launch, auto-saves on graceful shutdown
Changes:
- Updated bag_recorder_node.py with new parameters and services
- Changed default bag_dir to ~/.saltybot-data/bags/
- Set max_storage_gb to 20 (FIFO limit)
- Changed storage_format to MCAP by default
- Added start/stop recording service callbacks
- Updated package.xml description for mission logging
Co-Authored-By: Claude Haiku 4.5 <noreply@anthropic.com>
2026-03-05 17:08:21 -05:00
b986702aed
feat: Docking station behavior for auto-charging (Issue #489 )
...
- Integrate saltybot_docking package into full_stack.launch.py
- Auto-trigger docking when battery drops to 20% (configurable via battery_low_pct)
- Launch docking at t=7s (after sensors, before Nav2)
- Add /saltybot/docking_state publisher (std_msgs/String) for state monitoring
- Update docking_params.yaml:
- battery_low_pct: 15% → 20% per Issue #489
- Add references to Issue #475 for conservative FC+hoverboard speeds
- Docking behavior includes:
- ArUco marker or IR beacon detection for dock location
- Nav2-based approach to pre-dock pose (~1m away)
- Visual servoing final alignment with contact detection
- Auto-undocking on full charge (80%) or command
- Integration with power management for mission interruption/resumption
Co-Authored-By: Claude Haiku 4.5 <noreply@anthropic.com>
2026-03-05 17:08:21 -05:00
a4285b5ecd
feat: Docking station behavior for auto-charging (Issue #489 )
...
- Integrate saltybot_docking package into full_stack.launch.py
- Auto-trigger docking when battery drops to 20% (configurable via battery_low_pct)
- Launch docking at t=7s (after sensors, before Nav2)
- Add /saltybot/docking_state publisher (std_msgs/String) for state monitoring
- Update docking_params.yaml:
- battery_low_pct: 15% → 20% per Issue #489
- Add references to Issue #475 for conservative FC+hoverboard speeds
- Docking behavior includes:
- ArUco marker or IR beacon detection for dock location
- Nav2-based approach to pre-dock pose (~1m away)
- Visual servoing final alignment with contact detection
- Auto-undocking on full charge (80%) or command
- Integration with power management for mission interruption/resumption
Co-Authored-By: Claude Haiku 4.5 <noreply@anthropic.com>
2026-03-05 17:08:15 -05:00
d770cb99a3
feat: Multi-sensor fusion for obstacle avoidance (Issue #490 )
...
- saltybot_sensor_fusion: ROS2 node for LIDAR + depth sensor fusion
- Fuses RPLIDAR A1M8 (360° 2D) + RealSense D435i (front 87° 3D)
- Message filters for time-synchronized sensor inputs
- Smart blind spot handling: rear/sides LIDAR-only, front uses both
- Publishes /scan_fused (unified LaserScan) + PointCloud2 for voxel layer
- Configurable front sector angle (±45°), range multiplier, max range limit
- Parameters: depth_range_multiplier=0.9 (safety margin), max_range=5m
Co-Authored-By: Claude Haiku 4.5 <noreply@anthropic.com>
2026-03-05 17:05:25 -05:00
fabfd5e974
feat: TTS personality engine (Issue #494 )
...
Implement context-aware text-to-speech with emotion-driven expression for SaltyBot.
Features:
✓ Context-aware greetings (time of day, person names, emotion)
✓ Priority queue management (safety > social > idle)
✓ Emotion-based rate/pitch modulation (happy: faster+higher, sad: slower+lower)
✓ Integration with emotion engine (Issue #429 ) and TTS service (Issue #421 )
✓ Configurable personality parameters
✓ Person recognition for personalized responses
✓ Queue management with 16-item buffer
Architecture:
Node: tts_personality_node
- Subscribes: /saltybot/tts_request, /saltybot/emotion_state, /saltybot/person_detected
- Publishes: /saltybot/tts_command (formatted for TTS service), /saltybot/personality_state
- Runs worker thread for asynchronous queue processing
Personality Parameters:
- Name: "Luna" (default, configurable)
- Speed modulation: happy=1.1x, sad=0.9x, neutral=1.0x
- Pitch modulation: happy=1.15x, sad=0.85x, neutral=1.0x
- Time-based greetings for 4 periods (morning, afternoon, evening, night)
- Known people mapping for personalization
Queue Priority Levels:
- SAFETY (3): Emergency/safety messages
- SOCIAL (2): Greetings and interactions
- IDLE (1): Commentary and chatter
- NORMAL (0): Default messages
Files Created:
- saltybot_tts_personality package with main personality node
- config/tts_personality_params.yaml with configurable parameters
- launch/tts_personality.launch.py for easy startup
- Unit tests for personality context and emotion handling
- Comprehensive README with usage examples
Integration Points:
- Emotion engine (Issue #429 ): Listens to emotion updates
- TTS service (Issue #421 ): Publishes formatted commands
- Jabra SPEAK 810: Output audio device
- Person tracking: Uses detected person names
Co-Authored-By: Claude Haiku 4.5 <noreply@anthropic.com>
2026-03-05 17:05:11 -05:00
6d6909d9d9
feat: Voice command router (Issue #491 )
...
Natural language voice command routing with fuzzy matching for speech variations.
Supported Commands:
- Follow me / Come with me
- Stop / Halt / Freeze
- Go home / Return to dock / Charge
- Patrol / Autonomous mode
- Come here / Approach
- Sit / Sit down
- Spin / Rotate / Turn around
- Dance / Groove
- Take photo / Picture / Smile
- What's that / Identify / Recognize
- Battery status / Battery level
Features:
- Fuzzy matching (rapidfuzz token_set_ratio) with 75% threshold
- Multiple pattern support per command for natural variations
- Three routing types: velocity (/cmd_vel), actions (/saltybot/action_command), services
- Command monitoring via /saltybot/voice_command
- Graceful handling of unrecognized speech
Architecture:
- Input: /saltybot/speech/transcribed_text (lowercase text)
- Fuzzy match against 11 command groups with 40+ patterns
- Route to: /cmd_vel (velocity), /saltybot/action_command (actions), or services
Files:
- saltybot_voice_router_node.py: Main router with fuzzy matching
- launch/voice_router.launch.py: Launch configuration
- VOICE_ROUTER_README.md: Usage documentation
Dependencies:
- rapidfuzz: Fuzzy string matching for natural speech handling
- rclpy, std_msgs, geometry_msgs: ROS2 core
Performance: <100ms per command (fuzzy matching + routing)
Co-Authored-By: Claude Haiku 4.5 <noreply@anthropic.com>
2026-03-05 17:05:02 -05:00
d79e38eb5b
feat: OTA firmware update (Issue #492 )
...
Complete over-the-air (OTA) firmware update system with:
Features:
- Downloads releases from Gitea (seb/saltylab-firmware)
- Automatic colcon build in staging directory
- Symlink-based atomic deployment
- ROS2 service restart via systemd
- Automatic rollback on build failure
- Version tracking in ~/.saltybot-data/versions.json
- Update history with timestamps
Safety:
- Blocks updates if robot velocity > 0.05 m/s
- Velocity monitoring via odometry subscription
- Backup before update for recovery
Triggers:
- MQTT /saltybot/ota_command: 'check', 'update:<version>', 'rollback'
- /saltybot/ota_status: JSON status updates
- Dashboard integration ready
Configuration:
- Gitea API base, repo info, directories
- Build timeout: 3600s (1 hour)
- Service restart automation
- Backup retention policy
ROS2 package structure complete with launch files and config.
2026-03-05 17:04:35 -05:00
7b22141142
feat: OTA firmware update (Issue #492 )
...
Complete over-the-air (OTA) firmware update system with:
Features:
- Downloads releases from Gitea (seb/saltylab-firmware)
- Automatic colcon build in staging directory
- Symlink-based atomic deployment
- ROS2 service restart via systemd
- Automatic rollback on build failure
- Version tracking in ~/.saltybot-data/versions.json
- Update history with timestamps
Safety:
- Blocks updates if robot velocity > 0.05 m/s
- Velocity monitoring via odometry subscription
- Backup before update for recovery
Triggers:
- MQTT /saltybot/ota_command: 'check', 'update:<version>', 'rollback'
- /saltybot/ota_status: JSON status updates
- Dashboard integration ready
Configuration:
- Gitea API base, repo info, directories
- Build timeout: 3600s (1 hour)
- Service restart automation
- Backup retention policy
ROS2 package structure complete with launch files and config.
2026-03-05 17:04:27 -05:00
285178b2f9
feat: Configure Nav2 navigation stack conservative speeds (Issue #475 )
...
- Update max_vel_x to 0.3 m/s (conservative for FC + hoverboard ESC)
- Update max_vel_theta to 0.5 rad/s (conservative for FC + hoverboard ESC)
- Set robot_radius to 0.22 m for 0.4m x 0.4m footprint
- Configure velocity smoother with conservative limits
- Both DWB local planner and velocity smoother updated for consistency
- RPLIDAR (/scan) + depth_to_laserscan (/depth_scan) costmap layers enabled
- NavFn global planner, DWB local planner configured
Co-Authored-By: Claude Haiku 4.5 <noreply@anthropic.com>
2026-03-05 14:50:41 -05:00
56a48b4e25
Merge PR #486 : Issue #480 - Map save/load
2026-03-05 14:48:59 -05:00
8f0215d461
Merge PR #485 : Issue #483 - Monitoring dashboard
2026-03-05 14:48:46 -05:00
f5877756d5
feat: Map save/load service for SLAM Toolbox persistence (Issue #480 )
...
Implement automatic map serialization and persistence for slam_toolbox:
- New SlamToolboxPersistenceNode with auto-save every 5 minutes
- Auto-load most recent map on startup
- Services: /saltybot/save_map, /saltybot/load_map, /saltybot/list_maps
- Export to Nav2-compatible YAML + PGM format
- Stores maps in ~/.saltybot-data/maps/ with .posegraph format
- Integrates with slam_toolbox serialize/deserialize services
Changes:
- Created saltybot_mapping/slam_toolbox_persistence.py
- Added slam_toolbox_persistence.launch.py
- Updated slam.launch.py to include persistence service
- Updated CMakeLists.txt to install new executable
- Added slam_toolbox dependency to package.xml
Co-Authored-By: Claude Haiku 4.5 <noreply@anthropic.com>
2026-03-05 14:46:33 -05:00
33036e2967
feat: Add URDF robot description (Issue #477 )
2026-03-05 14:43:01 -05:00
50d1ebbdcc
feat: Behavior tree coordinator for autonomous mode (Issue #482 )
...
State machine: idle → patrol → investigate → interact → return
- IDLE: Waiting for activation or battery recovery
- PATROL: Autonomous patrolling with curiosity-driven exploration (#470 )
- INVESTIGATE: Approach and track detected persons
- INTERACT: Social interaction with face recognition and gestures
- RETURN: Navigate back to home/dock with recovery behaviors
Integrations:
- Patrol mode (#446 ): Waypoint routes with geofence (#441 )
- Curiosity behavior (#470 ): Autonomous exploration
- Person following: Approach detected persons
- Emergency stop cascade (#459 ): Highest priority safety
- Geofence constraint (#441 ): Keep patrol within boundaries
Blackboard variables:
- battery_level: Current battery percentage
- person_detected: Person detection state
- current_mode: Current behavior tree state
- home_pose: Home/dock location
Files:
- behavior_trees/autonomous_coordinator.xml: BehaviorTree definition
- launch/autonomous_mode.launch.py: Full launch setup
- saltybot_bringup/bt_nodes.py: Custom BT node plugins
- BEHAVIOR_TREE_README.md: Documentation
Co-Authored-By: Claude Haiku 4.5 <noreply@anthropic.com>
2026-03-05 14:42:57 -05:00
60e16dc6ca
feat: Add URDF robot description (Issue #477 )
2026-03-05 14:42:49 -05:00
e66bcc2ab0
feat: Configure Nav2 costmaps (Issue #478 )
...
- Create nav2_params.yaml in saltybot_bringup/config/
- Global costmap: static layer + obstacle layer with /scan + /depth_scan
- Local costmap: rolling window 3m×3m, voxel layer + obstacle layer
- Inflation radius: 0.3m (robot_radius 0.15m + 0.15m padding)
- Robot footprint: 0.4m × 0.4m square [-0.2, +0.2] in x, y
- RPLIDAR A1M8 at /scan (360° LaserScan)
- RealSense D435i via depth_to_laserscan at /depth_scan
- Surround vision support for dynamic obstacles
Co-Authored-By: Claude Haiku 4.5 <noreply@anthropic.com>
2026-03-05 14:41:41 -05:00
7379aa459c
feat: Configure Nav2 recovery behaviors (Issue #479 )
...
Implement conservative recovery behaviors for autonomous navigation on FC + Hoverboard ESC drivetrain.
Recovery Sequence (round-robin, 6 retries):
1. Clear costmaps (local + global)
2. Spin 90° @ 0.5 rad/s max (conservative for self-balancer)
3. Wait 5 seconds (allow dynamic obstacles to move)
4. Backup 0.3m @ 0.1 m/s (deadlock escape, very conservative)
Configuration Details:
- backup: 0.3m reverse, 0.1 m/s speed, 0.15 m/s max, 5s timeout
- spin: 90° rotation, 0.5 rad/s max angular velocity, 1.6 rad/s² accel
- wait: 5-second pause for obstacle clearing
- progress_checker: 20cm minimum movement threshold in 10s window
Safety:
- E-stop (Issue #459 ) takes priority over recovery behaviors
- Emergency stop system runs independently on STM32 firmware
- Conservative speeds for FC + Hoverboard ESC stability
Files Modified:
- jetson/config/nav2_params.yaml: behavior_server parameters
- jetson/ros2_ws/src/saltybot_bringup/behavior_trees/navigate_to_pose_with_recovery.xml: BT updates
- jetson/config/RECOVERY_BEHAVIORS.md: Configuration documentation
Co-Authored-By: Claude Haiku 4.5 <noreply@anthropic.com>
2026-03-05 14:41:19 -05:00
dd459c0df7
feat: Configure Nav2 recovery behaviors (Issue #479 )
...
Implement conservative recovery behaviors for autonomous navigation on FC + Hoverboard ESC drivetrain.
Recovery Sequence (round-robin, 6 retries):
1. Clear costmaps (local + global)
2. Spin 90° @ 0.5 rad/s max (conservative for self-balancer)
3. Wait 5 seconds (allow dynamic obstacles to move)
4. Backup 0.3m @ 0.1 m/s (deadlock escape, very conservative)
Configuration Details:
- backup: 0.3m reverse, 0.1 m/s speed, 0.15 m/s max, 5s timeout
- spin: 90° rotation, 0.5 rad/s max angular velocity, 1.6 rad/s² accel
- wait: 5-second pause for obstacle clearing
- progress_checker: 20cm minimum movement threshold in 10s window
Safety:
- E-stop (Issue #459 ) takes priority over recovery behaviors
- Emergency stop system runs independently on STM32 firmware
- Conservative speeds for FC + Hoverboard ESC stability
Files Modified:
- jetson/config/nav2_params.yaml: behavior_server parameters
- jetson/ros2_ws/src/saltybot_bringup/behavior_trees/navigate_to_pose_with_recovery.xml: BT updates
- jetson/config/RECOVERY_BEHAVIORS.md: Configuration documentation
Co-Authored-By: Claude Haiku 4.5 <noreply@anthropic.com>
2026-03-05 14:41:11 -05:00
fd742f6890
feat: Configure Nav2 recovery behaviors (Issue #479 )
...
Implement conservative recovery behaviors for autonomous navigation on FC + Hoverboard ESC drivetrain.
Recovery Sequence (round-robin, 6 retries):
1. Clear costmaps (local + global)
2. Spin 90° @ 0.5 rad/s max (conservative for self-balancer)
3. Wait 5 seconds (allow dynamic obstacles to move)
4. Backup 0.3m @ 0.1 m/s (deadlock escape, very conservative)
Configuration:
- backup: 0.3m reverse, 0.1 m/s speed, 5s timeout
- spin: 90° rotation, 0.5 rad/s max angular velocity
- wait: 5-second pause for obstacle clearing
- progress_checker: 20cm minimum movement threshold in 10s window
Safety:
- E-stop (Issue #459 ) takes priority over recovery behaviors
- Emergency stop system runs independently on STM32 firmware
- Conservative speeds for FC + Hoverboard ESC stability
Files Modified:
- jetson/config/nav2_params.yaml: behavior_server parameters
- jetson/ros2_ws/src/saltybot_bringup/behavior_trees/navigate_to_pose_with_recovery.xml: BT updates
- jetson/config/RECOVERY_BEHAVIORS.md: Configuration documentation
Co-Authored-By: Claude Haiku 4.5 <noreply@anthropic.com>
2026-03-05 14:40:45 -05:00
d7051fe854
feat: Add Issue #467 - Power management supervisor with battery protection
...
social-bot integration tests / Lint (flake8 + pep257) (push) Failing after 11s
social-bot integration tests / Core integration tests (mock sensors, no GPU) (push) Has been skipped
social-bot integration tests / Latency profiling (GPU, Orin) (push) Has been cancelled
- New ROS2 node: power_supervisor_node for battery state monitoring
- Battery thresholds: 30% warning, 20% dock search, 10% graceful shutdown, 5% force kill
- Charge cycle tracking and battery health estimation
- CSV logging to battery_log.csv for external analysis
- Publishes /saltybot/power_state for MQTT relay
- Graceful shutdown cascade: save state, stop motors, disarm on critical low battery
- Replaces/extends Issue #125 battery_node with supervisor-level power management
Co-Authored-By: Claude Haiku 4.5 <noreply@anthropic.com>
2026-03-05 14:34:37 -05:00
6293d2ec60
Merge Issue #473 : event logger - structured JSON activity logging
2026-03-05 14:22:45 -05:00
b178614e6e
Merge Issue #468 : object detection - perception system enhancements
2026-03-05 14:22:32 -05:00
e26301c7ca
Merge Issue #472 : dance choreography - behavioral sequences
2026-03-05 14:22:06 -05:00
c96c68a7c4
feat: YOLOv8n object detection with RealSense depth integration (Issue #468 )
...
- saltybot_object_detection_msgs: DetectedObject, DetectedObjectArray, QueryObjects.srv
- saltybot_object_detection: YOLOv8n TensorRT FP16 node with depth projection
- Message filters for RGB-depth sync, TF2 transform to base_link
- Configurable confidence and class filtering (COCO 80 classes)
- Query service for voice integration ("whats in front of you")
- TensorRT build script with ONNX fallback
- Launch file with parameter configuration
- Full stack integration at t=6s (30 FPS target alongside person tracker)
Co-Authored-By: Claude Haiku 4.5 <noreply@anthropic.com>
2026-03-05 12:14:50 -05:00