Files
Tutorial/docs/FleetCrabWalkWorkContext.md
T

334 lines
19 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.
# 自动蟹行(FleetCrabWalk)工作上下文
> 本文档汇总 **当前仓库状态、外部依赖、运行/日志路径、代码地图与待解决问题**,便于后续继续调试「车队联动-自动蟹行」。
>
> 最后更新:2026-06-29
---
## 1. 功能现状
| 阶段 | 状态 | 说明 |
|------|------|------|
| 动作能启动、能下发运动 | ✅ 已解决 | 方案 1(预热)修复了启动期 `(0,0,0)` 快照导致 `Track()` 立即结束(`iter=0`)的问题 |
| 路径跟踪质量 | 🔧 已改,待实测 | 2026-06-29 继续处理:自动蟹行改为复用手动蟹行同款 `mode=1` 下发链路,只叠加小幅平滑横向纠偏 |
| 与手动蟹行对照 | ✅ 已验证 | 手动模式(FleetRemote `mode==1`)丝滑;因此自动抖动主要来自纠偏链路而非底盘执行能力 |
**触发方式**:主车 Clumsy → MovementTest 面板 → **「车队联动-自动蟹行」**`FleetCrabWalkTest`)。
**前提**
- 主车 `MultiVehicleMasterEndpoint="/"`
- 主车有 Detour 定位(反推车队中心起点)
- 双车 Medulla + Clumsy + Detour 均已启动,编队成员数 = `MultiVehicleFleetNum`
---
## 2. 当前已知问题(待排查)
### 2.1 向 Y+ 方向漂移、偏离路径
**现象**:车队整体沿世界坐标 Y 正方向持续偏移,横向误差越来越大,未收敛到 `LineTrack`
**可能相关机制**(按优先级,供下一轮对照日志):
1. **控制器读到的「当前位姿」与真实 SLAM 中心不同步**
- `AbstractGeometricController.Track()``MultiVehicleSync=true` 时通过 `MultiVehicleGetFleetPos()``PilotDefinition.GetFleetCenterSnapshot()`
- 已处理:`TickMultiVehicle` 每拍开头的 `PublishFleetCenter(0,0,0)` 已移除,避免动作/控制线程并发读到假中心。
2. **横向纠偏 `bias` 项在蟹行模式下的参考系**
- `MultiWheelGeometricController.PerformGoing``bias = -bias` 后按 Stanley 形式修正 gcp`BiasFac` / `BiasThreshold`)。
- 蟹行时 `thDiff` 来自路径切线(≈夹角),`dTh` 参考固定 `CrabTargetHeading`;若 `bias` 符号或 fleet 中心更新滞后,会持续向一侧推。
- 已绕开:`FleetCrabWalk` 当前不再用几何控制器直接下发 gcp;改为 Detour 计算 `along/lateral/remain`,再写脚本 `MultiVehicleScriptVx/Vy`
3. **`MultiVehicleSyncUseDetour=true` 时的 POS 补偿与控制器抢方向盘**
- 当前 `deploy/clumsy_agv1/clumsy.json``MultiVehicleSyncUseDetour: true`
- 各车 SLAM 偏差经 `PosBias*` 叠加到 `SendMotion`,可能与几何控制器横向纠偏形成耦合振荡。
4. **动作期间关闭了 `MultiVehicleAutoUseIdealCenter`**
- 有意为之(避免 ideal 中心回灌快照、抹平真实 bias)。副作用是仅依赖「快照中心 + bias 闭环」,对快照质量更敏感。
5. **路径/起点几何**
- 起点:`TryGetFleetCenterFromSlam()`;路径:`LineTrack(x0,y0 → dst)``phi = theta + CrabAngleDeg`
-`theta` 与运行时 `CenterTh` 不一致,或 layout 反推中心与控制器使用的快照中心有系统偏差,会表现为沿某一轴漂移。
**建议下一轮日志对照**
- `FleetCrabDbg``lateral` 是否收敛、`corr/localAngle/cmd` 是否平滑、有无到达纠偏上限
- `MultiVehicleDbg``frontTh/rearTh/speed` 是否接近手动蟹行、POS/Detect 补偿是否在持续驱动,`CRAB in/raw/limit/rev` 是否显示 `raw=-95°` 这类角度未被反向等价转换
- 如需回退旧几何控制器路线,再看 `CrabDbg``bias/biasItem/gcp/fleetPos`
**2026-06-29 DLog 结论(自动蟹行仍抖动)**
- `FleetCrabDbg``along/lateral/remain/corr/localAngle/cmd` 基本平滑,横向误差多在几十 mm 内,未见路径控制器发散。
- 主/从 `MultiVehicleDbg``BASE vx` 在正负之间跳,同时 `fTh/rTh``+90°/-90°` 附近翻转;这是同一横移矢量被错误地按 ±90° 边界转换成两种等价表示,底盘执行层会看到接近 180° 的转向跳变。
- POS 补偿在该批日志中为关闭/零补偿(`corr:false``POS comp 0`),Detect 补偿有小幅值但不是主因。
- 因此本轮判定为 **mode=1 蟹行矢量合成把 ±90° 误当舵角边界**,不是优先调 `FleetCrabCorrectionGain`。Medulla 侧 `WheelAngleLowerLimit/UpperLimit` 默认约为 `-120/+120`,自动蟹行应允许 `-95°` 直接下发。
**2026-06-29 DLog 结论(±120 修复后仍 Y+ 漂移)**
- Clumsy 侧 `MultiVehicleDbg` 已显示 `CRAB raw=-9x``limit=120.0``rev:false``BASE vx` 不再正负翻转,说明上层 `mode=1` 表达已连续,剧烈抖动问题已消失。
-`FleetCrabDbg``lateral` 仍从 `0` 单调增长到约 `+171mm``corr` 到达 `-8°` 上限后无法拉回;主/从 `DETECT dy` 也增长到百毫米量级,`DETECT comp y` 达到 `20mm/s` 上限。
- 进一步检查 Playground 发现:`D:\MDCS\Source\Core\Medulla\Playground\default_scene.json` 与运行目录 `bin\Debug\net8.0\default_scene.json` 中两台 `multi-steering` 仍为 `"maxSteeringAngle": 90`,而 `ActuatorModels.cs` 会把模块舵角 clamp 到 `[-MaxSteeringAngleRad,+MaxSteeringAngleRad]`
- 这意味着 Clumsy 发出的 `-98°` 路径纠偏,在 Playground 实际执行时会被夹回 `-90°`,纠偏分量被吞掉;这比继续调 `FleetCrabCorrectionGain` 更像 Y+ 漂移的直接原因。
- 已把 Playground 源码场景和运行目录场景改为 `maxSteeringAngle: 120`,并在仿真器中加入 `multi-steering clamp` 节流日志;复测前必须重启 Playground 使场景重载。若复测时仍出现该日志,说明还有其他配置或场景副本在限制舵角。
### 2.2 两车抖动、不丝滑
**可能原因**
1. 上节 **快照 `(0,0,0)` 窗口** + 50ms 联动周期 + 50ms `DriveTaskInterval` beat frequency
2. **notify 经 GET fire-and-forget**`MultiVehicleAutoSyncReview.md` §F),从车命令阶跃
3. **`dTh` 差动 + `bias` 限幅** 在阈值边界来回切换(`DthLinearThreshold` / `BiasThreshold`
4. **`MultiVehicleSyncUseDetour` POS 补偿** 与主车控制器不同相位
5. 预热结束后 **`PrimeMasterAutoFromSlam` 不再调用**(正常);若 `WARMUP` 期间日志显示 `cnt` 反复变化,说明编队 TTL/register 不稳定
**建议对照实验**
- 手动 FleetRemote 蟹行(同速度、同角度)是否也抖
- 临时 `MultiVehicleSyncUseDetour=false` 复测
-`FleetCrabDbg``corr/localAngle/cmd``MultiVehicleDbg``frontTh/rearTh` 是否周期跳变
---
## 3. Tutorial 仓库(本仓库)
**路径**`D:\MDCS\Source\Tutorial`
**分支**`master`(截至文档编写时,自动蟹行相关改动**尚未单独 commit**,均为工作区修改)
### 3.1 已修改文件(git status
| 路径 | 作用 |
|------|------|
| `MultiWheel/MultiWheelC/MovementTests.cs` | `FleetCrabWalk` / `FleetCrabWalkTest`;预热 WARMUP;诊断 `FleetCrabDbg` |
| `MultiWheel/MultiWheelC/PilotDefinition.cs` | `TryGetFleetCenterFromSlam``PrimeMasterAutoFromSlam`;联动循环;fleet 快照 |
| `MultiWheel/MultiWheelC/PilotConfig.cs` | `FleetCrab*` 配置字段 |
| `MultiWheel/MultiWheelC/ChassisController.cs` | `MultiVehicleSendMotion` / `MultiVehicleGetFleetPos``SENDMOTION` 诊断 |
| `MultiWheel/MultiWheelC/VehicleSyncModels.cs` | 同步模型(联动机制相关) |
| `MultiWheel/MultiWheelM/MotorRoutine.cs` | Medulla 侧电机例程 |
| `deploy/clumsy_agv1/clumsy.json` | 主车 Clumsy 配置模板 |
| `deploy/clumsy_agv2/clumsy.json` | 从车 Clumsy 配置模板 |
| `docs/MultiVehicleConfig.md` | §6 自动蟹行参数说明 |
| `docs/MultiVehicleAutoSyncReview.md` | 自动联动机制问题清单 |
| `docs/RunAndDeploy.md` | 运行部署说明 |
### 3.2 相关文档(本仓库)
| 文档 | 内容 |
|------|------|
| [RunAndDeploy.md](./RunAndDeploy.md) | 编译、双车启动、端口/tag 对照 |
| [MultiVehicleConfig.md](./MultiVehicleConfig.md) | 全部联动参数;§6 自动蟹行 |
| [MultiVehicleSync.md](./MultiVehicleSync.md) | 联动算法背景 |
| [MultiVehicleAutoSyncReview.md](./MultiVehicleAutoSyncReview.md) | 自动联动已知缺陷(A–H) |
| [BugFixes.md](./BugFixes.md) | 历史修复清单 |
---
## 4. 外部仓库 / 依赖(非 Tutorial git 管理)
Tutorial 插件通过 **`D:\MDCS\Release\`** 引用预编译二进制;改 MDCSToolbox **源码后须先编译再编 Tutorial**
| 组件 | 源码 / 产物路径 | 说明 |
|------|-----------------|------|
| **MDCSToolBox** | 源码:`D:\MDCS\Source\Products\mdcstoolbox\` | 几何控制器、BasicGo、LineTrack |
| | 编译:`dotnet build D:\MDCS\Source\Products\mdcstoolbox\MDCSToolBox.csproj -c Release` | PostBuild → `D:\MDCS\Release\MDCSToolBox.dll` |
| | 蟹行相关改动:`Clumsy/MotionControllers/MultiWheelGeometricController.cs` | `CrabHoldHeading` / `CrabTargetHeading``CrabDbg` |
| | | `Clumsy/MotionControllers/AbstractGeometricController.cs` | `MultiVehicleSync` 时跳过 `firstTurnN`TODO |
| | 参考:`Clumsy/AgvInterfaces/BasicInterface.cs` | `BasicGo` + `AddTrack` 模式 |
| **Clumsy** | `D:\MDCS\Release\Clumsy\ClumsyLite.exe` | 运行时宿主 |
| **Medulla** | `D:\MDCS\Release\Medulla\` | 车体插件宿主 |
| **CommonUsage** | `D:\MDCS\Release\CommonUsage.dll` | `CommonMath`、坐标变换 |
| **FundamentalLib** | `D:\MDCS\Release\deps\RefFundamentalLib.dll` | `DLog` 落盘 |
| **Simple**(可选调度) | `D:\MDCS\Source\Core\Simple\` | `MultiWheelS``SimpleComposer.exe` |
| **Detour / Playground** | 通常随仿真环境部署 | 非 Tutorial 子目录;见 §5 运行目录 |
### 4.1 编译顺序(改动了 MDCSToolBox 时)
```powershell
# 1. 工具箱
dotnet build D:\MDCS\Source\Products\mdcstoolbox\MDCSToolBox.csproj -c Release
# 2. Tutorial 插件(MultiWheelC PostBuild 会把 Release 下 DLL 复制到 build/Clumsy*
cd D:\MDCS\Source\Tutorial
dotnet build MultiWheel\MultiWheelC\MultiWheelC.csproj
dotnet build MultiWheel\MultiWheelM\MultiWheelM.csproj
```
仅改 Tutorial 侧 C# 时,只需第二步。
---
## 5. 测试执行:程序与工作目录
`build/`**gitignore 运行目录**(首次编译后生成)。下列路径均相对于 `D:\MDCS\Source\Tutorial\`
### 5.1 双车仿真典型启动顺序
1. **Playground**(仿真场景,含 `agv_multi_1` / `agv_multi_2`
2. **Detour ×2**(工作目录一般在 Clumsy build 树下)
3. **Medulla ×2**
4. **ClumsyLite ×2**
| 角色 | 工作目录 | 主程序 | 关键配置 |
|------|----------|--------|----------|
| AGV1 主车 | `build\Medulla\` | Medulla 控制台 | `startup.iocmd``SetShareObjectTag Multi1``CarNum 1` |
| AGV1 Clumsy | `build\Clumsy\` | `ClumsyLite.exe` | `deploy\clumsy_agv1\` 模板;port **8008** |
| AGV1 Detour | `build\Clumsy\`(或同树 `Detour\` | DetourLite | HTTP **4321**tag `Multi1` |
| AGV2 从车 | `build\Medulla_AGV2\` | Medulla 控制台 | tag `Multi2``CarNum 2` |
| AGV2 Clumsy | `build\Clumsy_AGV2\` | `ClumsyLite.exe` | port **8009**master `127.0.0.1:8008` |
| AGV2 Detour | `build\Clumsy_AGV2\Detour_AGV2\` 等 | DetourLite | HTTP **4421**tag `Multi2` |
**快捷脚本**(在已配置好的 build 目录内):
- `deploy\start_clumsy_agv1.bat` → 复制配置后启动 `ClumsyLite.exe`(主车)
- `deploy\start_clumsy_agv2.bat` → 从车
- 一键 7 进程(若环境已装):`DetourLite\bin\Debug\net8.0\start_all_sim.bat`(路径见 [RunAndDeploy.md](./RunAndDeploy.md)
**编译产物落点**
| 项目 | 输出 |
|------|------|
| `MultiWheelC.csproj` | `build\Clumsy\MultiWheelC.dll` + PostBuild 同步到 `build\Clumsy_AGV2\` |
| `MultiWheelM.csproj` | `build\Medulla\plugins\MultiWheelM.dll`AGV2 Medulla 需另行复制或 PostBuild |
### 5.2 触发自动蟹行测试
1. 按上表启动双车栈
2. 主车 Medulla 开启「车队联动」(手动联调时常按 **F**;纯自动蟹行 MovementTest 依赖 `MultiVehicleAutoEnabled`,动作内会自行置位 + 预热)
3. 主车 `build\Clumsy\` 的 Clumsy UI → MovementTest → **车队联动-自动蟹行**
参数来源:`clumsy.json``msConf``PilotConfig`(未写入 json 的字段用代码默认值)。
---
## 6. DLog 日志目录与 Topic
### 6.1 落盘根目录
DLog 由 **Clumsy 进程工作目录**下的 `dlog\` 管理(FundamentalLib)。双车仿真时:
| 进程 | 日志根目录 |
|------|------------|
| 主车 Clumsy | `D:\MDCS\Source\Tutorial\build\Medulla\dlog\` |
| 从车 Clumsy | `D:\MDCS\Source\Tutorial\build\Medulla_AGV2\dlog\` |
> 说明:用户实测路径为上述两处;topic 名对应子文件夹/文件。若 Clumsy 工作目录 strictly 为 `build\Clumsy*`,也可能在 `build\Clumsy\dlog\` —— **以实际进程 cwd 下是否生成 `dlog` 为准**。
目录结构(概念上):`dlog\<TopicName>\` 下按 topic 滚动;同一 topic 的 `DLog.Log(msg, topic)` 归并到同一目录。
### 6.2 自动蟹行相关 Topic
| Topic | 来源 | 内容 |
|-------|------|------|
| **`FleetCrabDbg`** | `MovementTests.cs` | `ENTER/CENTER/START/WARMUP/ITER/DONE`,含 `along/lateral/remain/corr/localAngle/cmd` |
| **`CrabDbg`** | `MultiWheelGeometricController.cs` | 旧几何控制器路线诊断;当前脚本蟹行实现不再依赖 |
| **`MultiVehicleDbg`** | `PilotDefinition.cs` | 联动循环:速度、舵角、补偿、ready 状态 |
| **`FleetDiagClumsy`** | `PilotDefinition.cs` | 精简 fleet 诊断(带 `car{N}` 前缀) |
| **`MultiVehicle`** | `PilotDefinition.cs` | 初始化、心跳、HTTP 错误 |
| **`MotionControl`** | 控制器框架 | 通用运动控制(若启用) |
### 6.3 建议抓取顺序(排查漂移/抖动)
1. 主车 `FleetCrabDbg``WARMUP done``ITER#``lateral/remain/corr/localAngle/cmd`
2. 主车 + 从车 `MultiVehicleDbg``frontTh/rearTh``PosBias*`、是否 `ready=false`
3. 若回退旧几何控制器路线,再看主车 `CrabDbg``bias` 是否单调增大;`fleetPos` 是否偶发 `(0,0,0)`
4. 从车 `FleetDiagClumsy`:是否频繁掉线 / register 超时
---
## 7. 代码地图(数据流)
```text
MovementTest「车队联动-自动蟹行」
FleetCrabWalk.Get()
TryGetFleetCenterFromSlam() → 路径起点 (x0,y0,θ)
phi = theta + FleetCrabAngleDeg
MultiVehicleScriptEnabled = true
MultiVehicleScriptMode = 1 → 复用 FleetRemote 手动蟹行下发链路
WARMUP → 等编队成员就位
loop:
TryGetFleetCenterFromSlam() → 当前车队中心
along/lateral/remain → 沿线进度、横向偏差、剩余距离
corr = clamp(Stanley(lateral), ±FleetCrabCorrectionAngleDeg)
localAngle = (phi + corr) - currentTheta
Vx/Vy slew limit → FleetCrabCommandAccel 平滑
MultiVehicleScriptVx/Vy = cmd
PilotDefinition.TickMultiVehicle (50ms)
manual/script mode==1
Vx/Vy → speed + frontTh==rearTh
notify → 从车 SendMotion + POS/Detect 补偿
```
**对照 baseline**`PilotDefinition.cs` 手动分支 `fleetMode == 1`FleetRemote 蟹行)直接合成 `frontTh/rearTh`,不经几何控制器 `bias` 闭环。
---
## 8. 配置参数速查
### 8.1 自动蟹行专用(`PilotConfig` / `msConf`
| 字段 | 默认 | 作用 |
|------|------|------|
| `FleetCrabAngleDeg` | 45 | 路径与车队朝向夹角 (deg) |
| `FleetCrabLengthMm` | 2000 | 路径长度 (mm) |
| `FleetCrabSpeed` | 0.2 | 速度 (m/s) |
| `FleetCrabGcpThetaThreshold` | 95 | 兼容旧几何控制器实现;当前脚本蟹行不直接使用 |
| `FleetCrabCorrectionGain` | 1.0 | 横向误差纠偏增益 |
| `FleetCrabCorrectionAngleDeg` | 8 | 自动纠偏最大改向角,越小越接近手动蟹行 |
| `FleetCrabCommandAccel` | 0.4 | 脚本 `Vx/Vy` 命令斜率限制(m/s²) |
动作行为:当前不再改 `MultiVehicleAutoUseIdealCenter`,结束/急停会清零 `MultiVehicleScript*``MultiVehicleAuto*`
### 8.2 影响跟踪/手感的全局项(节选)
| 字段 | deploy 主车当前值 | 备注 |
|------|-------------------|------|
| `MultiVehicleSyncUseDetour` | **true** | 逐车 SLAM POS 补偿;怀疑与漂移/抖动相关 |
| `MultiVehicleUseDetect` | false(默认) | true 时互识别安全门 |
| `TestCarSyncDistance` | 2400 | 与 Playground 双车间距一致 |
| `MultiVehicleSyncInterval` | 50 | 联动周期 ms |
| `DriveTaskInterval` | 50 | `clumsy.json` 顶层 |
| `BiasFac` / `DthLinearFac` 等 | 继承 `MultiWheelPilotConfig` | 几何控制器 PID 形态参数 |
详见 [MultiVehicleConfig.md](./MultiVehicleConfig.md) §2–§6。
---
## 9. 已实现的关键修复(便于回溯)
| 问题 | 处理 |
|------|------|
| 自动蟹行完全不动 (`iter=0`) | 方案1`PrimeMasterAutoFromSlam` + WARMUP 后再 `Track()` |
| 蟹行要求朝向不变但有纠偏 | `CrabHoldHeading` + `CrabTargetHeading`;保留 `dTh` |
| 多车 firstTurn 破坏队形 | `MultiVehicleSync` 时跳过 `firstTurnN`TODO 整队预旋转) |
| gcp 被 45° 上限截断 | 动作侧 `GcpThetaThreshold=95` |
| ideal 中心抹平横向误差 | 动作期间关 `MultiVehicleAutoUseIdealCenter` |
| Tick 中间窗口发布 `(0,0,0)` 假中心 | 已移除 tick 开头 `PublishFleetCenter(0,0,0)` |
| 自动蟹行纠偏导致抖动 | 已改为脚本手动蟹行链路 + 小幅平滑横向纠偏 |
| 接近纯横移时速度符号/舵角表示翻转 | `fleetMode==1` 改为按 `MultiVehicleCrabSteerLimitDeg`(默认 120°)归一化;`-95°` 直接下发,超过上限才做速度取反的等价转换,并在 `MultiVehicleDbg` 输出 `CRAB in/raw/limit/rev` |
---
## 10. 后续工作建议(优先级)
1. **复测 -90° 自动蟹行**:重点看 `MultiVehicleDbg``CRAB raw=-9x``limit=120.0``rev:false`,以及 `BASE vx/fTh/rTh` 是否不再正负翻转。
2. **A/B`MultiVehicleCrabSteerLimitDeg`** 默认 120,应与 Medulla 侧 `WheelAngleLowerLimit/UpperLimit` 匹配;若实际轮角限制不同,先同步该值。
3. **A/B`FleetCrabCorrectionAngleDeg`** 先试 4、8、12:4 最接近手动,12 收敛更快;当前不再因跨 ±90° 直接翻面。
4. **A/B`MultiVehicleSyncUseDetour=false`** 若仍抖,跑同一条蟹行,区分脚本纠偏 vs POS 补偿贡献。
5. **路径误差**:若仍持续 Y+ 漂移,看 `lateral` 是否持续单向增长;若增长但 `corr` 已到上限,增大 `FleetCrabCorrectionAngleDeg``FleetCrabCorrectionGain`
6. **notify 平滑**(中长期):见 `MultiVehicleAutoSyncReview.md` §F。
---
## 11. 快速命令备忘
```powershell
# 编译
dotnet build D:\MDCS\Source\Products\mdcstoolbox\MDCSToolBox.csproj -c Release
dotnet build D:\MDCS\Source\Tutorial\MultiWheel\MultiWheelC\MultiWheelC.csproj
# 查看工作区状态
cd D:\MDCS\Source\Tutorial
git status --short
# 查看最新 FleetCrab 日志(主车,PowerShell
Get-ChildItem D:\MDCS\Source\Tutorial\build\Medulla\dlog\FleetCrabDbg -ErrorAction SilentlyContinue |
Sort-Object LastWriteTime -Descending | Select-Object -First 3
Get-ChildItem D:\MDCS\Source\Tutorial\build\Medulla\dlog\CrabDbg -ErrorAction SilentlyContinue |
Sort-Object LastWriteTime -Descending | Select-Object -First 3
```