Files
ParkingRobot/docs/architecture.md

10 KiB
Raw Permalink Blame History

系统架构

解决方案与依赖边界

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/**/*.csMedullaAdapter 只链接其需要的模型、数学、校验和底盘适配文件。CommonUsage 是独立底盘库,不反向依赖 Shared、M层或C层。来源:三个 .csproj

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] 类型由宿主发现并执行,例如 NewControllerStraight4mTestNewControllerReverseStraight4mTestNewControllerCrab45Straight4mTestTestRotateAngleCompositeStopTurnGoTest
  • MovementDefinition.Get()IEnumerable<bool> 形式协作执行:true 表示继续,结束动作时返回/产生 false 或退出枚举。具体宿主调度细节来自外部程序集,仓库内不可完全确认。

M层

  • DiverCartDefinition : MultiWheelCartDefinition 是Medulla车型定义。
  • CommunicationInit() 打开并配置MCU桥。
  • [UseLadderLogic] 注册 AlarmRoutine50ms)、MotorRoutine50ms)和 MCURoutine(20ms);这些是声明的扫描间隔,不能直接等同于实测稳定周期。
  • [UseManualController] 注册 Remote

新版轨迹跟踪调用链

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、速度有效标志和控制周期,不依赖 VehicleStateFleetState、底盘或通信。ParkingGeometricController 负责把单车状态源和实体底盘接到该核心;横向、纵向控制算法仍通过接口组合注入,没有采用控制器继承层次。

TrajectoryTrackingMovement 默认从 PilotDefinition.Conf 读取车辆级参数,同时保留少量动作级覆盖字段;横向控制器可通过 LateralControllerFactory 替换,纵向控制器当前固定创建为 PidLongitudinalController

车队组件与首版运行链

夹紧且静止时的成员世界位姿快照
  → 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、实际成员状态采集、无线串口和真实跨机时间换算。实际部署仍是每车独立电脑;主车也是普通成员,其本车命令不经传输层回环。无线实现不能改变已经定义的任务号、序列号、命令有效期和本地失联停车语义。

状态数据流

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.csMultiWheelChassis.cs::SetOriginBiasSendMotionCalculateAxes

动作组织

  • PrepareWheelsForward:停车、下发任意固定方向β并等待稳定;名称保留“Forward”,但功能已支持非零方向。
  • TrajectoryTrackingMovement:准备运动系、创建控制器、周期执行、失败停车,可选完成后回正。
  • MultiWheelRotateInPlace:准备自转舵角、交接到XYTh解算、世界航向PID、完成后回正。
  • MotionPlanExecutor:开始运动前预检全部段,顺序执行 TrackMotionPlanSegmentRotateInPlaceMotionPlanSegment,共享状态源。

构建与打包

build-and-package.ps1 顺序构建 CommonUsage、M层和C层,将新 CommonUsage.dll 复制到 ref/,最后生成 output/Moutput/C。两个部署包必须使用同一份 CommonUsage.dll。构建产物目录不作为知识来源,也不直接编辑。