feat: align project with OZON Track 3 official specification

- Fix critical parameters: min dimensions 10×10×2 mm (was 10×10×10)
- Fix roundness threshold: K ≥ 0.7 (was 0.8)
- Add input_info analysis document (INPUT_INFO_ANALYSIS.md)
- Update Hero: new title, badges (Min 10×10×2, K≥0.7→D, C priority), proof-line
- Add CurrentProofCard summary block: Category/Command/Target/Why (cyan border)
- Add CPriorityExplanation component (orange card, dedicated section)
- Update all docs: README, DEMO_SCRIPT (7-min timing), JURY_QA, SUBMISSION_CHECKLIST
- Update tests: 16/16 passed under new parameters
- Update 3D twin: dynamic DIMENSION_LIMITS display
- Update criteria cards: roundness ≥ 0.7
- Tested: build OK, Docker OK, domains OK (arhipovdan.ru, www, ai-shorts.ru)
This commit is contained in:
root
2026-07-04 13:09:49 +02:00
parent e0a655db4f
commit 17c37c2580
17 changed files with 709 additions and 29 deletions

View File

@@ -0,0 +1,26 @@
interface CPriorityExplanationProps {
onShowCPriority: () => void;
}
export default function CPriorityExplanation({ onShowCPriority }: CPriorityExplanationProps) {
return (
<section className="c-priority-section" aria-labelledby="c-priority-title">
<div className="c-priority-card">
<div className="c-priority-icon" aria-hidden="true">
C
</div>
<div className="c-priority-content">
<h3 id="c-priority-title">Почему C имеет приоритет?</h3>
<p>
Если товар одновременно негабаритный и имеет круг в сечении, он направляется в C.
Сначала проверяются габариты, и только если они проходят — форма.
Это предотвращает попадание негабаритных объектов в основной сортировщик.
</p>
<button type="button" className="btn-primary" onClick={onShowCPriority}>
Показать C-priority
</button>
</div>
</div>
</section>
);
}

View File

@@ -29,7 +29,7 @@ const PRODUCT_CRITERIA: CriteriaCard[] = [
{
id: 'round-section',
title: 'Круг в сечении',
evidence: 'Roundness ≥ 0.8 направляет товар в зону D.',
evidence: 'Roundness ≥ 0.7 направляет товар в зону D.',
status: 'covered',
linkedScenario: 'round_object',
linkedLabel: 'Круглый объект',

View File

@@ -40,6 +40,33 @@ export default function CurrentProofCard({ simulation }: { simulation: Simulatio
<h3>{item?.name}</h3>
</div>
<div className="proof-summary">
<div className="summary-row">
<span className="summary-label">Category:</span>
<strong className={`category-${result?.category ?? 'default'}`}>{result?.category ?? '—'}</strong>
</div>
<div className="summary-row">
<span className="summary-label">Command:</span>
<strong>{command}</strong>
</div>
<div className="summary-row">
<span className="summary-label">Target:</span>
<strong>{result?.category ? `Zone ${result.category}` : '—'}</strong>
</div>
<div className="summary-row">
<span className="summary-label">Why:</span>
<em>
{isCPriority
? `dimensions failed, so C has priority even though K = ${item?.roundness.toFixed(2)}`
: result?.dimensionsPass === false
? 'dimensions failed (oversized or undersized)'
: result?.roundnessPass === false
? `dimensions pass, but K = ${item?.roundness.toFixed(2)} ≥ 0.7`
: 'dimensions pass and round section is not detected'}
</em>
</div>
</div>
<div className="proof-grid">
<div className="proof-item">
<span className="proof-label">Dimensions</span>
@@ -55,7 +82,7 @@ export default function CurrentProofCard({ simulation }: { simulation: Simulatio
<strong className={result?.roundnessPass === false && result?.dimensionsPass ? 'fail-text' : 'pass-text'}>
{item?.roundness.toFixed(2)}
</strong>
<em>{result?.roundnessPass ? 'PASS' : 'DETECTED (≥0.8)'}</em>
<em>{result?.roundnessPass ? 'PASS' : 'DETECTED (≥0.7)'}</em>
</div>
<div className="proof-item">
<span className="proof-label">Category</span>

View File

@@ -14,19 +14,18 @@ export default function HeroSection({
<div className="hero-content">
<p className="hero-eyebrow">OZON Tech · Product Demo</p>
<h1 id="hero-title" className="hero-title">
Интеллектуальная система сортировки товаров
Интеллектуальная система предварительной сортировки товаров
</h1>
<p className="hero-subtitle">
Симуляция показывает полный цикл: обнаружение товара, классификация по правилам,
управляющая команда и маршрутизация в зоны B/C/D.
3D-симуляция ПАК показывает полный цикл: товар поступает из A, определяется CV-модулем, классифицируется в B/C/D и физически маршрутизируется исполнительной частью.
</p>
<div className="hero-badges" aria-label="Ключевые возможности">
<span className="hero-badge">Computer Vision</span>
<span className="hero-badge">Rule-based classification</span>
<span className="hero-badge">Actuator routing</span>
<span className="hero-badge">Cycle time</span>
<span className="hero-badge">Fault handling</span>
<div className="hero-badges" aria-label="Параметры системы">
<span className="hero-badge">Конвейер 1 м/с</span>
<span className="hero-badge">Min 10×10×2 мм</span>
<span className="hero-badge">Max 450×320×320 мм</span>
<span className="hero-badge">K ≥ 0.7 → D</span>
<span className="hero-badge">C priority</span>
</div>
<div className="hero-actions">
@@ -65,7 +64,7 @@ export default function HeroSection({
</div>
</div>
<p className="hero-chain-caption">
Результат демо: категория B/C/D, команда ROUTE_TO_* и целевая зона
Detection → Classification → ROUTE_TO_* → Actuator → B/C/D
</p>
</div>
</section>

View File

@@ -11,6 +11,7 @@ import RouteArrows3D from './RouteArrows3D';
import SceneLabels3D from './SceneLabels3D';
import { PHYSICS_ENGINE_ENABLED } from './itemMotion';
import { NOMINAL_CONVEYOR_SPEED_MPS } from '../../domain/simulation';
import { DIMENSION_LIMITS } from '../../domain/classifier';
export interface SorterDigitalTwinProps {
simulation: SimulationState;
@@ -142,7 +143,9 @@ export default function SorterDigitalTwin({
{category ? <span className={`twin-chip category-${category}`}>Zone {category}</span> : null}
<span className="twin-chip">{command}</span>
<span className="twin-chip">Conveyor {NOMINAL_CONVEYOR_SPEED_MPS.toFixed(2)} m/s</span>
<span className="twin-chip">Min 10×10×10 mm</span>
<span className="twin-chip">
Min {DIMENSION_LIMITS.min.width}×{DIMENSION_LIMITS.min.depth}×{DIMENSION_LIMITS.min.height} mm
</span>
{showFps ? <span className="twin-chip">FPS ~{fps}</span> : null}
<span className="twin-chip muted-chip">
Motion: {PHYSICS_ENGINE_ENABLED ? 'physics' : 'state-machine'}