Files
Tutorial/docs/MultiVehicleSync.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

5.2 KiB
Raw Blame History

多车联动(MultiVehicleSync)算法原理

本文说明 MDCSToolBox 中 N 车联动的架构与几何原理。Tutorial MultiWheelC 与产品 StandardMultiWheelLifterC 均继承 MultiWheelPilotDefinition,调用 InitMultiVehicleCoordination() 启用同步。

1. 总体架构

每台 AGV 运行 Detour + Medulla (M) + Clumsy (C)

实例 Detour shareObjectTag Medulla/Clumsy soTag Clumsy 角色 MultiVehicleMasterEndpoint Clumsy port Detour HTTP CarNum
AGV1 Multi1 Multi1 主车 master / 8008 4321 1
AGV2 Multi2 Multi2 从车 slave 127.0.0.1:8008 8009 4421 2

Medulla web API(与 Clumsy 车队同步端口无关):AGV1 8007AGV2 8108(单机部署时 Medulla #2 不可占用 8008,该端口留给 Clumsy 主车)。

同机隔离(Core 层)

  • Detour 写入 DObject("DetourPos{shareObjectTag}")Clumsy 读取 DObject("DetourPos{soTag}")tag 必须一致。
  • Clumsy 通过 detourHost/detourPortclumsyconsole.jsonclumsy.json)访问对应 Detour HTTP 端口(4321/4421)。
  • 每台 Clumsy 绑定独立 WebAPI.port8008/8009),register/notify 使用 VehicleSyncInfo.Port 寻址。

M 与 C 通过 CartActivator 共享 DObjectMedullaCartUpperIO{tag}),不直接 DLL 调用。

从车 --GET /multi-vehicle-register--> 主车:8008   (上报本车位姿、layout、Port
主车 --GET /multi-vehicle-notify----> 从车:8009   (广播车队中心、fleet 命令、完整 fleet 状态)

2. 数据模型

定义于 MDCSToolBox/Clumsy/Pilot/MultiWheel/VehicleSyncModels.cs

2.1 VehicleSyncInfo(从车 → 主车)

字段 含义
Master 是否主车
Ip / Port 本车同步端点(notify 寻址)
PosAvailable 本车 Detour/SLAM 是否有效
X/Y/Th 本车世界位姿(mm, deg
LayoutX/Y/Th 本车在车队坐标系下的 固定 slot
Aligned 本车互识别/精度是否满足(见 §4

2.2 VehicleSyncNotification(主车 → 从车)

除原 fleet 命令外,主车广播 CenterX/Y/Th(世界系车队中心)、SyncTh/SyncDistance、完整 Fleet 快照等。

3. 编队几何与车队中心

3.1 编队布局(双车)

布局由 TestCarSyncDistanceTestCarSyncTh 唯一确定(不再有独立 slot 表):每车相对车队中心沿编队方向对称分布于 ±TestCarSyncDistance/2,从车朝向额外翻转 180°。实现见 GetLayoutPoseTestCarSyncDistance 同时是检测环(detectDistance = TestCarSyncDistance - DeltaDetectCenter)与 SLAM 位姿环的唯一间距来源,二者据此自洽。

3.2 车队中心反推(非位姿平均)

世界系中心 不是 对各车 X/Y/Th 取平均,而是由 当前 PosAvailable==true 的车 按固定 slot 反推:

Transform2D(fleetCenter, layoutSlot) = carWorldPose
⇒ fleetCenter = Transform2D(carWorld, -layoutSlot)   // 实现见 InferFleetCenterFromCar
  • 多台有效车:对各车反推的中心取平均(理论上应一致,差异可作互检)。
  • 零台有效车:无世界系中心 → 手动模式仍可通过互识别保持编队;自动模式门控拒绝(见 §5)。

4. 互识别接口(插件实现)

基类 MultiWheelPilotDefinition 提供虚方法:

protected virtual (bool Valid, float Dx, float Dy, float Dth) DetectNeighborBias(float detectDistance);
  • 基类:MultiVehicleUseDetect 门控 → 计算 AlignedSendMotion(localCompensate*)
  • 具体检测(雷达名、两腿/反光板等)由车体插件重写。
    • 产品:StandardMultiWheelLifterCVehicleMoverHelper.GetSyncBias
    • Tutorial:默认 Valid=false(无检测硬件时可纯靠手动+SLAM

5. 手动 / 自动门控

模式 条件
手动 始终可用;可无 Detour,靠 DetectNeighborBias 纠正
自动 主车要求 fleet 中 至少 1 台 PosAvailable;否则 toast 拒绝并清零 MultiVehicleAutoEnabled

6. 主循环(默认 50ms

逻辑位于 MultiWheelPilotDefinition.MultiVehicle.csTickMultiVehicle

  1. 判断 master/slave、手动/自动是否启用
  2. 读取本车 SLAM(若 PosAvailable
  3. 主车:计算 fleet 命令;从 notification 同步
  4. GetLayoutPose → 本车布局位姿(由 TestCarSyncDistance/TestCarSyncTh 推导)
  5. DetectNeighborBias(可选)→ 互识别补偿
  6. 有有效中心时 SLAM posBias 补偿
  7. SendMotion(fleetVx, FrontTh, RearTh, localCompensate*)
  8. masterregister 汇总 + notify 各从车(按 Ip:Port,跳过自身 CarNum

7. 配置文件

RunAndDeploy.mdclumsyconsole.jsonsoTag/port/detour)、clumsy.jsonmsConf slot/主车端点)、detour.jsonshareObjectTag/DetourPort)。

修复与迁移记录见 BugFixes.md