EnglishDeutsch/api/energyGitHub · iceccarelli
Grimaldi EngineeringCluster control · Frankfurt
Docs

Read the format. Read the states.

Everything the planner accepts, everything it emits, and what the cell does with it.

SKU CSV

Header required. Comma or semicolon delimited; German decimals (8,5) accepted. Column names are matched case-insensitively and a few aliases are understood (length / laenge, weight / gewicht, qty / anzahl).

ColumnUnitNote
sku_idtextRequired. Repeated across rows or with qty.
length_mmmmRequired. Footprint along the pallet length before rotation.
width_mmmmRequired. Footprint along the pallet width before rotation.
height_mmmmRequired.
weight_kgkgOptional, default 0. Drives payload limit, centre of mass and crush load.
qtycountOptional, default 1. Expands the row.
max_stack_kgkgOptional. Maximum mass this box may carry on top. When present, exceeding it is a FAULT.

Sample

sku_id,length_mm,width_mm,height_mm,weight_kg,qty,max_stack_kg
SKU-01,400,300,250,8.5,6,60
SKU-02,600,400,300,15,4,120
SKU-03,300,200,200,4,10,20
SKU-04,400,400,280,11,6,80
SKU-05,250,250,200,3.2,8,15
SKU-06,400,200,250,2.4,3,20

The browser planner accepts up to 400 boxes per pallet. Larger lists run in the Python engine. sku_id,length_mm,width_mm,height_mm,weight_kg,qty,max_stack_kg

Units and frames

mm
All lengths. Pallet origin is the deck corner; x runs along pallet length, y along width, z up from the deck surface.
kg
All masses. Pallet own weight is not part of the payload limit.
rot_deg
0 or 90. A rotated box swaps its footprint edges; height never changes.
layer
1-based in exports, 0-based in the JSON plan.
cycle
Cycle time is boxes × 6 s, a planning assumption stated next to the number. Measured cycle time replaces it at acceptance.

How the numbers are produced

Boxes are grouped into layers from the tallest down; a layer only admits boxes within 10 % of its tallest box so its top face is near-flat. Each layer is shelf-packed first-fit-decreasing by footprint, both orientations tried.

Base support per box is the share of its footprint resting on boxes of the layer below (1.0 on the deck). Centre-of-mass score is 1 minus the weighted offset from the pallet centre over the half diagonal. Stability = 0.6 × mean support + 0.4 × centre-of-mass score.

Density is placed box volume over pallet footprint × stack height. Load on top of a box is the mass of every higher box in proportion to footprint overlap; it is compared against max_stack_kg when given.

The Python engine (palletizer_full/optimizer.py) uses the same packing and scoring; the browser planner additionally applies the 10 % layer-height tolerance and the crush check, which the engine does not yet. Where they differ, this page says so.

Codes

CodeLevelMeaning
E-CSV-EMPTYFAULTEmpty input.
E-CSV-HEADERFAULTA required column is missing from the header.
E-ROW-DIM / E-ROW-KG / E-ROW-QTY / E-ROW-STACKFAULTA row has a non-positive or non-numeric value. The row is skipped and named.
F-DECKFAULTA SKU does not fit the deck in either orientation.
F-HEIGHTFAULTA SKU is taller than the stack limit.
F-CRUSHFAULTLoad on a SKU exceeds its max_stack_kg. Copy: "SKU-04 exceeds crush stack."
H-HEIGHT / H-PAYLOADHOLDBoxes left off because the stack or payload limit was reached. They are listed.
H-SUPPORTHOLDA layer has under 85 % mean base support.
H-COMHOLDCentre-of-mass score under 0.8.
H-CSV-CAPHOLDList capped at 400 boxes.
OKRUNAll SKUs placed, stability ≥ 0.6, no fault.

State machine

StateDefinition
IDLENo plan loaded or planner has no placements. Robot holds at home. Exits to RUN on a valid plan and an operator start.
RUNPlan valid, cell executing placements in order. Telemetry: current index, layer, stability of the partial stack. Exits to HOLD on a hold code or an operator pause; to FAULT on a fault code, gripper feedback loss or safety stop.
HOLDMotion paused at a safe pose, plan retained. Operator resolves the named condition (re-plan, remove SKU, adjust limit) and returns to RUN, or aborts to IDLE.
FAULTMotion stopped, plan invalidated, fault code latched. Requires acknowledge; exits only to IDLE. Safety functions live on the safety PLC, not here.
IDLE ──plan valid + start──▶ RUN
RUN  ──hold code / pause───▶ HOLD ──resolved──▶ RUN
HOLD ──abort───────────────▶ IDLE
RUN  ──fault code / e-stop─▶ FAULT ──acknowledge──▶ IDLE

Reference numbering for the OPC UA exposure in the gateway: state 0 IDLE, 1 RUN, 2 HOLD, 3 FAULT, plus the active code string, placement index, layer, stability and density of the stack so far. Confirm node ids against the version you deploy.

Written and maintained by Vincenzo Ceccarelli Grimaldi, Frankfurt am Main.