# RM75 Drag Teach Trajectory Workflow

本文档说明正式的 RM75 末端拖动示教、同步 CSV 记录、C++ TCP 路径转换和 skill 封装边界。

`examples/realman_trajectory_record.cpp` 和 `examples/realman_trajectory_replay.cpp` 是早期最小验证入口。后续维护优先看 `RM/` 子工程。

## 目标

- C++ 底层模块：在 `RM/include/rm_control` 和 `RM/src` 中维护，可编译、可测试。
- Codex skill：在 `skills/rm75-drag-trajectory` 和 `~/.codex/skills/rm75-drag-trajectory` 中维护，负责指导以后如何安全操作。
- 数据目录：用文件夹管理轨迹产物，避免 CSV、厂商文件、转换代码混在一起。

## 维护边界

| 层 | 路径 | 维护内容 |
| --- | --- | --- |
| HAL/interface | `RM/include/rm_control/interfaces/robot_arm.h` | 抽象机械臂能力，不包含 RM SDK 头文件 |
| Driver | `RM/include/rm_control/drivers/realman`, `RM/src/drivers/realman` | `rm_start_multi_drag_teach`、`rm_stop_drag_teach`、`rm_save_trajectory` 等 RM SDK 调用 |
| Core | `RM/include/rm_control/core/drag_teach_recorder.h`, `RM/src/core/drag_teach_recorder.cpp` | 拖动示教记录流程、采样、停止、保存 |
| Module | `RM/include/rm_control/modules/trajectory`, `RM/src/modules/trajectory` | CSV 读写、目录管理、C++ TCP 路径导出 |
| Application | `RM/src/drag_teach_record_main.cpp`, `RM/src/trajectory_convert_main.cpp` | 参数解析、驱动装配、启动流程 |
| Skill | `skills/rm75-drag-trajectory` | 给 Codex 的操作步骤和安全约束 |

## 数据目录

默认根目录：

```text
RM/data/trajectories/
├── csv/        # 我们同步采样的主数据源
├── vendor/     # rm_save_trajectory 尽力保存的厂商轨迹文件
├── converted/  # CSV 转成的 C++ TCP waypoint 文件
└── reports/    # 后续扩展：记录摘要、误差报告、回放日志
```

## CSV 格式

```text
sample_index,elapsed_ms,j1_deg,j2_deg,j3_deg,j4_deg,j5_deg,j6_deg,j7_deg,tcp_x_m,tcp_y_m,tcp_z_m,tcp_rx_rad,tcp_ry_rad,tcp_rz_rad
```

当前主目标是 TCP 空间路径复现，因此转换阶段会把 `tcp_*` 字段导出为 C++ waypoint 表。`j1_deg..j7_deg` 仍保留，用于复现原始姿态、做逆解种子或误差对比。

## 构建

```bash
cd /home/mashiro/project/linkerhand-cpp-sdk
cmake -S RM -B RM/build -DCMAKE_BUILD_TYPE=Debug
cmake --build RM/build -j
ctest --test-dir RM/build --output-on-failure
```

## 六维力拖动示教录制

```bash
./RM/build/rm_drag_teach_record
```

默认行为：

- 连接 `192.168.1.18:8080`
- 使用 RM75 三代控制器复合拖动示教：`mode=3`，即六维力位置和姿态同时可拖动
- 默认开启拖动奇异墙
- 录制 `15` 秒
- 采样周期 `100 ms`
- 主产物写到 `RM/data/trajectories/csv/<session>.csv`
- 停止拖动后尝试把厂商轨迹保存到 `RM/data/trajectories/vendor/<session>_vendor.txt`

自定义 session、时长和采样周期：

```bash
./RM/build/rm_drag_teach_record \
  demo_pick_path \
  15 \
  100
```

完整参数：

```text
rm_drag_teach_record [session_name] [duration_seconds] [sample_period_ms] [storage_root] [--no-vendor-save] [--ordinary-recorded] [--no-singular-wall]
```

## CSV 转 C++ TCP 路径

离线转换，不连接机械臂：

```bash
./RM/build/rm_trajectory_convert \
  RM/data/trajectories/csv/demo_pick_path.csv
```

默认输出：

```text
RM/data/trajectories/converted/demo_pick_path_tcp_path.cpp
```

完整参数：

```text
rm_trajectory_convert <input_csv> [output_cpp]
```

## 安全边界

- `rm_drag_teach_record` 会启动拖动示教，必须清空工作空间，急停可触达。
- 当前实现不自动执行 TCP 回放；转换出来的 C++ 文件只是 waypoint 数据。
- 六维力复合拖动接口没有暴露 `trajectory_record` 开关，CSV 是主数据源；厂商轨迹保存失败只作为警告处理。
- 后续做 TCP 复现时，应先用 CSV 里的关节角作为逆解参考，再做低速、小步、dry-run 校验。
