Files
StandardSence/StandardScene拆分计划.md
T
2026-06-14 11:19:15 +08:00

51 KiB
Raw Blame History

StandardScene 插件化拆分计划(导航场景插件化 · Phase C 落地)

版本:草案 v2(按评审反馈更新) 编写依据:对当前工程 E:\Work\Core\Simple-FR\StandardSence.NET Framework 4.8 单体插件)的逐文件精读。 上游设计:承接并细化《配置向导与导航场景插件化设计.md》第 5 节「StandardScene 拆分」与第 11.3 节「Phase C」。 本文目标:把上游"框架级"拆分意图,落地为基于真实代码事实、可直接执行的文件级/类级拆分计划。 范围声明:本文原为计划文档自「会话1」(2026-06-09) 起已开始落地实施,实际进度与代码现状见 §11 实施进度记忆(含已落地改动、当前可编译状态、待确认阻塞项)。

⚠️ 架构决策变更(2026-06-12,用户拍板):「磁 / 二维码 / 激光」三场景 → 两场景平台

原计划的 Magnetic / QrCode / Laser 三个导航 dll 调整为 两个场景平台插件(已落地,全解决方案 0 错误):

插件 dll scene id 内容 说明
StandardScene.Magnetic.dll scene.mag Kiva、MultiWheelLifterCar + MagneticTrackCoder 磁导航平台(保留车型上的 Qr 地标段能力)
StandardScene.QrLidar.dll scene.qrlidar Forklift、MultiWheelForkLifter、DualLiftingCar、MultiVehicleCar、ArmCar + SyncQrMap 激光+二维码融合平台:激光坐标导航由内核 GhostCar.BasicGo 兜底,QrGo 按轨道 tag 逐段触发,融合或单独使用均可
StandardScene.Devices.dll scene.device 不变 清单 id 由 devices 规范化
StandardScene.Protocol.VDA5050.dll scene.vda5050 不变 清单 id 由 protocol.vda5050 规范化

关键机制结论与配套改动:

  1. 车型按平台归位(推翻 v2 "车型留基座"):依据 = 项目存档按短类名JSONLoadertype.Name.ToLower())匹配车型,类迁 dll 不破坏旧存档;coder 特性 GetCustomAttributes(inherit:true) 沿继承链收集,内核 GhostCar 的 BasicGo 天然被所有车型继承。
  2. 共享字段袋下沉基座KivaFields.cs / MultiWheelLifterFields.csArmCar、MultiVehicleCar 跨平台继承它们);IScriptErrorRecoverable 接口解耦 AbstractLoopMission 对 Kiva 的反向依赖。
  3. 清单命名修正:内核只识别 <dll>.scene.json,原裸 scene.json 永远不会被扫描到——已全部改名并规范 id。
  4. 内核配套Simple 仓库):① Startup.LoadPlugins 两阶段加载——清单 requiresCore 声明的基座(StandardScene.dll)自动并入 alwaysLoad 且 non-collectible 先行加载(否则衍生插件的 collectible ALC 解析不到基座,运行期必炸);② SceneManifest.navKinds 多导航声明 + INavigationProfile.Kindsqrlidar 同时覆盖 Laser+QrCodeFindByKind 按集合匹配);③ ShouldLoad 规则改为「有清单(含设备/协议)即参与激活判定,无清单兼容全加载」,scene.device 因此可被选择性加载。
  5. 平台配套Migu2.0):DeploymentProfile.NavKindToSceneId 改映射 magnetic→scene.mag、qrcode/laser→scene.qrlidar;向导写 active-scenes.json 时固定并入 scene.device。

v2 评审反馈要点(本次更新依据)

  1. 宿主切换StandardScene 改为依赖 SimpleLitenet8.0SimpleComposer.exenet4.8)废弃。内核引用层(命名空间 SimpleComposer.RCSSimpleLite.RCS 等)正由另一个 AI 会话同步改造,本文按新宿主表述。
  2. 目标框架统一 net8.0(与 SimpleLite 一致;非 net8.0-windows)。SimpleLite UI 采用 CycleGUI、WebApi 采用 EmbedIO,故 StandardScene 需去除 WinForms 依赖,窗体迁移到 CycleGUI 或平台 Web。
  3. 设备驱动必须独立 dll,且支持热卸载/加载(配合 SimpleLite /plugins reload/unload + collectible ALC)。
  4. FactoryTest 与松灵残留:直接删除,不纳入 Core,也不纳入 Customer。
  5. WebApi.cs 是面向老平台的 Nancy 接口:本次整理后暂留 Core后期废弃,能力迁移到 SimpleLite 接口(见 E:\Work\Core\Simple-FR\Simple\SimpleLite\Docs\MIGU-API.md)。此版本先保留。

0. TL;DR(结论先行)

  1. 导航方式与车型是正交的两个维度。导航(磁 / 二维码 / 激光)由轨道/站点字段 + TrackCoder决定,不是车型固有属性;同一车型(如 Kiva)的类上同时挂磁、二维码、激光避障三类 coder。上游"按车型整包切到某导航 dll"切不干净,修正为「车型留基座 + 导航能力抽离为可插拔 coder」。
  2. 激光"避障"(LidarArea) ≠ 激光"导航定位"(LidarMap/SLAM):避障通用留 Core,仅 SLAM 地图进 Laser。
  3. WebApi.cs(123KB) 是老平台 Nancy 接口,导航耦合极弱(仅二维码 QrMap、激光 getLidarMap)。整理后暂留 Core,标记 deprecated,后期迁 SimpleLite EmbedIO 接口(§4.7 给出端点映射)。
  4. 存在大量重复代码可借本次"抽离标准功能"沉淀:磁导航循迹器写了两份newReset/newTrafficReset 在 3 个车型复制、SetDisplayInfo/GetCarStatus/Mstsc/EmergencyStop 雷同。
  5. 三个正交维度:①导航(磁/二维码/激光) ②车型(顶升/叉车/Kiva/机械臂…) ③设备驱动(充电桩/门/按钮盒)。设备驱动独立成可热插拔 dll
  6. VDA5050 是自成一体的 MQTT 协议栈,独立 dll。
  7. 两大技术主线:① 把 TrackCoder 从"编译期特性硬绑定车型"改为"导航插件运行期注册",需内核 SimpleCore 配合;② net4.8 → net8.0 迁移:换宿主(SimpleComposer→SimpleLite+ 去 WinForms(窗体迁 CycleGUI/Web

1. 现状盘点(基于代码事实)

1.1 工程概况(来自 StandardScene.csproj

现状 目标(本次方向)
输出类型 Library(插件) 多个 Library 插件 dll
目标框架 .NET Framework 4.8 net8.0(与 SimpleLite 一致,去 WinForms
宿主 SimpleComposer.exe(net4.8) SimpleLite(net8.0),老 Composer 废弃
契约引用 RefSimpleCore.dll + SimpleComposer.exe SimpleCore(netstandard2.0/net8) + SimpleLite 程序集
UI System.Windows.Forms(大量窗体) CycleGUI / 平台 Web(移除 WinForms
对外接口 WebApi.csNancy 1.4.5 暂留 Core;后期迁 SimpleLite EmbedIOMIGU-API
其它程序集 CommonUsageMDCSToolBoxleegKeys-sdkLessokajiWeaverUtilities 随归属 dll 保留/下沉
NuGet MQTTnetEasyModbusTCPIoTClientJintNancy(1.4.5)Newtonsoft.JsonDocumentFormat.OpenXml 随归属拆分(Nancy 验证 net8 兼容或对齐 SimpleLite 的 Nancy 2.0
产物落地 PostBuildEvent 拷 dll → build\plugins\ 各 dll + scene.json → SimpleLite plugins\

1.2 模块与文件分组(约 110 个有效 .cs

目录 内容 现状性质
CarTypes/ ForkliftKivaArmCarDualLiftingCarMultiWheelForkLifterMultiVehicleCarMultiWheelLifterCarDummyCarUselessCarBasicFieldsVehicleMonitor(窗体) 车型 + 内联导航 coder
CarTypes/VDACar/ VDA5050CarVDA5050Commons/Helper/Interface/Segment/WebApiMasterMQTTCommunicationTextViewer(窗体) VDA5050 通信协议栈
Chained/(含 Loop/ 搬运/环线任务 + DeliveryViewer/LoopViewer(窗体) 任务调度
Charge/ 充电任务 + ChargeStation*/ChargeStrategy*/Alarm*/Communication* + 多个 *Form(窗体) 充电逻辑 + UI/服务
ChargeStationType/ AbstractChargeStationFL/MuXing/PCB 充电桩厂商驱动
InterLock/ AbstractInterlockMissionTrafficInterlockMissionTrafficInterlockViewer(窗体) 互锁/交管
Scheduler/ HeartBeat/NodeIsEnable/RegionalTrafficControl/SecuritySignal Mission 调度信号
ExtendDevice/Door/ BasicDoorControllerModbusDoorControllerDoorMissionDoorTypeAttributeDoorManager/DoorMonitor(窗体) 门控驱动
ExtendDevice/ButtonBox/ BasicButtonBoxLeegButtonBox/AzowieButtonBoxButtonMissionButtonBoxManager(窗体) 呼叫器驱动
Model/ Map(含 LidarMap)、SimpleMapTaskModelLoopTask、各 *SettingVehicleStatusMissionStateMapStructure 数据模型
Utils/ TCP/ CommonTools/ Json/Modbus/WebAPIHelper、AsyncTcpClient、Snowflake/AtomicFile 基础设施
Commons.csHeuristic.csLadderLogic.csStandardCADTool.csWebApi.csFactoryTest.cs 公共 + 契约 + 老 API + 产测

1.3 车型清单与继承

车型类 [CarType] 基类 关键特征
Kiva "Kiva" GhostCar 内联磁 coder AllCarMagTrackCoder + Qr + 避障 + 取放货 + KivaCarTrackCoder(转弯)
Forklift "叉车" GhostCar 避障 + 取放货(无显式磁/二维码)
MultiWheelLifterCar(CarTypes) "多舵轮顶升车" GhostCar 内联磁 coder MagTrackCoder + Qr + 钻车/夹抱
MultiWheelForkLifter "多舵轮叉车" GhostCar 简化取放货
MultiVehicleCar "多车联动AGV" GhostCar 多车 sync + Qr + 钻车
DualLiftingCar "锂电双举升" GhostCar 无 coder(仅 UI/测试)
ArmCar "ArmCar" GhostCar 机械臂动作;依赖 VDA5050SiteField、继承 Kiva*Fields
DummyCar "模拟车-包络" Car 命名空间 AMRScene1Jint 仿真
UselessCar (已注释,未注册) GhostCar 测试残留

1.4 Mission 继承体系(均派生内核 Mission,导航无关)

Mission
├─ AbstractChainedDeliveryMission / ChainedDeliveryMission(→TransportDelivery)   Chained/
├─ AbstractLoopMission(→LoopMission)                                             Chained/
├─ TrafficInterlockMission / AbstractInterlockMission                            InterLock/
│   └─ AbstractChargeLogiceMission(→StandardChargeMission)                       Charge/
├─ HeartBeat/NodeIsEnable/RegionalTrafficControl/SecuritySignal Mission          Scheduler/
├─ DoorMission / ButtonMission                                                   ExtendDevice/
└─ FactoryTest(产测,本次删除)                                                  根

1.5 设备驱动体系(第三正交维度,本次独立 dll + 热插拔)

  • 充电桩:AbstractChargeStationFLChargeStation / MuXingChargeStation(牧星) / PCBChargeStationChargeStationType 枚举;StandardChargeMissioncar.fields["MuXing"] 区分 FRLD/MuXing。
  • 门:BasicDoorControllerModbusDoorControllerDoorTypeAttribute(注册契约)。
  • 按钮盒:BasicButtonBoxLeegButtonBox(依赖 leegKeys-sdk/leegiot) / AzowieButtonBox

1.6 VDA5050 子系统(独立 MQTT 协议栈)

  • VDA5050Car : Car + MasterMQTTCommunication + VDA5050Interface/Helper/Commons/Segment/WebApi + TextViewer(窗体);依赖 CommonUsage.Protocols.VDA5050.* + MQTTnet
  • VDA5050 车端自管导航定位,与磁/二维码/激光维度无关。
  • 耦合点:ArmCar 引用 VDA5050SiteField(拆分时解依赖)。

1.7 删除项(拆分前清理,不进 Core/Customer

文件/类 原因 处置
FactoryTest.cs 产测专用,非标准能力 删除(评审已确认)
SongLingDeliveryViewer.Designer.cs 松灵客户残留,仅 .Designer.cs、无主文件、未被 csproj 收录 删除
MultiWheelLifterCar.cs CarTypes/MultiWheelLifterCar.cs 重名旧文件,未被 csproj 收录(死文件) 删除
CarTypes/UselessCar.cs [CarType] 已注释、仅反射示例 删除(或移测试样例)

2. 关键洞察(精读结论 → 对上游设计的修正)★

2.1 洞察 A:导航是"轨道/站点字段 + Coder",与车型正交

  • CarTypes/BasicFields.cs:23 TagValue //磁导航,二维码值,或者rfid 值(站点字段)。
  • 磁:Kiva.cs:37CarTypes/MultiWheelLifterCar.cs:34 track.fields["Magnet"]/NaiveMagnet(轨道字段)。
  • 二维码:车型 coder useVerb="dst.tag>0 && src.tag>0"agv.QrGo(...)
  • 激光避障:useVerb="track.LidarArea != -2"agv.SwitchLidarArea(...)
  • 结论:同一车型在不同轨道字段下走不同 coder 分支;按车型切 dll 会复制车型或丢能力。

2.2 洞察 B:导航逻辑以"特性"内联在车型,且多导航混杂

  • [TemplateTrackCoderSettings]/[ProgramTrackCoderSettings(program=typeof(...))] 编译期硬绑定到车型类型。
  • Kiva 同时挂磁(prio19)+二维码(prio30)+避障+取放货。
  • 结论:导航 dll 要可插拔地为车型提供 coder,必须把 coder 外置并由内核支持运行期注册(§7.1)。

2.3 洞察 C:激光"避障" ≠ 激光"导航定位"

  • 避障:LidarArea/SwitchLidarArea/ChangeAvoidanceDistance/FrontLidarDetect——几乎所有车型都有,通用 → Core。
  • 定位:Model/Map.cs:183 LidarMap(拉 127.0.0.1:4321 SLAM 栅格) + WebApi.cs:1021 /map/getLidarMap → Laser。

2.4 洞察 D:可"抽离为标准功能"的重复代码

重复项 位置 抽离目标
磁循迹器(选路+MagGo/NaiveMagGo Kiva.cs:32 AllCarMagTrackCoderCarTypes/MultiWheelLifterCar.cs:29 MagTrackCoder 合并为唯一 MagneticTrackCoder(Magnetic dll)
newReset/newTrafficReset Kiva.cs:715Forklift.cs:279CarTypes/MultiWheelLifterCar.cs:347 上提 Core 车型基类
SetDisplayInfo 各车型雷同 Core 基类默认实现
Mstsc/EmergencyStop/ResetClumsy(HTTP:8008) 多车型重复 Core 基类
避障/IO/纠偏 coder 模板 各车型重复粘贴 Core 通用 coder 模板集
GetCarStatus CommonsMultiWheelForkLifter 各一份 统一 Commons

2.5 洞察 EWebApi.cs 是老平台 Nancy 接口,整体面临废弃

  • ApiController : NancyModule(WebApi.cs:35)40+ 端点;导航相关仅二维码 QrMap(:38/:40/:2050)+QrSite(:2807) 与激光 getLidarMap(:1021)。
  • 其能力在 SimpleLite 已由 EmbedIO/projection/*(投影快照 + reflection + map-edit + scenes,见 MIGU-API.md)覆盖。
  • 处置(本版):整理后暂留 Core(标 [Obsolete]/注释 deprecated);后期整体废弃,迁移索引见 §4.7。

2.6 洞察 F:设备驱动是第三个正交维度(本次独立 dll + 热插拔)

  • 充电桩/门/按钮盒按厂商/型号扩展,与导航、车型都正交。
  • 通过既有特性(ChargeStationType/DoorTypeAttribute/新增 ButtonBoxType)注册,编译为独立 Devices.* dll,支持 SimpleLite /plugins 热加载/卸载。

2.7 洞察 GUI 形态需从 WinForms 迁到 CycleGUI/Webnet8.0 约束)

  • SimpleLite = net8.0(纯)、UI 用 CycleGUI、WebApi 用 EmbedIO不依赖 System.Windows.Forms
  • StandardScene 现有窗体:DeliveryViewer/LoopViewer/TrafficInterlockViewer/VehicleMonitor/各 Charge*Form/Door*/ButtonBox*/TextViewer + CommonsMessageBox
  • 统一 net8.0 ⇒ 必须移除 WinForms:窗体迁 CycleGUISimpleLite 立即模式 UI)或平台 WebMessageBox 类提示改 CycleGUI 弹窗 / 平台通知。这是本次重要工作量与风险

3. 目标架构与目录规划

3.1 分层依赖图

flowchart TD
    SC["SimpleCore (netstandard2.0/net8)<br/>AbstractCar/CarType/Mission/ITrackCoder/Heuristics<br/>+ 导航契约 NavKind/INavigationProfile/ISceneContext<br/>+ (新增)TrackCoder 运行期注册表"]
    SL["SimpleLite (net8.0 宿主)<br/>CycleGUI UI · EmbedIO WebApi · /plugins 热插拔 · /scenes 选择性加载"]
    CORE["StandardScene.Core (net8.0)<br/>导航无关基座:车型本体+任务/充电/互锁/调度+模型/工具+Commons+通用避障coder<br/>(暂留)WebApi.Core(Nancy, deprecated)"]
    MAG["StandardScene.Magnetic"]
    QR["StandardScene.QrCode"]
    LAS["StandardScene.Laser"]
    VDA["StandardScene.Protocol.VDA5050"]
    DCH["StandardScene.Devices.Charge<br/>(热插拔)"]
    DDR["StandardScene.Devices.Door<br/>(热插拔)"]
    DBT["StandardScene.Devices.ButtonBox<br/>(热插拔)"]

    SC --> CORE
    SC --> SL
    CORE --> MAG & QR & LAS & VDA & DCH & DDR & DBT
    SL -. 加载/卸载 .-> CORE & MAG & QR & LAS & VDA & DCH & DDR & DBT

3.2 解决方案目录布局(单工程 → 多工程,统一 net8.0)

StandardScene/                          解决方案根
├─ StandardScene.Core/                  net8.0,标准基座(alwaysLoad,不单独作为导航场景)
│   ├─ Navigation/                      INavigationProfile/NavKind/ISceneContext/Registry
│   ├─ Cars/                            车型基类 StandardCarBase + 各车型本体(无导航 coder、无 WinForms
│   │   └─ Sim/                         DummyCar(仿真,AMRScene1 命名空间收敛)
│   ├─ Coders/                          通用 coder(避障/IO/纠偏/取放货模板)
│   ├─ Chained/ Charge/ ChargeStationType(抽象) / InterLock/ Scheduler/
│   ├─ ExtendDevice/                    设备框架(基类 + 注册特性)
│   ├─ Model/ Utils/ TCP/ CommonTools/
│   ├─ Ui/                              CycleGUI 面板(替代原 WinForms 窗体)
│   ├─ Commons.cs Heuristic.cs LadderLogic.cs StandardCADTool.cs
│   └─ WebApi.Core.cs                   老 Nancy APIdeprecated,暂留,后期删)
├─ StandardScene.Magnetic/             → plugins/ + scene.json
├─ StandardScene.QrCode/               → plugins/ + scene.json
├─ StandardScene.Laser/                → plugins/ + scene.json
├─ StandardScene.Protocol.VDA5050/     → plugins/ + scene.json
├─ StandardScene.Devices.Charge/       → plugins/(热插拔)
├─ StandardScene.Devices.Door/         → plugins/(热插拔)
├─ StandardScene.Devices.ButtonBox/    → plugins/(热插拔)
└─ StandardScene.sln

3.3 各 dll 职责

dll 职责 可激活/热插拔
StandardScene.Core 导航无关一切:车型本体、任务/充电/互锁/调度、模型/工具、Commons/契约、通用避障 coder、(暂留)老 WebApi 基座(alwaysLoad
StandardScene.Magnetic 统一 MagneticTrackCoder + 磁条字段语义
StandardScene.QrCode QrTrackCoder + SyncQrMap + 二维码地图下发
StandardScene.Laser LidarMap/getLidarMapSLAM
StandardScene.Protocol.VDA5050 VDA5050/MQTT 协议栈 + VDA5050Car
StandardScene.Devices.Charge 充电桩 FL/MuXing/PCB 驱动 是(热插拔)
StandardScene.Devices.Door 门 Modbus 驱动 是(热插拔)
StandardScene.Devices.ButtonBox 按钮盒 Leeg/Azowie 驱动 是(热插拔)

4. 功能归属矩阵(文件级 / 类级)★

动作:移动/拆分/抽离/保留/删除/迁UI(WinForms→CycleGUI/Web)/待复核

4.1 车型(CarTypes/

现状 目标 动作 说明
BasicFields.cs Core 移动 车型公共字段
Kiva.cs::Kiva Core(Cars) 拆分 本体留 Core;移除内联磁/Qr coder 特性
Kiva.cs::AllCarMagTrackCoder Magnetic 抽离 并入唯一 MagneticTrackCoder
Kiva.cs::KivaCarTrackCoder Core(Coders) 移动 转弯,导航无关
Forklift.cs Core(Cars) 移动 通用避障/取放货
CarTypes/MultiWheelLifterCar.cs::MultiWheelLifterCar Core(Cars) 拆分 本体留 Core;移除内联磁/Qr
CarTypes/MultiWheelLifterCar.cs::MagTrackCoder Magnetic 抽离 并入 MagneticTrackCoder(去重)
MultiWheelForkLifter.cs Core(Cars) 移动 GetCarStatus 并入 Commons
MultiVehicleCar.cs Core(Cars) 拆分 联动留 CoreQr coder 外移 QrCode
DualLiftingCar.cs Core(Cars) 移动 无 coder
ArmCar.cs Core(Cars) 拆分/解耦 解除 VDA5050SiteField 依赖
DummyCar.cs Core(Cars/Sim) 移动 AMRScene1 命名空间收敛
UselessCar.cs 删除 未注册
VehicleMonitor.cs(.Designer) Core(Ui) 迁UI WinForms → CycleGUI

4.2 VDA5050CarTypes/VDACar/

现状 目标 动作
VDA5050* + MasterMQTTCommunication Protocol.VDA5050 移动(整子目录)
TextViewer.cs(.Designer) Protocol.VDA5050(Ui) 迁UICycleGUI
VDA5050SiteField(被 ArmCar 引用) Core 公共字段 或 VDA dll 待复核(ArmCar 留 Core 则下沉 Core

4.3 任务族(Chained/ InterLock/ Scheduler/

现状 目标 动作
Chained/*InterLock/*Scheduler/* 逻辑 Core 移动(导航无关)
DeliveryViewer/LoopViewer/TrafficInterlockViewer(窗体) Core(Ui) 迁UICycleGUI/Web

4.4 充电(Charge/ ChargeStationType/

现状 目标 动作
AbstractChargeLogicMissionStandardChargeMission Core 移动 充电逻辑
ChargeStation*/ChargeStrategy*/Alarm*/Communication*(服务) Core 移动 充电管理/服务
Charge/*Form(窗体) Core(Ui) 迁UI CycleGUI/Web
ChargeStationType/AbstractChargeStation.cs Core 移动 抽象 + 注册契约
ChargeStationType/{FL,MuXing,PCB}ChargeStation.cs Devices.Charge 拆分 厂商驱动,独立热插拔 dll

4.5 扩展设备(ExtendDevice/

现状 目标 动作 说明
Door/BasicDoorControllerDoorMissionDoorModelDoorTypeAttribute Core(框架) 移动 门控框架 + 注册契约
Door/ModbusDoorController Devices.Door 拆分 Modbus 驱动,独立热插拔
Door/DoorManager/DoorMonitor(窗体) Core(Ui)/Devices.Door(Ui) 迁UI CycleGUI
ButtonBox/BasicButtonBoxButtonMissionButtonBoxModel Core(框架) 移动 按钮盒框架
ButtonBox/LeegButtonBox(leegKeys-sdk)、AzowieButtonBox Devices.ButtonBox 拆分 厂商驱动,leegKeys-sdk 随驱动走
ButtonBox/ButtonBoxManager(窗体) 对应 dll(Ui) 迁UI CycleGUI

4.6 公共 / 契约 / 模型 / 基础设施

现状 目标 动作 说明
Commons.cs::Commons Core 移动 解除对 DummyCar 硬引用(GetVehicleStatus
Commons.cs::CustomOperationsBeforeLoading 各可激活 dll 各一份 复制/分发 MessageBox 死锁提醒改 CycleGUI 弹窗
Commons.cs::NoReflectionApi/ReflectionApiWithParameter SimpleCore 或 Core 待复核 多 dll 共用建议下沉 SimpleCore
Heuristic.cs Core 移动 启发式(宿主反射注册)
LadderLogic.cs Core 移动 防抖/梯形逻辑
StandardCADTool.cs(多数 CADTool Core 移动 地图编辑工具
StandardCADTool.cs::SyncQrMap QrCode 拆分 二维码地图下发
Model/Map.cs::Map/ArcHelper Core 移动 地图序列化
Model/Map.cs::LidarMap Laser 拆分 SLAM 栅格图
Model/*(其余) Core 移动 数据模型
Utils/*TCP/*CommonTools/* Core 移动 基础设施
FactoryTest.cs 删除 评审确认
MultiWheelLifterCar.cs、根 SongLingDeliveryViewer.Designer.cs 删除 死/残留

4.7 老 WebApiWebApi.cs)整理与迁移索引

本版处置:通用端点整理为 WebApi.Core.cs 暂留 Core 并标 deprecated;二维码/激光端点随导航 dll;后期整体删除,前端改用 SimpleLite 接口。下表为废弃迁移索引(老 Nancy → SimpleLite EmbedIO,依据 MIGU-API.md):

老端点(WebApi.cs 行号 SimpleLite 替代(/api/sl/projection/...
car_reflection/mission_reflection get_type/methods/fields/execute 191537 reflection/methods/*/fields/*/execute/*/bundle/*
car/getAllCarsapi/agv/list 1047、2095 projection/cars
task/getTask 1099 projection/missions
map/getMap 995 projection/sites+/tracks、或 map-edit
car/goSite 1070 reflection/car/{id}/goto-site
car/reset/repair/blown/ForceStop/ReStart/... 767+ reflection/execute/{kind}/{id}/{method}[MethodMember]
car/createTask/carTask/cancelTask 542/597/900 reflection/execute + projection/deliveries/*
set{Charging,Envelope,TrafficControl,PlanRules}Setting 1680+ reflection/fields/{kind}/{id}/{field}(写字段)
api/CreateSite 2055 map-edit/objects/site
api/QrMap(二维码) 2050 暂随 QrCode dllSimpleLite 侧待新增(无直接对应)
map/getLidarMap(激光) 1021 暂随 Laser dllSimpleLite 侧待新增(无直接对应)

注:二维码地图下发、激光 SLAM 取图在 SimpleLite 现有 MIGU-API 中无直接对应,迁移时需在 SimpleLite/场景插件侧补接口,故这两块随导航 dll 先行保留。


5. "抽离标准功能"清单(去重与沉淀)

  1. 统一磁导航循迹器AllCarMagTrackCoder + MagTrackCoder → 唯一 StandardScene.Magnetic.MagneticTrackCoder(参数化 fields)。
  2. 车型基类 StandardCarBase(Core):上提 newReset/newTrafficResetSetDisplayInfoMstscEmergencyStop/ReleaseResetClumsyGetCarStatus 默认实现。
  3. 通用 Coder 模板集(Core/Coders):沉淀避障/IO/纠偏/避障尺寸等重复 [TemplateTrackCoderSettings]
  4. 导航能力抽象 INavigationProfile:每个导航 dll 实现一个 Profile(声明 NavKind + 提供的 coder/字段语义),Core/宿主反射收集。
  5. Commons 去重:合并 GetCarStatusGetVehicleStatus 去除对 DummyCar 的硬编码(改标记接口)。
  6. 设备注册标准化:充电桩/门/按钮盒统一特性注册,驱动 dll 即插即用 + 热插拔。
  7. UI 标准化:原 WinForms 窗体统一迁 CycleGUI 面板(沉淀少量通用面板基类)。

6. 命名空间与依赖治理

  • 宿主/命名空间迁移SimpleComposer.RCS/SimpleComposer.UISimpleLite.RCS/对应(以内核改造为准,另一会话进行中);引用 SimpleComposer.exeSimpleLite 程序集 + SimpleCore 契约。
  • 命名空间收敛DummyCarAMRScene1StandardScene.Core.Cars.Sim
  • 去 WinForms:移除 System.Windows.Forms 引用,窗体迁 CycleGUI/WebMessageBox 改 CycleGUI 弹窗。
  • 反向依赖治理Commons.GetVehicleStatusDummyCarArmCarVDA5050SiteField;二维码相关集中 QrCode dll,Core 仅留中立扩展点。
  • 三方依赖随归属MQTTnet→VDA5050leegKeys-sdk→ButtonBox 驱动;EasyModbusTCP/IoTClient→Door/Charge 驱动或 Core 工具;Nancy→(暂留的 WebApi.Core,验证 net8 兼容或对齐 SimpleLite 的 Nancy 2.0);Jint→含 DummyCar 仿真的 Core。

7. 关键技术难点与对策

7.1 难点①:TrackCoder 由"编译期特性"改为"运行期注册"

  • 现状:coder 通过特性硬绑定车型类型。
  • 目标:导航 dll 不改 Core 车型源码即可为车型补 coder。
  • 对策:① 内核扩展(推荐)——SimpleCore 增 coder 注册表,导航 dll 在 INavigationProfile.OnActivate 注册/卸载时移除(契合 /plugins 热插拔);② 车型留占位、导航 dll 实现委派;③ 兜底——Core 内置全量 coder,导航 dll 只承载 API/地图/字段/清单。
  • 行动项:与正在改内核引用的会话同步,确认是否纳入注册表 API。

7.2 难点②:net4.8 → net8.0 迁移(换宿主 + 去 WinForms

  • 宿主:引用 SimpleComposer.exe(net4.8) → SimpleLite/SimpleCore(net8)SimpleComposer 独有类型在内核侧补齐/下沉(与另一会话协作)。
  • 去 WinForms(重点):所有窗体迁 CycleGUISimpleLite 立即模式 UI)或平台 Web;MessageBox→CycleGUI 弹窗/平台通知。工作量集中在 Charge/*FormDelivery/Loop/TrafficInterlock ViewerVehicleMonitorDoor/ButtonBox 管理窗体、VDACar/TextViewer
  • 三方库 net8 验证:Nancy(1.4.5)(暂留 WebApi,验证或升 2.0)、MQTTnet/EasyModbusTCP/IoTClient/Jint/Newtonsoft/DocumentFormat.OpenXml
  • Fody/LessokajiWeaver:与内核一致(注意上游 §13.2 环境约束)。

7.3 难点③:插件钩子与多 dll 初始化

  • CustomOperationsBeforeLoading.Set() 宿主按 dll 反射调用:拆分后每个可激活 dll 各保留一份;用 INavigationProfile.OnActivate 做导航 dll 自初始化,避免重复注册全局回调。

7.4 难点④:设备/导航 dll 热插拔(collectible 卸载)

  • 配合 SimpleLite /plugins/reload/plugins/{name}/unload/scenes/applydll 须可被 collectible ALC 干净卸载(卸载前无存活 Car/Mission 实例),OnDeactivate 清理注册的 coder/设备/回调/MQTT 连接/TCP 客户端。

7.5 难点⑤:老 WebApi 暂留与最终下线

  • WebApi.Core(Nancy) 暂留 Core 仅为过渡;新功能一律走 SimpleLite EmbedIO。按 §4.7 索引逐步迁移,迁完即删;二维码/激光取图需先在 SimpleLite/场景插件侧补接口。

8. 分阶段实施计划(务实路线)

原则:每阶段都能编译、能加载、可回退。

C0 · 准备与对齐(低风险,先做)

  • 删除:FactoryTest.cs、根 SongLingDeliveryViewer.Designer.cs、根 MultiWheelLifterCar.csUselessCar
  • 去重沉淀(§5):统一 MagTrackCoderGetCarStatus;提取 StandardCarBase
  • 命名空间收敛 AMRScene1→Core。
  • 与内核会话对齐:SimpleLite/SimpleCore 引用与命名空间、coder 注册表(§7.1)、导航契约(上游 Phase A 已就绪)。
  • 验收:编译通过、行为不变。

C1 · Core 基座 net8.0 化(换宿主 + 去 WinForms 闭环)

  • 新建 StandardScene.Core(net8.0),迁入导航无关全部内容;引用切到 SimpleLite/SimpleCore
  • 去 WinForms:窗体迁 CycleGUIMessageBox→CycleGUI。
  • 整理老 WebApiWebApi.Core(deprecated, 暂留)。
  • coder 先用兜底(§7.1 方案③)保证不回归。
  • 验收:StandardScene.Core.dll 被 SimpleLite 加载、跑通搬运/充电/交管。

C2 · 抽离导航能力 dll

  • Magnetic(唯一 MagneticTrackCoder/ QrCodeQrTrackCoder+SyncQrMap+QrMap/ LaserLidarMap+getLidarMap),各带 scene.json
  • 按 §7.1 选定方案把 coder 接到车型。
  • 验收:仅激活某导航时对应能力可用,其余不加载。

C3 · 设备驱动 dll 化(必做,热插拔)

  • Devices.Charge(FL/MuXing/PCB)、Devices.Door(Modbus)、Devices.ButtonBox(Leeg/Azowie)leegKeys-sdk 随驱动。
  • 验证 /plugins reload/unload 热插拔;OnDeactivate 清理连接。
  • 验收:设备驱动可独立热加载/卸载。

C4 · VDA5050 协议 dll

  • Protocol.VDA5050(整 VDACar/ 迁出,含 MQTT);解 ArmCar↔VDA5050SiteField
  • 验收:激活后 VDA5050 车可用、可卸载。

C5 · 联调、WebApi 迁移与文档

  • 三导航 + 设备 + 协议组合联调;对接 /scenes/apply + active-scenes.json
  • 按 §4.7 把可迁的 WebApi 端点切到 SimpleLite,逐步删 WebApi.Core
  • 更新本文件 §11 进度 + scene.json 实际清单 + README/DEVELOPMENT_GUIDE

9. 插件清单契约(scene.json,对接上游 §5.5 与 SimpleLite /scenes

{
  "id": "scene.magnetic",
  "displayName": "磁导航场景",
  "navKind": "Magnetic",
  "assembly": "StandardScene.Magnetic.dll",
  "requiresCore": "StandardScene.Core.dll",
  "provides": { "trackCoders": ["MagneticTrackCoder"], "carTypeBindings": ["*"] }
}
  • 平台「配置向导」→ WizardController 写配置 → 调 SimpleLite POST /api/sl/projection/scenes/apply(写 active-scenes.json + 增量 reload)。
  • 数据契约:data/config-deployment.json(平台)/ plugins/active-scenes.json(内核)/ plugins/<dll>.scene.json(插件)。

10. 风险、待确认与验收口径

已确认(v2

  • 宿主 = SimpleLite;老 SimpleComposer 废弃。
  • 目标框架 = net8.0(去 WinFormsUI 迁 CycleGUI/Web)。
  • 设备驱动 = 独立 dll + 热插拔。
  • FactoryTest、松灵残留 = 删除。
  • WebApi.cs = 整理后暂留 Core、后期废弃迁 SimpleLite。

待确认

  1. coder 注册表:内核是否纳入"运行期把 TrackCoder 注册到车型"的 API(否则 C2 用兜底方案③)。
  2. UI 迁移范围与节奏:窗体一次性迁 CycleGUI,还是按 dll 分批;是否部分仅保留平台 Web 入口。
  3. VDA5050 独立 dll 确认(推荐独立)。
  4. 二维码地图下发 / 激光 SLAM 取图SimpleLite 侧补接口的归属与时间点。
  5. 车型↔导航映射:是否存在车型仅支持单一导航的硬约束。

验收口径(每阶段通用)

  • 编译 0 错误;搬运/环线/充电/交管不回归。
  • 选择性加载 + 热插拔:激活集合内能力可用,未激活不加载、可干净卸载。
  • 反射 APISimpleLite /reflection)、车型/面板随已激活 dll 自然收敛。

11. 实施进度记忆(跨会话持续更新)

状态: 未开始 / 🟦 进行中 / 完成 / ⏸ 暂缓。 最近更新:会话1(续3,2026-06-09)——设备三 dll 合并为单一 StandardScene.Devices + ChangeAvoidanceParam 去重(方案 B),全解 dotnet build 0 错误。

11.0 当前代码现状(重要:已领先早期文档)

会话1 接手时发现代码已被先前会话推进,与 v2 文档/会话14交接摘要描述的「net4.8 单体、未动代码」不一致。以 StandardScene.csproj 实际为准:

早期文档记述 当前实际
目标框架 net4.8 net8.0-windows(仍 UseWindowsForms=true,过渡态,尚未去 WinForms 到纯 net8.0
宿主/契约引用 SimpleComposer.exe + RefSimpleCore 已切 SimpleLite.dll + SimpleCore.dll(netstandard2.0)
Nancy 1.4.5 已对齐 2.0.0
死代码 在仓库 csproj 已 Compile Remove,会话1 已物理删除
命名空间 SimpleComposer.RCS 车型 using 已是 SimpleLite.RCS(内核改造会话已推进)

可编译基线dotnet buildnet8.0-windowsdotnet SDK 10.0.300= 0 错误 / 47 警告(均无害:重复 using、隐藏成员 CS0108、未用变量、Thread.Abort SYSLIB0006、CS4014 未 await 等)。

11.1 步骤状态

步骤 内容 状态 说明
P0 精读现状 + 产出拆分计划 v1 逐文件精读
P0.1 按评审反馈更新 v2
路线决策 评审定 路线乙:先「纯搬运不改逻辑」的结构拆分,去重在新结构里从容做 会话1 用户拍板
C0-a 物理删除死代码 + 清理 csproj 见 §11.3
C0-b 抽离 4 个通用(导航无关) coder 并在 4 车型切换 见 §11.3;编译 0 错误
C0-c 合并两份磁循迹器为唯一 MagneticTrackCoder 用户定:采用含 track.SpeedNaiveMagGo;MWL 旧类已删、引用改向;编译 0 错误
C0-d ChangeAvoidanceParam 去重 方案 B4 参 flag 版 AvoidanceParamCoder(MWL+MultiVehicle) + 2 参 L,W 版 AvoidanceParamLWCoder(Kiva+Forklift);见 §11.4-2
C0-e 提取 StandardCarBasenewReset/Mstsc/GetCarStatus 等上提) 未启动
C0-f AMRScene1 命名空间收敛 建议并入 C1 建 Core 工程时一起做
路线乙·1 工程迁入 StandardScene.Core/ + 重写 sln(纯搬运) 编译 0 错;AssemblyName 仍=StandardScene,对外 dll 名不变
C1 去 WinForms + WebApi.Core 整理 用户暂缓(窗体后续迁 migu 平台);过渡期各工程暂 net8.0-windows
C2 Magnetic/QrCode/Laser 三导航 dll 受阻于内核 coder 注册表(§11.4-4) + 用户将自行重构 coder
C3 设备驱动 dll 化(Charge/Door/ButtonBox,热插拔) 见 §11.3-E3合为单一 StandardScene.Devices(用户定,不分多个),编译 0 错、scene.json 产出
C4 VDA5050 协议 dll 见 §11.3-E2VDACar/ 整迁出、VDA5050SiteField 下沉 Core
C5 联调 + WebApi 迁移 SimpleLite + 文档收尾 含卫星 dll→宿主 plugins/ 部署 + 真机联调(见 §11.4-5)

11.2 关键决策记录

  • 路线乙(会话1 确认):结构拆分优先、纯搬运不改逻辑;去重沉淀在新结构内做。理由:本环境无法跑真实 AGV 回归,纯搬运行为风险低、编译即可保障。
  • 导航与车型正交;导航 coder 外置为可插拔(运行期注册,内核配合;当前用兜底=Core/单体内置 coder,用户要求"先抽离合适的通用 coder")。
  • 激光避障(LidarArea)留 Core,仅 SLAM 地图(LidarMap/getLidarMap)进 Laser。
  • 设备驱动单列 Devices.* 独立 dll + 热插拔(评审确认)。
  • 宿主 SimpleComposer→SimpleLite;框架统一 net8.0UI 去 WinForms 迁 CycleGUI/Web(评审确认)。
  • FactoryTest、松灵残留删除(评审确认,会话1 已执行)。
  • WebApi.cs(Nancy) 暂留 Core、标 deprecated,后期迁 SimpleLite EmbedIO,迁移索引见 §4.7(评审确认)。

11.3 会话1 已落地改动明细(2026-06-09

A. C0 死代码物理删除(编译范围不变,0 错误)

  • FactoryTest.cs[MissionType] 展会演示进程,反射注册,无其它引用)
  • 删 根 MultiWheelLifterCar.cs(与 CarTypes/MultiWheelLifterCar.cs 重名死文件)
  • 删 根 SongLingDeliveryViewer.Designer.cs(松灵残留,无主文件)
  • CarTypes/UselessCar.cs[CarType] 已注释、未注册)
  • csproj:移除上述 3 条 Compile Remove保留 Chained\AbstractChainedDeliveryMission.cs 的 Remove(孤立未编译旧版本,去留待后续核对)

B. 抽离通用(导航无关) coder —— 新增 Coders/CommonTrackCoders.cs(命名空间 StandardScene.Coders

  • 基类 CommonTemplateTrackCoder : ITrackCoder:内部复用内核 ProgramCoderHelper.PrepareTrackEngine + Topaz 求值,useVerb/templateString 与原模板逐字一致;统一用 BasicXxxFields(这些 coder 仅引用 Basic 字段,等价)。priority 由车型 [ProgramTrackCoderSettings] 指定。
  • 4 个通用 coder
    • LidarAreaSwitchCoder(避障,track.LidarArea != -2SwitchLidarArea
    • AvoidanceDistanceCoder(无 useVerb → ChangeAvoidanceDistance(StopDistance,SlowDistance)
    • IoAreaSwitchCodertrack.IOArea != -1SwitchIoArea
    • TrackingErrThreshCoderBiasAlarmThresh>0||DthAlarmThresh>0ChangeTrackingErrThresh
  • 4 车型已把对应内联 [TemplateTrackCoderSettings] 删除,改为 [ProgramTrackCoderSettings] 引用(保留各自原 priority):
车型 LidarArea AvoidanceDistance IoArea TrackingErrThresh
Kiva 17 20 20 20
MultiWheelLifterCar 27 20 20 20
MultiVehicleCar 27 20 20 20
Forklift 20 —(原无) 20 20
  • 各车型加 using StandardScene.Coders;
  • 验证:每步 dotnet build 均 0 错误(Kiva 单切先验范式,再批量推 MWL/MultiVehicle/Forklift)。

C. 仍保留为内联 Template / 程序 coder(本次未动)

  • 磁程序 coderKiva.AllCarMagTrackCoderMultiWheelLifterCar.MagTrackCoder(待 C0-c 合并)
  • ChangeAvoidanceParam(三变体,待 C0-d
  • Kiva.KivaCarTrackCoder(转弯)、CalibrateWheelEncoder(仅 Kiva)
  • 二维码 QrGo(导航专用,归 QrCode dll);各车型取放货/钻车/夹抱/TireFollowing 等(车型专用)

D. 会话1(续)去重落地(编译 0 错误 / 0 lint

  • 磁循迹器合并(C0-cKiva.AllCarMagTrackCoder 重命名为唯一 MagneticTrackCoder(含 ${track.Speed}NaiveMagGo,用户确认);MultiWheelLifterCar.MagTrackCoder 整类删除,其 [ProgramTrackCoderSettings(priority=19)] 改向 MagneticTrackCoder。(暂置 Kiva.csStandardScene.CarTypes 命名空间,C2 抽 Magnetic dll 时物理迁出。)
  • 避障 4 参对合并(C0-d 部分):新增 Coders.AvoidanceParamCoderCommonTemplateTrackCoder 子类,覆写站点字段袋为含 ChangeAvoidanceParam 标志位的 AvoidanceParamSiteFields),useVerb/模板与原 MWL/MultiVehicle 逐字一致;两车型删内联 4 参模板、改 [ProgramTrackCoderSettings(priority=20)] 引用。基类新增可覆写 SiteFieldsType 钩子(默认 BasicSiteFields)。

E. 会话1(续2)结构性拆分落地(路线乙·结构拆分;全解决方案 dotnet build 0 错误 / 45 无害警告)

E1. 工程迁入 StandardScene.Core/(纯搬运)

  • 原单体整体迁入子目录 StandardScene.Core/StandardScene.csprojStandardScene.Core.csprojAssemblyName 仍=StandardScene,对外 dll 名不变);重写 StandardScene.sln
  • 新增 Properties/InternalsVisibleTo.cs:对 4 卫星程序集开放 internal(Protocol.VDA5050/Devices.Charge/Devices.Door/Devices.ButtonBox),使卫星以"纯搬运"访问 Core internal,免去大量 internal→public 侵入式改动。

E2. StandardScene.Protocol.VDA5050C4

  • CarTypes/VDACar/10 文件)整迁至新工程;scene.json(provides VDA5050Car)csproj 引 Core(ProjectReference)+SimpleLite/SimpleCore/CommonUsage/Topaz/Weaver + MQTTnet/Nancy/Jint/Newtonsoft。
  • 解耦:VDA5050SiteFieldVDACar/VDA5050Car.cs 下沉至 Core CarTypes/ArmCar.csArmCar 留 Core 且引用它,不能反依赖 VDA dll)。

E3. StandardScene.DevicesC3,用户选 A门/充电桩/按钮盒合并为单一 dll,用户定不分多个;内部按 Door/Charge/ButtonBox/ 子目录组织,Core 的 IVT 仅 StandardScene.Devices 一项)

  • 搬出 6 具体驱动(命名空间不变,仍 StandardScene.ExtendDevice.* / StandardScene.ChargeStationType,以满足发现谓词 t.Namespace==基类.Namespace):
    • DoorModbusDoorController(基类 BasicDoorController+[DoorType] 留 Core
    • ChargeFL/PCB/MuXingChargeStation(基类 AbstractChargeStation+ChargeUdpService/StandardChargeMission 留 Core
    • ButtonBoxLeeg/AzowieButtonBox(基类 BasicButtonBox+ButtonMission/ButtonBoxManager 留 Core;该 dll 额外引 Ref/leegKeys-sdk.dll
  • 行为保持解耦(2 处下转型→基类虚方法)
    • ChargeUdpServiceif(cs is PCBChargeStation s) s.IndexReceive=msg[1]cs.OnUdpMessage(msg)AbstractChargeStation 空实现、PCB override)。
    • ButtonMissionif(bb is AzowieButtonBox a) a.ClearButtonRegister(i)bb.ClearButtonRegister(i)BasicButtonBox 空实现、Azowie 改 override)。
  • 类型发现改跨程序集(5 处,关键):原 Core 限定扫描(Type.GetType(简单名) / typeof(基类).Assembly.GetTypes() / Assembly.GetExecutingAssembly().GetTypes())只在 Core 内找类型,驱动外移后运行期将找不到。统一改用内核公开的 SimpleLite.Utils.UiTypeDiscovery.AllTypes()AppDomain.GetAssemblies() 全域 + 内置 ReflectionTypeLoadException 安全枚举),谓词不变 → 今天在 Core 内仍找到原类型(行为等价)、外移后亦能发现。涉及 StandardChargeMission / DoorMission / DoorManager / ButtonMission / ButtonBoxManager
  • 关键依据:SimpleLite 自身类型发现即 UiTypeDiscovery(AppDomain 全域) + PluginManager(从 ./plugins/*.dll 以 collectible ALC 热加载)→卫星 dll 路线运行期成立(同时回证 VDA5050Car 可被发现)。

11.4 待确认 / 阻塞项(影响 C0 收尾与 C2)

  1. NaiveMagGo 参数差异 【会话1 已决】:用户定采用含 ${track.Speed} 的版本(Kiva 版)。已合并为唯一 MagneticTrackCoderMultiWheelLifterCar.MagTrackCoder 删除并改向引用。编译 0 错误。(普通 MagGo 两份原本一致;合并后磁逻辑全平台统一。)
  2. ChangeAvoidanceParam 统一方式 【会话1续3 已决:方案 B】:用户选 B。落地=4 参 flag 版 AvoidanceParamCoder(MWL+MultiVehicle) + 新增 2 参 L,W 版 AvoidanceParamLWCoder(Kiva+Forklift,触发统一取 dst.CarLength!=-1 && dst.CarWidth!=-1);两车型内联 [TemplateTrackCoderSettings][ProgramTrackCoderSettings(priority=20)] 引用。Forklift 行为不变;Kiva 原无条件→统一后未配置长宽(-1)时不再下发 (-1,-1)(预期内安全收敛)。编译 0 错。原分析留档如下:
    • 现状:Kiva=无条件/2 参;Forklift=L≠-1&&W≠-1/2 参;MWL/MultiVehicle=ChangeAvoidanceParam==true/4 参(含中心点)。
    • 已落地(零行为变更):把逐字相同MWL+MultiVehicle 4 参对合并为 Coders.AvoidanceParamCoder
    • 关键事实:CarLength/CarWidth/CarCenterX/CarCenterY 均已在 BasicSiteFields 定义(中心点默认 0),故 4 参模板对各车型都可解析编译;差异只剩「触发条件 + 参数个数」。
    • 选项(已在会话中给用户):A=真·单 coder 分支(flag→4 参 / 否则 L,W 有效→2 参;副作用:Kiva 未配置站点不再发 (-1,-1) + MWL 设了 L,W 但 flag=false 会新发 2 参);B=两 coder4 参 flag 版+2 参 L,W 版;仅 Kiva (-1,-1) 行为差,无 MWL 污染);C=只留已合并的同构对,Kiva/Forklift 维持内联(零变更)。建议 B(避障涉安全,最小行为差)。
  3. 去 WinForms 迁移策略 【会话1 暂定】:用户"暂不/去掉",本阶段不动窗体,留待 C1 专门处理。
  4. 内核 coder 运行期注册表 【会话1 已核查】:当前内核无插件化 coder 注册表SegmentPlan.SetCoders() 仅硬接 TemplateCoderSet+ProgramCoderSet 两套,均按车型类特性([*TrackCoderSettings])反射、在同程序集Activator.CreateInstance(无参构造)实例化——无外部 dll 扫描/动态注册 API。
    • 推论①:本次抽出的 StandardScene.Coders.* 程序 coder 能被正确加载(车型特性 typeof() 引用 + 无参构造,命名空间无关),故 C0-b/c/d 成立。
    • 推论②:C2「导航 coder 拆独立可热插拔 dll」受阻——需内核侧(另一会话)补「运行期 coder 注册 / 插件程序集扫描」插桩;在此之前继续兜底=coder 留在 Core 同程序集、由车型特性引用。
  5. 设备驱动外移后运行期发现 【会话1续2 已解】StandardScene 自有的设备类型发现原为 Core 限定扫描(与内核 UiTypeDiscovery 全域发现不一致),直接外移会断。已把 5 处统一改 UiTypeDiscovery.AllTypes()(行为等价、跨程序集)。遗留验证项(运行期,归 C5:卫星 dll 须被 SimpleLite 实际加载入 AppDomainPluginManager./plugins/ 加载)发现方生效——需将 StandardScene.Devices.*.dll+scene.json 部署到宿主 plugins/ 并做一次真机/集成联调。与 coder(§11.4-4) 不同:设备发现码在本仓库、可自主修改,故 C3 不受内核阻塞。

11.5 下一会话推荐起手式

  1. 读 §11.0(代码现状)+ §11.3(已落地,含 E. 结构拆分+ §11.4(待确认/已解)。
  2. 结构拆分现状StandardScene.Core + 卫星 Protocol.VDA5050Devices.{Door,Charge,ButtonBox} 已建并全解 0 错;导航 dll(C2) 待用户重构 coder + 内核注册表后再动。
  3. 待用户就 §11.4-2 拍板:ChangeAvoidanceParam 收尾(建议 B)。coder 整体重构由用户主导。
  4. C5 验证项:把 StandardScene.Devices.*.dll+scene.json 部署到宿主 plugins/,真机/集成验证设备与 VDA 车型的运行期发现(§11.4-5)。
  5. 校验手段:每步 dotnet build StandardScene.slnnet8.0-windows)须保持 0 错误;真机回归留待有环境时。

11.6 变更日志

时间 步骤 改动 备注
初始 P0 新增 StandardScene拆分计划.md(v1) 现状精读 + 归属矩阵 + 抽离清单 + 技术难点 + 分阶段
v2 P0.1 全文更新 宿主 SimpleLite、框架 net8.0、去 WinForms、设备独立 dll、删除项、WebApi 暂留+迁移索引
会话1 C0-a 物理删除 4 个死代码文件 + 清理 csproj 编译 0 错误
会话1 C0-b 新增 Coders/CommonTrackCoders.cs4 通用 coder);Kiva/MWL/MultiVehicle/Forklift 切换为 ProgramTrackCoder 引用 编译 0 错误;NaiveMag/AvoidanceParam 留待确认
会话1续 C0-c 磁循迹器去重:AllCarMagTrackCoder→唯一 MagneticTrackCoder(含 track.Speed);删 MagTrackCoder 改向引用 用户确认 track.Speed 版;编译 0 错误
会话1续 C0-d 避障同构对去重:MWL+MultiVehicle 4 参模板→AvoidanceParamCoder;基类加 SiteFieldsType 钩子 零行为变更;Kiva/Forklift 并法待定(§11.4-2)
会话1续 核查 内核 coder 注册机制核查:无插件注册表,仅车型特性+同程序集反射 见 §11.4-4C2 需内核插桩
会话1续2 路线乙·1 工程迁入 StandardScene.Core/.csprojStandardScene.Core.csproj、重写 .sln、加 Properties/InternalsVisibleTo.cs(4 卫星) 纯搬运;编译 0 错
会话1续2 C4 Protocol.VDA5050CarTypes/VDACar/(10 文件)整迁出;VDA5050SiteField 下沉 ArmCar.cs 解耦;scene.json 编译 0 错
会话1续2 C3 Devices.{Door,Charge,ButtonBox}6 驱动外移;2 处 is 具体类→基类虚方法;5 处类型发现→UiTypeDiscovery.AllTypes() 跨程序集 行为等价;全解编译 0 错、3 dll+scene.json 产出
会话1续3 C3 Devices.* 合并为单一 StandardScene.Devices(内部 Door/Charge/ButtonBox 子目录;IVT 3→1;删旧 3 工程、重写 sln) 用户定"不分多个";编译 0 错、单 dll+scene.json 产出
会话1续3 C0-d ChangeAvoidanceParam 去重收尾(方案 B):新增 2 参 AvoidanceParamLWCoderKiva/Forklift 内联模板→[ProgramTrackCoderSettings(priority=20)] 引用 编译 0 错;Forklift 不变、Kiva (-1,-1) 安全收敛

附:本计划引用的类/文件/行号均来自当前工程 E:\Work\Core\Simple-FR\StandardSence 实际代码走查;SimpleLite 接口依据 E:\Work\Core\Simple-FR\Simple\SimpleLite\Docs\MIGU-API.mdSimpleLite.csprojnet8.0 / CycleGUI / EmbedIO)。