docs(javaTest): design dispatch visualizer
This commit is contained in:
@@ -0,0 +1,306 @@
|
||||
# javaTest 调度过程可视化审计台设计
|
||||
|
||||
## 1. 目标
|
||||
|
||||
在 `javaTest` 内新增一个只绑定本机地址的离线调度审计台,让使用者能够:
|
||||
|
||||
- 输入任意有效 A、B 物理站点,调用现有 Java 调度中心完成一次真实的单任务仿真;
|
||||
- 看到调度中心选择的车辆、车辆到 A 的接近路径、A 到 B 的服务路径和逐 tick 实际移动轨迹;
|
||||
- 运行并检查固化的 240 条真实历史任务负载;
|
||||
- 检查 HOLD、PLC 重试、清障、重新选车、完成、归档和 WMS 幂等证据;
|
||||
- 明确看到节点双占、资源超容量、对向换边、死锁等安全不变量是否为零。
|
||||
|
||||
审计台必须复用 `HistoricalDispatchSimulator`、`GridPathPlanner`、
|
||||
`VehicleAssignmentService` 和现有交通资源组件。浏览器只负责呈现结果,不复制或改写一套
|
||||
JavaScript 调度算法。
|
||||
|
||||
本工具属于纯内存离线仿真,不连接生产 SQL Server、PLC 或 WMS,也不作为现场 SHADOW、
|
||||
HIL、LIMITED_ACTIVE 或 ACTIVE 验收的替代品。
|
||||
|
||||
## 2. 方案选择
|
||||
|
||||
### 2.1 采用方案:javaTest 内置本地审计服务
|
||||
|
||||
使用 Java 8 自带的 `com.sun.net.httpserver.HttpServer`,在 `javaTest` 进程中提供静态页面和
|
||||
JSON API。服务仅监听 `127.0.0.1`,默认端口 `18084`。
|
||||
|
||||
采用该方案的原因:
|
||||
|
||||
- API 直接调用现有调度代码,页面结果与自动测试使用同一实现;
|
||||
- 不引入 Spring、Node 运行时或生产后端依赖;
|
||||
- Maven 编译后即可启动,部署和排查边界清晰;
|
||||
- 可以同时支持任意 A/B 单任务和 240 条历史负载。
|
||||
|
||||
### 2.2 不采用方案:接入 ruoyi-ui
|
||||
|
||||
Vue、Element UI 和 ECharts 可以缩短常规管理页开发时间,但会把离线验证工具与生产前端
|
||||
耦合,还需要生产式前后端启动流程。当前目标是算法审计,不需要扩大部署边界。
|
||||
|
||||
### 2.3 不采用方案:纯静态报告查看器
|
||||
|
||||
纯静态页面能够读取既有报告,但无法输入任意 A/B 后调用当前 Java 算法重新执行,因此不能
|
||||
满足“亲眼检查新规划路径”的核心要求。
|
||||
|
||||
## 3. 运行边界
|
||||
|
||||
启动入口为:
|
||||
|
||||
```text
|
||||
com.ft546.wcs.shadow.history.visualizer.HistoricalDispatchVisualizerApplication
|
||||
```
|
||||
|
||||
启动命令为:
|
||||
|
||||
```bash
|
||||
mvn compile exec:java \
|
||||
-Dexec.mainClass=com.ft546.wcs.shadow.history.visualizer.HistoricalDispatchVisualizerApplication \
|
||||
-Dexec.args="18084"
|
||||
```
|
||||
|
||||
服务启动后打印准确访问地址。端口被占用时启动失败并明确提示,不静默切换到未知端口。
|
||||
|
||||
安全边界:
|
||||
|
||||
- 只监听 `127.0.0.1`,不对局域网或公网开放;
|
||||
- 只读取 classpath 中固化的 `shadow/history` 数据;
|
||||
- 不接受任意文件系统路径,不执行用户提供的命令;
|
||||
- POST 请求体限制为 64 KiB,仅接受已知字段、任务类型和故障预设;
|
||||
- 同一时间只允许一个仿真运行,保证确定性并避免重复占用 CPU;
|
||||
- 页面和 API 同源,不启用宽泛 CORS;
|
||||
- 默认不写报告文件,结果保存在当前浏览器会话和进程内存中。
|
||||
|
||||
## 4. 后端模块
|
||||
|
||||
### 4.1 `HistoricalDispatchVisualizerApplication`
|
||||
|
||||
负责加载固化历史数据、创建共享地图上下文、启动本地 HTTP 服务并注册关闭钩子。它不包含
|
||||
业务规划逻辑。
|
||||
|
||||
### 4.2 `HistoricalDispatchVisualizerServer`
|
||||
|
||||
负责静态资源、HTTP 路由、请求大小限制、错误响应和串行运行门禁。所有错误统一返回:
|
||||
|
||||
```json
|
||||
{
|
||||
"code": "UNKNOWN_SITE",
|
||||
"message": "起点不存在:A",
|
||||
"details": {}
|
||||
}
|
||||
```
|
||||
|
||||
### 4.3 `PointToPointSimulationService`
|
||||
|
||||
把页面请求转换成一个新的 `HistoricalSimulationTask`,复用完整地图、真实车辆初始站点和现有
|
||||
仿真器。历史 `agv_id` 和 `path_info` 仅作为可选对照字段,不参与选车或规划。
|
||||
|
||||
请求字段:
|
||||
|
||||
- `sourceSite`:物理起点;
|
||||
- `targetSite`:物理终点;
|
||||
- `taskType`:`INBOUND`、`OUTBOUND` 或 `RELOCATION`;
|
||||
- `priority`:整数优先级;
|
||||
- `acceleration`:`10` 或 `100`;
|
||||
- `historicalVehicleId`:可选,仅用于结果对照;
|
||||
- `historicalPath`:可选,仅用于结果对照;
|
||||
- `faultPreset`:`NONE`、`PLC_FIRST_SEND_FAILURE`、`VEHICLE_RESTART`、
|
||||
`LOW_BATTERY` 或 `DISCONNECT_RECONNECT`。
|
||||
|
||||
未知站点返回 `UNKNOWN_SITE`;已知但不可达返回任务终态 `FAILED/NO_ROUTE`;没有当前合格车辆
|
||||
时按现有调度逻辑保持等待或由 watchdog 明确关闭,页面不伪造成功结果。
|
||||
|
||||
### 4.4 `HistoricalWorkloadSimulationService`
|
||||
|
||||
使用 `HistoricalSimulationInputFactory` 创建完整 240 条任务输入,并运行当前确定性故障计划。
|
||||
页面每次点击“运行 240 条”都会调用当前代码重新计算,而不是直接展示写死的成功数字。
|
||||
|
||||
### 4.5 `SimulationVisualizationMapper`
|
||||
|
||||
把现有结果转换为专用展示 DTO,不改变仿真对象:
|
||||
|
||||
- 摘要、耗时分位数、HOLD/重试/失败原因;
|
||||
- 每条任务的历史/模拟车辆、历史/规划路径、状态、耗时和差异;
|
||||
- 全部 tick 事件;
|
||||
- 路径涉及站点的 `siteId/floor/x/y/channel`;
|
||||
- 归档、WMS 和安全不变量。
|
||||
|
||||
单任务返回完整地图站点索引,页面可搜索有效站点;具体路径只返回涉及节点及相邻背景节点,
|
||||
避免一次渲染 1,175 个可通行节点造成视觉噪声。
|
||||
|
||||
## 5. HTTP API
|
||||
|
||||
### `GET /api/bootstrap`
|
||||
|
||||
返回模式声明、地图版本、地图 SHA、规划器版本、车辆初始状态、楼层列表和可搜索站点列表。
|
||||
|
||||
### `POST /api/simulations/point-to-point`
|
||||
|
||||
运行一个任意 A/B 任务并返回任务结果、路径节点、事件、摘要和不变量。
|
||||
|
||||
### `POST /api/simulations/historical`
|
||||
|
||||
运行 240 条历史任务并返回完整审计结果。请求执行期间再次发起仿真返回
|
||||
`409 SIMULATION_BUSY`。
|
||||
|
||||
### `GET /api/health`
|
||||
|
||||
返回服务状态、地图是否加载和当前是否正在运行仿真,不连接任何外部系统。
|
||||
|
||||
静态资源仅允许访问 `/`、`/index.html`、`/assets/app.css` 和 `/assets/app.js`。
|
||||
|
||||
## 6. 页面信息架构
|
||||
|
||||
第一屏直接进入调度审计工作台,不制作营销式落地页。整体为安静、紧凑的运维工具界面。
|
||||
|
||||
### 6.1 顶部状态栏
|
||||
|
||||
显示“离线内存仿真”、地图 SHA、规划器版本、服务状态和最近一次运行时间。离线边界始终可见,
|
||||
避免把结果误认为现场数据。
|
||||
|
||||
### 6.2 主模式切换
|
||||
|
||||
使用分段控件提供三个模式:
|
||||
|
||||
1. `A → B 单任务`
|
||||
2. `240 条历史任务`
|
||||
3. `安全审计`
|
||||
|
||||
### 6.3 A → B 单任务视图
|
||||
|
||||
顶部是紧凑配置工具栏:可搜索起点、终点、交换按钮、任务类型、优先级、加速倍率、故障预设
|
||||
和“运行调度”按钮。
|
||||
|
||||
主要区域分为:
|
||||
|
||||
- 路径画布:占据最大面积,按真实 `x/y/floor` 坐标绘制;
|
||||
- 任务检查器:显示模拟车辆、历史车辆、状态、HOLD、PLC 尝试和耗时;
|
||||
- 时间线:提供播放、暂停、前一步、后一步、速度和 tick 滑块;
|
||||
- 事件表:支持按事件类型、车辆和原因过滤。
|
||||
|
||||
### 6.4 240 条历史任务视图
|
||||
|
||||
展示完成/等待/失败、每车完成数、重派和路径变化、平均/P95/P99 等摘要;下方为可搜索、排序、
|
||||
过滤的任务表。点击一条任务后复用同一条路径画布和时间线播放该任务。
|
||||
|
||||
### 6.5 安全审计视图
|
||||
|
||||
集中展示:
|
||||
|
||||
- 节点双占;
|
||||
- 资源超容量;
|
||||
- 对向换边;
|
||||
- 死锁;
|
||||
- 重复归档;
|
||||
- WMS 重复业务效果;
|
||||
- HOLD、重试和失败原因分布;
|
||||
- 归档数、WMS 投递次数和唯一业务效果。
|
||||
|
||||
任一安全不变量不为零时,顶部状态立即变为红色“验收不通过”,并提供对应任务和事件过滤入口。
|
||||
|
||||
## 7. 路径可视化语义
|
||||
|
||||
路径图必须显示真实站点编号和坐标,不能使用装饰性随机连线。
|
||||
|
||||
- 灰色虚线:选中车辆当前位置到 A 的接近路径;
|
||||
- 绿色实线:调度中心返回的 A 到 B `plannedPath`;
|
||||
- 蓝色高亮:截至当前 tick 已实际通过的边;
|
||||
- 琥珀色:当前 HOLD 或等待资源的边/节点;
|
||||
- 红色:被拒绝或违反安全不变量的位置;
|
||||
- 空心节点:尚未经过;实心节点:已经经过;
|
||||
- A、B 和车辆当前位置使用稳定、不同的标记。
|
||||
|
||||
`plannedPath` 直接来自 `SimulationTaskResult`。实际轨迹来自同一任务的 `MOVE` 事件。
|
||||
接近路径通过首次 `ASSIGN` 后、到达 A 之前的 `MOVE` 事件还原;若车辆初始站点就是 A,则显示
|
||||
单节点接近路径。发生重派时,按 `REDISPATCH/ASSIGN` 分段,并保留每次车辆和路线变更证据。
|
||||
|
||||
多楼层路径按楼层切换查看;当前 tick 所在楼层自动聚焦,但不隐藏其他楼层存在路径的提示。
|
||||
等长最短路的选择遵循当前 `GridMap.getNeighbors()` 的站点编号排序,不由前端重新决定。
|
||||
|
||||
## 8. 交互与状态
|
||||
|
||||
- 初始态:加载站点和地图元数据,不自动运行仿真;
|
||||
- 运行态:禁用重复运行按钮,显示当前请求类型和耗时;
|
||||
- 成功态:默认停在 tick 0,由用户播放或单步检查;
|
||||
- HOLD 态:时间线暂停并突出原因,用户可继续播放;
|
||||
- 失败态:保留已产生的路径和事件,不清空证据;
|
||||
- 空结果:明确显示未知地图、无路可达或无合格车辆,不能显示空白画布;
|
||||
- 大任务态:任务表使用分页或窗口化渲染,事件列表限制可见行数;
|
||||
- 页面刷新:清除内存结果,避免把旧结果误认为新运行。
|
||||
|
||||
键盘和鼠标均可完成播放、暂停、单步、筛选和查看任务。按钮尺寸固定,动态数字变化不能导致
|
||||
工具栏或画布跳动。桌面为主,窄屏时配置、画布、检查器和时间线纵向排列且无重叠。
|
||||
|
||||
## 9. 视觉规范
|
||||
|
||||
界面采用明亮中性色背景、深色正文、绿色通过状态、蓝色实际轨迹、琥珀色 HOLD 和红色失败。
|
||||
避免单一蓝色、深色大屏、渐变装饰和浮动卡片堆叠。
|
||||
|
||||
页面区块使用全宽带状布局;卡片只用于重复任务项和确需边界的检查器。圆角不超过 8px。
|
||||
播放、暂停、单步和交换操作使用熟悉符号并提供 tooltip;明确命令使用图标加文字。
|
||||
|
||||
## 10. 错误处理
|
||||
|
||||
后端错误代码至少包括:
|
||||
|
||||
- `BAD_REQUEST`
|
||||
- `UNKNOWN_SITE`
|
||||
- `SAME_ENDPOINT`
|
||||
- `INVALID_TASK_TYPE`
|
||||
- `INVALID_ACCELERATION`
|
||||
- `SIMULATION_BUSY`
|
||||
- `NO_ROUTE`
|
||||
- `WATCHDOG_DEADLOCK`
|
||||
- `TICK_LIMIT_EXCEEDED`
|
||||
- `INTERNAL_ERROR`
|
||||
|
||||
响应不暴露本地绝对路径或堆栈。服务端记录完整异常,页面显示业务可读信息和再次运行入口。
|
||||
前端网络失败时保留上一次已完成结果并明确标记“当前服务不可用”,不得把旧结果显示为当前结果。
|
||||
|
||||
## 11. 测试策略
|
||||
|
||||
### 11.1 Java 自动测试
|
||||
|
||||
- API 使用实际地图完成一个已知 A/B 单任务;
|
||||
- 返回的 `plannedPath` 首尾分别是 A、B,连续站点均为真实邻居;
|
||||
- 历史 `path_info` 改变后新路径保持不变;
|
||||
- 多辆合格车辆时返回中心调度选择结果;
|
||||
- 未知站点、相同端点、无路、busy 和错误请求返回稳定错误;
|
||||
- 240 条历史任务结果继续满足 240/0/0;
|
||||
- 所有安全不变量为零;
|
||||
- 归档和 WMS 幂等指标正确;
|
||||
- 静态资源和健康接口可访问。
|
||||
|
||||
### 11.2 前端浏览器测试
|
||||
|
||||
- 桌面和移动视口均无文字、工具栏、画布或时间线重叠;
|
||||
- A/B 搜索、交换、运行、播放、暂停、单步、速度和筛选均有效;
|
||||
- 路径画布包含非空真实坐标内容,并且 A、B、规划路径和车辆标记可见;
|
||||
- tick 推进时车辆标记移动,已通过路径同步高亮;
|
||||
- 历史任务列表可筛选并能打开任务详情;
|
||||
- HOLD、PLC 重试、重派、失败和安全告警状态可正确呈现;
|
||||
- 浏览器控制台无 JavaScript 错误;
|
||||
- 使用 Playwright 保存桌面与移动截图并进行画布像素检查。
|
||||
|
||||
### 11.3 回归验证
|
||||
|
||||
实现完成后必须运行:
|
||||
|
||||
```bash
|
||||
mvn clean test
|
||||
```
|
||||
|
||||
现有 630 项测试和新增测试必须全部由 Surefire 发现,Failures 和 Errors 均为 0。
|
||||
|
||||
## 12. 验收标准
|
||||
|
||||
只有同时满足以下条件才视为完成:
|
||||
|
||||
- 输入有效 A、B 后,页面实际调用当前 Java 调度代码并返回结果;
|
||||
- 页面明确显示模拟选择车辆、接近路径、A 到 B 规划路径和逐节点轨迹;
|
||||
- 路径节点都存在于完整地图且每一段均为真实邻接边;
|
||||
- 可按 tick 播放全部关键调度事件;
|
||||
- 可重新运行并检查 240 条历史任务;
|
||||
- 完成/等待/失败、每车任务数、耗时分位数、HOLD/重试原因全部可见;
|
||||
- 资源冲突、死锁、归档和 WMS 幂等结果有独立审计视图;
|
||||
- 页面不连接生产系统,不发送真实设备命令;
|
||||
- 自动测试和浏览器验证通过;
|
||||
- 页面始终提示:离线仿真可以降低上线风险,但不能单独保证现场上线绝对无故障。
|
||||
Reference in New Issue
Block a user