# SaltyBot Voice Command Router (Issue #491)

## Overview

Natural language voice command routing with fuzzy matching for handling speech variations.

**Supported Commands**:
- Follow me
- Stop / Halt
- Go home / Return to dock
- Patrol
- Come here
- Sit
- Spin
- Dance
- Take photo
- What's that (object identification)
- Battery status

## Features

### Fuzzy Matching
Uses `rapidfuzz` library with `token_set_ratio` for robust pattern matching:
- Tolerates speech variations ("stop", "halt", "hold", "freeze")
- Configurable threshold (default 80%)
- Matches against multiple patterns per command

### Command Routing
Three routing types:
1. **Publish**: Direct topic publishing (most commands)
2. **Service**: Service calls (photo capture)
3. **Velocity**: Direct `/cmd_vel` publishing (stop command)

### Monitoring
- Publishes all recognized commands to `/saltybot/voice_command`
- JSON format with timestamp
- Enables logging and UI feedback

## Architecture

```
/speech_recognition/transcribed_text
       ↓
[VoiceCommandRouter]
       ↓
   Fuzzy Match
       ↓
   Execute
   /cmd_vel │ /saltybot/action_command │ Services
       ↓
   [Robot Actions]
```

## Command Mapping

| Voice Command | Type | Topic/Service | Args |
|---|---|---|---|
| Follow me | publish | /saltybot/action_command | action: follow_person |
| Stop | publish | /cmd_vel | velocity: 0,0,0 |
| Go home | publish | /saltybot/action_command | action: return_home |
| Patrol | publish | /saltybot/action_command | action: start_patrol |
| Come here | publish | /saltybot/action_command | action: approach_person |
| Sit | publish | /saltybot/action_command | action: sit |
| Spin | publish | /saltybot/action_command | action: spin, count: 1 |
| Dance | publish | /saltybot/action_command | action: dance |
| Take photo | service | /photo/capture | save: true |
| What's that | publish | /saltybot/action_command | action: identify_object |
| Battery status | publish | /saltybot/action_command | action: report_battery |

## Launch

```bash
ros2 launch saltybot_voice_router voice_router.launch.py
```

## Integration

Subscribe to `/speech_recognition/transcribed_text`:
- Typically from wake word engine (e.g., Porcupine)
- Or manual speech recognition node
- Format: `std_msgs/String` with lowercase text

## Parameters

- `fuzzy_match_threshold`: Fuzzy matching score (0-100, default 80)
- `enable_debug_logging`: Detailed command matching logs

## Adding New Commands

Edit `_init_commands()` in `voice_router_node.py`:

```python
'new_command': VoiceCommand(
    'new_command',
    ['pattern 1', 'pattern 2', 'pattern 3'],
    'publish',  # or 'service'
    topic='/saltybot/action_command',
    args={'action': 'new_action'}
),
```

## Dependencies

- `rclpy`: ROS2 Python client
- `rapidfuzz`: Fuzzy string matching

Install: `pip install rapidfuzz`

## Example Usage

### With Speech Recognition
```bash
# Terminal 1: Start voice router
ros2 launch saltybot_voice_router voice_router.launch.py

# Terminal 2: Test with manual transcription
ros2 topic pub /saltybot/speech/transcribed_text std_msgs/String '{data: "follow me"}'
```

### Monitor Commands
```bash
ros2 topic echo /saltybot/voice_command
```

## Performance

- Fuzzy matching: <10ms per command
- Multiple pattern matching: <50ms worst case
- No blocking operations

## Safety

- Stop command has highest priority
- Can be integrated with emergency stop system
- All commands validated before execution
- Graceful handling of unknown commands

## Future Enhancements

- [ ] Confidence scoring display
- [ ] Command feedback (audio confirmation)
- [ ] Learning user preferences
- [ ] Multi-language support
- [ ] Voice emotion detection
- [ ] Command context awareness
