sl-webui 6d6909d9d9 feat: Voice command router (Issue #491)
Natural language voice command routing with fuzzy matching for speech variations.

Supported Commands:
- Follow me / Come with me
- Stop / Halt / Freeze
- Go home / Return to dock / Charge
- Patrol / Autonomous mode
- Come here / Approach
- Sit / Sit down
- Spin / Rotate / Turn around
- Dance / Groove
- Take photo / Picture / Smile
- What's that / Identify / Recognize
- Battery status / Battery level

Features:
- Fuzzy matching (rapidfuzz token_set_ratio) with 75% threshold
- Multiple pattern support per command for natural variations
- Three routing types: velocity (/cmd_vel), actions (/saltybot/action_command), services
- Command monitoring via /saltybot/voice_command
- Graceful handling of unrecognized speech

Architecture:
- Input: /saltybot/speech/transcribed_text (lowercase text)
- Fuzzy match against 11 command groups with 40+ patterns
- Route to: /cmd_vel (velocity), /saltybot/action_command (actions), or services

Files:
- saltybot_voice_router_node.py: Main router with fuzzy matching
- launch/voice_router.launch.py: Launch configuration
- VOICE_ROUTER_README.md: Usage documentation

Dependencies:
- rapidfuzz: Fuzzy string matching for natural speech handling
- rclpy, std_msgs, geometry_msgs: ROS2 core

Performance: <100ms per command (fuzzy matching + routing)

Co-Authored-By: Claude Haiku 4.5 <noreply@anthropic.com>
2026-03-05 17:05:02 -05:00

4.6 KiB

TTS Personality Engine (Issue #494)

Context-aware text-to-speech with emotion-based rate/pitch modulation for SaltyBot.

Features

Context-Aware Responses

  • Time-based greetings: Different greetings for morning, afternoon, evening, night
  • Person recognition: Uses detected person names in responses
  • Emotion-driven speech: Adjusts rate and pitch based on current emotion state
  • Personality identity: Configurable personality name (default: "Luna")

Priority Queue Management

  • Safety (Priority 3): Emergency/safety messages (immediate)
  • Social (Priority 2): Greetings and interactions (high priority)
  • Idle (Priority 1): Commentary and chatter (medium priority)
  • Normal (Priority 0): Default messages

Emotion-Based Rate/Pitch Modulation

  • Happy: Faster (1.1x) with higher pitch (1.15x)
  • Sad: Slower (0.9x) with lower pitch (0.85x)
  • Neutral: Normal speech (1.0x)

Architecture

Node: tts_personality_node

Subscribes

  • /saltybot/tts_request - Text to synthesize with personality
  • /saltybot/emotion_state - Current emotion ("happy", "sad", "angry", "neutral")
  • /saltybot/person_detected - Detected known person name

Publishes

  • /saltybot/tts_command - Formatted TTS command with personality parameters (JSON)
  • /saltybot/personality_state - Current personality state

Integration Flow

tts_request → personality_node → apply context/emotion → tts_service → audio device
                                                                        (Jabra SPEAK 810)

Configuration

Parameters (tts_personality_params.yaml)

personality_name: "Luna"           # Robot's personality name
enable_context_aware: true         # Use time/person/emotion context

# Emotion modulation
speed_happy: 1.1                   # Rate multiplier when happy
speed_sad: 0.9                     # Rate multiplier when sad
pitch_happy: 1.15                  # Pitch multiplier when happy
pitch_sad: 0.85                    # Pitch multiplier when sad

# Time-based greetings
greetings_morning: [...]           # 5am-12pm
greetings_afternoon: [...]         # 12pm-5pm
greetings_evening: [...]           # 5pm-9pm
greetings_night: [...]             # 9pm-5am

# Known people for personalization
known_people:
  person_001: "Seb"
  person_002: "Alex"

Usage

Launch

ros2 launch saltybot_tts_personality tts_personality.launch.py personality_name:=Luna

Send TTS Request

ros2 topic pub /saltybot/tts_request std_msgs/String "data: 'hello world'"

Update Emotion

ros2 topic pub /saltybot/emotion_state std_msgs/String "data: 'happy'"

Detect Person

ros2 topic pub /saltybot/person_detected std_msgs/String "data: 'Seb'"

Monitor Personality State

ros2 topic echo /saltybot/personality_state

Example Personalities

Luna (Default)

  • Morning: "Good morning! I hope you slept well."
  • Happy speech: Faster, higher pitch
  • Emotion context: Uses detected mood

Alternative: Customize in Config

personality_name: "Atlas"
greetings_morning:
  - "Systems online. Good morning, Commander."
  - "Wake-up sequence initiated."
speed_happy: 1.2        # Atlas speaks faster when happy

Integration with Other Components

Emotion Engine (Issue #429)

  • Listens to /saltybot/emotion_state
  • Adjusts rate/pitch based on emotion
  • Integrates with personality for consistent expression

TTS Service (Issue #421)

  • Receives formatted TTS commands via /saltybot/tts_command
  • Handles actual speech synthesis with Piper-TTS
  • Outputs to Jabra SPEAK 810 audio device

Person Tracking

  • Subscribes to detected person names
  • Personalizes responses with known person names
  • Maintains recent person context (30-second window)

Testing

# Run unit tests
colcon test --packages-select saltybot_tts_personality

# Manual testing
ros2 launch saltybot_tts_personality tts_personality.launch.py
ros2 topic pub /saltybot/tts_request std_msgs/String "data: 'test message'"

Safety Considerations

  • Safety messages cannot be overridden by emotions (always use neutral rate/pitch)
  • Queue has maximum size of 16 items to prevent memory exhaustion
  • Emergency/safety keywords trigger highest priority queue level
  • Personality does not interfere with critical safety protocols

Future Enhancements

  • Machine learning-based emotion detection from voice analysis
  • Multi-language support
  • Voice variants (male, female, child)
  • Custom personality training from recordings
  • Integration with dialogue system for context-aware responses