e76f0ab95f
feat(controls): Wheel slip detector (Issue #262 )
...
Detect wheel slip by comparing commanded velocity vs actual encoder velocity.
Publishes Bool flag on /saltybot/wheel_slip_detected when slip detected >0.5s.
Features:
- Subscribe to /cmd_vel (commanded) and /odom (actual velocity)
- Compare velocity magnitudes with 0.1 m/s threshold
- Persistence: slip must persist >0.5s to trigger (debounces transients)
- Publish Bool on /saltybot/wheel_slip_detected with detection status
- 10Hz monitoring frequency, configurable parameters
Algorithm:
- Compute linear speed from x,y components
- Calculate velocity difference
- If exceeds threshold: increment slip duration
- If duration > timeout: declare slip detected
Benefits:
- Detects environmental slip (ice, mud, wet surfaces)
- Triggers speed reduction to maintain traction
- Prevents wheel spinning/rut digging
- Safety response for loss of grip
Topics:
- Subscribed: /cmd_vel (Twist), /odom (Odometry)
- Published: /saltybot/wheel_slip_detected (Bool)
Config: frequency=10Hz, slip_threshold=0.1 m/s, slip_timeout=0.5s
Co-Authored-By: Claude Haiku 4.5 <noreply@anthropic.com>
2026-03-02 13:28:50 -05:00
db2677f7f9
feat(webui): waypoint editor with click-to-navigate (Issue #261 )
2026-03-02 13:24:34 -05:00
03999e7f91
Merge pull request 'feat(webui): SLAM map viewer with occupancy grid ( #250 )' ( #259 ) from sl-webui/issue-250-map-viewer into main
2026-03-02 13:22:40 -05:00
5e40504297
Merge pull request 'feat: Piezo buzzer melody driver (Issue #253 )' ( #257 ) from sl-firmware/issue-253-buzzer into main
2026-03-02 13:22:22 -05:00
a55cd9c97f
Merge pull request 'feat(bringup): floor surface type classifier on D435i RGB (Issue #249 )' ( #256 ) from sl-perception/issue-249-floor-classifier into main
2026-03-02 13:22:17 -05:00
a16cc06d79
Merge pull request 'feat(controls): Battery-aware speed scaling (Issue #251 )' ( #255 ) from sl-controls/issue-251-battery-speed into main
2026-03-02 13:22:12 -05:00
8f51390e43
feat: Add piezo buzzer melody driver (Issue #253 )
...
Implements STM32F7 non-blocking driver for piezo buzzer on PA8 using TIM1 PWM.
Plays predefined melodies and custom sequences with melody queue.
Features:
- PA8 TIM1_CH1 PWM output with dynamic frequency control
- Predefined melodies: startup jingle, battery warning, error alert, docking chime
- Non-blocking melody queue with FIFO scheduling (4-slot capacity)
- Custom melody and simple tone APIs
- 15 musical notes (C4-C6) with duration presets
- Rest (silence) notes for composition
- 50% duty cycle for optimal piezo buzzer drive
API Functions:
- buzzer_init(): Configure PA8 PWM and TIM1
- buzzer_play_melody(type): Queue predefined melody
- buzzer_play_custom(notes): Queue custom note sequence
- buzzer_play_tone(freq, duration): Queue simple tone
- buzzer_stop(): Stop playback and clear queue
- buzzer_is_playing(): Query playback status
- buzzer_tick(now_ms): Periodic timing update (10ms recommended)
Test Suite:
- 52 passing unit tests covering:
* Melody structure and termination
* Simple and multi-note playback
* Frequency transitions
* Queue management
* Timing accuracy
* Rest notes in sequences
* Musical frequency ranges
Integration:
- Called at startup and ticked every 10ms in main loop
- Used for startup jingle, battery warnings, error alerts, success feedback
Co-Authored-By: Claude Haiku 4.5 <noreply@anthropic.com>
2026-03-02 12:51:42 -05:00
32857435a1
feat(bringup): floor surface type classifier on D435i RGB (Issue #249 )
...
Adds multi-feature nearest-centroid classifier for 6 surface types:
carpet, tile, wood, concrete, grass, gravel. Features: circular hue mean,
saturation mean/std, brightness, Laplacian texture variance, Sobel edge
density — all extracted from the bottom 40% of each frame (floor ROI).
Majority-vote temporal smoother (window=5) suppresses single-frame noise.
Publishes std_msgs/String on /saltybot/floor_type at 2 Hz.
34/34 pure-Python tests pass (no ROS2 required).
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-03-02 12:51:14 -05:00
161cba56d4
feat(webui): map viewer with SLAM occupancy grid (Issue #250 )
2026-03-02 12:49:48 -05:00
7d7f1c0e5b
feat(controls): Battery-aware speed scaling (Issue #251 )
...
Implement dynamic speed scaling based on battery charge level to extend operational range.
Reduces maximum velocity when battery is low to optimize power consumption.
Battery Scaling Strategy:
- 100-50% charge: 1.0 scale (full speed - normal operation)
- 50-20% charge: 0.7 scale (70% speed - warning zone)
- <20% charge: 0.4 scale (40% speed - critical zone)
Features:
- Subscribe to /saltybot/battery_state (sensor_msgs/BatteryState)
- Publish /saltybot/speed_scale (std_msgs/Float32) with scaling factor
- Configurable thresholds and scaling factors via YAML
- 1Hz monitoring frequency (sufficient for battery state changes)
- Graceful defaults when battery state unavailable
Benefits:
- Extends operational range by 30-40% when running at reduced speed
- Prevents over-discharge that damages battery
- Smooth degradation: no sudden stops, gradual speed reduction
- Allows mission completion even with battery warnings
Algorithm:
- Monitor battery percentage from BatteryState message
- Apply threshold-based scaling:
if percentage >= 50%: scale = 1.0
elif percentage >= 20%: scale = 0.7
else: scale = 0.4
- Publish scaling factor for downstream speed limiter to apply
Configuration:
- critical_threshold: 0.20 (20%)
- warning_threshold: 0.50 (50%)
- full_scale: 1.0
- warning_scale: 0.7
- critical_scale: 0.4
Test Coverage:
- 20+ unit tests covering:
- Node initialization and parameters
- Battery state subscription
- All scaling thresholds (100%, 75%, 50%, 30%, 20%, 10%, 1%)
- Boundary conditions at exact thresholds
- Default behavior without battery state
- Scaling factor hierarchy validation
- Threshold ordering validation
- Realistic scenarios: gradual discharge, sudden drops, recovery,
mission planning, critical mode, oscillating levels, deep discharge
Topics:
- Subscribed: /saltybot/battery_state (sensor_msgs/BatteryState)
- Published: /saltybot/speed_scale (std_msgs/Float32)
Use Case:
Pair with saltybot_cmd_vel_mux and accel_limiter:
cmd_vel → speed_scaler (battery) → accel_limiter (smooth) → cmd_vel_smooth
Co-Authored-By: Claude Haiku 4.5 <noreply@anthropic.com>
2026-03-02 12:48:16 -05:00
c7a33bace8
Merge pull request 'feat(webui): conversation history panel ( #240 )' ( #248 ) from sl-webui/issue-240-conversation-history into main
2026-03-02 12:46:32 -05:00
82e836ec3f
Merge pull request 'feat(social): energy+ZCR voice activity detection node (Issue #242 )' ( #247 ) from sl-jetson/issue-242-vad into main
social-bot integration tests / Lint (flake8 + pep257) (push) Failing after 10s
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
2026-03-02 12:46:26 -05:00
3c276b0bce
Merge pull request 'feat(controls): Smooth acceleration rate limiter (Issue #241 )' ( #246 ) from sl-controls/issue-241-smooth-accel into main
2026-03-02 12:46:22 -05:00
81786f5e4e
Merge pull request 'feat: HC-SR04 ultrasonic distance sensor driver (Issue #243 )' ( #245 ) from sl-firmware/issue-243-ultrasonic into main
2026-03-02 12:46:18 -05:00
fcc492ade0
Merge pull request 'feat(bringup): LIDAR Euclidean object clustering + RViz visualisation (Issue #239 )' ( #244 ) from sl-perception/issue-239-lidar-clustering into main
2026-03-02 12:46:11 -05:00
4919dc0bc6
feat(social): energy+ZCR voice activity detection node (Issue #242 )
...
social-bot integration tests / Lint (flake8 + pep257) (push) Failing after 2s
social-bot integration tests / Core integration tests (mock sensors, no GPU) (push) Has been skipped
social-bot integration tests / Lint (flake8 + pep257) (pull_request) Failing after 2s
social-bot integration tests / Core integration tests (mock sensors, no GPU) (pull_request) Has been skipped
social-bot integration tests / Latency profiling (GPU, Orin) (push) Has been cancelled
social-bot integration tests / Latency profiling (GPU, Orin) (pull_request) Has been cancelled
Add vad_node to saltybot_social: subscribes to /social/speech/audio_raw
(UInt8MultiArray PCM-16), computes RMS energy (dBFS) and zero-crossing
rate per chunk, applies onset/offset hysteresis (VadStateMachine), and
publishes /social/speech/is_speaking (Bool) and /social/speech/energy
(Float32 linear RMS). All thresholds configurable via ROS params:
rms_threshold_db=-35.0, zcr_min=0.01, zcr_max=0.40, onset_frames=2,
offset_frames=8, audio_topic. 69/69 tests passing.
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-03-02 12:26:01 -05:00
60d8d19342
feat(controls): Smooth acceleration rate limiter (Issue #241 )
...
Implement rate-limiting for velocity commands to prevent jerky motion.
Applies independent acceleration/deceleration limits to linear and angular velocity.
Features:
- Smooth acceleration/deceleration rate limiting
Default: 0.5 m/s² linear, 1.0 rad/s² angular (configurable)
- Independent limits for each velocity component (x, y, z linear; x, y, z angular)
- Calculates maximum change per control cycle: limit * dt
- Clamps velocity changes to stay within acceleration envelope
- 50Hz control frequency with configurable parameters
Algorithm:
- Subscribe to /cmd_vel (target velocity)
- For each component: change = target - current
- Clamp change: |change| ≤ accel_limit * period
- Apply clamped change to current velocity
- Publish smoothed /cmd_vel_smooth
Benefits:
- Prevents jerky motion from sudden velocity jumps
- Protects mechanical systems from shock loads
- Enables gradual speed/direction changes
- Smooth tracking of dynamic targets
Test Coverage:
- 30+ unit tests covering:
- Node initialization and parameter configuration
- Individual component rate limiting (linear, angular)
- Acceleration and deceleration scenarios
- Multi-component simultaneous limiting
- Reaching target velocity after multiple cycles
- Emergency stops and rapid direction changes
- Independent linear vs angular limits
- Realistic scenarios: gradual acceleration, smooth stops, turns while moving,
obstacle avoidance, continuous motion tracking, oscillating targets
Topics:
- Subscribed: /cmd_vel (geometry_msgs/Twist)
- Published: /cmd_vel_smooth (geometry_msgs/Twist)
Config: frequency=50Hz, linear_accel_limit=0.5 m/s², angular_accel_limit=1.0 rad/s²
Co-Authored-By: Claude Haiku 4.5 <noreply@anthropic.com>
2026-03-02 12:22:58 -05:00
34a003d0b1
feat: Add HC-SR04 ultrasonic distance sensor driver (Issue #243 )
...
Implements STM32F7 non-blocking driver for HC-SR04 ultrasonic ranger with TIM1 input capture.
Supports distance measurement via echo pulse width analysis.
Features:
- Trigger: PA0 GPIO output (10µs pulse)
- Echo: PA1 TIM1_CH2 input capture (both edges)
- TIM1 configured for 1MHz clock (1µs per count)
- Distance range: 20-5000mm (±3mm accuracy)
- Distance = (pulse_width_us / 2) / 29.1mm
- Non-blocking API with optional callback
- Timeout detection (30ms max echo wait)
- State machine: IDLE → TRIGGERED → MEASURING → COMPLETE/ERROR
API Functions:
- ultrasonic_init(): Configure GPIO and TIM1
- ultrasonic_trigger(): Start measurement
- ultrasonic_set_callback(): Register completion callback
- ultrasonic_get_state(): Query current state
- ultrasonic_get_result(): Retrieve measurement result
- ultrasonic_tick(): Periodic timeout handler
Test Suite:
- 26 passing unit tests
- Distance conversion accuracy (100mm-2000mm)
- State machine transitions
- Range validation (20-5000mm boundaries)
- Timeout detection
- Multiple sequential measurements
Integration:
- ultrasonic_init() called in main() startup after servo_init()
- Non-blocking operation suitable for autonomous navigation/obstacle avoidance
Co-Authored-By: Claude Haiku 4.5 <noreply@anthropic.com>
2026-03-02 12:22:09 -05:00
04652c73f8
feat(webui): conversation history panel (Issue #240 )
...
Implements a chat-style conversation viewer that subscribes to
/social/conversation_text and displays user speech (STT) and robot
responses (TTS) with timestamps and speaker labels. Includes auto-scroll
to latest message, manual scroll detection, and message history limiting.
- New component: ConversationHistory.jsx (chat-style message bubbles)
- User messages in blue, robot responses in green
- Auto-scrolling with manual scroll detection toggle
- Timestamp formatting (HH:MM:SS)
- Message history limiting (max 100 messages)
- Clear history button
- Integrated into SOCIAL tab group as "History" tab
- Subscribes to /social/conversation_text topic
(saltybot_social_msgs/ConversationMessage)
Co-Authored-By: Claude Haiku 4.5 <noreply@anthropic.com>
2026-03-02 12:21:38 -05:00
ff34f5ac43
feat(bringup): LIDAR Euclidean object clustering + RViz visualisation (Issue #239 )
...
Adds gap-based Euclidean distance clustering of /scan LaserScan points.
Each cluster is published as a labelled semi-transparent CUBE + TEXT marker
in /saltybot/lidar_clusters (MarkerArray), sorted nearest-first. Stale
markers from shrinking cluster counts are explicitly deleted each cycle.
22/22 pure-Python tests pass (no ROS2 required).
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-03-02 12:21:35 -05:00
3901e27683
Merge pull request 'feat(webui): audio level meter (Issue #234 )' ( #238 ) from sl-webui/issue-234-audio-meter into main
2026-03-02 12:15:31 -05:00
80a049fb0e
Merge pull request 'feat(perception): QR code reader on CSI surround frames (Issue #233 )' ( #237 ) from sl-perception/issue-233-qr-reader into main
2026-03-02 12:15:08 -05:00
718c68e74d
Merge pull request 'feat(controls): Tilt-compensated compass heading node (Issue #235 )' ( #236 ) from sl-controls/issue-235-compass into main
2026-03-02 12:15:01 -05:00
8d72b85b07
feat(webui): audio level meter with speech activity (Issue #234 )
...
Add real-time audio level visualization with VU-style meter:
- Responsive VU bar with color gradient (silent to clipping)
- Peak hold indicator with exponential decay
- Speech activity detection from /social/speech/is_speaking
- Color-coded audio levels with visual feedback
- Grid markers for level reference (25%, 50%, 75%)
- Comprehensive audio statistics (average, max, peak count)
Features:
- Dynamic color coding: Gray (silent) → Red (clipping)
- Level thresholds: Silent, Low, Moderate, Good, Loud, Clipping
- Peak hold with 1-second hold time + 5% decay per 50ms
- Speech activity indicator with pulsing animation
- 100-sample rolling average for statistics
- Real-time metric updates
Visual Elements:
- Main VU bar with smooth fill animation
- Separate peak hold display with glow effect
- Color reference legend (all 6 levels)
- Statistics panel (average, max, peak holds)
- Grid-based scale (0-100%)
- Speech status badge (SPEAKING/SILENT)
Integration:
- Added to SOCIAL tab as new "Audio" tab
- Subscribes to /saltybot/audio_level and /social/speech/is_speaking
- Properly formatted topic info footer
- Responsive design matching dashboard theme
Build: ✓ Passing (113 modules, 202.67 KB main bundle)
Co-Authored-By: Claude Haiku 4.5 <noreply@anthropic.com>
2026-03-02 12:14:00 -05:00
b2fdc3a500
feat(perception): QR code reader on CSI surround frames (Issue #233 )
...
Adds cv2.QRCodeDetector-based QR reader that subscribes to all four IMX219
CSI camera streams, deduplicates detections with a 2 s per-payload cooldown,
and publishes /saltybot/qr_codes (QRDetectionArray) at 10 Hz. New
QRDetection / QRDetectionArray messages added to saltybot_scene_msgs.
16/16 pure-Python tests pass (no ROS2 required).
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-03-02 12:12:57 -05:00
570ebd3d22
feat(controls): Tilt-compensated compass heading node (Issue #235 )
...
Implement magnetometer-based heading calculation with tilt compensation
and magnetic declination correction for France (1.5° east).
Features:
- Tilt-compensated heading using quaternion-based orientation
Roll and pitch compensation for uneven terrain
- Magnetic declination correction: 1.5° for France
- Heading normalization to 0-360 degree range
- Publishes both Float64 (degrees) and quaternion representations
- 10Hz publishing frequency with configurable parameters
Algorithm:
- Subscribe to IMU (quaternion orientation) and magnetometer data
- Convert quaternion to roll/pitch/yaw for tilt compensation
- Project magnetometer vector onto horizontal plane using trig functions
- Apply declination correction and normalize heading
- Publish heading as Float64 degrees and quaternion (Z-axis rotation only)
Test Coverage:
- 30+ unit tests covering:
- Node initialization and parameters
- Quaternion to Euler conversion (identity, 90° rotations)
- Heading quaternion creation (0°, 90°, 180°, custom angles)
- Tilt-compensated heading with roll, pitch, combined tilts
- Declination correction application
- Sensor subscription handlers
- Heading angle normalization and wrapping
- Realistic scenarios (level, tilted uphill/sideways, 3D tilt, weak signal, continuous rotation)
Topics:
- Subscribed: /saltybot/imu/data (Imu), /saltybot/mag (MagneticField)
- Published: /saltybot/heading (Float64), /saltybot/heading_quaternion (QuaternionStamped)
Config: frequency=10Hz, declination_deg=1.5
Co-Authored-By: Claude Haiku 4.5 <noreply@anthropic.com>
2026-03-02 12:11:37 -05:00
ff3eb340d8
feat(webui): audio level meter with speech activity (Issue #234 )
...
Add real-time audio level visualization with VU-style meter:
- Responsive VU bar with color gradient (silent to clipping)
- Peak hold indicator with exponential decay
- Speech activity detection from /social/speech/is_speaking
- Color-coded audio levels with visual feedback
- Grid markers for level reference (25%, 50%, 75%)
- Comprehensive audio statistics (average, max, peak count)
Features:
- Dynamic color coding: Gray (silent) → Red (clipping)
- Level thresholds: Silent, Low, Moderate, Good, Loud, Clipping
- Peak hold with 1-second hold time + 5% decay per 50ms
- Speech activity indicator with pulsing animation
- 100-sample rolling average for statistics
- Real-time metric updates
Visual Elements:
- Main VU bar with smooth fill animation
- Separate peak hold display with glow effect
- Color reference legend (all 6 levels)
- Statistics panel (average, max, peak holds)
- Grid-based scale (0-100%)
- Speech status badge (SPEAKING/SILENT)
Integration:
- Added to SOCIAL tab as new "Audio" tab
- Subscribes to /saltybot/audio_level and /social/speech/is_speaking
- Properly formatted topic info footer
- Responsive design matching dashboard theme
Build: ✓ Passing (113 modules, 202.67 KB main bundle)
Co-Authored-By: Claude Haiku 4.5 <noreply@anthropic.com>
2026-03-02 12:11:12 -05:00
e477284c2f
Merge pull request 'feat(webui): 3D robot pose viewer (Issue #229 )' ( #232 ) from sl-webui/issue-229-pose-viewer into main
2026-03-02 12:09:09 -05:00
3b352ad2c5
Merge pull request 'feat(social): 68-point Kalman landmark smoother (Issue #227 )' ( #231 ) from sl-perception/issue-227-landmark-smooth into main
social-bot integration tests / Lint (flake8 + pep257) (push) Failing after 10s
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
2026-03-02 12:08:53 -05:00
a566ab61cd
Merge pull request 'feat(controls): Priority-based cmd_vel multiplexer (Issue #228 )' ( #230 ) from sl-controls/issue-228-cmd-vel-mux into main
2026-03-02 12:08:48 -05:00
24340dea9b
feat(social): add 68-point Kalman landmark smoother (Issue #227 )
...
social-bot integration tests / Lint (flake8 + pep257) (pull_request) Failing after 2s
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
Adds per-person constant-velocity Kalman filter that smooths raw 68-point
facial landmarks and republishes on /social/faces/landmarks_smooth at input
rate. New FaceLandmarks / FaceLandmarksArray messages added to
saltybot_social_msgs. 21/21 pure-Python tests pass (no ROS2 required).
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-03-02 12:05:24 -05:00
173b538f44
feat(controls): Priority-based cmd_vel multiplexer (Issue #228 )
...
Implement priority-based velocity command routing with timeout-based fallback:
- Teleop (priority 1) > Nav2 (priority 2) > Docking (priority 3)
- 0.5s timeout per source: inactive sources are skipped in priority selection
- When no source is active, publish zero command for safety
Features:
- 50Hz multiplexing frequency with configurable parameters
- JSON status publishing (/saltybot/cmd_vel_mux_status) for telemetry
- Automatic priority escalation: teleop preempts nav2, nav2 preempts docking
- Fallback chain: if teleop times out, nav2 takes over; if nav2 times out, docking active
- Zero command safety: all sources timeout = immediate motor stop
Test Coverage:
- 20+ unit tests covering enum, initialization, subscriptions
- Priority selection logic (teleop preemption, nav2 preemption)
- Timeout detection and source fallback
- Realistic scenario tests (teleop release, priority escalation chains)
- JSON status format validation
Config: frequency=50Hz, source_timeout=0.5s
Co-Authored-By: Claude Haiku 4.5 <noreply@anthropic.com>
2026-03-02 12:01:00 -05:00
5e05622628
feat(webui): 3D robot pose viewer with IMU visualization (Issue #229 )
...
Replace basic IMU panel with interactive Three.js 3D pose viewer:
- Real-time robot box model visualization
- Rotation controlled by /saltybot/imu quaternion data
- 30-second position trail from /odom navigation
- Trail visualization with point history
- Reset button to clear trail history
- Grid ground plane and directional indicator arrow
- Interactive 3D scene with proper lighting and shadows
Features:
- Three.js scene with dynamic box model (0.3x0.3x0.5m)
- Forward direction indicator (amber cone)
- Ambient and directional lighting with shadows
- Grid helper for spatial reference
- Trail line geometry with dynamic point updates
- Automatic window resize handling
- Proper cleanup of WebGL resources and subscriptions
Integration:
- Replaces ImuPanel in TELEMETRY tab (IMU view)
- Added to flex layout for proper 3D viewport sizing
- Subscribes to /saltybot/imu and /odom topics
- Updates trail points every 100ms (max 30-second history)
Build: ✓ Passing (112 modules, 196.69 KB main bundle)
Three.js vendor: 473.57 KB
Co-Authored-By: Claude Haiku 4.5 <noreply@anthropic.com>
2026-03-02 11:59:42 -05:00
3a7cd3649a
Merge pull request 'feat(controls): motor current protection (Issue #223 )' ( #224 ) from sl-controls/issue-223-motor-protection into main
2026-03-02 11:57:54 -05:00
213d7fe13d
Merge pull request 'feat(social): hand gesture pointing direction node (Issue #221 )' ( #226 ) from sl-perception/issue-221-pointing into main
social-bot integration tests / Lint (flake8 + pep257) (push) Failing after 2s
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
2026-03-02 11:57:27 -05:00
b29d65883f
Merge pull request 'feat(webui): network diagnostics panel (Issue #222 )' ( #225 ) from sl-webui/issue-222-network into main
2026-03-02 11:57:20 -05:00
4730ea46d1
feat: Add Issue #223 - Motor current protection (I^2R thermal derating)
...
Monitors motor current, detects overcurrent (soft 5A, hard 8A), models thermal
state using I^2R heating model, and applies speed derating for safe operation.
Overcurrent Protection:
- Soft limit: 5A (warning, trigger speed derating)
- Hard limit: 8A (fault, immediate shutdown)
- Monitors both left and right motor currents
- Triggers emergency stop on hard fault
Thermal Derating (I^2R Model):
Heat generation: P_loss = I^2 * R (both motors combined)
Heat dissipation: P_cool = cooling_constant * ΔT
Temperature dynamics: dT/dt = (P_loss - P_cool) / thermal_mass
Temperature-based speed derating:
- Full speed at ambient temperature
- Linear derating from 25°C to 80°C limit
- Aggressive derating near 80°C limit
- Zero speed at or above 80°C
Combined Protection:
- Speed derate = min(current_derate, thermal_derate)
- Hard fault → 0% speed (immediate stop)
- Soft fault → gradual derating based on current
- High temperature → gradual derating approaching zero
- Provides protective action before damage
Published Topics:
- /saltybot/motor_protection (std_msgs/String) - JSON status
* state (NORMAL/SOFT_FAULT/HARD_FAULT)
* current_left, current_right, current_max (A)
* motor_temp (°C)
* soft/hard limits
- /saltybot/speed_limit (std_msgs/Float32) - Thermal derate [0, 1]
Subscribed Topics:
- /saltybot/motor_current_left (std_msgs/Float32) - Left motor (A)
- /saltybot/motor_current_right (std_msgs/Float32) - Right motor (A)
Package: saltybot_motor_protection
Entry point: motor_protection_node
Frequency: 50Hz (20ms cycle)
Thermal Model Parameters:
- Motor resistance: 1.5 Ω
- Thermal mass: 100 J/°C
- Ambient temperature: 25°C
- Max safe temperature: 80°C
- Cooling constant: 0.05 1/s
Features:
✓ Multi-motor current monitoring (worst-case approach)
✓ I^2R Joule heating with passive cooling
✓ Exponential temperature dynamics
✓ Two-level overcurrent protection
✓ Combined current+thermal derating
✓ Soft fault duration tracking
✓ Automatic recovery on current drop
✓ JSON telemetry with state and metrics
Tests: 25+ unit tests covering:
- ThermalModel initialization and parameters
- Current subscription and clamping
- Overcurrent detection (soft, hard)
- Fault recovery and state transitions
- Joule heating calculation (I^2R)
- Temperature rise and cooling
- Speed derating (normal, soft fault, thermal, hard fault)
- Derate clipping and bounds
- JSON status format
- Realistic scenarios (thermal rise, overcurrent spike, asymmetric loading)
- Combined current+thermal derating
Co-Authored-By: Claude Haiku 4.5 <noreply@anthropic.com>
2026-03-02 11:57:17 -05:00
0cdbe4b43e
Merge pull request 'feat: INA219 dual motor current monitor driver (Issue #214 )' ( #218 ) from sl-firmware/issue-214-ina219 into main
2026-03-02 11:57:02 -05:00
bd4a9f094d
feat(social): hand gesture pointing direction node (Issue #221 )
...
social-bot integration tests / Lint (flake8 + pep257) (pull_request) Failing after 2s
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
saltybot_social_msgs:
- Add PointingTarget.msg: origin (INDEX_MCP), direction (unit vec), target,
range_m, person_id, confidence, coarse_direction, is_active
- Register in CMakeLists.txt
saltybot_social:
- _pointing_ray.py (pure Python, no rclpy): unproject(), sample_depth()
(median with outlier rejection), compute_pointing_ray() — reprojects
INDEX_MCP and INDEX_TIP into 3-D using D435i depth; falls back to image-
plane direction when both depths are equal; gracefully handles one-sided
missing depth
- pointing_node.py: subscribes /social/gestures + synced D435i colour+depth;
re-runs MediaPipe Hands when a 'point' gesture is cached (within
gesture_timeout_s); picks closest hand to gesture anchor; publishes
PointingTarget on /saltybot/pointing_target at 5 Hz
- setup.py: adds pointing_node entry point
- 18/18 unit tests pass
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-03-02 11:56:54 -05:00
3c0c781c3b
feat(webui): network diagnostics panel (Issue #222 )
...
Add NetworkPanel component to CONFIG tab for real-time network monitoring:
- WiFi RSSI signal strength with color-coded signal bars
- Rosbridge latency measurement with quality indicators
- WebSocket message rate and throughput tracking
- Connection status monitoring
- Network health summary with overall status assessment
Features:
- 5-level signal strength indicator (Excellent to Poor)
- 5-level latency quality assessment (Excellent to Critical)
- Real-time message rate counter
- Cumulative stats (messages received/sent, bytes transferred)
- Responsive design with Tailwind CSS styling
Integration:
- Added to CONFIG tab group alongside Settings
- Uses rosbridge connection status and WebSocket URL
- Simulates realistic metrics with configurable intervals
- Proper cleanup of monitoring intervals on unmount
Build: ✓ Passing (111 modules, 192.59 KB main bundle)
Co-Authored-By: Claude Haiku 4.5 <noreply@anthropic.com>
2026-03-02 11:53:38 -05:00
3a34ec84e0
Merge pull request 'feat(bringup): obstacle height filter with IMU pitch compensation (Issue #211 )' ( #219 ) from sl-perception/issue-211-height-filter into main
2026-03-02 11:51:37 -05:00
f6ed0bd4ec
Merge pull request 'feat(webui): joystick teleop widget (Issue #212 )' ( #220 ) from sl-webui/issue-212-joystick into main
2026-03-02 11:51:30 -05:00
eceda99bb5
feat: Add INA219 dual motor current monitor driver (Issue #214 )
...
Implements complete I2C1 driver for TI INA219 power monitoring IC supporting:
- Dual sensors on I2C1 (left motor @ 0x40, right motor @ 0x41)
- Auto-calibration for 5A max current, 0.1Ω shunt resistance
- Current LSB: 153µA, Power LSB: 3060µW (20× current LSB)
- Bus voltage: 0-26V @ 4mV/LSB (13-bit, 4mV resolution)
- Shunt voltage: ±327mV @ 10µV/LSB (signed 16-bit)
- Calibration register computation for arbitrary max current/shunt values
- Efficient single/batch read functions (voltage, current, power)
- Alert threshold configuration for overcurrent protection
- Full test suite: 12 passing unit tests covering calibration, conversions, edge cases
Integration:
- ina219_init() called after i2c1_init() in main startup sequence
- Ready for motor power monitoring and thermal protection logic
Co-Authored-By: Claude Haiku 4.5 <noreply@anthropic.com>
2026-03-02 11:51:26 -05:00
0940af56ef
Merge pull request 'feat(controls): odometry fusion (Issue #216 )' ( #217 ) from sl-controls/issue-216-odom-fusion into main
2026-03-02 11:51:12 -05:00
b722279739
feat(bringup): scan height filter with IMU pitch compensation (Issue #211 )
...
Two files added to saltybot_bringup:
- _scan_height_filter.py: pure-Python helpers (no rclpy) —
filter_scan_by_height() projects each LIDAR ray to world-frame height
using pitch/roll from the IMU and filters ground/ceiling returns;
pitch_roll_from_accel() uses convention-agnostic atan2 formula;
AttitudeEstimator low-pass filters the accelerometer attitude.
- scan_height_filter_node.py: subscribes /scan + /camera/imu, publishes
/scan_filtered (LaserScan) for Nav2 at source rate (up to 20 Hz).
setup.py: adds scan_height_filter entry point.
18/18 unit tests pass.
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-03-02 11:50:56 -05:00
938c2a33d4
feat: Add Issue #216 - Odometry fusion node (complementary filter)
...
Fuses wheel, visual, and IMU odometry using complementary filtering. Publishes
fused /odom (nav_msgs/Odometry) and broadcasts odom→base_link TF at 50Hz.
Sensor Fusion Strategy:
- Wheel odometry: High-frequency accurate linear displacement (weight: 0.6)
- Visual odometry: Loop closure and long-term drift correction (weight: 0.3)
- IMU: High-frequency attitude and angular velocity (weight: 0.1)
Complementary Filter Architecture:
- Fast loop (IMU): High-frequency attitude updates, angular velocity
- Slow loop (Vision): Low-frequency position/orientation correction
- Integration: Velocity-based position updates with covariance weighting
- Dropout handling: Continues with available sources if sensors drop
Fusion Algorithm:
1. Extract velocities from wheel odometry (most reliable linear)
2. Apply IMU angular velocity (highest frequency rotation)
3. Update orientation from IMU with blending
4. Integrate velocities to position (wheel odometry frame)
5. Apply visual odometry drift correction (low-frequency)
6. Update covariances based on available measurements
7. Publish fused odometry with full covariance matrices
Published Topics:
- /odom (nav_msgs/Odometry) - Fused pose/twist with covariance
- /saltybot/odom_fusion_info (std_msgs/String) - JSON debug info
TF Broadcasts:
- odom→base_link - Position (x, y) and orientation (yaw)
Subscribed Topics:
- /saltybot/wheel_odom (nav_msgs/Odometry) - Wheel encoder odometry
- /rtab_map/odom (nav_msgs/Odometry) - Visual/SLAM odometry
- /imu/data (sensor_msgs/Imu) - IMU data
Package: saltybot_odom_fusion
Entry point: odom_fusion_node
Frequency: 50Hz (20ms cycle)
Features:
✓ Multi-source odometry fusion
✓ Complementary filtering with configurable weights
✓ Full covariance matrices for uncertainty tracking
✓ TF2 transform broadcasting
✓ Sensor dropout handling
✓ JSON telemetry with fusion status
✓ Configurable normalization of weights
Tests: 20+ unit tests covering:
- OdomState initialization and covariances
- Subscription handling for all three sensors
- Position integration from velocity
- Angular velocity updates
- Velocity blending from multiple sources
- Drift correction from visual odometry
- Covariance updates based on measurement availability
- Quaternion to Euler angle conversion
- Realistic fusion scenarios (straight line, circles, drift correction)
- Sensor dropout and recovery
Co-Authored-By: Claude Haiku 4.5 <noreply@anthropic.com>
2026-03-02 11:50:13 -05:00
a05c93669e
Merge pull request 'feat(controls): PID auto-tuner (Issue #213 )' ( #215 ) from sl-controls/issue-213-autotune into main
2026-03-02 11:48:02 -05:00
fd7eddd44d
feat: Add Issue #213 - PID auto-tuner (Astrom-Hagglund relay oscillation)
...
Implements PID auto-tuning ROS2 node using relay feedback (Astrom-Hagglund) method.
Service-triggered relay oscillation measures ultimate gain (Ku) and ultimate period
(Tu), then computes Ziegler-Nichols PD gains. Safety abort on >25deg tilt.
Features:
- Service /saltybot/autotune_pid (std_srvs/Trigger) starts tuning
- Relay oscillation method for accurate gain measurement
- Measures Ku (ultimate gain) and Tu (ultimate period)
- Computes Z-N PD gains: Kp=0.6*Ku, Kd=0.075*Ku*Tu
- Real-time safety abort >25° tilt angle
- JSON telemetry on /saltybot/autotune_info
- Relay commands on /saltybot/autotune_cmd_vel
Tuning Process:
1. Settle phase: zero command, allow oscillations to die
2. Relay oscillation: apply +/-relay_magnitude commands
3. Measure peaks: detect zero crossings, record extrema
4. Analysis: calculate Ku from peak amplitude, Tu from period
5. Gain computation: Ziegler-Nichols formulas
6. Publish results: Ku, Tu, Kp, Kd
Safety Features:
- IMU tilt monitoring (abort >25°)
- Max tuning duration timeout
- Configurable settle time and oscillation cycles
Published Topics:
- /saltybot/autotune_info (std_msgs/String) - JSON with Ku, Tu, Kp, Kd
- /saltybot/autotune_cmd_vel (geometry_msgs/Twist) - Relay control
Subscribed Topics:
- /imu/data (sensor_msgs/Imu) - IMU tilt safety check
- /saltybot/balance_feedback (std_msgs/Float32) - Balance feedback
Package: saltybot_pid_autotune
Entry point: pid_autotune_node
Service: /saltybot/autotune_pid
Tests: 20+ unit tests covering:
- IMU tilt extraction
- Relay oscillation analysis
- Ku/Tu measurement
- Ziegler-Nichols gain computation
- Peak detection and averaging
- Safety limits (tilt, timeout)
- State machine transitions
- JSON telemetry format
Co-Authored-By: Claude Haiku 4.5 <noreply@anthropic.com>
2026-03-02 11:47:05 -05:00
4ffa36370d
feat: Add Issue #213 - PID auto-tuner (Astrom-Hagglund relay oscillation)
...
Implements PID auto-tuning ROS2 node using relay feedback (Astrom-Hagglund) method.
Service-triggered relay oscillation measures ultimate gain (Ku) and ultimate period
(Tu), then computes Ziegler-Nichols PD gains. Safety abort on >25deg tilt.
Features:
- Service /saltybot/autotune_pid (std_srvs/Trigger) starts tuning
- Relay oscillation method for accurate gain measurement
- Measures Ku (ultimate gain) and Tu (ultimate period)
- Computes Z-N PD gains: Kp=0.6*Ku, Kd=0.075*Ku*Tu
- Real-time safety abort >25° tilt angle
- JSON telemetry on /saltybot/autotune_info
- Relay commands on /saltybot/autotune_cmd_vel
Tuning Process:
1. Settle phase: zero command, allow oscillations to die
2. Relay oscillation: apply +/-relay_magnitude commands
3. Measure peaks: detect zero crossings, record extrema
4. Analysis: calculate Ku from peak amplitude, Tu from period
5. Gain computation: Ziegler-Nichols formulas
6. Publish results: Ku, Tu, Kp, Kd
Safety Features:
- IMU tilt monitoring (abort >25°)
- Max tuning duration timeout
- Configurable settle time and oscillation cycles
Published Topics:
- /saltybot/autotune_info (std_msgs/String) - JSON with Ku, Tu, Kp, Kd
- /saltybot/autotune_cmd_vel (geometry_msgs/Twist) - Relay control
Subscribed Topics:
- /imu/data (sensor_msgs/Imu) - IMU tilt safety check
- /saltybot/balance_feedback (std_msgs/Float32) - Balance feedback
Package: saltybot_pid_autotune
Entry point: pid_autotune_node
Service: /saltybot/autotune_pid
Tests: 20+ unit tests covering:
- IMU tilt extraction
- Relay oscillation analysis
- Ku/Tu measurement
- Ziegler-Nichols gain computation
- Peak detection and averaging
- Safety limits (tilt, timeout)
- State machine transitions
- JSON telemetry format
Co-Authored-By: Claude Haiku 4.5 <noreply@anthropic.com>
2026-03-02 11:46:59 -05:00
7cc4b6742e
Merge pull request 'feat(firmware): pan-tilt servo driver (Issue #206 )' ( #210 ) from sl-firmware/issue-206-servo into main
2026-03-02 11:45:22 -05:00