Document arhipovdan.ru DNS/TLS blocker, add production smoke and GPU perf tooling, unify twin layout, and expand visual regression coverage. Co-authored-by: Cursor <cursoragent@cursor.com>
64 lines
3.1 KiB
Markdown
64 lines
3.1 KiB
Markdown
# Twin Geometry Alignment
|
||
|
||
## Goal
|
||
|
||
Keep `/` (continuous twin) and `/details` (state-machine twin) as projections of one sorter layout — same belt height, zone X/Z, sensors, gate, and category colors — without rewriting both scenes or enabling a physics engine.
|
||
|
||
## What was unified
|
||
|
||
| Concern | Source of truth | Consumers |
|
||
| --- | --- | --- |
|
||
| Conveyor dims, `BELT_TOP_Y` (0.7 m), zones A/B/C/D, gate, roll cages | `src/domain/physicalLayout.ts` | Continuous twin, `conveyorNetwork`, cameras |
|
||
| Shared bridge + details-derived layout | `src/domain/layout/sharedLayout.ts` | Details `TWIN_LAYOUT`, route/color tokens |
|
||
| Category / route colors | `src/domain/industrialTheme.ts` → `CATEGORY_COLORS` | Both twins, details `ROUTE_COLORS` |
|
||
| Class route directions (B→+X, C→+Z, D→−Z) | `CLASS_ROUTE_DIRECTIONS` in `sharedLayout` | Documentation / consistency |
|
||
|
||
### Details twin derivation
|
||
|
||
`itemMotion.ts` no longer hardcodes a compact layout (`beltY: 0.35`, divergent X). It exports:
|
||
|
||
```ts
|
||
TWIN_LAYOUT = DETAILS_TWIN_LAYOUT // from sharedLayout
|
||
ROUTE_COLORS = CATEGORY_COLORS
|
||
PHYSICS_ENGINE_ENABLED = false
|
||
```
|
||
|
||
Aligned meters (vs previous details values):
|
||
|
||
- `beltY` → `BELT_TOP_Y` (0.7)
|
||
- `startX` / `zoneBX` / `zoneCZ` / `zoneDZ` → `ZONES.A/B/C/D`
|
||
- `cameraX` / `laserX` / `gateX` → `ZONES.CAMERA/LASER/GATE`
|
||
- `rollCageSize` → `ROLL_CAGE`
|
||
- Progress keyframes (`progressForState`) unchanged — only absolute meters moved
|
||
|
||
Details scene helpers (conveyor materials, zone pads, sensor poles, label Y) use `TWIN_LAYOUT.beltY` or `INDUSTRIAL_PALETTE` so the presentation layer tracks the shared height.
|
||
|
||
### Consistency test
|
||
|
||
`src/domain/routeConsistency.test.ts` asserts for each non-fault `DEMO_PLAYLIST` case:
|
||
|
||
1. `classifyItem` category === `expectedCategory`
|
||
2. Continuous playback `targetCategory` matches after seek
|
||
3. `CATEGORY_COLORS` has an entry for that category
|
||
4. `getPhysicalItemPose` at mid-routing has `activeRoute` === category and `phase === 'routing'`
|
||
|
||
## Intentional differences (keep)
|
||
|
||
| Continuous (`/`) | Details (`/details`) |
|
||
| --- | --- |
|
||
| Engineering HUD: measurement, events, physical surfaces from `conveyorNetwork` | Presentation / teaching twin: state-machine progress keyframes |
|
||
| Deterministic `getPhysicalItemPose` along network surfaces | `itemPosition3D` progress along a simplified X (and Z for C/D) |
|
||
| Light industrial floor / grid (`INDUSTRIAL_PALETTE` light) | Dark engineering projection of the same palette |
|
||
| Full B receiver spur + chutes + cage floors | Simplified zone boxes + roll-cage visuals |
|
||
| Ultrasonic not a separate continuous station | Details-only `ultrasonicX` between laser and gate |
|
||
| Cinematic camera / playlist director | OrbitControls + machine-state HUD chips |
|
||
|
||
Motion remains **state-machine / kinematic** only (`PHYSICS_ENGINE_ENABLED === false`). Do not enable a physics engine for alignment.
|
||
|
||
## How to extend
|
||
|
||
1. Change geometry in `physicalLayout.ts` (or zone map there).
|
||
2. Re-export / map in `layout/sharedLayout.ts` if details needs a new derived field.
|
||
3. Keep details keyframe ratios in `itemMotion.ts` unless timing intentionally changes.
|
||
4. Prefer `INDUSTRIAL_PALETTE` / `CATEGORY_COLORS` for new materials.
|