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