Document domain, launch/build commands, structure, env vars, cloud split, and the real CV prototype on drho1y-mvp_1 for the final submission. Co-authored-by: Cursor <cursoragent@cursor.com>
OZON Sorter Digital Twin
Web digital twin of an Ozon Tech Track 3 conveyor sorting line: continuous product playback, camera/classification stage, B/C/D routing, and author-CAD diverter motion.
Production domain: https://arhipovdan.ru
Current solution
This repository (main) contains the final web simulation:
- continuous 3D conveyor digital twin (
/); - engineering documentation page (
/documentation); - author CAD conveyor source (
3d_models/conveer.FCStd); - runtime conveyor GLB (
public/models/sorter/conveyor-clean.glb); - product STL assets (
public/models/*.stl); - camera-triggered measurement / rule-based classification (digital sensor simulation);
- B / C / D route mapping with CAD left/right diverters (−45° / +45°);
- Rapier physics: belt ≈ 1.0 m/s, fixed timestep 1/120 s, CCD on product profiles, discharge into receivers.
Main functions
- Continuous SKU playback on a three-module CAD conveyor (clean → camera → sorter).
- Camera-volume triggered measurement and B/C/D classification.
- Physical diverter routing and receiver settle detection.
- Desktop WebGL twin + mobile-capable 3D policy.
- Canonical engineering status on
/documentation.
Technology stack
| Layer | Packages |
|---|---|
| UI | React, react-router-dom |
| 3D | three, @react-three/fiber, @react-three/drei, @react-three/postprocessing |
| Physics | @react-three/rapier, @dimforge/rapier3d-compat |
| Build | Vite, TypeScript, @vitejs/plugin-react |
| Tests | Vitest, Playwright |
See package.json for exact versions. Do not treat transitive npm packages as first-class product dependencies.
Dependencies / Node
- Node.js 20+
- npm (lockfile:
package-lock.json)
Exact commands
npm ci
npm run dev # development: http://127.0.0.1:3100
npm test -- --run # unit tests
npm run build # production build → dist/
npm run preview # serve build: http://127.0.0.1:3100
npm run test:e2e # Playwright (needs preview or PLAYWRIGHT_BASE_URL)
Active routes
| Route | Purpose |
|---|---|
/ |
Continuous digital-twin simulation |
/documentation |
Canonical product / engineering status |
* |
Redirects to / |
Removed routes (/details, /device-test) are not part of the product.
Project structure
src/ React app, domain logic, 3D twin, pages
public/ Runtime static assets (models, draco)
models/ Product STL + sorter/conveyor-clean.glb
3d_models/ Author CAD (conveer.FCStd)
docs/ Engineering notes (ENGINEERING.md)
e2e/ Playwright smoke / routes
input_info/ Official Ozon input packs (PDFs/ZIPs)
official_sources/ Classifier bounds PDF cited by code
Dockerfile Multi-stage Vite build + nginx
docker-compose.server.yml
nginx.conf
.github/workflows/ci.yml
Environment variables
No runtime secrets are required for local demo or production static hosting.
Optional build-time identity (Docker / CI only; never commit real secrets):
| Variable | Purpose |
|---|---|
VITE_BUILD_COMMIT |
Short git commit in /version.json |
VITE_BUILD_BRANCH |
Branch name in /version.json |
VITE_BUILD_RELEASE |
Release label in /version.json |
Do not commit .env files. Local npm run build derives identity from git when available.
Active assets
| Path | Role |
|---|---|
3d_models/conveer.FCStd |
Author CAD (canonical source) |
public/models/sorter/conveyor-clean.glb |
Active runtime conveyor |
public/models/*.stl |
Product models |
input_info/* |
Official Ozon packs (PDFs/ZIPs) |
official_sources/doc-1783095831.pdf |
Official classifier bounds source cited by code |
Frozen checksums (SHA-256)
3d_models/conveer.FCStd
90c1844a4ca05e26def783d6130fc4b993430dde14307534ef8fbb21c9fac2e6
public/models/sorter/conveyor-clean.glb
1dc7a8d7891bfe756e277ad5368df74cb73410156b2fe0f92845afb8a56f285a
Classifier vs real CV
Web twin (main): classification is a digital sensor simulation. When a product enters the camera scan volume, dimensions / roundness are measured in the twin and routed with the same B/C/D rules as Track 3 (src/domain/classifier.ts, src/domain/cameraClassification.ts). This is not a neural network and is not wired to a live RealSense camera in production.
Real CV (parallel prototype, not merged into the web app): preserved on branch drho1y-mvp_1 under vision_classifier/ (OpenCV + RealSense D415 depth → L×W×H + circle_ratio → B/C/D → MQTT). No PyTorch/YOLO weights are stored in git.
git fetch origin
git switch drho1y-mvp_1
cd vision_classifier
# see vision_classifier/README.md and START.md
./demo.sh # browser HUD demo
.venv/bin/python test_classify.py
./run.sh --preview # full pipeline on hardware (Orange PI + RealSense)
Integration status: WORKING_PROTOTYPE on drho1y-mvp_1, not integrated into https://arhipovdan.ru.
Sorting logic
CURRENT_IMPLEMENTATION_VERIFIED_IN_CODE (src/domain/classifier.ts, src/domain/pusherMotion.ts, unit tests).
| Category | Physical route | Active CAD diverter |
|---|---|---|
| B | STRAIGHT | none |
| C | PHYSICAL_LEFT | LEFT, −45° |
| D | PHYSICAL_RIGHT | RIGHT, +45° |
Frozen diverter timing / planes (verified in code + tests):
- rotation duration: 0.50 s
- opening safety margin: 0.15 s
- contact plane S: 1.0538 (fallback hinge geometry ≈ 1.0536)
- clear plane S: 1.6000
Classifier bounds (code + official_sources/doc-1783095831.pdf reference; PDF not re-parsed in this doc pass):
- dimensions strictly > 10×10×10 mm and < 450×320×320 mm
- circular when K > 0.8
- check order: dimensions → C, else circular → D, else B
Physical simulation
- Fixed timestep 1/120 s, max 4 substeps, gravity [0, −9.81, 0]
- Belt target speed 1.0 m/s (supported-body velocity coupling)
- CCD enabled on active product physics profiles
- Single dynamic product rigid body through spawn → junction → receiver settle
- LEFT/RIGHT CAD diverters:
kinematicPositionBasedcolliders synced to CAD yaw - Discharge edge ends belt support; gravity fall into receivers
- Receiver volumes are sensors for completion
Details: docs/ENGINEERING.md, /documentation.
Validation
npm ci
npm test -- --run # currently 245 unit tests
npm run build
# focused E2E (with preview on :3101):
npx vite preview --host 127.0.0.1 --port 3101 &
PLAYWRIGHT_BASE_URL=http://127.0.0.1:3101 npm run test:e2e -- e2e/routes.spec.ts e2e/smoke.spec.ts
- Two-page routing:
/+/documentation - CAD / GLB checksums: verified against values above
- Diverter frozen angles / duration: covered by unit tests
- Junction / discharge / camera classification: covered by domain tests (engineering-derived, not production-calibrated)
Production deploy (this host)
Nginx terminates TLS for arhipovdan.ru and proxies to Docker owl-web-1 on 127.0.0.1:3100 (docker-compose.server.yml + Dockerfile).
cd /opt/arhipovdan/app # or your checkout
COMMIT=$(git rev-parse --short HEAD)
BRANCH=$(git rev-parse --abbrev-ref HEAD)
RELEASE=$(date -u +%Y%m%d-%H%M%S)
docker compose -p owl -f docker-compose.server.yml build \
--build-arg "BUILD_COMMIT=${COMMIT}" \
--build-arg "BUILD_BRANCH=${BRANCH}" \
--build-arg "BUILD_RELEASE=${RELEASE}"
docker compose -p owl -f docker-compose.server.yml up -d --force-recreate
curl -s https://arhipovdan.ru/version.json
Repository vs cloud materials
| Material | In git | Cloud expected |
|---|---|---|
| Source, README, docs, configs, tests | yes | — |
| Runtime GLB/STL used by the deployed app | yes (required for deploy) | recommended mirror |
Author CAD conveer.FCStd (~5 MB) |
yes | recommended upload |
Official PDFs/ZIPs under input_info/, official_sources/ |
yes | optional mirror |
| Presentation / video demonstration | not in repo | required for platform field |
| ML weights | none (CV is classical OpenCV depth) | N/A |
Confirmed public presentation / video / cloud-folder URLs are not stored in this repository. Add them in the platform submission field when available.
Презентация / видеодемонстрация: links must be supplied by the owner (not invented here).
Current limitations
- Web classifier is a digital sensor simulation, not live RealSense inference.
- Product profiles are engineering-derived, not production-calibrated.
- Author CAD horn / complete transmission is absent or incomplete in the active GLB (
AUTHOR_CAD_INCOMPLETE). - Official compliance claims are limited by the missing extracted task PDF and by not re-parsing PDFs in every doc pass.
- Generated screenshots, videos, Gate stage folders, and tool
out/trees are not canonical.
Repository policy
- Keep author CAD, active runtime assets, official sources, build configs, and tests that protect active behavior.
- Generated outputs and historical media are not product truth.
- Real CV remains on
drho1y-mvp_1; do not force-merge it intomainwithout a validated web integration. - Rollback point for the pre-cleanup web baseline: git
4413f01ondan_branchhistory.
See also: /documentation in the running app, and docs/ENGINEERING.md.