feat: add 3D digital twin visualization

This commit is contained in:
root
2026-07-04 12:33:20 +02:00
parent a7025ca50c
commit b749cef14e
30 changed files with 1897 additions and 41 deletions

View File

@@ -6,22 +6,23 @@ Open https://arhipovdan.ru/ (или http://127.0.0.1:3100/).
## 30-Second Pitch
«Мы сделали инженерную симуляцию сортировочной ячейки OZON. Полный цикл: detection → classification → command → routing. Показываем happy path B/C/D, fault handling и timing. Главный экран — product demo, инженерные панели ниже.»
«Мы сделали инженерную симуляцию сортировочной ячейки OZON с 3D digital twin. Полный цикл: detection → classification → command → routing. Товар физически уходит в B/C/D. Physics engine не используем — motion по state machine, демо предсказуемо.»
## 3-Minute Demo
1. На первом экране укажите Hero: что это за система и цепочку Detection → Classification → Command → Routing.
2. Нажмите **Запустить демо**.
3. В блоке **Главное демо** покажите упрощённую сцену и карточку результата:
- товар;
3. В блоке **Главное демо** покажите **3D Digital Twin** и карточку результата:
- товар на конвейере;
- накопитель и stop-gate;
- категория B/C/D;
- причина решения;
- команда `ROUTE_TO_*`;
- целевая зона.
4. Нажимайте **Next step**, следите за **Этапами цикла**.
5. В **Сценариях** нажмите **Показать** на «Негабарит» — приоритет C.
6. Затем «Круглый объект» — зона D.
7. Затем «Застревание» или «Аварийная остановка» — FAULT / EMERGENCY_STOP, Reset.
- подсветка маршрута в зону.
4. Нажимайте **Next step**, следите за **Этапами цикла** и движением в 3D.
5. В **Сценариях** нажмите **Показать** на «Негабарит» — оранжевый route C, roll-cage C.
6. Затем «Круглый объект» — фиолетовый route D.
7. Затем «Застревание» или «Аварийная остановка» — красная подсветка, FAULT / EMERGENCY_STOP, Reset.
8. При необходимости переключите **2D fallback** — логика та же.
## 5-Minute Demo
@@ -86,12 +87,19 @@ docker compose -p owl -f /opt/arhipovdan/app/docker-compose.server.yml ps
document.documentElement.scrollWidth <= document.documentElement.clientWidth
```
## 3D / WebGL
- Desktop: по умолчанию 3D Digital Twin (если WebGL есть).
- Mobile: по умолчанию 2D; 3D можно включить вручную.
- Capability check: Engineering Details → блок **3D capability check** (WebGL, FPS).
- Physics engine: **не подключён** (state-machine animation).
## What Each Block Proves
- Hero — смысл проекта за 10 секунд.
- Product Demo scene — физический маршрут и команда.
- 3D digital twin — физическая маршрутизация A → CV → gate → B/C/D.
- Proof card — почему выбрана категория B/C/D.
- Storyline — текущий этап цикла.
- Scenario cards — jury test cases без узкого скролл-списка.
- Criteria cards — покрытие критериев OZON.
- Engineering Details — timeline, PID, event log, sensors.
- Engineering Details — timeline, PID, event log, sensors, 3D capability check.

View File

@@ -24,9 +24,9 @@ Open scenario **Аварийная остановка**. The system enters `EMER
Low confidence is logged as a warning. The system still applies deterministic dimensions/roundness rules as a fallback and shows this on the proof card.
## 7. Why 2D, Not 3D?
## 7. Why 3D Digital Twin Without Physics Engine?
2D is enough for MVP validation: it shows geometry, timing, sensor positions, routes and state transitions without heavy rendering.
The main demo uses a lightweight React Three Fiber digital twin driven by the state machine (keyframe motion). A physics engine would add wasm weight and unpredictable collisions, which is worse for a live jury pitch. 2D SVG remains as fallback when WebGL is unavailable or on narrow mobile screens.
## 8. What Is Needed For A Physical Prototype?
@@ -42,7 +42,7 @@ The proof card shows dimensions, roundness and reason. Tests cover key boundary
## 11. How Are Dimensions And Circular Section Handled?
Dimensions are checked first against min/max width, depth and height. If they pass, roundness is checked against threshold 0.8.
Dimensions are checked first against min/max: 10×10×10 mm to 450×320×320 mm. If they pass, roundness K = r_in / r_out is checked against threshold 0.8. Conveyor target speed is 1.00 m/s.
## 12. Why Does C Have Priority Over D?
@@ -74,8 +74,20 @@ Scroll to **Engineering Details** or click **Инженерный режим**.
## 19. How to check mobile and no horizontal scroll?
Use widths 1920×1080, 1440×900 and 390×844. On mobile the layout is one column, buttons are large, the scene scales with `width: 100%`. In console:
Use widths 1920×1080, 1440×900 and 390×844. On mobile the layout is one column, buttons are large, default view is 2D fallback. In console:
```js
document.documentElement.scrollWidth <= document.documentElement.clientWidth
```
## 20. How to show B / C / D / C-priority / fault in 3D?
- Normal item → green route B.
- Oversized → orange route C into roll-cage C.
- Round object → purple route D into roll-cage D.
- Oversized + round → still C (dimensions priority), D route stays inactive.
- Jam / emergency → red overlay, conveyor stopped, Reset required.
## 21. Where is the WebGL / FPS check?
Open Engineering Details → **3D capability check**.

View File

@@ -9,17 +9,25 @@ Before final submission:
- [ ] `https://www.arhipovdan.ru/` opens.
- [ ] `https://ai-shorts.ru/` still works and was not affected.
- [ ] Product Demo page opens (Hero first, not engineering dashboard).
- [ ] Start demo / Next step / Reset work.
- [ ] 3D Digital Twin loads on desktop when WebGL is available.
- [ ] Toggle **3D Digital Twin** / **2D fallback** works.
- [ ] Mobile defaults to 2D fallback (or simplified 3D if enabled).
- [ ] Start demo / Next step / Reset move the item in 3D by state machine.
- [ ] Routes B / C / D are visible in 3D.
- [ ] C-priority works for oversized + round.
- [ ] Jam / emergency stop show red fault state.
- [ ] Physics engine is NOT required for the demo (state-machine motion).
- [ ] Engineering Details includes 3D capability check (WebGL / FPS).
- [ ] Min dimensions are 10×10×10 mm; conveyor target is 1.00 m/s.
- [ ] Storyline Stepper updates with machine state.
- [ ] Scenario cards open cases with **Показать**.
- [ ] Criteria cards show OZON coverage and linked scenarios.
- [ ] Engineering Details is collapsed by default and opens from CTA.
- [ ] Engineering Details shows full panels (state machine, sensors, PID, timeline, event log, criteria).
- [ ] App is responsive on Desktop (1920×1080), Laptop (1440×900) and Mobile (390×844).
- [ ] NO horizontal scroll on body / `#root` / product page.
- [ ] Mobile: one column, buttons ≥ 44px, scene scales.
- [ ] Scenarios checked: normal_flow, oversized_item, round_object, boundary_dimensions, close_items, low_confidence, jam, emergency_stop.
- [ ] Docs present: README, ARCHITECTURE, DEMO_SCRIPT, SCENARIOS, JURY_QA, UI_UX_REDESIGN_AUDIT, SUBMISSION_CHECKLIST.
- [ ] Cursor rules present in `.cursor/rules/`.
- [ ] Docs present: README, ARCHITECTURE, DEMO_SCRIPT, SCENARIOS, JURY_QA, UI_UX_REDESIGN_AUDIT, THREE_D_FEASIBILITY, SUBMISSION_CHECKLIST.
- [ ] Cursor rules present in `.cursor/rules/` (including 3D / physics / WebGL rules).
- [ ] Branch ready for manual push to `origin/dan_branch`.
- [ ] Nginx / SSL / neighboring projects were not modified.

View File

@@ -0,0 +1,69 @@
# 3D Digital Twin Feasibility
## Выбранный стек
- `three`
- `@react-three/fiber`
- `@react-three/drei` (OrbitControls, Html labels)
- **Без** `@react-three/rapier` на первом этапе
## Почему
- R3F хорошо ложится на текущий React UI.
- Простые box/cylinder геометрии достаточны для digital twin.
- Drei нужен только для камеры и коротких labels.
- Physics engine в браузере добавляет wasm, непредсказуемость и риск лагов на защите.
## Physics engine
**Не подключается.**
Анимация: keyframe / state-machine interpolation по `machineState` + `elapsedInStateMs`.
Архитектура готова к physics позже:
- позиции товара и actuator вычисляются в `itemMotion.ts`;
- статические меши сцены отделены от motion layer;
- можно заменить motion layer на kinematic/dynamic bodies без смены domain logic.
## Риски
| Риск | Митигация |
|------|-----------|
| Bundle size | lazy-load 3D, простые геометрии |
| Нет WebGL | 2D `SorterScene` fallback |
| Mobile FPS | simplified 3D или auto-2D при width < 640 |
| Непредсказуемая физика | не используем rapier |
## Fallback
1. WebGL unavailable → 2D.
2. User toggle «2D fallback».
3. Mobile narrow screen → default 2D (можно вручную включить 3D).
Сообщение: «3D недоступен, включён 2D fallback. Логика симуляции та же.»
## Performance budget
- Без shadows / postprocessing / textures.
- < ~50 mesh-объектов.
- FPS overlay в capability check.
- Target: стабильный interactive FPS на desktop.
## Integration point
`ProductDemoSection`: toggle 3D Digital Twin / 2D fallback.
Props из `SimulationState`: item, machineState, scenario, classification, sensors, actuators, metrics, gate.
## Definition of Done
- [x] Build/test/Docker OK
- [x] 3D показывает A → conveyor → CV → gate → B/C/D
- [x] State machine двигает товар предсказуемо
- [x] ROUTE_TO_* виден цветом и стрелкой
- [x] 2D fallback работает
- [x] min dimensions 10×10×10, conveyor 1.00 m/s
- [x] Нет horizontal scroll
## Decision log
Physics (`@react-three/rapier`) **не установлен**: для хакатона важнее предсказуемый route, чем dynamic collisions. Motion layer — `itemMotion.ts` (`PHYSICS_ENGINE_ENABLED = false`).