Files
ParkingRobot/docs/architecture.md
T

175 lines
10 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.
# 系统架构
## 解决方案与依赖边界
`ParkingRobot.sln` 包含三个项目:
| 项目 | 目标框架 | 职责 |
| --- | --- | --- |
| `CommonUsage-MultiVehicleSync/commonusage/CommonUsage.csproj` | `netstandard2.0` | 通用底盘、轮子模型、`SendMotion`/`SendXYThSpeed`和四轮几何解算 |
| `MedullaAdapter/MedullaAdapter.csproj` | `net8.0` | Medulla M层插件、MCU/CAN/串口/IO、遥控、报警和硬件反馈 |
| `MultiWheelC/MultiWheelC.csproj` | `netstandard2.0` | Clumsy C层插件、动作、控制器、轨迹、状态估计、实验记录 |
`Shared/` 没有独立项目:`MultiWheelC` 链接全部 `Shared/**/*.cs``MedullaAdapter` 只链接其需要的模型、数学、校验和底盘适配文件。`CommonUsage` 是独立底盘库,不反向依赖 `Shared`、M层或C层。来源:三个 `.csproj`
```text
Clumsy宿主
└─ MultiWheelC
├─ Trajectory / StateEstimation / Control / Movements
├─ Shared
└─ CommonUsage.dll
Medulla宿主
└─ MedullaAdapter
├─ Shared(链接的必要文件)
├─ CommonUsage.dll
└─ mcu_serial_bridge.dll → MCU → CAN / Serial / IO
```
## 目录职责
| 路径 | 当前职责 |
| --- | --- |
| `MultiWheelC/Configuration/` | 停车控制、状态估计、原地自转和完成条件的车辆级运行参数 |
| `MultiWheelC/Trajectory/` | 弧长参数化轨迹、插值、投影和进度窗口;`LegacyTrackAdapter.cs` 目前仅占位 |
| `MultiWheelC/StateEstimation/` | Detour位姿校验/差分速度、轮组反馈速度组合与低通滤波 |
| `MultiWheelC/Control/Abstractions/` | 横向、纵向控制器接口与周期输入/输出模型 |
| `MultiWheelC/Control/Lateral/` | 当前默认 `StanleyLateralController` |
| `MultiWheelC/Control/Longitudinal/` | 当前默认 `PidLongitudinalController` |
| `MultiWheelC/Control/Allocation/` | 横纵结果组合、GCP限幅及GCP与刚体速度的转换 |
| `MultiWheelC/Control/Execution/` | `PathTrackingCore` 共享纯控制周期、单车命令执行、终点策略和耗时诊断 |
| `MultiWheelC/Movements/` | 舵轮准备、轨迹跟踪、原地自转和组合动作计划 |
| `MultiWheelC/Experiments/` | Clumsy宿主人工测试、测试轨迹工厂和CSV记录 |
| `MultiWheelC/Old/` | 保留的旧实现;不能仅因仍参与编译就视为新版流程依赖 |
| `Shared/` | M/C共享的SI数据模型、坐标变换、数值校验和底盘适配 |
| `MedullaAdapter/` | 车型定义、LadderLogic、MCU桥、CAN/串口、遥控、诊断 |
| `CommonUsage-MultiVehicleSync/commonusage/Chassis/` | 实际轮子模型、GCP/ICR求解、舵角/轮速分配和机械约束 |
| `data_process/` | 离线实验数据处理;日常代码任务不扫描其中的实验日志 |
| `参考文档/` | 参数样例和历史设计资料;不等同于运行时配置 |
## 入口与宿主生命周期
### C层
- `PilotDefinition : MultiWheelPilotDefinition<PilotConfig, PilotDefinition>` 是Clumsy车型定义和M/C IO边界。
- `PilotDefinition.Conf` 是动作读取运行配置的统一入口;`PilotConfig` 字段提供元数据和默认值。
- `[MovementTest]` 类型由宿主发现并执行,例如 `NewControllerStraight4mTest``NewControllerReverseStraight4mTest``NewControllerCrab45Straight4mTest``TestRotateAngle``CompositeStopTurnGoTest`
- `MovementDefinition.Get()``IEnumerable<bool>` 形式协作执行:`true` 表示继续,结束动作时返回/产生 `false` 或退出枚举。具体宿主调度细节来自外部程序集,仓库内不可完全确认。
### M层
- `DiverCartDefinition : MultiWheelCartDefinition` 是Medulla车型定义。
- `CommunicationInit()` 打开并配置MCU桥。
- `[UseLadderLogic]` 注册 `AlarmRoutine`50ms)、`MotorRoutine`50ms)和 `MCURoutine`(20ms);这些是声明的扫描间隔,不能直接等同于实测稳定周期。
- `[UseManualController]` 注册 `Remote`
## 新版轨迹跟踪调用链
```text
MovementTest / MotionPlanExecutor
→ TrajectoryTrackingMovement.Get()
→ PrepareWheelsForward(DirectionRadians=β)
→ MultiWheelChassisAdapter.ActivateMotionFrame(β)
→ ParkingVehicleStateProviderFactory.Create()
→ ParkingGeometricController.Start()/ExecuteCycle()
→ IVehicleStateProvider.TryGetState()
→ PathTrackingCore.Compute()
→ TrajectoryProjector.Project()
→ ILateralController.Compute()
→ ILongitudinalController.ComputeSpeedMetersPerSecond()
→ GcpCommandAllocator.Allocate()
→ GcpCommandExecutor.Execute()
→ GcpKinematics.ToBodyTwist()
→ MultiWheelChassisAdapter.SendBodyTwist()
→ MultiWheelChassis.SendMotion()
→ 四个真实舵轮角度和速度
```
`PathTrackingCore` 只依赖受控刚体的 `Pose2D`、车体系 `Twist2D`、速度有效标志和控制周期,不依赖 `VehicleState``FleetState`、底盘或通信。`ParkingGeometricController` 负责把单车状态源和实体底盘接到该核心;横向、纵向控制算法仍通过接口组合注入,没有采用控制器继承层次。
`TrajectoryTrackingMovement` 默认从 `PilotDefinition.Conf` 读取车辆级参数,同时保留少量动作级覆盖字段;横向控制器可通过 `LateralControllerFactory` 替换,纵向控制器当前固定创建为 `PidLongitudinalController`
## 车队组件与首版运行链
```text
夹紧且静止时的成员世界位姿快照
→ FleetLayoutCapture.Capture()
→ 初始FleetPoseInWorld + 不可变FleetLayout
成员状态样本 FleetMemberStateSample[]
→ FleetStateEstimator.Estimate()
→ FleetState + FleetMemberLayoutError[]
→ FleetCoordinator.ExecuteCycle()
→ FleetController(虚拟中心轨迹闭环和固定β_fleet)
→ 相对布局误差统一速度缩放
→ FleetKinematics.Decompose()
→ FleetMemberCommandCorrector
→ FleetMemberCommand[]
车队动作主要滚动方向β_fleet
→ FleetPreparationCoordinator(换算每车β_i并等待全员Ready)
→ FleetMemberAgent(本车停车准备、舵轮到位、激活、Execute/Stop
主车FleetCommand
→ IFleetTransport
→ 从车FleetMemberAgent
从车FleetMemberReport
→ IFleetTransport
→ 主车状态缓存 / FleetSafetySupervisor
FleetRuntime
├─ 主车:准备屏障 → 状态/安全 → FleetCoordinator → 本车执行/远端分发
└─ 从车:接收命令 → FleetMemberAgent → 本地看门狗 → 状态上报
```
`FleetLayoutCapture` 只负责固定布局的几何计算:车队原点X/Y取成员车体中心的算术平均,车队Yaw取主车Yaw,再把各成员世界位姿反变换为 `VehicleLayout.PoseInFleet`。它不读取通信或Detour,也不负责静止/夹紧确认、时间对齐和布局激活。
`Shared/Fleet/FleetProtocol.cs` 已定义最小任务命令和成员报告值类型,`IFleetTransport` 已把运行逻辑与无线串口或内存队列隔离;测试项目中的 `InMemoryFleetTransport` 只用于无通信硬件验证,不进入正式部署。`FleetSafetySupervisor` 在主车侧按成员报告接收时间、状态和故障锁存整队停车决定,`FleetMemberAgent.UpdateCommandWatchdog()` 在每辆车本地按命令有效期独立停车,避免通信中断时只依赖主车广播停止。
`MultiWheelC/Fleet/FleetRuntime.cs` 已贯通首版固定布局滚动任务:同一类型按 `selfVehicleId`/`leaderVehicleId` 区分角色;主车执行β准备、全员Ready、统一激活、状态缓存、安全判定、周期协调、本车直接执行和远端分发;从车执行任务/序列校验、舵轮准备、激活、速度命令、本地看门狗和状态上报。完成、通信/状态/成员故障和取消都会由运行层转换为本车停车及可达成员停止命令,失联成员最终由本地命令有效期兜底。
当前端到端链路只通过测试项目的内存传输验证,尚未接入C层正式 `Movement/Experiment`、实际成员状态采集、无线串口和真实跨机时间换算。实际部署仍是每车独立电脑;主车也是普通成员,其本车命令不经传输层回环。无线实现不能改变已经定义的任务号、序列号、命令有效期和本地失联停车语义。
## 状态数据流
```text
DetourInterface.getCartLocation()
→ DetourVehicleStateProvider
├─ 位姿单位转换、重复帧处理、跳变/预测残差校验
└─ VelocityEstimator2DDetour差分Vx/Vy/Omega
MultiWheelChassis.GetCarSpeed(true)
→ WheelFeedbackVehicleStateProvider
├─ Vx、Vy分别使用同一时间常数低通滤波
├─ 轮组估计有效后覆盖Detour的Vx、Vy和Omega
└─ 保留Detour位姿
→ VehicleState(世界位姿、世界Twist、车体Twist)
→ ParkingGeometricController
```
## 运动坐标系与四轮解算数据流
`MultiWheelChassisAdapter` 对外只接收真实车体系 `Twist2D`。滚动动作开始前先固定运动方向β:
1. `ActivateMotionFrame(β)` 调用 `MultiWheelChassis.SetOriginBias(0,0,-β)`
2. 车体线速度通过 `R(-β)` 表达到运动坐标系。
3. 运动系中以 `±ControlPointRadius` 作为虚拟前后GCP,计算GCP方向。
4. `MultiWheelChassis.SendMotion` 由两个GCP方向求瞬时旋转中心ICR。
5. 每个真实轮子的 `PhysicalPosition` 被旋转成运动系 `Position`,再由ICR分别求切线角和速度半径比例。
6. `sTh - sw.ZeroDirection` 把运动系方向转成真实舵轮机械命令;距离和速度大小不因坐标旋转改变。
关键位置:`Shared/Chassis/MultiWheelChassisAdapter.cs``MultiWheelChassis.cs::SetOriginBias``SendMotion``CalculateAxes`
## 动作组织
- `PrepareWheelsForward`:停车、下发任意固定方向β并等待稳定;名称保留“Forward”,但功能已支持非零方向。
- `TrajectoryTrackingMovement`:准备运动系、创建控制器、周期执行、失败停车,可选完成后回正。
- `MultiWheelRotateInPlace`:准备自转舵角、交接到XYTh解算、世界航向PID、完成后回正。
- `MotionPlanExecutor`:开始运动前预检全部段,顺序执行 `TrackMotionPlanSegment``RotateInPlaceMotionPlanSegment`,共享状态源。
## 构建与打包
`build-and-package.ps1` 顺序构建 `CommonUsage`、M层和C层,将新 `CommonUsage.dll` 复制到 `ref/`,最后生成 `output/M``output/C`。两个部署包必须使用同一份 `CommonUsage.dll`。构建产物目录不作为知识来源,也不直接编辑。