# 系统架构

## 解决方案与依赖边界

`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
      ├─ 位姿单位转换、重复帧处理、跳变/预测残差校验
      └─ VelocityEstimator2D：Detour差分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`。构建产物目录不作为知识来源，也不直接编辑。
