9.0 KiB
WCS 中心调度与交通管制 Demo 设计
1. 背景与目标
本设计依据 01-P0-A现有链路稳固实施计划.md,在 FT546-WCS 优化工作树根目录新增独立的 javaTest Maven 项目,用纯 Java 内存模型模拟 WCS 中心调度与交通管制。
Demo 的目标是:
- 建立一个可运行的调度中心,模拟每周期任务准入、车辆分配、路径规划、交通管制、任务下发和完成。
- 用真实 JUnit 5 测试覆盖关键调度规则,确保测试数量大于 0。
- 固化当前 LEGACY 链路的重要语义,为后续从
BaseSRgvThread提取可测试边界提供参考。 - 输出可读的控制台事件,使开发人员能观察每个周期的决策原因和状态变化。
2. 范围与约束
2.1 范围内
- 独立 Maven 项目
javaTest。 - Java 8 源码兼容。
- JUnit 5 自动测试。
- 内存车辆快照、业务任务、调度队列、地图和事件记录。
- 每周期一次任务准入。
- 确定性车辆选择。
- 网格最短路径、路径占用和通道占用。
- 避让任务生成。
- 模拟协议下发与队列状态流转。
- 命令行 Demo 场景。
2.2 范围外
- 不修改生产
BaseSRgvThread、PlcSrgvRead或数据库表。 - 不连接 SQL Server、PLC、WMS 或 Spring 容器。
- 不发送真实 PLC 指令。
- 不建立生产中央路权服务,不写交通运行表。
- 不启用 SHADOW 或 ACTIVE 模式。
- 不使用
default02至default08保存新增交通状态。 - 不猜测 PLC 寄存器偏移或载货字段布局。
Demo 中的“调度中心”只协调内存任务、车辆与路径,不改变 P0-A 的 LEGACY 生产控制边界。
3. 方案选择
采用独立 Maven 项目,而不是加入现有 Reactor 或直接放入 ruoyi-admin/src/test。
理由:
- 可独立运行,不污染生产 Reactor 和依赖关系。
- 不需要 Spring、MyBatis、HslCommunication 或数据库。
- 能强制使用 JUnit 5 和现代 Surefire,避免现有工程“构建成功但测试数为 0”的假阳性。
- 后续可把验证成熟的纯领域服务迁移到生产模块。
4. 目录结构
javaTest/
├── pom.xml
├── README.md
└── src/
├── main/java/com/ft546/wcs/demo/
│ ├── DemoApplication.java
│ ├── center/
│ ├── model/
│ ├── repository/
│ ├── traffic/
│ └── simulation/
└── test/java/com/ft546/wcs/demo/
包边界如下:
model:不可变输入快照和明确的状态枚举。center:调度周期、任务准入和车辆选择。traffic:路径规划、资源占用与避让决策。repository:内存任务、队列和历史。simulation:场景构造、周期推进和事件输出。
5. 核心模型
5.1 车辆快照
VehicleSnapshot 至少包含:
vehicleIdfloorcurrentSiteworkModestatusbatteryconnectedallowSendcargo
快照不可变。车辆只有同时满足在线、自动模式 workMode=5、空闲 status=1、允许下发且电量大于 30 时才具备普通任务资格。
5.2 业务任务
DispatchTask 包含:
taskIdtypesourceSitetargetSitefloorprioritystate
Demo 支持入库、出库和移库的统一调度输入,但不模拟真实 WMS 回调。
5.3 调度队列
DispatchQueueEntry 使用明确字段表达:
taskIdvehicleIdqueueTypestartSiteendSitepriorityissuedexecutionStatuspath
状态语义与旧链路保持一致:
- 新建:
issued=0、executionStatus=1 - 下发成功:
issued=1、executionStatus=3 - 完成:
executionStatus=4,随后归档并从活动队列删除
避让任务使用 queueType=AVOIDANCE 和优先级 9,不把新增交通状态塞入旧扩展字段。
6. 调度中心
LegacyDispatchCenter.runCycle() 是每个模拟周期的唯一入口,固定顺序为:
- 冻结当轮车辆快照,并按
vehicleId排序。 - 调用一次
QueueAdmissionService.createPendingQueues()。 - 对未分配业务任务调用
VehicleAssignmentService.select()。 - 对每辆车处理已有队列。
- 调用
TrafficController.plan()获得路径、等待或避让决策。 - 通过
SimulatedProtocolAdapter模拟指令下发。 - 根据车辆位置推进队列完成和历史归档。
无论车辆数是多少,每周期业务准入只能调用一次。
7. 确定性车辆选择
车辆选择采用稳定比较顺序:
- 不符合资格的车辆排除,并记录排除原因。
- 同楼层优先。
- 绝对楼层差更小者优先。
- 保留旧链路的 Y 距离优先、X 距离次优语义。
- 全部相同时,
vehicleId字典序更小者优先。
站点编码必须能解析为坐标。编码无效时返回 REJECT_INVALID_SITE,不得按坐标 0 静默参与比较。
VehicleAssignmentDecision 必须包含被选车辆和可读的选择理由;没有可用车辆时返回明确的 HOLD 决策。
8. 交通管制
8.1 地图与路径
GridMap 保存可通行点及站点坐标。GridPathPlanner 使用确定性最短路径算法,只允许通过可通行节点。
每次规划前,TrafficController 从当前内存状态构建占用视图:
- 锁定其他车辆队列中从其当前位置开始的剩余路径。
- 锁定离线车辆当前位置。
- 锁定场景中声明不可用的提升机或障碍点。
占用视图只存在于当前模拟周期,不写数据库。
8.2 通道与路径冲突
如果目标通道存在同层阻挡车辆:
- 阻挡车辆没有活动队列时,为其生成高优先级避让任务。
- 当前业务任务返回
HOLD_CHANNEL_BLOCKED。 - 避让任务完成并删除后,下一周期重新规划。
如果路径被其他车辆占用但存在替代路线,则规划绕行;没有替代路线时返回 HOLD_NO_PATH。
同一阻挡车辆在已有避让队列时不得重复创建避让任务。
9. 协议模拟与状态流转
SimulatedProtocolAdapter 只记录命令,不进行 I/O。它支持成功和可注入失败两种结果:
- 成功时,队列更新为
issued=1、executionStatus=3。 - 失败时,队列保持未下发状态,并记录
HOLD_PROTOCOL_FAILURE及失败原因。 - 同一队列已成功下发后不得重复发送。
模拟器把车辆移动到路径下一站。到达目标站后:
- 普通任务归档业务历史并删除活动队列。
- 避让任务只归档避让事件并删除活动队列。
- 删除队列后,其路径占用在下一周期自然释放。
10. 错误处理
Demo 使用决策结果表达预期异常,不使用空值表示失败:
HOLD_NO_ELIGIBLE_VEHICLEREJECT_INVALID_SITEHOLD_NO_PATHHOLD_CHANNEL_BLOCKEDHOLD_PROTOCOL_FAILURE
构造时拒绝重复任务号、重复车辆号和缺失地图站点。不可恢复的模型错误抛出 IllegalArgumentException;调度等待条件作为正常决策返回。
11. 模拟场景
DemoApplication 至少运行以下场景:
- 三辆车、一个业务任务:证明每周期只准入一次,并稳定选出车辆。
- 同层与跨层车辆竞争:证明同层、楼层差、Y/X 距离和车辆编号裁决。
- 其他车辆剩余路径占用:证明绕行或等待。
- 同通道阻挡:生成优先级 9 的避让任务,当前车等待。
- 避让完成:删除避让队列,下一周期原任务重新规划并下发。
- 无可达路径:返回
HOLD_NO_PATH,不抛异常。 - 协议失败后重试:第一次保持未下发,下一周期成功进入执行中。
- 到达目标:队列完成、归档并释放路径。
控制台按周期输出任务、车辆、选车原因、路径、HOLD 原因、队列状态和历史结果。
12. 自动测试
JUnit 5 测试至少覆盖:
LegacyDispatchCenterTest:三车每周期只准入一次、稳定处理顺序。VehicleAssignmentServiceTest:资格过滤、同层优先、楼层差、Y/X 距离、稳定裁决和无效站点。TrafficControllerTest:路径锁、离线点、绕行、无路、通道阻挡、避让去重和释放。QueueLifecycleTest:新建、下发、失败重试、完成归档和幂等。DemoScenarioTest:端到端运行关键场景并验证真实事件结果。
验证命令:
cd javaTest
mvn test
mvn exec:java
验收时必须从 Surefire 报告确认测试数量大于 0、失败数为 0、错误数为 0;不能只依据 Maven 退出码。
13. 验收标准
满足以下条件才认为 Demo 完成:
- 工作树根目录存在独立
javaTestMaven 项目。 - 源码编译目标为 Java 8。
- 调度中心真实执行每周期一次准入和逐车处理。
- 确定性选车规则及理由可测试。
- 交通管制能处理路径锁、通道阻挡、避让任务和占用释放。
- 队列状态按 LEGACY 语义流转。
DemoApplication可运行并打印完整模拟结果。- JUnit 5 测试数量大于 0,全部通过。
- 项目不访问真实数据库、PLC 或 WMS,不修改生产控制代码。