# Simulation Bridge Node

**Package:** `mecha10-nodes-simulation-bridge`
**Binary:** `simulation-bridge`
**Purpose:** Translate between Redis pub/sub (framework) and Godot RL Agents protocol (simulation)

---

## Overview

The simulation bridge is the **only** component that talks to Godot directly. All other framework components communicate via Redis pub/sub, making the framework hardware-agnostic.

**Architecture:**
```
Framework Nodes → Redis ← Simulation Bridge → Godot
```

**Not:**
```
Framework Nodes → Godot ❌
RL Training → Godot ❌
```

---

## Features

- ✅ **Hardware abstraction** - Framework never knows it's talking to simulation
- ✅ **Godot RL Agents protocol** - WebSocket-based communication with Godot
- ✅ **Redis pub/sub** - Subscribes to commands, publishes sensor data
- ✅ **Async operation** - Concurrent handling of Redis and Godot
- ✅ **Automatic reconnection** - Handles Godot disconnections gracefully
- ✅ **Configurable** - Environment variables for Redis and Godot URLs

---

## Redis Topics

### Subscribed Topics (Commands from Framework)

| Topic | Message Type | Description |
|-------|--------------|-------------|
| `robot/actuators/motor` | `MotorCommand` | Motor commands (left, right velocity) |
| `sim/control/reset` | `SimResetCommand` | Reset simulation environment |
| `sim/control/pause` | `SimPauseCommand` | Pause/resume simulation |
| `sim/rl/request` | `RLRequest` | Synchronous RL step request |

### Published Topics (Observations to Framework)

| Topic | Message Type | Description |
|-------|--------------|-------------|
| `robot/sensors/imu` | `ImuData` | IMU readings (accel, gyro, orientation) |
| `robot/sensors/encoders` | `EncoderData` | Motor encoder positions |
| `robot/sensors/camera/rgb` | `CameraImage` | RGB camera images (base64) |
| `sim/rl/response` | `RLResponse` | Synchronous RL step response |

---

## Usage

### Development Mode

```bash
# Start simulation bridge
cargo run -p mecha10-nodes-simulation-bridge

# Or use binary name
cargo run --bin simulation-bridge
```

### Environment Variables

```bash
# Redis connection (default: redis://localhost:6379)
export REDIS_URL="redis://localhost:6379"

# Godot RL Agents URL (default: ws://localhost:11008)
export GODOT_URL="ws://localhost:11008"
```

### With Framework (`mecha10 dev`)

The simulation bridge can be integrated into the framework development workflow:

```bash
# In the future, mecha10 dev will support:
# Press 's' to start simulation bridge + Godot
```

### RL Training

For RL training, start the bridge first, then Godot, then the training script:

```bash
# Terminal 1: Start simulation bridge
cargo run -p mecha10-nodes-simulation-bridge

# Terminal 2: Start Godot simulation
mecha10 sim run --env basic_arena

# Terminal 3: Start RL training (uses Redis)
cd packages/taskrunner
./scripts/run.sh --type=TRAIN --environment_map=basic_arena
```

---

## Message Formats

### MotorCommand

```rust
pub struct MotorCommand {
    pub left: f32,    // Left motor velocity (-1.0 to 1.0)
    pub right: f32,   // Right motor velocity (-1.0 to 1.0)
    pub timestamp: u64,
}
```

### ImuData

```rust
pub struct ImuData {
    pub linear_acceleration: [f32; 3],  // m/s^2
    pub angular_velocity: [f32; 3],     // rad/s
    pub orientation: [f32; 4],          // quaternion (w, x, y, z)
    pub timestamp: u64,
}
```

### EncoderData

```rust
pub struct EncoderData {
    pub left: f32,   // Left motor encoder position (radians)
    pub right: f32,  // Right motor encoder position (radians)
    pub timestamp: u64,
}
```

### RLRequest / RLResponse

```rust
pub struct RLRequest {
    pub correlation_id: String,  // UUID for matching request/response
    pub action: Vec<f32>,         // Action vector
}

pub struct RLResponse {
    pub correlation_id: String,
    pub observation: Vec<f32>,
    pub reward: f32,
    pub done: bool,
    pub info: HashMap<String, String>,
}
```

---

## Architecture

The bridge runs three concurrent tasks:

### 1. Godot Connection Task

- Connects to Godot via WebSocket
- Performs handshake to get environment info
- Automatically reconnects on disconnection

### 2. Redis Subscription Task

- Subscribes to command topics
- Forwards motor commands to Godot as actions
- Handles reset/pause commands
- Processes synchronous RL requests

### 3. Sensor Publishing Task

- Runs at configurable rate (default: 30 Hz)
- Sends pending actions to Godot
- Receives step results (observation, reward, done)
- Publishes sensor data to Redis topics

---

## Godot RL Agents Protocol

The bridge implements the [godot-rl-agents](https://github.com/edbeeching/godot_rl_agents) WebSocket protocol:

### Protocol Flow

```
1. Client → Server: Handshake { major_version, minor_version }
2. Server → Client: EnvInfo { n_agents, action_space, obs_space }
3. Client → Server: ResetEnv
4. Server → Client: Reset { obs }
5. Loop:
   - Client → Server: Action { action }
   - Server → Client: Step { reward, done, obs }
6. Client → Server: Close
```

### Message Format

All messages are JSON sent as WebSocket text frames:

```json
{
  "type": "handshake",
  "major_version": "1",
  "minor_version": "0"
}
```

---

## Development

### Building

```bash
cargo build -p mecha10-nodes-simulation-bridge
```

### Testing

```bash
# Run tests
cargo test -p mecha10-nodes-simulation-bridge

# Run with logging
RUST_LOG=debug cargo run -p mecha10-nodes-simulation-bridge
```

### Logging Levels

- `error` - Errors only
- `warn` - Warnings and errors
- `info` - General info (default)
- `debug` - Detailed debugging
- `trace` - Very verbose

---

## Troubleshooting

### Bridge Fails to Connect to Godot

**Error:** `Failed to connect to Godot`

**Solution:**
1. Ensure Godot is running with godot-rl-agents plugin
2. Check Godot is listening on correct port (default: 11008)
3. Verify `GODOT_URL` environment variable

### Bridge Fails to Connect to Redis

**Error:** `Failed to connect to Redis`

**Solution:**
1. Ensure Redis is running (`redis-server`)
2. Check Redis is listening on correct port (default: 6379)
3. Verify `REDIS_URL` environment variable

### No Sensor Data Published

**Issue:** Bridge runs but no data appears on Redis topics

**Solution:**
1. Check that motor commands are being sent to `robot/actuators/motor`
2. Verify Godot is responding to actions with step results
3. Enable debug logging: `RUST_LOG=debug`

### Handshake Fails

**Error:** `Unexpected message during handshake`

**Solution:**
1. Ensure Godot environment has godot-rl-agents plugin installed
2. Check Godot console for errors
3. Verify protocol version compatibility

---

## Integration with Framework

### mecha10.json

When using `mecha10 init`, the simulation bridge is automatically included:

```json
{
  "robot": "my-robot",
  "nodes": [
    {
      "name": "simulation-bridge",
      "package": "mecha10-nodes-simulation-bridge",
      "enabled": true,
      "placement": "local"
    }
  ]
}
```

### Generated Project Structure

```
my-robot/
├── nodes/
│   └── simulation-bridge/   # Copied from monorepo
│       ├── Cargo.toml
│       └── src/
│           ├── main.rs
│           ├── bridge.rs
│           ├── godot_client.rs
│           └── topics.rs
└── Cargo.toml
```

---

## Future Enhancements

### Multi-Simulator Support

Add bridge nodes for other simulators:
- `gazebo-bridge` - ROS/Gazebo Classic
- `isaac-sim-bridge` - NVIDIA Isaac Sim
- `mujoco-bridge` - MuJoCo physics engine

All would use the **same Redis interface**.

### Camera Support

- Decode camera images from Godot observation
- Publish to `robot/sensors/camera/rgb` and `robot/sensors/camera/depth`
- Support image compression (JPEG, PNG)

### LiDAR Support

- Extract LiDAR scan data from observation
- Publish to `robot/sensors/lidar`
- Support configurable scan parameters

### Hardware-in-the-Loop

Run some nodes on real hardware, some in simulation:
```bash
cargo run -p my-robot-motor --features target-robot  # Real hardware
cargo run -p simulation-bridge  # Simulated sensors
```

---

## Related Documentation

- [Simulation Architecture](../../../docs/architecture/SIMULATION_ARCHITECTURE.md)
- [Getting Started](../../../docs/GETTING_STARTED.md)
- [Godot RL Agents](https://github.com/edbeeching/godot_rl_agents)

---

## License

MIT
