Metadata-Version: 2.4
Name: focus-mocap
Version: 0.1.0
Summary: Centralized multi-robot motion capture orchestration server
License-Expression: MIT
Requires-Python: >=3.8
Description-Content-Type: text/markdown
Requires-Dist: fastapi>=0.100.0
Requires-Dist: uvicorn>=0.20.0
Requires-Dist: websockets>=11.0
Requires-Dist: pyyaml>=6.0

# Mocap Multi-Robot Orchestration Platform

集中式多机器人动作捕捉编排系统 —— 通过 WebSocket 实现多个机器人的统一控制、动作回放、工作流编排和音乐同步播放。

## 功能概览

- **多机器人管理** — WebSocket 长连接注册/心跳，实时管理多台机器人
- **动作回放** — 支持预设动作与 HDF5 文件回放，可配置速度、循环、反向、缓入缓出等参数
- **工作流编排** — JSON 定义多步骤工作流，支持暂停等待外部信号（`__pause__`）
- **音乐播放** — 基于 FFmpeg + aplay 的低延迟音乐播放，支持播放/暂停/变速
- **Web 控制台** — 实时状态监控 Dashboard 和交互式控制面板
- **DDS 集成** — 通过 DDS 消息直接控制机器人硬件

## 架构

```
┌─────────────┐    HTTP/WS     ┌──────────────┐    WebSocket    ┌──────────────┐
│  Web 浏览器  │ ◄────────────► │   Server     │ ◄────────────► │  Robot Client│
│  Dashboard   │   /ws/ui      │  (FastAPI)   │  /ws/robot/{id}│  (DDS/Mocap) │
│  控制面板    │   REST API    │              │                │              │
└─────────────┘               │  Music API   │                │  ┌──────────┐│
                              │  /api/music/ │                │  │MocapClient││
┌─────────────┐               └──────────────┘                │  └──────────┘│
│  音乐文件    │ ◄── FFmpeg ──►│  music/      │                │  ┌──────────┐│
│  (MP3)      │               └──────────────┘                │  │ DDS Pub  ││
└─────────────┘                                               │  └──────────┘│
                                                              └──────────────┘
```

## 快速开始

### 环境要求

- Python 3.8+
- FFmpeg, aplay（音乐播放功能需要）
- DDS 运行时（可选，机器人硬件控制需要）

### 安装依赖

```bash
pip install fastapi uvicorn pyyaml websockets
```

### 1. 启动服务端

```bash
python server.py --host 0.0.0.0 --port 8080
```

| 参数 | 默认值 | 说明 |
|------|--------|------|
| `--host` | `0.0.0.0` | 绑定地址 |
| `--port` | `8080` | 绑定端口 |

启动后可访问：
- `http://localhost:8080/docs` — Swagger API 文档
- `http://localhost:8080/ui/dashboard.html` — 实时状态 Dashboard
- `http://localhost:8080/ui/index.html` — 交互式控制面板

### 2. 启动机器人客户端

编辑 `robots/robot_config.yaml`：

```yaml
robot_id: FOURIER                                    # 唯一标识
server: ws://192.168.10.10:8080/ws/robot/FOURIER     # 服务端 WebSocket 地址
signal_port: 9001                                    # 外部信号 TCP 端口（0 禁用）
mocap_ip: 192.168.137.220                            # 本地 Mocap 服务地址
mocap_port: 19000                                    # 本地 Mocap 服务端口
```

启动客户端：

```bash
cd robots
python robot_client_dds.py --config robot_config.yaml
```

可选 `--disable-dds` 参数跳过 DDS 初始化（调试用）。

### 3. 音乐文件

将 MP3 文件放入项目根目录下的 `music/` 文件夹，系统自动扫描识别。

## 项目结构

```
├── server.py                 # 主服务：HTTP API + WebSocket 路由
├── app/
│   ├── adapter/
│   │   └── music_adapter.py  # 音乐播放引擎（FFmpeg + aplay）
│   └── api/
│       └── music_api.py      # 音乐 REST API 路由
├── mocap_client/
│   ├── main.py               # MocapClient：与 Mocap 服务通信
│   └── struct/
│       ├── req_struct.py     # 请求数据结构（ReplayRequest 等）
│       ├── ret_struct.py     # 响应数据结构（HttpJsonResult 等）
│       └── status_code.py    # 状态码常量
├── robots/
│   ├── robot_client_dds.py   # 机器人端 WebSocket 客户端 + DDS
│   ├── robot_config.yaml     # 机器人端配置
│   └── client_launcher.py    # PyInstaller 启动入口
├── web/
│   ├── dashboard.html        # 实时状态面板
│   ├── index.html            # 控制面板
│   └── music-control.js      # 音乐控制前端组件
├── workflows/
│   ├── workflow.json         # 工作流示例
│   └── workflow_guitar.json  # 吉他演奏工作流示例
├── music/                    # MP3 音乐文件目录
└── docs/
    └── server_api.md         # API 详细参考文档
```

## WebSocket 通信协议

### 机器人连接

路径：`/ws/robot/{robot_id}`

**注册消息（由机器人发送）：**

```json
{"type": "register", "robot_id": "FOURIER"}
```

**心跳（每 5 秒）：**

```json
{"type": "heartbeat", "t": 1713600000.123}
```

**服务端心跳响应：**

```json
{"type": "pong"}
```

### 命令下发与响应

**服务端 → 机器人：**

```json
{
  "type": "command",
  "command": "mocap_replay",
  "cmd_id": "abc12345",
  "payload": {"target": "neutral", "loop": false}
}
```

**机器人 → 服务端（ACK）：**

```json
{
  "type": "ack",
  "cmd_id": "abc12345",
  "data": {"ok": true, "status_code": 200},
  "robot_id": "FOURIER",
  "timestamp": 1713600001.456
}
```

### UI 实时推送

路径：`/ws/ui`

Dashboard 通过此连接接收所有机器人的实时状态更新。

## 支持的命令

| 分类 | 命令 | 说明 |
|------|------|------|
| **工作控制** | `start_work` | 开始工作模式 |
| | `stop_work` | 停止工作模式 |
| | `start_monitor` | 启动监控 |
| **方向控制** | `direction` / `up` / `down` | 方向控制（附 `direction` 参数） |
| **抓取/视觉** | `grasp_complete` | 抓取完成通知 |
| | `grasp_vision_trigger` | 触发视觉检测 |
| **Mocap 状态** | `mocap_status` | 获取 Mocap 服务状态 |
| | `mocap_presets` | 获取预设列表 |
| | `mocap_files` | 获取 HDF5 文件列表 |
| | `mocap_exit` | 关闭 Mocap 服务 |
| **动作回放** | `mocap_replay` | 执行动作回放 |
| | `mocap_break` | 中断当前回放 |
| **工作流** | `mocap_workflow_start` | 启动工作流 |
| | `mocap_workflow_run` | 立即执行工作流 |
| | `mocap_workflow_stop` | 停止工作流 |
| | `mocap_workflow_skip` | 跳过当前步骤 |
| | `mocap_workflow_status` | 查询工作流状态 |

## 工作流格式

工作流以 JSON 文件定义，存放在 `workflows/` 目录：

```json
{
  "version": 2,
  "workflow": [
    {"id": 1, "target": "neutral", "speed": 1},
    {"id": 2, "target": "ready_to_grab.hdf5", "first": true},
    {"id": 3, "target": "__pause__"},
    {"id": 4, "target": "grab.hdf5"},
    {"id": 5, "target": "play.hdf5", "loop": true}
  ]
}
```

- `target` — 预设名 / HDF5 文件路径 / `__pause__`（等待外部信号）
- 支持的步骤参数：`first` `last` `state` `reverse` `loop` `speed` `fps` `duration`

## 音乐播放

通过 `/api/music/` 端点控制，支持：

| 操作 | 端点 | 方法 |
|------|------|------|
| 文件列表 | `/api/music/files` | GET |
| 播放 | `/api/music/play` | POST |
| 暂停 | `/api/music/pause` | POST |
| 恢复 | `/api/music/resume` | POST |
| 停止 | `/api/music/stop` | POST |
| 变速 | `/api/music/speed` | POST |
| 状态 | `/api/music/status` | GET |
| 播放/暂停切换 | `/api/music/toggle` | POST |

- 支持速度：0.5x ~ 2.0x（0.25 步进）
- 格式：MP3
- 暂停机制：SIGSTOP/SIGCONT 信号控制

## API 文档

完整的 HTTP API 参考请查看 [docs/server_api.md](docs/server_api.md)。

启动服务后也可访问 `http://localhost:8080/docs` 查看 Swagger 交互文档。

## License

Private — 内部使用
