# SaltyBot Emergency Stop Cascade System

Critical safety emergency stop system with <50ms latency response.

## Features

### Trigger Sources
- **Voice**: "stop", "emergency", "e-stop"
- **Gamepad**: Emergency button
- **Tilt**: >45 degrees (IMU-based)
- **Obstacle**: <0.3m (LiDAR)
- **Geofence**: Boundary violation
- **Watchdog**: Timeout trigger
- **MQTT**: Remote kill signal

### Cascade Response (within 500ms)
1. **Zero cmd_vel** (<50ms) - Priority critical
2. **Disable autonomous** - Prevent override
3. **Face alert** - Emergency animation
4. **LED red** - Visual indicator
5. **TTS alert** - Audio confirmation
6. **Log event** - Sensor snapshot + timestamp

### Safety Properties
- **Cannot be overridden** once triggered
- **Manual resume only** - Gamepad Start or voice
- **Non-blockable** - Uses separate thread
- **Redundant triggers** - Multiple independent sources

## Launch

```bash
ros2 launch saltybot_emergency_stop estop.launch.py
```

## Topics

**Published**:
- `/saltybot/estop_active` (Bool) - System state
- `/saltybot/estop_event` (String) - Event JSON log

**Subscribed**:
- `/camera/imu` (Imu) - Tilt detection
- `/scan` (LaserScan) - Obstacle detection
- `/voice/command` (String) - Voice triggers
- `/gamepad/emergency` (Bool) - Gamepad e-stop
- `/gamepad/start` (Bool) - Resume control
- `/saltybot/geofence_violation` (Bool)
- `/saltybot/watchdog_timeout` (Bool)
- `/saltybot/mqtt_kill` (Bool) - Remote kill

## Response Times

- **cmd_vel zeroed**: <50ms
- **Full cascade**: <500ms
- **Resume pending**: Manual only

## Logging

Location: `/home/seb/saltybot-data/estop/`

Format: `estop_YYYYMMDD_HHMMSS.json`

Includes:
- Trigger source
- State transitions
- Sensor snapshot (tilt angle, IMU, LiDAR)
- Timestamp

## Resume Procedure

E-stop can only be resumed via:
1. **Gamepad**: Press Start button
2. **Voice**: Say "resume"
3. Manual override not possible

System will:
- Clear alert state
- Set LED to green
- Publish TTS resume message
- Resume normal operation
