Part of #83. Depends on the assembly-line scene builder.
Tie the operator's route to a work order: as each workstation operation completes, tick off the matching line-item, so the run produces an order.json showing the assembly fulfilled step by step.
Scope
- Define the build as a
BillOfMaterials / Order (the parts/operations that make one finished unit).
- Map station completion -> line-item: reaching + dwelling at a station emits a placement/action. Reuse
order.ItemPlacement and order.ActionEvent (a place event time-synced to the frame, carrying the operator's hand-joint world position — the same channel examples/assembly_station.py uses).
- e.g. station_1 ->
base, station_2 -> subassembly, station_3 -> fasteners, station_4 -> inspection pass, station_5 -> unit complete (exact mapping is a design decision — propose in the PR).
- Run
order.verify_order(...) and write the order.json sidecar; the analytic manifest stays byte-golden (order GT rides in the sidecar, per order.py).
Acceptance
- Deterministic
order.json where status goes missing -> ... -> fulfilled as stations complete, one ActionEvent per station-completion at the correct frame.
- Test asserts final
OrderStatus == fulfilled and action-event frames line up with the scene's dwell frames.
- Typed, mypy-strict, ruff clean.
Pointers
Part of #83. Depends on the assembly-line scene builder.
Tie the operator's route to a work order: as each workstation operation completes, tick off the matching line-item, so the run produces an
order.jsonshowing the assembly fulfilled step by step.Scope
BillOfMaterials/Order(the parts/operations that make one finished unit).order.ItemPlacementandorder.ActionEvent(aplaceevent time-synced to the frame, carrying the operator's hand-joint world position — the same channelexamples/assembly_station.pyuses).base, station_2 ->subassembly, station_3 ->fasteners, station_4 ->inspection pass, station_5 -> unit complete (exact mapping is a design decision — propose in the PR).order.verify_order(...)and write theorder.jsonsidecar; the analytic manifest stays byte-golden (order GT rides in the sidecar, perorder.py).Acceptance
order.jsonwhere status goesmissing -> ... -> fulfilledas stations complete, oneActionEventper station-completion at the correct frame.OrderStatus == fulfilledand action-event frames line up with the scene's dwell frames.Pointers
src/multicam_sim/order.py(BillOfMaterials,Order,ItemPlacement,ActionEvent,verify_order,write_order_json),examples/assembly_station.py, issue Assembly-station: emit placement-synced operator action events (for causal action↔change fusion) #34 (placement-synced action events).