fix: restore live V2X signal and vehicle fidelity in Cesium preview
The ported overlay used the correct REST paths but lost the data handling
from the source dashboard's live-intersection view (HologramCross), so
signals rendered permanently red and vehicles often never appeared.
- Lamp status codes now follow the dashboard dictionary (11/21/22/23/31).
The previous 2/3 reading made every real push fall through to red. The
dictionary lives only in the overlay; the preview consumes normalized
{nodeKeys, color, countDown} entries so the two copies cannot drift.
- Bind V2X phases to native signal heads geometrically. The runtime
document has no phaseNo, so the old lookup fell back to signal.id and
never matched, leaving the dynamic assembly dark. Travel heading is
recovered as faceHeadingDegrees + 180, per the generator's
mast = travel - 90 / face = travel + 180. Verified 7/7 exact matches
against the fengshu-er-road runtime document.
- A phase now lights every approach it drives; the phase -> single entity
map silently overwrote all but the last.
- Drive the countdown assets from the push's countDown field.
- All three sockets heartbeat every 30s and reconnect with backoff,
replaying their subscription frame. Without this the service dropped
the connection and the scene emptied after about a minute.
- The OBU socket sends its bounds frame on connect and on camera move;
it previously sent nothing at all.
- Vehicles are swept when a push goes stale and their slots reused, so
they no longer accumulate as ghosts. Models follow the dashboard's
car_obu.glb / ${type}${subType}.glb naming.
- Parse vehicle pushes leniently, since the dashboard uses saferEval and
the payload is not guaranteed to be strict JSON. Failures are counted
and surfaced rather than dropped; no eval is introduced.
- Drop FlowTravelRatio/queryListWeek, which is not part of this view.
Also corrects a stale spec rule that required vehicleModelNames to be
empty. Live V2X vehicles need packaged models; the real invariant is no
generated routes or traffic simulation.
Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
This commit is contained in:
99
.trellis/tasks/08-24-v2x-realtime-cross-fidelity/prd.md
Normal file
99
.trellis/tasks/08-24-v2x-realtime-cross-fidelity/prd.md
Normal file
@@ -0,0 +1,99 @@
|
||||
# 还原 V2X 实时路口信号灯与车辆展示
|
||||
|
||||
## Goal
|
||||
|
||||
把 `v2x_web` dashboard「实时路口」(`HologramCross`) 的实时数据行为完整搬到本项目的 Cesium 预览中,使
|
||||
`outputs/<area>/…-cesium-preview.html` 在登录后能持续、正确地显示 **信号灯相位灯色与倒计时** 和
|
||||
**OBU / 目标识别车辆**。
|
||||
|
||||
当前实现(Codex 移植)接口地址是对的,但数据处理与渲染层基本失真,实际效果是:灯永远红、车可能一辆都不出现、
|
||||
出现后也不消失、连接几十秒后被服务端断开。本任务修复这条链路。
|
||||
|
||||
## Source of Truth
|
||||
|
||||
参照实现(只读,不修改):
|
||||
`/Users/que01/Project/v2x_web/applications/dashboard/src/views/dashboard/components/Content/Map/HologramCross/`
|
||||
|
||||
- `components/CrossTrafficLights3D.vue` — 信号灯:link 相位、WS 订阅、灯色/倒计时
|
||||
- `components/utils.ts` — 灯色状态字典、航向角计算
|
||||
- `components/CrossCars/hooks/useObuCars.ts` — OBU 车辆
|
||||
- `components/CrossCars/hooks/useTargetCars.ts` — 目标识别车辆
|
||||
- `components/CrossCars/type.ts` — 车辆数据结构
|
||||
|
||||
## Requirements
|
||||
|
||||
### R1 WebSocket 连接层对齐
|
||||
- 三个 socket(`signal` / `obuPosition` / `targetPosition`)均按源项目发送心跳
|
||||
`{"heartBeat":"ping"}`,间隔 30000ms。
|
||||
- 断线自动重连,重连后重新发送各自的订阅消息(signal 发 `junctionId`,target 发 `deviceId`,obu 发 bounds)。
|
||||
- 页面 `visibilitychange` 回到可见时行为不得导致重复连接堆积;`dispose()` 必须清掉心跳与重连计时器。
|
||||
|
||||
### R2 信号灯灯色映射修正
|
||||
- 采用源项目 `utils.ts` 的状态字典:`11=灭灯 21=红 22=黄 23=绿 31=其他`。
|
||||
- 现有 `lampColor()`(overlay)与 `lampColorName()`(`cesium-preview.js`)中基于 `2`/`3` 的判断必须移除。
|
||||
- 未知状态码按「其他/灭灯」处理,不得静默落到红色。
|
||||
|
||||
### R3 相位到原生信号灯的映射
|
||||
- `traffic-signals.json` 中不存在 V2X `phaseNo`(只有 `phaseGroup: 0`),当前回退到 `signal.id` 导致永不匹配。
|
||||
必须建立一条真实可用的 V2X `phaseNo` → 原生信号灯头的映射。
|
||||
- 映射结果必须可诊断:面板要能显示「N 个相位已绑定 / M 个未绑定」。
|
||||
- 允许区域配置提供显式覆盖映射。
|
||||
|
||||
### R4 一个相位可点亮多条进口道
|
||||
- 同一 `phaseNo` 对应的所有 link / 信号灯头都要被点亮,当前 `Map<phase, entity>` 的覆盖行为必须消除。
|
||||
|
||||
### R5 倒计时
|
||||
- 使用推送中的 `countDown` 字段(源项目 `phaseValue['time'] = signal.countDown`),驱动预览中已有的
|
||||
countdown 资产或等效显示。
|
||||
|
||||
### R6 车辆订阅正确建立
|
||||
- OBU socket 连接后必须发送订阅消息(源项目 `send(bounds || '')`),相机视野变化时发送
|
||||
`{"bounds": "<lng,lat;…>"}`。
|
||||
- target socket 连接后发送 `{"deviceId": "<ids joined by comma>"}`,无配置时发送 `{"deviceId": null}`。
|
||||
|
||||
### R7 车辆生命周期
|
||||
- 按源项目实现超时隐藏:超过 `interval * 1.5` 未更新的车辆隐藏并可复用槽位;`interval` 取自推送体,
|
||||
`0` 时回退 `500`。
|
||||
- socket 断开时清空车辆列表。
|
||||
- 车辆位置更新使用推送间隔做平滑插值,避免逐帧跳变。
|
||||
|
||||
### R8 车辆模型命名对齐
|
||||
- OBU 固定使用 `car_obu.glb` 语义的模型槽;目标识别车辆使用 `${type}${subType}.glb` 语义的模型槽。
|
||||
- 包内缺少对应模型时回退到默认车模型,并在面板提示,不得静默显示错误车型。
|
||||
|
||||
### R9 推送体解析健壮性
|
||||
- 源项目对两个车辆 socket 使用 `saferEval` 而非 `JSON.parse`,说明载荷不保证严格 JSON。
|
||||
- 解析必须容忍非严格 JSON,且解析失败要计数并在面板可见,不得整条静默丢弃。
|
||||
|
||||
### R10 范围纠正
|
||||
- `/facilities/api/FlowTravelRatio/queryListWeek`(周流量比)不属于「实时路口」,从实时加载链路移除。
|
||||
|
||||
## Non-Goals
|
||||
|
||||
- 不移植 AMap 底图 / 矢量瓦片图层(`linkVectorHdMapTileUrl`)。
|
||||
- 不移植 `CrossDevices/Model3D.vue` 的 3D 杆件模型;设备维持点位显示(可后续独立任务)。
|
||||
- 不移植 `useV2XEvents` 的 V2X 事件气泡。
|
||||
- 不改变原生包产物(GLB / metadata / traffic-signals.json 的生成逻辑)。
|
||||
|
||||
## Constraints
|
||||
|
||||
- 不得提交上游地址、账号、令牌、AMap key;`v2xPreview` 配置保持非敏感。
|
||||
- 令牌只存 `sessionStorage`,页面始终从登录门进入。
|
||||
- 坐标契约不变:V2X 数据 GCJ-02,进 Cesium 前转一次 WGS84;原生数据不得二次转换。
|
||||
- `v2xPreview.enabled` 默认 `false`,关闭时生成页不含 V2X 面板。
|
||||
- 生成的预览为静态页,无构建步骤,overlay 保持零依赖 IIFE。
|
||||
|
||||
## Acceptance Criteria
|
||||
|
||||
- [ ] AC1 三个 socket 均可见 30s 心跳;模拟服务端在 60s+ 后连接仍存活。
|
||||
- [ ] AC2 单测覆盖灯色映射:`21→红 22→黄 23→绿 11→灭 31→其他`,且 `2`/`3` 不再被当作黄/绿。
|
||||
- [ ] AC3 单测覆盖相位映射:给定 V2X link 相位与 `traffic-signals.json`,输出的绑定数 > 0,
|
||||
未绑定项被明确列出。
|
||||
- [ ] AC4 单测覆盖同相位多进口道:一个 `phaseNo` 对应 2 条 link 时,两条都被点亮。
|
||||
- [ ] AC5 单测覆盖车辆超时:注入两次推送并推进时间超过 `interval*1.5`,车辆转为不可见。
|
||||
- [ ] AC6 单测覆盖 OBU/target 订阅消息:连接后发出的首帧内容与源项目一致。
|
||||
- [ ] AC7 单测覆盖非严格 JSON 推送体能被解析,且失败计数可读。
|
||||
- [ ] AC8 `npm run test:v2x-cesium-preview`、`test:v2x-preview-server`、`test:preview-assets` 全绿。
|
||||
- [ ] AC9 真机(`npm run serve:v2x-preview` 接真实上游)登录后可见:信号灯随相位变色并显示倒计时、
|
||||
车辆出现并移动、离开后消失。此项由开发者人工确认。
|
||||
- [ ] AC10 `v2xPreview.enabled=false` 重新生成后,页面不含 V2X 面板,包产物字节不变。
|
||||
Reference in New Issue
Block a user