139 lines
6.5 KiB
Markdown
139 lines
6.5 KiB
Markdown
# Live V2X Cesium Preview
|
|
|
|
The Cesium preview displays live V2X operational data on a compiled native
|
|
intersection. The package manifest, native road geometry, and traffic signals
|
|
remain independent of the service. Vehicle entities and their trace lines are
|
|
created only from authenticated V2X streams; generated routes and traffic
|
|
simulation are never rendered as a substitute.
|
|
|
|
## Configuration
|
|
|
|
Add a non-sensitive `v2xPreview` object to the area configuration:
|
|
|
|
```json
|
|
{
|
|
"v2xPreview": {
|
|
"enabled": true,
|
|
"apiBaseUrl": "/api",
|
|
"wsBaseUrl": "/websocket",
|
|
"crossCode": "420100023333"
|
|
}
|
|
}
|
|
```
|
|
|
|
`apiBaseUrl` and `wsBaseUrl` should normally be relative, same-origin paths.
|
|
The deployment server proxies them to the V2X REST and WebSocket services. Do
|
|
not commit a private upstream address, an account, a token, or an AMap key.
|
|
`crossCode` is deployment configuration for the selected intersection. It is
|
|
never shown or editable in the browser login panel.
|
|
|
|
### Optional phase binding overrides
|
|
|
|
`traffic-signals.json` carries no V2X phase number, so live phases are bound to
|
|
native signal heads geometrically (see *Phase Binding* below). Three optional
|
|
keys tune or replace that binding:
|
|
|
|
| Key | Default | Purpose |
|
|
| --- | --- | --- |
|
|
| `maxDistanceMeters` | `30` | Stop-line proximity tolerance. |
|
|
| `maxHeadingDeltaDegrees` | `45` | Approach heading tolerance. |
|
|
| `phaseSignalMap` | none | Explicit `{"<phaseNo>": ["<nodeKey>", …]}`; bypasses geometry for the listed phases. |
|
|
|
|
Use `phaseSignalMap` when the V2X link geometry cannot be matched — the V2X
|
|
panel reports how many phases bound and how many did not.
|
|
|
|
The page always starts at the login gate. After authentication it resolves the
|
|
current intersection with the same source-dashboard rule: request the HD-map
|
|
cross list and cross-device configuration list, prefer a configured cross, then
|
|
use the first available HD-map cross. Only after that resolution succeeds does
|
|
it issue the operational REST requests or open signal, OBU, and target-vehicle
|
|
WebSockets.
|
|
|
|
The browser sends `POST {apiBaseUrl}/facilities/api/sys/login` with `userName`
|
|
and an MD5-hashed password, matching the source V2X dashboard. It holds the
|
|
returned token in `sessionStorage` only, sends it as the raw `Authorization`
|
|
header for REST calls, and uses it as the `authorization` parameter for the
|
|
signal WebSocket. Closing the tab clears the session token.
|
|
|
|
## Data Sources
|
|
|
|
After sign-in the preview reads the selected intersection's links, pole
|
|
configuration, bound devices, and device configuration, and subscribes to
|
|
`/network/ws/network/signal` for phase updates. It also subscribes to
|
|
`/network/ws/network/obuPosition` and `/network/ws/network/targetPosition` for
|
|
the only vehicle and vehicle-line sources. Failures are shown in the V2X panel;
|
|
the static Cesium scene stays available and the vehicle layer stays empty.
|
|
|
|
All three sockets mirror the source dashboard's connection behaviour: a
|
|
`{"heartBeat":"ping"}` frame every 30 s, automatic reconnect with backoff, and
|
|
the subscription frame replayed on every reconnect. Without the heartbeat the
|
|
service drops the connection and the scene silently empties after a minute.
|
|
|
|
Subscription frames match the dashboard exactly:
|
|
|
|
| Socket | Frame on every (re)connect |
|
|
| --- | --- |
|
|
| `signal` | `{"junctionId":"<crossCode>"}` |
|
|
| `obuPosition` | `{"bounds":"<four GCJ-02 corners>"}`, or an empty frame when the camera rectangle is unavailable (no viewport filter) |
|
|
| `targetPosition` | `{"deviceId":"<ids>"}`, or `{"deviceId":null}` when no targets are configured |
|
|
|
|
## Phase Binding
|
|
|
|
The runtime traffic-signal document has no V2X `phaseNo`, so phases are bound to
|
|
native signal heads by geometry: the V2X link's last segment ends at the stop
|
|
line, and each native signal records its own stop-line point and heading. The
|
|
generator in `scripts/lib/traffic-signals.js` derives `mast = travel - 90` and
|
|
`face = travel + 180` from the approach travel direction, so the travel heading
|
|
is recovered as `faceHeadingDegrees + 180`.
|
|
|
|
One link may bind several heads on the same approach, and several links may
|
|
share one phase; both are unions, so a phase lights every approach it drives.
|
|
Unbound phases are counted in the panel — override them with `phaseSignalMap`.
|
|
|
|
## Vehicle Lifecycle
|
|
|
|
Vehicles follow the dashboard's rules: the push `interval` (`0` falls back to
|
|
500 ms) sets the animation duration, a vehicle not updated within
|
|
`interval * 1.5` is hidden, and hidden entries stay as reusable slots rather
|
|
than being removed. The OBU data hook calls its model `car_obu.glb`, but the
|
|
dashboard's final `CrossCars` template renders `11.glb`; the preview uses that
|
|
final rendering contract. Targets use `${type}${subType}.glb`. The dashboard
|
|
vehicle assets are packaged under `_preview/v2x-vehicles/`. Valid live vehicles
|
|
are lifted clear of the road, remain at least 28 screen pixels in overview, and
|
|
the first live push focuses the camera near the vehicle group.
|
|
|
|
## Coordinate Contract
|
|
|
|
| Data | Coordinate system | Preview handling |
|
|
| --- | --- | --- |
|
|
| Native package placement and traffic signals | WGS84 and local ENU | Existing Cesium contract; unchanged. |
|
|
| V2X dashboard road/link/device data | GCJ-02 | Converted once to WGS84 immediately before Cesium entity creation. |
|
|
| High德 reference GeoJSON | GCJ-02 | Compiler calibration input only; never loaded by this preview. |
|
|
|
|
Do not convert native WGS84 data again, and do not pass V2X GCJ-02 coordinates
|
|
directly to Cesium. Either error produces a visible intersection offset.
|
|
|
|
## Proxy Requirements
|
|
|
|
Use an HTTPS reverse proxy which forwards the configured REST prefix and supports
|
|
WebSocket upgrade for the configured WS prefix. For development or a simple host
|
|
without Nginx, use the repository's proxy static server instead of
|
|
`python3 -m http.server`:
|
|
|
|
```bash
|
|
V2X_UPSTREAM=http://<v2x-api-host>:<port>/dashboardApi \
|
|
V2X_WS_UPSTREAM=http://<v2x-ws-host>:<port>/dashboardWebsocket \
|
|
npm run serve:v2x-preview -- --root outputs/fengshu-er-road --host 0.0.0.0 --port 7862
|
|
```
|
|
|
|
It rewrites `/api/*` and `/websocket/*` before proxying, matching the source
|
|
dashboard's Vite proxy. The upstream address stays an environment value, not a
|
|
browser configuration or committed area file. The generated preview is static,
|
|
so direct cross-origin calls are likely to fail CORS or expose an internal origin.
|
|
|
|
## Rollback
|
|
|
|
`v2xPreview.enabled` defaults to `false`; set it to `true` for a selected area.
|
|
Set it back to `false` and regenerate the preview. The generated
|
|
page omits the V2X panel; published package contents remain unchanged.
|