Files
Tutorial/docs/MultiVehicleConfig.md
T
ruifeng.zhouandCursor 235c6c70ac Add Clumsy plugins and dual-vehicle fleet sync demo.
Restructure into DiffWheel/MultiWheel folders, add DiffWheelC and MultiWheelC with MovementTests, FleetRemote multi-vehicle manual sync, deploy templates, and documentation. Update dependency paths to D:\MDCS\Release and mirror motor feedback in MotorRoutine for simulation.

Co-authored-by: Cursor <cursoragent@cursor.com>
2026-06-28 15:04:55 +08:00

167 lines
9.6 KiB
Markdown
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
# 多车联动 配置与参数清单
本文件汇总 **MultiWheel 多车联动** 需要调整的全部配置项,分三层:
1. **每台车都不同**的身份/通信项(必须按车区分,配错直接导致组不成队或互相抢占)。
2. **编队几何**项(决定车间距、布局、互识别 ROI,全队应一致)。
3. **闭环/遥控/安全**调参项(手感与稳定性,可按需微调)。
涉及文件:
| 端 | 文件 | 作用 |
|----|------|------|
| Medulla | `build/Medulla*/startup.iocmd` | 插件加载、车号 `CarNum`、共享内存 tag、Playground 绑定、雷达初始化 |
| Medulla | 车体「Fields」面板 / `loader setp <字段> <值>` | `CartDefinition``[AsInitParam]` 字段(车号、手动最大速度等) |
| Clumsy | `build/Clumsy*/clumsy.json``msConf` | `PilotConfig` 全部联动参数(间距、检测、补偿、遥控系数等) |
| Clumsy | `build/Clumsy*/clumsyconsole.json` | `port``soTag``detourPort`(通信端口/共享内存/定位) |
> 提示:`msConf` 的 key 与 `MultiWheelC/PilotConfig.cs` 字段一一对应;Medulla 的 `[AsInitParam]` 字段见 `MultiWheelM/CartDefinition.cs`。
---
## 1. 每台车都不同(身份与通信)
以 Playground 双车(车1=主、车2=从)为例,**逐项对照**:
| 配置位置 | 字段 | 车1(主车) | 车2(从车) | 说明 |
|----------|------|-------------|-------------|------|
| Medulla `startup.iocmd` | `SetShareObjectTag` | `Multi1` | `Multi2` | 必须与对应 Clumsy 的 `soTag` 一致 |
| Medulla `startup.iocmd` | `loader setp CarNum` | `1` | `2` | 车号,决定编队 slot(±半间距)。**每台必须唯一** |
| Medulla `startup.iocmd` | `SetPlaygroundBinding` | `agv_multi_1` | `agv_multi_2` | 绑定的仿真小车名 |
| Medulla `startup.iocmd` | `lidar init ... <robot>` | `agv_multi_1` | `agv_multi_2` | 雷达挂到对应小车 |
| Clumsy `clumsyconsole.json` | `port` | `8008` | `8009` | 本车 HTTP/同步端口 |
| Clumsy `clumsyconsole.json` | `soTag` | `Multi1` | `Multi2` | 与 Medulla 的 ShareObjectTag 一致 |
| Clumsy `clumsyconsole.json` | `detourPort` | `4321` | `4421` | 与对应 Detour 实例一致 |
| Clumsy `clumsy.json` | `MultiVehicleMasterEndpoint` | `/` | `127.0.0.1:8008` | `/`=本车为主车;从车填**主车的 ip:port** |
| Clumsy `clumsy.json` | `PlaygroundRobotName` | `agv_multi_1` | `agv_multi_2` | WebAPI 操作/查询的小车名 |
| Clumsy `clumsy.json` | `TwoLegLidarName` | `rear_left_lidar_1,rear_right_lidar_1` | `rear_left_lidar_2,rear_right_lidar_2` | 互识别用的后向雷达名(与本车 startup 中的雷达名一致) |
| Detour | 运行目录 / `detourPort` | `Detour` (4321) | `Detour_AGV2` (4421) | 两套独立定位 |
**关键点**
- `MultiVehicleMasterEndpoint`:只有主车为 `/`;从车必须指向主车端口(这里主车 Clumsy `port=8008`,故从车填 `127.0.0.1:8008`)。
- `CarNum` 通过 Medulla 的 `[AsInitParam]` 配置(`setp` / Fields 面板 / `cartparams.json`),并以 `[AsLowerIO]` 上报给 Clumsy。**不要**改成 Clumsy 端写死。
- 全队 `MultiVehicleFleetNum` 必须等于实际车数(这里=2),否则永远 `ready=false`,不下发运动。
---
## 2. 编队几何(全队一致)
| 字段(`clumsy.json` | 含义 | Playground 参考值 | 默认值 |
|------|------|------|--------|
| `TestCarSyncDistance` | 车队两端**中心到中心**间距(mm) | `2400` | 2400 |
| `TestCarSyncTh` | 编队布局方向偏角(deg),0=沿 X 排布 | `0` | 0 |
| `DeltaDetectCenter` | 车中心到「互识别参考点」的偏移(mm) | `800` | 350 |
| `TwoLegGuessX` | 2腿检测初始猜测 X(车体系, mm) | `-1600` | 2000 |
| `MultiVehicleFleetNum` | 车队总数 | `2` | 2 |
**几何来源(Playground 默认场景 `default_scene.json`**
- `agv_multi_1` 初始位 `x=20200``agv_multi_2` 初始位 `x=17800` → 中心间距 = **2400 mm**,朝向相差 180°。
-`TestCarSyncDistance = 2400`
**必须遵守的换算关系**
```text
互识别检测距离 detectDistance = TestCarSyncDistance - DeltaDetectCenter
TwoLegGuessX = -(TestCarSyncDistance - DeltaDetectCenter)
= -(2400 - 800) = -1600
```
- `TwoLegGuessX` 取**负号**:邻车在本车后方(用后向雷达 `rear_*`),猜测点在车体 -X 方向。
-`TestCarSyncDistance` 时,**务必同步**更新 `TwoLegGuessX`,否则检测 ROI 偏离 → 检测失败 → 安全门拦停。
- `布局`(每车 slot)由 `TestCarSyncDistance`/`TestCarSyncTh` 唯一推导:车1=+半间距、车2=−半间距并翻转 180°。已删除独立的 `FormationSlots`,不要再引入重复参数。
---
## 3. 2 腿互识别(ROI / 聚类)
与「多舵轮-2腿检测」MovementTest 共用同一套参数;调好 MovementTest 再用于联动。
| 字段(`clumsy.json` | 含义 | Playground 参考值 | 默认值 |
|------|------|------|------|
| `TwoLegLidarName` | 后向雷达名(逗号分隔,按车区分,见 §1) | `rear_left_lidar_X,rear_right_lidar_X` | — |
| `TwoLegGuessX` | 初始猜测 X(见 §2 换算) | `-1600` | 2000 |
| `TwoLegWidth` | 两腿间距(mm) | `473` | 800 |
| `TwoLegWidthErr` | 两腿间距允许误差(mm) | `100` | 100 |
| `TwoLegFilterLength` | ROI 滤波框长(mm) | `500` | 1800 |
| `TwoLegFilterWidth` | ROI 滤波框宽(mm) | `1000` | 600 |
| `TwoLegBlobDist` / `TwoLegBlobSize` / `TwoLegBlobPtCount` | 聚类间距/尺寸/最小点数 | `100/200/5` | 100/200/5 |
| `TwoLegSgnDir` | 方向符号(±1) | `1` | 1 |
| `TwoLegCenterChangeX` | 中心 X 微调(mm) | `0` | 0 |
---
## 4. 手动遥控(Medulla 车队遥控)
遥控在 Medulla 侧产生指令(`MultiVehicleManual*``[AsLowerIO]` 上报 Clumsy)。摇杆输出已是物理单位,Clumsy 端系数应保持 **1(直通)**
| 端 | 字段 | 含义 | 推荐值 |
|----|------|------|--------|
| Medulla `[AsInitParam]` | `MaxManualSpeed` | 车队手动**最大线速度(m/s)** | `0.3` |
| Medulla `[AsInitParam]` | `MaxManualAngularSpeed` | 车队手动**最大转向角(deg)** | `45` |
| Clumsy `clumsy.json` | `ManualCarSyncVxFac` | 手动 Vx 系数(**保持 1,勿再缩放**) | `1.0` |
| Clumsy `clumsy.json` | `ManualCarSyncVthFac` | 手动 Vth 系数(**保持 1** | `1.0` |
| Clumsy `clumsy.json` | `SyncThAccPerSec` | 转向角爬升速率(deg/s) | `30` |
> 历史坑:`ManualCarSyncVxFac=0.2 × MaxManualSpeed=0.3 → 0.06 m/s`,肉眼几乎不动;`VthFac=5 → 225°` 超舵轮范围。已统一为系数=1。
操作:在 Medulla 打开车体工具 **「FleetRemote / 车队联动遥控」**workspace 摇杆,松手自动回零),开「车队联动」开关后拖摇杆即可。主车摇杆驱动全队;从车由主车广播自动跟随,**无需**各自开开关。**不要**同时打开普通「手动控制」面板(会抢占优先级)。
---
## 5. 闭环补偿与安全门
| 字段(`clumsy.json` | 含义 | 推荐值 |
|------|------|--------|
| `MultiVehicleUseDetect` | 启用互识别纠正 **+ 安全门**(任一车检测不到邻车→整队停车) | `true` |
| `MultiVehicleDetectBiasXFac/YFac/ThFac` | 互识别补偿系数 | `0.5/0.5/0.5` |
| `MultiVehicleDetectBiasXThreshold/YThreshold/ThThreshold` | 互识别补偿上限(mm/mm/deg) | `50/50/5` |
| `MultiVehiclePosBiasXFac/YFac/ThFac` | SLAM 编队保持补偿系数 | `0.5/0.5/0.5` |
| `MultiVehiclePosBiasXThreshold/YThreshold/ThThreshold` | SLAM 补偿上限(mm/mm/deg) | `50/50/5` |
| `SingleCarSyncPrecisionXy` / `SingleCarSyncPrecisionTh` | 对齐精度 / 补偿死区(mm/deg) | `10 / 0.2` |
| `PosAvailable` | 是否启用 Detour 定位 | `true` |
**要点**
- `MultiVehicleUseDetect=true` 时若 2 腿检测没锁定,`fleetVx` 会被安全门置零(表现为摇杆"无效"——这是预期安全行为,不是 bug)。先确保检测稳定。
- SLAM 补偿(`PosBias*`)要求两车**共享同一 SLAM 世界系**;否则编队中心反推会错。Playground 两车同图,满足。
- 不需要绝对编队保持时,可把 `MultiVehiclePosBias*Fac` 设 0,仅靠互识别维持间距。
---
## 6. 常见坑位(排查清单)
- **组不成队 / `ready=false`**`MultiVehicleFleetNum` 与实际车数不符;从车 `MultiVehicleMasterEndpoint` 没指向主车端口;`soTag` 不匹配。
- **摇杆无反应**`MultiVehicleUseDetect=true` 但检测没锁(安全门);或误把系数设成 <1 / 滑条乘零;或在从车而非主车上操作。
- **两车一起匀速跑飞**:编队中心反推必须用**真正的 SE(2) 逆**(`SolveTransform2D`),不能用逐分量取负 `-layout`(从车 `layoutTh=180` 会算错 → 补偿正反馈发散)。已修复于 `InferFleetCenterFromCar`
- **检测框位置不对**`TwoLegGuessX` 未随 `TestCarSyncDistance` 同步更新(见 §2 换算)。
- **车号不对/全为 1**`CarNum` 未通过 `[AsInitParam]``setp CarNum X`)按车配置。
---
## 7. 参考:Playground 双车验证值速查
```jsonc
// clumsy.json -> msConf (主车=agv_multi_1;从车把标注项改为车2值)
"TestCarSyncDistance": 2400,
"TestCarSyncTh": 0,
"DeltaDetectCenter": 800,
"TwoLegGuessX": -1600,
"MultiVehicleFleetNum": 2,
"MultiVehicleUseDetect": true,
"ManualCarSyncVxFac": 1.0,
"ManualCarSyncVthFac": 1.0,
"SyncThAccPerSec": 30,
"MultiVehicleMasterEndpoint": "/", // 从车: "127.0.0.1:8008"
"PlaygroundRobotName": "agv_multi_1", // 从车: "agv_multi_2"
"TwoLegLidarName": "rear_left_lidar_1,rear_right_lidar_1" // 从车: *_2
```
```text
# Medulla startup.iocmd (主车)
loader SetShareObjectTag Multi1 # 从车: Multi2
loader setp CarNum 1 # 从车: 2
loader SetPlaygroundBinding agv_multi_1 tutorial-multi-wheel # 从车: agv_multi_2
```