# SaltyBot Emotion Engine (Issue #429)

Context-aware facial expression and emotion selection system for SaltyBot.

## Features

### 1. State-to-Emotion Mapping
Maps robot operational state to emotional responses:
- **Navigation commands** → Excited (high intensity)
- **Social interactions** → Happy/Curious/Playful
- **Low battery** → Concerned (intensity scales with severity)
- **Balance issues** → Concerned (urgent)
- **System degradation** → Concerned (moderate)
- **Idle (no interaction >10s)** → Neutral (with smooth fade)

### 2. Smooth Emotion Transitions
- Configurable transition durations (0.3–1.2 seconds)
- Easing curves for natural animation
- Confidence decay during uncertainty
- Progressive intensity ramping

### 3. Personality-Aware Responses
Configurable personality traits (0.0–1.0):
- **Extroversion**: Affects how eager to interact (playful vs. reserved)
- **Playfulness**: Modulates happiness intensity with people
- **Responsiveness**: Speed of emotional reactions
- **Anxiety**: Baseline concern level and worry responses

### 4. Social Memory & Familiarity
- Tracks interaction history per person
- Warmth modifier (0.3–1.0) based on relationship tier:
  - Stranger: 0.5 (neutral warmth)
  - Regular contact: 0.6–0.8 (warmer)
  - Known favorite: 0.9–1.0 (very warm)
- Positive interactions increase familiarity
- Warmth applied as intensity multiplier for happiness

### 5. Idle Behaviors
Subtle animations triggered when idle:
- **Blink**: ~30% of time, interval ~3–4 seconds
- **Look around**: Gentle head movements, ~8–10 second interval
- **Breathing**: Continuous oscillation (sine wave)
- Published as flags in emotion state

## Topics

### Subscriptions
| Topic | Type | Purpose |
|-------|------|---------|
| `/social/voice_command` | `saltybot_social_msgs/VoiceCommand` | React to voice intents |
| `/social/person_state` | `saltybot_social_msgs/PersonStateArray` | Track people & engagement |
| `/social/personality/state` | `saltybot_social_msgs/PersonalityState` | Personality context |
| `/saltybot/battery` | `std_msgs/Float32` | Battery level (0.0–1.0) |
| `/saltybot/balance_stable` | `std_msgs/Bool` | Balance/traction status |
| `/saltybot/system_health` | `std_msgs/String` | System health state |

### Publications
| Topic | Type | Content |
|-------|------|---------|
| `/saltybot/emotion_state` | `std_msgs/String` (JSON) | Current emotion + metadata |

#### Emotion State JSON Schema
```json
{
  "emotion": "happy|curious|excited|concerned|confused|tired|playful|neutral",
  "intensity": 0.0–1.0,
  "confidence": 0.0–1.0,
  "expression": "happy_intense|happy|happy_subtle|...",
  "context": "navigation_command|engaged_with_N_people|low_battery|...",
  "triggered_by": "voice_command|person_tracking|battery_monitor|balance_monitor|idle_timer",
  "social_target_id": "person_id or null",
  "social_warmth": 0.0–1.0,
  "idle_flags": {
    "blink": true|false,
    "look_around": true|false,
    "breathing": true|false
  },
  "timestamp": unix_time,
  "battery_level": 0.0–1.0,
  "balance_stable": true|false,
  "system_health": "nominal|degraded|critical"
}
```

## Configuration

Edit `config/emotion_engine.yaml`:

```yaml
personality:
  extroversion: 0.6       # 0=introvert, 1=extrovert
  playfulness: 0.5        # How playful with people
  responsiveness: 0.8     # Reaction speed
  anxiety: 0.3            # Baseline worry level

battery_warning_threshold: 0.25    # 25% triggers mild concern
battery_critical_threshold: 0.10   # 10% triggers high concern

update_rate_hz: 10.0      # Publishing frequency
```

## Running

### From launch file
```bash
ros2 launch saltybot_emotion_engine emotion_engine.launch.py
```

### Direct node launch
```bash
ros2 run saltybot_emotion_engine emotion_engine
```

## Integration with Face Expression System

The emotion engine publishes `/saltybot/emotion_state` which should be consumed by:
- Face expression controller (applies expressions based on emotion + intensity)
- Idle animation controller (applies blink, look-around, breathing)
- Voice response controller (modulates speech tone/style by emotion)

## Emotion Logic Flow

```
Input: Voice command, person tracking, battery, etc.
  ↓
Classify event → determine target emotion
  ↓
Apply personality modifiers (intensity * personality traits)
  ↓
Initiate smooth transition (current emotion → target emotion)
  ↓
Apply social warmth modifier if person-directed
  ↓
Update idle flags
  ↓
Publish emotion state (JSON)
```

## Example Usage

Subscribe and monitor emotion state:
```bash
ros2 topic echo /saltybot/emotion_state
```

Example output (when person talks):
```json
{
  "emotion": "excited",
  "intensity": 0.85,
  "confidence": 0.9,
  "expression": "surprised_intense",
  "context": "navigation_command",
  "triggered_by": "voice_command",
  "social_target_id": "person_42",
  "social_warmth": 0.75,
  "idle_flags": {"blink": false, "look_around": true, "breathing": true},
  "timestamp": 1699564800.123
}
```

## Development Notes

- **Emotion types** are defined in `EmotionType` enum
- **Transitions** managed by `EmotionTransitioner` class
- **Idle behaviors** managed by `IdleBehaviorManager` class
- **Social memory** managed by `SocialMemoryManager` class
- Add new emotions by extending `EmotionType` and updating `_map_emotion_to_expression()`
- Adjust transition curves in `EmotionTransitioner.transition_curves` dict

## Future Enhancements

1. Machine learning model for context → emotion prediction
2. Voice sentiment analysis to modulate emotion
3. Facial expression feedback from /social/faces/expressions
4. Multi-person emotional dynamics (ensemble emotion)
5. Persistent social memory (database backend)
6. Integration with LLM for contextual emotion explanation
