694 Commits

Author SHA1 Message Date
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
27a95dce0a Merge pull request 'feat: social memory DB (Issue #443)' (#450) from sl-webui/issue-443-social-memory into main 2026-03-05 09:09:09 -05:00
1530104e22 Merge pull request 'feat: weather awareness (Issue #442)' (#448) from sl-android/issue-446-patrol into main 2026-03-05 09:09:00 -05:00
ab5dd97fcb feat: add consolidated params and stack state monitor (Issue #447) 2026-03-05 09:07:17 -05:00
41dc80ea7d feat: Add diagnostic self-test system (Issue #445)
Comprehensive hardware diagnostics and health monitoring for SaltyBot.

Startup hardware checks:
- RPLIDAR, RealSense, VESC, Jabra microphone, STM32 bridge
- Servo controller, WiFi, GPS module
- Disk space, system RAM, CPU temperature
- Boot result via TTS + face animation

Runtime monitoring:
- Temperature thresholds (Orin GPU >80C, VESC >60C)
- Network latency to 8.8.8.8
- System resource tracking (CPU, RAM, disk)

Features:
- Publishes /saltybot/diagnostics (DiagnosticArray)
- JSON logging to /home/seb/saltybot-data/diagnostics/
- Configuration-driven via YAML
- Boot animations and TTS announcements
- Configurable startup and runtime checks

Package structure:
- saltybot_diagnostics: Main diagnostics node
- diagnostic_checks.yaml: Hardware config + thresholds
- diagnostics.launch.py: Launch file with parameters
- Unit tests for check aggregation and logging

Co-Authored-By: Claude Haiku 4.5 <noreply@anthropic.com>
2026-03-05 09:06:18 -05:00
292c73fb60 feat: Add Issue #441 - Geofence safety with configurable boundary
Implement GPS-based geofence safety system:
- Subscribe to /phone/gps and /odom for position tracking
- Support circle (default 50m radius) or polygon geofence
- Three zones: SAFE, WARNING (2m buffer), VIOLATION
- WARNING zone: slow + concern emotion + TTS warning + amber LED
- VIOLATION zone: stop + auto-return + red LED + TTS alert
- Publish /saltybot/geofence_state (UInt8: 0=SAFE, 1=WARNING, 2=VIOLATION)
- LED feedback colors: off (safe), amber (warning), red (violation)
- Auto-return to safe zone when breaching boundary
- Configurable via geofence_config.yaml (type, radius, warning distance, etc)

Co-Authored-By: Claude Haiku 4.5 <noreply@anthropic.com>
2026-03-05 09:05:55 -05:00
c1076b8230 feat: full stack master launch with profiles (Issue #447)
Master saltybot_bringup.launch.py with:
- Profile support (full/minimal/headless) for flexible deployments
- Boot order: hardware → perception → control → social → monitoring
- Dependency-ordered launch with 30-second boot timeout
- Consolidated saltybot_params.yaml with all stack parameters
- Stack state publisher (/saltybot/stack_state)
- Post-launch diagnostics self-test
- Graceful shutdown support (motors first)

Boot sequence (Issue #447):
- t=0s:    hardware (robot description, STM32 bridge)
- t=2-6s:  perception (sensors, cameras, detection, SLAM)
- t=2-14s: control (cmd_vel bridge, follower, Nav2)
- t=17-19s: social & monitoring (rosbridge, stack state)

Features:
- full profile: complete stack (SLAM, Nav2, detection, follower)
- minimal profile: hardware + control only
- headless profile: sensors + control (no CSI cameras)
- Configurable modes: indoor (SLAM+Nav2), outdoor (GPS nav), follow

Parameters consolidated in config/saltybot_params.yaml:
- Hardware (bridge, motors)
- Perception (sensors, detection, SLAM)
- Control (follower, Nav2)
- Social (TTS, gestures, face tracking)
- Monitoring (rosbridge, health checks)

New: stack_state_monitor_node.py (publishes stack boot state)

Co-Authored-By: Claude Haiku 4.5 <noreply@anthropic.com>
2026-03-05 09:05:25 -05:00
2d144f5bcc feat: full stack master launch with profiles (Issue #447)
Master saltybot_bringup.launch.py with:
- Profile support (full/minimal/headless) for flexible deployments
- Boot order: hardware → perception → control → social → monitoring
- Dependency-ordered launch with 30-second boot timeout
- Consolidated saltybot_params.yaml with all stack parameters
- Stack state publisher (/saltybot/stack_state)
- Post-launch diagnostics self-test
- Graceful shutdown support (motors first)

Boot sequence (Issue #447):
- t=0s:    hardware (robot description, STM32 bridge)
- t=2-6s:  perception (sensors, cameras, detection, SLAM)
- t=2-14s: control (cmd_vel bridge, follower, Nav2)
- t=17-19s: social & monitoring (rosbridge, stack state)

Features:
- full profile: complete stack (SLAM, Nav2, detection, follower)
- minimal profile: hardware + control only
- headless profile: sensors + control (no CSI cameras)
- Configurable modes: indoor (SLAM+Nav2), outdoor (GPS nav), follow

Parameters consolidated in config/saltybot_params.yaml:
- Hardware (bridge, motors)
- Perception (sensors, detection, SLAM)
- Control (follower, Nav2)
- Social (TTS, gestures, face tracking)
- Monitoring (rosbridge, health checks)

New: stack_state_monitor_node.py (publishes stack boot state)

Co-Authored-By: Claude Haiku 4.5 <noreply@anthropic.com>
2026-03-05 09:05:18 -05:00
3830db8225 feat: night mode controller (Issue #444)
Automatic night mode detection and stealth operation:
- Ambient light detection: auto-switch at 50 lux threshold
- Motor speed reduction: 50% speed in stealth mode
- LED control: dim to 5% minimum brightness with slow blue fade
- Face-only mode: disable TTS speaker, show text on face
- IR-based tracking: use IR cameras only (RGB disabled)
- Face brightness: reduce to 30% for low-light visibility
- Manual override: voice commands and gamepad toggle (Y button)
- Smooth transitions: 1-second fade between modes with ramps

Features:
- Hysteresis: 5 lux band prevents mode flickering
- Light sensor smoothing: 5-sample averaging for stability
- Transition manager: smooth motor ramp (2s), LED fade (0.5s)
- Multiple sensor support: RealSense IR, phone ambient sensor
- Stealth LED pattern: slow breathing dim blue (0.3 Hz)

Configuration:
- YAML-based threshold and behavior settings
- Per-subsystem transition timing
- Tracking parameter tuning for IR mode
- Face control with contrast boost

Co-Authored-By: Claude Haiku 4.5 <noreply@anthropic.com>
2026-03-05 09:05:16 -05:00
7cad97d0db feat: Add Issue #443 - Social memory database with persistent person knowledge
Some checks failed
social-bot integration tests / Lint (flake8 + pep257) (pull_request) Failing after 29s
social-bot integration tests / Core integration tests (mock sensors, no GPU) (pull_request) Has been skipped
social-bot integration tests / Latency profiling (GPU, Orin) (pull_request) Has been cancelled
- SQLite database at /home/seb/saltybot-data/social_memory.db
- Tables: persons (name, embeddings, relationship_tier, notes), encounters (person_id, timestamp, transcript, mood)
- ROS2 services: /saltybot/social_memory/lookup, /update, /encounter, /stats
- Automatic tier promotion by encounter count (5→regular, 20→favorite)
- Quality-based promotion: 80%+ positive interactions required
- Custom greetings per relationship tier (stranger/regular/favorite)
- Encounter tracking: transcript, mood, engagement_score, positive_interaction flag
- Face embedding storage support for face recognition integration
- Relationship score computation from interaction history
- Thread-safe concurrent service calls
- Periodic stats publishing on /saltybot/social_memory/stats_update
- Backup/restore functionality with gzip compression
- Full database statistics: person counts by tier, total encounters, database size
- Configurable via social_memory.yaml: thresholds, backup dir, publish interval

Two packages:
- saltybot_social_memory: Service definitions (CMake, ROS2 services)
- saltybot_social_memory_node: Python service server with SQLite backend

Co-Authored-By: Claude Haiku 4.5 <noreply@anthropic.com>
2026-03-05 09:04:49 -05:00
sl-android
bd46aa5bc3 feat: Patrol mode - autonomous waypoint circuit (Issue #446)
Add autonomous patrol mode with idle behaviors and social integration:

Patrol Node:
- Nav2 /navigate_to_pose integration for autonomous navigation
- Idle behaviors at each waypoint (10-30s pan-tilt sweep + greetings)
- Person detection → pause patrol → social mode → resume
- Battery monitoring: automatic return to dock at <25%
- Teleop override: can be interrupted by joystick control
- Voice commands: 'patrol start/stop' via speech
- Randomized waypoint order for variety
- State publishing to /saltybot/patrol_state

Features:
- Waypoint loading from patrol_params.yaml (x, y, yaw coordinates)
- Random idle durations (configurable 10-30s)
- Pan-tilt sweep and greeting at each waypoint
- Person detection pause with timeout
- Automatic dock return when battery low
- Polling loop for state management
- Voice control integration

State Machine:
  IDLE ↔ NAVIGATE → IDLE_BEHAVIOR → (next waypoint)
           ↓
    [Person Detected] → PAUSE_PERSON
           ↓
    [Battery Low] → RETURN_TO_DOCK
           ↓
    [Teleop/Voice] → IDLE

Configuration:
- Waypoints with name, x, y, yaw
- Idle time range (min/max)
- Battery dock threshold (default 25%)
- Person detection pause timeout

Topics:
- /saltybot/patrol_state (String)
- /saltybot/speech_text (String)
- /saltybot/pan_tilt_cmd (String)
- /saltybot/person_detections (Detection2DArray)
- /saltybot/teleop_cmd (String)
- /saltybot/voice_cmd (String)

Co-Authored-By: Claude Haiku 4.5 <noreply@anthropic.com>
2026-03-05 09:04:10 -05:00
b950528079 Merge pull request 'feat: trick routines (Issue #431)' (#440) from sl-jetson/issue-431-tricks into main 2026-03-05 09:00:40 -05:00
d657696840 Merge pull request 'feat: system health monitor (Issue #408)' (#439) from sl-firmware/issue-408-health-monitor into main 2026-03-05 09:00:34 -05:00
27bf0efd94 Merge pull request 'feat: gamepad teleop (Issue #433)' (#438) from sl-controls/issue-433-gamepad-teleop into main 2026-03-05 08:59:29 -05:00
3b10d77208 Merge pull request 'feat: Android/Termux OpenClaw node (Issue #420)' (#437) from sl-android/issue-420-termux-openclaw into main 2026-03-05 08:59:24 -05:00
7c287e6f37 Merge pull request 'feat: LED strip controller (Issue #432)' (#436) from sl-mechanical/issue-432-led-controller into main 2026-03-05 08:59:19 -05:00
2203773377 Merge pull request 'feat: emotion engine (Issue #429)' (#435) from sl-webui/issue-429-emotion-engine into main 2026-03-05 08:59:14 -05:00
df0329d4f1 Merge pull request 'feat: audio direction estimator (Issue #430)' (#434) from sl-perception/issue-430-audio-direction into main 2026-03-05 08:59:09 -05:00
sl-android
eb37f160ce feat: Android/Termux OpenClaw node (Issue #420)
Add complete phone node infrastructure:

ROS2 Package (saltybot_phone):
- camera_node: /phone/camera/image_raw (320x240, 15 FPS)
- gps_node: /phone/gps (NavSatFix via termux-api)
- imu_node: /phone/imu (accelerometer data)
- openclaw_chat_node: Local LLM inference
  Subscribes /saltybot/speech_text
  Publishes /saltybot/chat_response
- ws_bridge: WebSocket bridge to Jetson Orin (:9090)

Phone Scripts:
- termux-bootstrap.sh: Complete Termux setup
- power-management.sh: Battery/thermal monitoring
- README.md: Setup documentation

Architecture:
- Termux on Android phone
- WiFi/USB tether to Jetson Orin
- ROS2 topic bridge for sensors
- Local LLM for on-device chat (Phi-2)
- Termux:Boot auto-start
- Power management for extended runtime

Co-Authored-By: Claude Haiku 4.5 <noreply@anthropic.com>
2026-03-05 08:55:55 -05:00
sl-android
df49eec21f feat: Android/Termux OpenClaw node (Issue #420)
Add complete phone node infrastructure:

ROS2 Package (saltybot_phone):
- camera_node: /phone/camera/image_raw (320x240, 15 FPS)
- gps_node: /phone/gps (NavSatFix via termux-api)
- imu_node: /phone/imu (accelerometer data)
- openclaw_chat_node: Local LLM inference
  Subscribes /saltybot/speech_text
  Publishes /saltybot/chat_response
- ws_bridge: WebSocket bridge to Jetson Orin (:9090)

Phone Scripts:
- termux-bootstrap.sh: Complete Termux setup
- power-management.sh: Battery/thermal monitoring
- README.md: Setup documentation

Architecture:
- Termux on Android phone
- WiFi/USB tether to Jetson Orin
- ROS2 topic bridge for sensors
- Local LLM for on-device chat (Phi-2)
- Termux:Boot auto-start
- Power management for extended runtime

Co-Authored-By: Claude Haiku 4.5 <noreply@anthropic.com>
2026-03-05 08:55:47 -05:00
54d4bd97f5 feat: LED strip controller (Issue #432)
NeoPixel status indicators with animated patterns:
- Breathing blue (idle state)
- Green pulse (follow mode)
- Red flash (error state)
- Rainbow animation (celebrate)
- Amber pulse (low battery <20%)
- White chase (search mode)

Features:
- Smooth transitions between states
- Configurable LED count (default 30) and GPIO pin (default GPIO18)
- Auto-dim brightness control
- Subscribes to battery, balance, social, emotion, health topics
- Publishes LED state JSON to /saltybot/led_state
- 30Hz update frequency with multiple animation patterns

Configuration:
- YAML-based hardware and pattern settings
- Per-pattern speed and color customization
- State priority system for concurrent status indicators

Co-Authored-By: Claude Haiku 4.5 <noreply@anthropic.com>
2026-03-05 08:55:41 -05:00
c00967f33d feat: trick routines action server (Issue #431)
Implement ROS2 node for fun behavior routines:
- spin: 360° rotation with audio
- dance: sway side-to-side + bob
- nod: head yes/no patterns
- celebrate: spin + look up + smile
- shy: back away + head down + bashful

Features:
- Voice command integration (/saltybot/voice_command)
- Timed sequences: /cmd_vel + pan_tilt controls
- Obstacle safety abort on /scan near-field detection
- 10s cooldown between tricks to prevent repetition
- Trick state publishing (/saltybot/trick_state)
- Background execution thread for non-blocking operation

Package structure:
- saltybot_tricks/trick_routines_node.py (main node)
- launch/tricks.launch.py (configurable launch)
- config/tricks_params.yaml (tuning parameters)
- test/test_tricks.py (module structure tests)

Co-Authored-By: Claude Haiku 4.5 <noreply@anthropic.com>
2026-03-05 08:54:06 -05:00
7000cbfbd3 feat: Add Issue #429 - Emotion engine with context-aware face expression selection
- ROS2 node subscribing to orchestrator state, battery, balance, person tracker, voice commands, health
- State-to-emotion mapping: navigation → excited, social → happy/curious, low battery → concerned, etc.
- Smooth emotion transitions (0.3–1.2s) with confidence tracking
- Idle behaviors: blink (~3s), look-around (~8s), breathing (sine wave)
- Social memory: familiarity-based warmth modifier (0.3–1.0) for known people
- Personality-aware responses: extroversion, playfulness, responsiveness, anxiety (0.0–1.0 configurable)
- Publishes /saltybot/emotion_state (JSON): emotion, intensity, confidence, expression name, context, idle_flags
- Configurable via emotion_engine.yaml: personality traits, battery thresholds, update rate
- Launch file: emotion_engine.launch.py

Co-Authored-By: Claude Haiku 4.5 <noreply@anthropic.com>
2026-03-05 08:53:56 -05:00
b8b29125d6 feat: trick routines action server (Issue #431)
Implement ROS2 node for fun behavior routines:
- spin: 360° rotation with audio
- dance: sway side-to-side + bob
- nod: head yes/no patterns
- celebrate: spin + look up + smile
- shy: back away + head down + bashful

Features:
- Voice command integration (/saltybot/voice_command)
- Timed sequences: /cmd_vel + pan_tilt controls
- Obstacle safety abort on /scan near-field detection
- 10s cooldown between tricks to prevent repetition
- Trick state publishing (/saltybot/trick_state)
- Background execution thread for non-blocking operation

Package structure:
- saltybot_tricks/trick_routines_node.py (main node)
- launch/tricks.launch.py (configurable launch)
- config/tricks_params.yaml (tuning parameters)
- test/test_tricks.py (module structure tests)

Co-Authored-By: Claude Haiku 4.5 <noreply@anthropic.com>
2026-03-05 08:53:55 -05:00
d7b1366d6c feat: Add audio direction estimator (Issue #430)
Implements GCC-PHAT beamforming for sound source localization via Jabra mic.
- GCC-PHAT cross-correlation for direction of arrival (DoA) estimation
- Voice activity detection (VAD) using RMS energy + smoothing
- Stereo/quadrophonic channel support (left/right/front/rear estimation)
- ROS2 publishers: /saltybot/audio_direction (Float32 bearing), /saltybot/audio_activity (Bool VAD)
- Configurable parameters: sample_rate, chunk_size, publish_hz, vad_threshold, gcc_phat_max_lag
- Integration-ready for multi-person tracker speaker tracking

Co-Authored-By: Claude Haiku 4.5 <noreply@anthropic.com>
2026-03-05 08:53:43 -05:00
d10c385bdc feat: Add Issue #429 - Emotion engine with context-aware face expression selection
- ROS2 node subscribing to orchestrator state, battery, balance, person tracker, voice commands, health
- State-to-emotion mapping: navigation → excited, social → happy/curious, low battery → concerned, etc.
- Smooth emotion transitions (0.3–1.2s) with confidence tracking
- Idle behaviors: blink (~3s), look-around (~8s), breathing (sine wave)
- Social memory: familiarity-based warmth modifier (0.3–1.0) for known people
- Personality-aware responses: extroversion, playfulness, responsiveness, anxiety (0.0–1.0 configurable)
- Publishes /saltybot/emotion_state (JSON): emotion, intensity, confidence, expression name, context, idle_flags
- Configurable via emotion_engine.yaml: personality traits, battery thresholds, update rate
- Launch file: emotion_engine.launch.py

Co-Authored-By: Claude Haiku 4.5 <noreply@anthropic.com>
2026-03-05 08:53:42 -05:00
1878b09eee feat: Add audio direction estimator (Issue #430)
Implements GCC-PHAT beamforming for sound source localization via Jabra mic.
- GCC-PHAT cross-correlation for direction of arrival (DoA) estimation
- Voice activity detection (VAD) using RMS energy + smoothing
- Stereo/quadrophonic channel support (left/right/front/rear estimation)
- ROS2 publishers: /saltybot/audio_direction (Float32 bearing), /saltybot/audio_activity (Bool VAD)
- Configurable parameters: sample_rate, chunk_size, publish_hz, vad_threshold, gcc_phat_max_lag
- Integration-ready for multi-person tracker speaker tracking

Co-Authored-By: Claude Haiku 4.5 <noreply@anthropic.com>
2026-03-05 08:53:25 -05:00
a9afcffc1d feat: LED strip controller (Issue #432)
NeoPixel status indicators with animated patterns:
- Breathing blue (idle state)
- Green pulse (follow mode)
- Red flash (error state)
- Rainbow animation (celebrate)
- Amber pulse (low battery <20%)
- White chase (search mode)

Features:
- Smooth transitions between states
- Configurable LED count (default 30) and GPIO pin (default GPIO18)
- Auto-dim brightness control
- Subscribes to battery, balance, social, emotion, health topics
- Publishes LED state JSON to /saltybot/led_state
- 30Hz update frequency with multiple animation patterns

Configuration:
- YAML-based hardware and pattern settings
- Per-pattern speed and color customization
- State priority system for concurrent status indicators

Co-Authored-By: Claude Haiku 4.5 <noreply@anthropic.com>
2026-03-05 08:53:12 -05:00
9683fd3685 feat: Add ROS2 system health monitor (Issue #408)
Implement centralized health monitoring node that:
- Subscribes to /saltybot/<node>/heartbeat from all tracked nodes
- Tracks expected nodes from YAML configuration
- Marks nodes DEAD if silent >5 seconds
- Triggers auto-restart via ros2 launch when nodes fail
- Publishes /saltybot/system_health JSON with full status
- Alerts face display on critical node failures

Features:
- Configurable heartbeat timeout (default 5s)
- Automatic dead node detection and restart
- System health JSON publishing (timestamp, uptime, node status, critical alerts)
- Face alert system for critical failures
- Rate-limited alerting to avoid spam
- Comprehensive monitoring config with critical/important node tiers

Package structure:
- saltybot_health_monitor: Main health monitoring node
- health_config.yaml: Configurable list of monitored nodes
- health_monitor.launch.py: Launch file with parameters
- Unit tests for heartbeat parsing and health status generation

Co-Authored-By: Claude Haiku 4.5 <noreply@anthropic.com>
2026-03-05 08:52:52 -05:00
c1b3a4368d Merge pull request 'feat: Nav2 SLAM integration (Issue #422)' (#428) from sl-controls/issue-422-nav2-slam into main 2026-03-04 23:59:32 -05:00
73263c1faa Merge pull request 'feat: remote monitoring relay (Issue #424)' (#427) from sl-jetson/issue-424-remote-monitor into main 2026-03-04 23:59:25 -05:00
524d2545ed Merge pull request 'feat: multi-person tracker (Issue #423)' (#426) from sl-perception/issue-423-multi-person into main 2026-03-04 23:59:17 -05:00
eda5154650 Merge pull request 'feat: Piper TTS service (Issue #421)' (#425) from sl-mechanical/issue-421-tts-service into main 2026-03-04 23:59:11 -05:00
ca95489b1d feat: Nav2 SLAM integration with RPLIDAR + RealSense (Issue #422)
Complete autonomous navigation stack for SaltyBot:
- SLAM Toolbox: online_async 2D LIDAR SLAM from RPLIDAR A1M8
- RealSense D435i: depth → pointcloud → costmap obstacle layer
- Nav2 stack: controllers, planners, behavior server, lifecycle management
- DWB planner: tuned for 20km/h (5.5 m/s) max velocity operation
- VESC odometry bridge: motor telemetry → nav_msgs/Odometry
- Costmap integration: LIDAR + depth for global + local costmaps
- TF tree: complete setup with base_link→laser, camera_link, odom
- Goal interface: /navigate_to_pose action for autonomous goals

Configuration:
- slam_toolbox_params: loop closure, scan matching, fine/coarse search
- nav2_params: AMCL, controllers, planners, behavior trees, lifecycle
- Global costmap: static layer + LIDAR obstacle layer + inflation
- Local costmap: rolling window + LIDAR + RealSense depth + inflation
- DWB planner: 20 vx samples, 40 theta samples, 1.7s horizon

Nodes and launch files:
- vesc_odometry_bridge: integrates motor RPM to wheel odometry
- nav2_slam_bringup: main integrated launch entry point
- depth_to_costmap: RealSense depth processing pipeline
- odometry_bridge: VESC telemetry bridge

Hardware support:
- RPLIDAR A1M8: 5.5 Hz, 12m range, 360° omnidirectional
- RealSense D435i: 15 Hz RGB-D, 200 Hz IMU, depth range 5m
- VESC Flipsky FSESC 4.20: dual motor control via UART
- SaltyBot 2-wheel balancer: 0.35m radius, hoverboard motors

Co-Authored-By: Claude Haiku 4.5 <noreply@anthropic.com>
2026-03-04 23:35:15 -05:00
16068aa3e4 feat: remote monitoring WebSocket relay (Issue #424)
Implement WebSocket telemetry relay with:
- 2Hz JSON aggregation (battery, motors, IMU, GPS, health, social)
- Port 9091 with token authentication
- msgpack compression option
- 5-minute circular history buffer
- Mobile-friendly responsive HTML UI
- Auto-reconnect WebSocket with fallback
- Critical alerts: low battery (< 15%), high temps, node crash
- Real-time dashboard with telemetry gauges

Features:
- Battery monitoring with SOC/voltage/current
- Motor command visualization (L/R duty)
- IMU attitude display (roll/pitch/yaw)
- CPU/GPU temperature with thresholds
- RAM/Disk usage progress bars
- GPS coordinates (lat/lon/alt)
- Social state (speaking, face tracking)
- Alert history with severity levels

Co-Authored-By: Claude Haiku 4.5 <noreply@anthropic.com>
2026-03-04 23:33:55 -05:00
33fcc9d935 feat: remote monitoring WebSocket relay (Issue #424)
Implement WebSocket telemetry relay with:
- 2Hz JSON aggregation (battery, motors, IMU, GPS, health, social)
- Port 9091 with token authentication
- msgpack compression option
- 5-minute circular history buffer
- Mobile-friendly responsive HTML UI
- Auto-reconnect WebSocket with fallback
- Critical alerts: low battery (< 15%), high temps, node crash
- Real-time dashboard with telemetry gauges

Features:
- Battery monitoring with SOC/voltage/current
- Motor command visualization (L/R duty)
- IMU attitude display (roll/pitch/yaw)
- CPU/GPU temperature with thresholds
- RAM/Disk usage progress bars
- GPS coordinates (lat/lon/alt)
- Social state (speaking, face tracking)
- Alert history with severity levels

Co-Authored-By: Claude Haiku 4.5 <noreply@anthropic.com>
2026-03-04 23:33:31 -05:00
31cfb9dcb9 feat: Add Issue #423 - Multi-person tracker with group handling + target priority
Implement multi-person tracking with:
- Track up to 10 people with persistent unique IDs
- Target priority: wake-word speaker > closest known > largest bbox
- Occlusion handoff with 3-second grace period
- Re-ID via face embedding (cosine similarity) + HSV color histogram
- Group detection and centroid calculation
- Lost target behavior: stop + rotate + SEARCHING state
- 15+ fps on Jetson Orin Nano Super
- PersonArray message publishing with active target tracking
- Configurable similarity thresholds and grace periods
- Unit tests for tracking, matching, priority, and re-ID

Co-Authored-By: Claude Haiku 4.5 <noreply@anthropic.com>
2026-03-04 23:33:18 -05:00
9e3e586fca feat: Issue #421 - Piper TTS service with queue + priority + Jabra output
- Central ROS2 TTS node using Piper (offline ONNX speech synthesis)
- Subscribe to /saltybot/tts_request (String messages) for TTS requests
- Priority queue management with interrupt capability
- Audio output to Jabra device via ALSA/PulseAudio
- Configurable voice, speed, pitch, and volume parameters
- Publish /saltybot/tts_state (idle/synthesizing/playing) for status tracking
- Preload Piper model on startup for faster synthesis
- Queue management with configurable max size (default 16)
- Non-blocking async playback via worker thread
- Complete ROS2 package with launch file and tests
2026-03-04 23:32:21 -05:00
a06821a8c8 Merge pull request 'feat: sensor feeds in HUD (Issue #413)' (#419) from sl-webui/issue-413-sensor-hud into main 2026-03-04 23:21:34 -05:00
eff69b2037 feat(hud): add sensor feeds (GPS, LIDAR, RealSense) (Issue #413)
Add tabbed sensor feed interface to the HUD center viewport:

GPS Map Panel:
- Fetches location data from /gps HTTP endpoint on port 8888
- Renders OpenStreetMap with real-time location marker
- Displays: coordinates, altitude, accuracy

LIDAR Point Cloud Visualization:
- Subscribes to /scan topic via rosbridge WebSocket
- 2D polar plot with grid, cardinal directions, forward indicator
- Real-time point cloud rendering with range statistics
- Displays: point count, max range (0-30m)

RealSense Dual Stream:
- Subscribes to /camera/color/image_raw/compressed (RGB)
- Subscribes to /camera/depth/image_rect_raw/compressed (Depth)
- Side-by-side canvas rendering with independent scaling
- FPS counter and resolution display

Tab System:
- 4-way view switching: 3D Model ↔ GPS ↔ LIDAR ↔ RealSense
- Persistent tab state, lazy initialization on demand
- Dark theme with cyan/orange accent colors
- Status indicators for each sensor (loading/error/ready)

Architecture:
- Browser native canvas for LIDAR visualization
- WebSocket rosbridge integration for sensor subscriptions
- Fetch API for HTTP GPS data (localhost:8888)
- Leaflet.js for OSM map rendering (CDN)
- 2s polling interval for GPS updates

Rosbridge Endpoints (assumes localhost:9090):
- /scan (sensor_msgs/LaserScan) — 1Hz LIDAR
- /camera/color/image_raw/compressed — RGB stream
- /camera/depth/image_rect_raw/compressed — Depth stream

HTTP Endpoints (assumes localhost:8888):
- GET /gps → { lat, lon, alt, accuracy, timestamp }

Integration:
- Preserves existing 3D HUD viewport and controls
- Left/right sidebars remain unchanged
- Bottom PID control bar operational
- Tab switching preserves center panel size/aspect ratio

Co-Authored-By: Claude Haiku 4.5 <noreply@anthropic.com>
2026-03-04 22:57:10 -05:00