f71fdae747
feat: Depth-to-costmap plugin for RealSense D435i (Issue #532 )
...
Add saltybot_depth_costmap — a Nav2 costmap2d plugin that converts
D435i depth images directly into obstacle markings on both local and
global costmaps.
Pipeline:
1. Subscribe to /camera/depth/image_rect_raw (16UC1 mm) + camera_info
2. Back-project depth pixels to 3D using pinhole camera intrinsics
3. Transform points to costmap global_frame via TF2
4. Apply configurable height filter (min_height..max_height above ground)
5. Mark obstacle cells as LETHAL_OBSTACLE
6. Inflate neighbours within inflation_radius as INSCRIBED_INFLATED_OBSTACLE
Parameters:
min_height: 0.05 m — floor clearance (ignores ground returns)
max_height: 0.80 m — ceiling cutoff (ignores lights/ceiling)
obstacle_range: 3.5 m — max marking distance from camera
clearing_range: 4.0 m — max distance processed at all
inflation_radius: 0.10 m — in-layer inflation (works before inflation_layer)
downsample_factor: 4 — process 1 of N rows+cols (~19k pts @ 640×480)
Integration (#478 ):
- Added depth_costmap_layer to local_costmap plugins list
- Added depth_costmap_layer to global_costmap plugins list
- Plugin registered via pluginlib (plugin.xml)
Files:
jetson/ros2_ws/src/saltybot_depth_costmap/
CMakeLists.txt, package.xml, plugin.xml
include/saltybot_depth_costmap/depth_costmap_layer.hpp
src/depth_costmap_layer.cpp
jetson/ros2_ws/src/saltybot_bringup/config/nav2_params.yaml (updated)
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-03-07 09:52:18 -05:00
5b7ee63d1e
Merge remote-tracking branch 'origin/sl-controls/issue-522-usart6-truncation'
2026-03-06 23:34:45 -05:00
7141e12320
feat: Integration test suite expanded (Issue #504 ) - resolve conflicts
2026-03-06 23:10:42 -05:00
e28f1549cb
feat: Orin motor control daemon (Issue #523 )
...
Add saltybot_motor_daemon ROS2 package — Python daemon that subscribes
to /cmd_vel and drives the FC via W<speed>,<steer>\n over /dev/ttyTHS1
at 921600 baud.
- motor_daemon_node.py: 50 Hz fixed-rate TX, 200ms safety watchdog,
Twist→ESC conversion (±1000 range), FC ack parsing (W:<s>,<st>),
periodic ? status query, /diagnostics publisher, auto-reconnect
- config/motor_daemon_params.yaml: all tunable params with comments
- launch/motor_daemon.launch.py: parameterised launch file
- test/test_motor_daemon.py: 25 unit tests (all passing)
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-03-06 23:02:57 -05:00
f14ce5c3ba
Merge remote-tracking branch 'origin/sl-perception/issue-469-terrain-classification'
2026-03-06 17:37:27 -05:00
2e2ed2d0a7
Merge remote-tracking branch 'origin/sl-controls/issue-506-launch-profiles'
2026-03-06 17:37:27 -05:00
5b9e9dd412
Merge pull request 'feat: Headscale VPN auto-connect (Issue #502 )' ( #517 ) from sl-jetson/issue-502-headscale-vpn into main
2026-03-06 17:37:07 -05:00
8d58d5e34c
feat: Terrain classification for speed adaptation (Issue #469 )
...
Implement multi-sensor terrain classification using RealSense D435i depth and RPLIDAR A1M8:
- saltybot_terrain_classification: New ROS2 package for terrain classification
- TerrainClassifier: Rule-based classifier matching depth variance + reflectance to terrain type
(smooth/carpet/grass/gravel) with hysteresis + confidence scoring
- DepthExtractor: Extracts roughness from depth discontinuities and surface gradients
- LidarExtractor: Extracts reflectance from RPLIDAR scan intensities
- terrain_classification_node: 10Hz node fusing both sensors, publishes:
- /saltybot/terrain_type (JSON with type, confidence, speed_scale)
- /saltybot/terrain_type_string (human-readable type)
- /saltybot/terrain_speed_scale (0.0-1.0 speed multiplier for smooth/carpet/grass/gravel)
Speed scales: smooth=1.0, carpet=0.9, grass=0.75, gravel=0.6
Co-Authored-By: Claude Haiku 4.5 <noreply@anthropic.com>
2026-03-06 16:43:21 -05:00
d3eca7bebc
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:38 -05:00
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
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
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
062c05cac0
feat: Add Issue #502 - Headscale VPN auto-connect on Orin
...
Configure Jetson Orin with Tailscale client connecting to Headscale
coordination server at tailscale.vayrette.com:8180. Device registers
as 'saltylab-orin' with persistent auth key for unattended login.
Features:
- systemd auto-start and restart on WiFi drops
- Persistent auth key storage at /opt/saltybot/tailscale-auth.key
- SSH + HTTP access over Tailscale tailnet (encrypted WireGuard)
- IP forwarding enabled for relay/exit node capability
- WiFi resilience with aggressive restart policy
- MQTT reporting of VPN status, IP, and connection type
Components added:
- jetson/scripts/setup-tailscale.sh: Tailscale package installation
- jetson/scripts/headscale-auth-helper.sh: Auth key management utility
- jetson/systemd/tailscale-vpn.service: systemd service unit
- jetson/docs/headscale-vpn-setup.md: Comprehensive setup documentation
- saltybot_cellular/vpn_status_node.py: ROS2 node for MQTT reporting
Updated:
- jetson/systemd/install_systemd.sh: Include tailscale-vpn.service
- jetson/scripts/setup-jetson.sh: Add Tailscale setup steps
Access patterns:
- SSH: ssh user@saltylab-orin.tail12345.ts.net
- HTTP: http://saltylab-orin.tail12345.ts.net:port
- Direct IP: 100.x.x.x (Tailscale allocated address)
Co-Authored-By: Claude Haiku 4.5 <noreply@anthropic.com>
2026-03-06 10:25:04 -05:00
767f377120
feat: Add Issue #504 - Integration test suite with launch_testing
...
Create saltybot_tests package with comprehensive automated testing:
Test Coverage:
- Node startup verification (all critical nodes within 30s)
- Topic publishing verification
- TF tree completeness (all transforms present)
- Sensor health checks (RPLIDAR, RealSense, IMU)
- Perception pipeline (person detection availability)
- Navigation stack (odometry, transforms)
- System stability (30-second no-crash test)
- Graceful shutdown verification
Features:
- launch_testing framework for automated startup tests
- NodeChecker: wait for nodes in ROS graph
- TFChecker: verify TF tree completeness
- TopicMonitor: track message rates and counts
- Follow mode tests (minimal hardware deps)
- Subsystem-specific tests for sensor health
- Comprehensive README with troubleshooting
Usage:
pytest src/saltybot_tests/test/test_launch.py -v -s
or
colcon test --packages-select saltybot_tests
Performance Targets:
- Node startup: <30s (follow mode)
- RPLIDAR: 10 Hz scan rate
- RealSense: 30 Hz RGB + depth
- Person detection: 5 Hz
- System stability: 30s no-crash validation
Co-Authored-By: Claude Haiku 4.5 <noreply@anthropic.com>
2026-03-06 10:22:38 -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
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
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
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
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
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
b178614e6e
Merge Issue #468 : object detection - perception system enhancements
2026-03-05 14:22:32 -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
sl-android
2e9fd6fa4c
feat: curiosity behavior — autonomous exploration when idle (Issue #470 )
...
- Frontier exploration toward unexplored areas
- Activates when idle >60s + no people detected
- Turns toward detected sounds via audio_direction node
- Approaches colorful/moving objects
- Self-narrates findings via TTS
- Respects geofence and obstacle boundaries
- 10-minute max duration with auto-return
- Configurable curiosity level (0-1.0)
- Publishes /saltybot/curiosity_state
Co-Authored-By: Claude Haiku 4.5 <noreply@anthropic.com>
2026-03-05 12:10:33 -05:00
0c03060016
feat: centralized parameter server + dynamic reconfiguration (Issue #471 )
...
ROS2 node and WebUI component for centralized dynamic parameter configuration.
- Parameter server node with validation, range checks, and persistence
- Organized into groups: hardware/perception/controls/social/safety/debug
- Service-based API for dynamic reconfiguration (/saltybot/set_param)
- Named presets: indoor/outdoor/demo/debug
- WebUI component with parameter browsing, editing, and preset loading
- Safety parameter confirmation dialogs
- Real-time parameter metadata display (type, range, description)
Files:
- jetson/ros2_ws/src/saltybot_param_server/ - ROS2 parameter server node
- ui/social-bot/src/components/ParameterServer.jsx - WebUI component
- App.jsx - Integrated into CONFIG tab group as 'Parameters'
Build status: ✅ PASSING (127 modules)
Co-Authored-By: Claude Haiku 4.5 <noreply@anthropic.com>
2026-03-05 12:10:04 -05:00
d421d63c6f
feat: Add Issue #473 - Event Logger with structured JSON logging
...
Comprehensive event logging system for SaltyBot with:
Features:
- MQTT subscription to /saltybot/* state topics (9 event types)
- Structured JSON event logging to ~/.saltybot-data/events/YYYY-MM-DD.jsonl
- Event types: encounter, voice_command, trick, e-stop, geofence, dock, error, boot, shutdown
- Query service (time range + type filter)
- Stats publisher (/saltybot/event_stats) with daily summaries
- Dashboard live feed (/saltybot/event_feed)
- Automatic log rotation: compress >7 days, delete >90 days
- CSV export functionality
- Thread-safe event processing
Components:
- EventLogger ROS2 node with background timers
- Event dataclass with timestamp/type/source/data
- File-based storage (JSONL + compressed archives)
- Query API for time/type filtering
- CSV export utility
- Comprehensive unit tests (15 test cases)
Configuration:
- Data directory: ~/.saltybot-data/events
- Rotation: 7 days compress, 90 days delete
- Stats interval: 60 seconds
- Rotation check: hourly
Launch:
- event_logger.launch.py - Standalone launch
- Config: event_logger.yaml with topic mappings
Co-Authored-By: Claude Haiku 4.5 <noreply@anthropic.com>
2026-03-05 12:09:07 -05:00
c25d63772a
Merge remote-tracking branch 'origin/sl-jetson/issue-456-photo-capture'
...
# Conflicts:
# jetson/ros2_ws/src/saltybot_obstacle_memory/package.xml
# jetson/ros2_ws/src/saltybot_photo_capture/package.xml
# jetson/ros2_ws/src/saltybot_photo_capture/setup.py
2026-03-05 11:09:41 -05:00
b38f948844
Merge remote-tracking branch 'origin/sl-controls/issue-455-smooth-velocity'
...
# Conflicts:
# jetson/ros2_ws/src/saltybot_smooth_velocity/config/smooth_velocity_config.yaml
# jetson/ros2_ws/src/saltybot_smooth_velocity/launch/smooth_velocity.launch.py
# jetson/ros2_ws/src/saltybot_smooth_velocity/package.xml
# jetson/ros2_ws/src/saltybot_smooth_velocity/saltybot_smooth_velocity/smooth_velocity_node.py
# jetson/ros2_ws/src/saltybot_smooth_velocity/setup.cfg
# jetson/ros2_ws/src/saltybot_smooth_velocity/setup.py
2026-03-05 11:09:32 -05:00
3ecf334642
Merge pull request 'feat: emergency stop cascade (Issue #459 )' ( #466 ) from sl-firmware/issue-459-estop into main
2026-03-05 11:08:01 -05:00
5a4150a2d0
Merge pull request 'feat: WiFi mesh handoff (Issue #458 )' ( #462 ) from sl-android/issue-458-wifi-handoff into main
2026-03-05 11:07:26 -05:00