533 Commits

Author SHA1 Message Date
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
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
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
Some checks failed
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
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
00e632ecbf 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:09:45 -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
02e9b15e6f Merge remote-tracking branch 'origin/sl-webui/issue-453-obstacle-map' 2026-03-05 11:09:46 -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
270507ad49 Merge pull request 'feat: Add gesture recognition system (Issue #454)' (#461) from sl-webui/sl-perception/issue-454-gestures into main 2026-03-05 11:07:13 -05:00
f47b01eff6 Merge pull request 'feat: sound effects (Issue #457)' (#460) from sl-mechanical/issue-457-sound-effects into main 2026-03-05 11:07:11 -05:00
2ba8df17fd feat: Add Issue #453 - Obstacle memory map with persistent hazard zones
- 2D occupancy grid (100x100 cells @ 10cm resolution, configurable)
- LIDAR integration: subscribes to /scan and /odom for real-time obstacle detection
- Ray-casting: marks hit points as obstacles, intermediate points as free space
- Cell states: unknown/free/obstacle/hazard with confidence tracking (0.0–1.0)
- Hazard classification: 3+ detections = permanent hazard (stays in memory)
- Temporal decay: 95%/day for hazards (30-day half-life), 85%/day for obstacles (~21-day)
- Decay interval: applied hourly, cells revert to free when confidence < 20%
- Persistence: auto-saves to /home/seb/saltybot-data/obstacle_map.yaml every 5 minutes
- YAML format: grid metadata + cell array with state/confidence/detection_count/timestamp
- OccupancyGrid publisher: /saltybot/obstacle_map for Nav2 integration at 5 Hz
- Thread-safe: all grid operations protected with locks for concurrent callbacks
- Statistics: hazard/obstacle/free cell counts and coverage percentage
- Dashboard overlay ready: color-coded cells (red=hazard, orange=obstacle, gray=free)
- Configurable via obstacle_memory.yaml: grid size/resolution, range limits, decay rates

Co-Authored-By: Claude Haiku 4.5 <noreply@anthropic.com>
2026-03-05 09:21:34 -05:00
fb93acee0a feat: Add Issue #453 - Obstacle memory map with persistent hazard zones
- 2D occupancy grid (100x100 cells @ 10cm resolution, configurable)
- LIDAR integration: subscribes to /scan and /odom for real-time obstacle detection
- Ray-casting: marks hit points as obstacles, intermediate points as free space
- Cell states: unknown/free/obstacle/hazard with confidence tracking (0.0–1.0)
- Hazard classification: 3+ detections = permanent hazard (stays in memory)
- Temporal decay: 95%/day for hazards (30-day half-life), 85%/day for obstacles (~21-day)
- Decay interval: applied hourly, cells revert to free when confidence < 20%
- Persistence: auto-saves to /home/seb/saltybot-data/obstacle_map.yaml every 5 minutes
- YAML format: grid metadata + cell array with state/confidence/detection_count/timestamp
- OccupancyGrid publisher: /saltybot/obstacle_map for Nav2 integration at 5 Hz
- Thread-safe: all grid operations protected with locks for concurrent callbacks
- Statistics: hazard/obstacle/free cell counts and coverage percentage
- Dashboard overlay ready: color-coded cells (red=hazard, orange=obstacle, gray=free)
- Configurable via obstacle_memory.yaml: grid size/resolution, range limits, decay rates

Co-Authored-By: Claude Haiku 4.5 <noreply@anthropic.com>
2026-03-05 09:21:30 -05:00
9027fa9e12 feat: add photo capture package files (Issue #456) 2026-03-05 09:21:26 -05:00
5e62e81a97 feat: photo capture service (Issue #456) 2026-03-05 09:20:57 -05:00
sl-android
f4e4f184ef feat: WiFi mesh handoff - seamless AP roaming (Issue #458)
Add WiFi mesh handoff infrastructure:

WiFiState.msg interface:
- SSID, signal strength (dBm), connection status
- AP address, frequency, link quality
- TX/RX rates, roaming flag
- Available APs for handoff decision

WiFi Monitor Node:
- Signal monitoring via iwconfig/nmcli
- Auto-roam at -70dBm threshold
- Seamless wpa_supplicant roaming
- Gateway ping (8.8.8.8) every 5s
- USB tethering fallback if offline >30s
- TTS warnings for connectivity issues
- Coverage logging with AP transitions

Features:
- Configurable roaming threshold (-70dBm default)
- Gateway connectivity verification
- Offline detection with configurable timeout
- USB tethering auto-activation/deactivation
- Signal strength change logging (>5dBm)
- AP transition logging
- Manual rescan/tether control commands

Topics:
- /saltybot/wifi_state (String)
- /saltybot/speech_text (String warnings)
- /saltybot/wifi_cmd (String commands)

Configuration:
- interface: wlan0
- roam_threshold_dbm: -70
- offline_warning_timeout: 30.0
- target_ssid: SaltyLab
- fallback_tether: true
- coverage_log_file: /tmp/wifi_coverage.log

Roaming Behavior:
- Monitors signal continuously
- When signal < -70dBm, scans for stronger AP
- wpa_supplicant performs seamless handoff
- Logs all AP transitions to coverage file

Fallback Behavior:
- Pings gateway every 5 seconds
- If unreachable for >30s, activates USB tether
- TTS alert: 'Warning: Lost WiFi connectivity...'
- Auto-deactivates when WiFi restored

Coverage Mapping:
- Logs timestamp, SSID, signal, connected status
- Tracks roaming events
- Useful for mesh network optimization

Co-Authored-By: Claude Haiku 4.5 <noreply@anthropic.com>
2026-03-05 09:20:42 -05:00
dc525d652c feat: Add gesture recognition system (Issue #454)
Implements hand and body gesture recognition via MediaPipe on Jetson Orin GPU.
- MediaPipe Hands (21-point hand landmarks) + Pose (33-point body landmarks)
- Recognizes: wave, point, stop_palm, thumbs_up, come_here, arms_up, arms_spread
- GestureArray publishing at 10–15 fps on Jetson Orin
- Confidence threshold: 0.7 (configurable)
- Range: 2–5 meters optimal
- GPU acceleration via Jetson Tensor RT
- Integrates with voice command router for multimodal interaction
- Temporal smoothing: history-based motion detection (wave, beckon)

Co-Authored-By: Claude Haiku 4.5 <noreply@anthropic.com>
2026-03-05 09:19:43 -05:00
569ac3fb35 feat: Add gesture recognition system (Issue #454)
Implements hand and body gesture recognition via MediaPipe on Jetson Orin GPU.
- MediaPipe Hands (21-point hand landmarks) + Pose (33-point body landmarks)
- Recognizes: wave, point, stop_palm, thumbs_up, come_here, arms_up, arms_spread
- GestureArray publishing at 10–15 fps on Jetson Orin
- Confidence threshold: 0.7 (configurable)
- Range: 2–5 meters optimal
- GPU acceleration via Jetson Tensor RT
- Integrates with voice command router for multimodal interaction
- Temporal smoothing: history-based motion detection (wave, beckon)

Co-Authored-By: Claude Haiku 4.5 <noreply@anthropic.com>
2026-03-05 09:19:40 -05:00
8538fa2f9d feat: Add Issue #455 - Smooth velocity controller with S-curve jerk reduction
Implement acceleration-limited velocity controller:
- Subscribe to /cmd_vel_raw, publish smoothed /cmd_vel
- Max linear acceleration: 0.5 m/s², angular: 1.0 rad/s²
- Deceleration: 0.8 m/s² (linear), 1.0 rad/s² (angular)
- S-curve jerk limiting with 0.2s ramp time
- E-stop immediate stop capability
- Command priority system (e-stop > teleop > geofence > follow-me > nav2 > patrol)
- Publish /saltybot/velocity_profile for monitoring
- 50Hz update rate (configurable)

Co-Authored-By: Claude Haiku 4.5 <noreply@anthropic.com>
2026-03-05 09:19:33 -05:00
381549b33f feat: Emergency stop cascade system (Issue #459)
Critical safety system with <50ms latency emergency response.

ROS2 action server /saltybot/estop with unified trigger sources:
- Voice commands: 'stop', 'emergency', 'e-stop'
- Gamepad emergency button
- IMU tilt detection (>45 degrees)
- LiDAR obstacle detection (<0.3m)
- Geofence boundary violation
- Watchdog timeout trigger
- MQTT remote kill signal

Cascade response (within 500ms):
1. Zero cmd_vel in <50ms (priority critical)
2. Disable autonomous mode
3. Face alert animation (emergency_stop)
4. LED red indicator
5. TTS alert announcement
6. Event logging + sensor snapshot

Safety properties:
- Cannot be overridden once triggered
- Manual resume only (gamepad Start or voice 'resume')
- Non-blockable execution (separate thread)
- Redundant trigger sources for reliability

Published topics:
- /saltybot/estop_active (Bool) - System state
- /saltybot/estop_event (String) - Event log (JSON)

Subscribed triggers:
- /camera/imu - Tilt detection
- /scan - Obstacle detection <0.3m
- /voice/command - Voice e-stop/resume
- /gamepad/emergency, /gamepad/start - Gamepad controls
- /saltybot/geofence_violation - Geofence boundary
- /saltybot/watchdog_timeout - Watchdog signal
- /saltybot/mqtt_kill - Remote kill signal

Package structure:
- estop_server: Main emergency stop node
- estop_config.yaml: Timing, triggers, cascade config
- estop.launch.py: Launch with safety parameters
- Unit tests for trigger detection and cascade timing

Logging: /home/seb/saltybot-data/estop/ (JSON format)

Co-Authored-By: Claude Haiku 4.5 <noreply@anthropic.com>
2026-03-05 09:19:31 -05:00
5c05874ed3 feat: sound effects library (Issue #457)
Event-driven audio feedback system with 9 sound events:
- boot_complete: Startup chime (ascending notes)
- person_detected: Subtle detection sound (800Hz sine)
- wake_word: Activation beep (1000Hz)
- low_battery: Warning tone (880Hz double beep)
- obstacle_close: Proximity beeps (rapid 1200Hz pulses)
- trick_complete: Success jingle (ascending arpeggio)
- error: Descending warning tone (800→400Hz)
- charging_start: Power-up tone (rising 400→1200Hz)
- geofence_warning: Boundary alert (950Hz)

Features:
- Priority queue for event handling
- Dynamic sound synthesis if WAV/OGG files missing
- Volume control with quiet/night mode support
- Fade in/out for smooth playback
- Configurable per-event duration and priority
- Caching of loaded audio files
- Background playback thread
- Real-time state publishing

Configuration:
- WAV/OGG file loading from /home/seb/saltybot-data/sounds/
- Programmatic sound generation (sine, chime, descending, power-up, beep, jingle, proximity, alert)
- Numpy/scipy-based synthesis
- YAML configuration for all events
- Volume and fade timing controls
- Sample rate: 16kHz, 16-bit audio

Co-Authored-By: Claude Haiku 4.5 <noreply@anthropic.com>
2026-03-05 09:19:21 -05:00
35e35a2997 feat: sound effects library (Issue #457)
Event-driven audio feedback system with 9 sound events:
- boot_complete: Startup chime (ascending notes)
- person_detected: Subtle detection sound (800Hz sine)
- wake_word: Activation beep (1000Hz)
- low_battery: Warning tone (880Hz double beep)
- obstacle_close: Proximity beeps (rapid 1200Hz pulses)
- trick_complete: Success jingle (ascending arpeggio)
- error: Descending warning tone (800→400Hz)
- charging_start: Power-up tone (rising 400→1200Hz)
- geofence_warning: Boundary alert (950Hz)

Features:
- Priority queue for event handling
- Dynamic sound synthesis if WAV/OGG files missing
- Volume control with quiet/night mode support
- Fade in/out for smooth playback
- Configurable per-event duration and priority
- Caching of loaded audio files
- Background playback thread
- Real-time state publishing

Configuration:
- WAV/OGG file loading from /home/seb/saltybot-data/sounds/
- Programmatic sound generation (sine, chime, descending, power-up, beep, jingle, proximity, alert)
- Numpy/scipy-based synthesis
- YAML configuration for all events
- Volume and fade timing controls
- Sample rate: 16kHz, 16-bit audio

Co-Authored-By: Claude Haiku 4.5 <noreply@anthropic.com>
2026-03-05 09:19:19 -05:00
9d36e1007d feat: Add Issue #455 - Smooth velocity controller with jerk reduction
Implement acceleration-limited velocity controller with S-curve jerk limiting:
- Subscribe to /cmd_vel_raw, publish smoothed /cmd_vel
- Max linear acceleration: 0.5 m/s²
- Max angular acceleration: 1.0 rad/s²
- Deceleration: 0.8 m/s² (linear), 1.0 rad/s² (angular)
- S-curve jerk limiting for smooth acceleration profiles (0.2s ramp)
- E-stop immediate stop capability
- Command priority system (e-stop > teleop > geofence > follow-me > nav2 > patrol)
- Publish /saltybot/velocity_profile for monitoring
- Configurable via smooth_velocity_config.yaml
- 50Hz update rate (configurable)

Co-Authored-By: Claude Haiku 4.5 <noreply@anthropic.com>
2026-03-05 09:18:58 -05:00
3ea19fbb99 Merge remote-tracking branch 'origin/sl-jetson/issue-447-full-launch'
# Conflicts:
#	jetson/ros2_ws/src/saltybot_geofence/saltybot_geofence/geofence_node.py
2026-03-05 09:10:33 -05:00
b9a6eaa3fa Merge remote-tracking branch 'origin/sl-firmware/issue-445-diagnostics'
# Conflicts:
#	jetson/ros2_ws/src/saltybot_diagnostics/README.md
#	jetson/ros2_ws/src/saltybot_diagnostics/config/diagnostic_checks.yaml
#	jetson/ros2_ws/src/saltybot_diagnostics/launch/diagnostics.launch.py
#	jetson/ros2_ws/src/saltybot_diagnostics/package.xml
#	jetson/ros2_ws/src/saltybot_diagnostics/saltybot_diagnostics/diagnostics_node.py
#	jetson/ros2_ws/src/saltybot_diagnostics/setup.py
#	jetson/ros2_ws/src/saltybot_diagnostics/test/test_diagnostics.py
2026-03-05 09:10:24 -05:00
3d008ddbb7 Merge remote-tracking branch 'origin/sl-controls/issue-441-geofence'
# Conflicts:
#	jetson/ros2_ws/src/saltybot_geofence/saltybot_geofence/geofence_node.py
2026-03-05 09:10:17 -05:00
fac873c261 Merge pull request 'feat: night mode (Issue #444)' (#451) from sl-mechanical/issue-444-night-mode into main 2026-03-05 09:09:14 -05:00