Export a pallet plan to a UR robot
What the URScript pose list contains, how the rotation vector is derived, why the exporter refuses an unverified plan, and why it authorizes nothing.
A plan is a list of case positions on a deck. A robot needs poses in its own base frame, in the order they can physically be reached, with approach and retreat moves between them. That translation is the export, and this page is what it does and what it refuses to do.
What comes out
# Palletizer OS 0.5.0 — plan plan_1f0c… # execution exec_… # # Pose list only. This is NOT a runnable robot program: it carries no # gripper I/O, no safety configuration and no controller preamble, and # it has never been executed on hardware. # # Poses are UR p[x, y, z, rx, ry, rz]: metres, and an axis-angle rotation # vector in RADIANS, in the robot base frame of the default CellLayout. # ACQUIRE CASE-A target = p[-0.5000, 0.3000, 0.9000, 3.141593, 0.000000, 0.000000] # PLACE CASE-A target = p[0.7000, -0.4000, 0.2500, 3.141593, 0.000000, 0.000000]
The rotation vector
Universal Robots poses carry orientation as an axis-angle vector in radians, not as roll-pitch-yaw degrees. The exporter builds the RPY rotation matrix, converts it to axis-angle, and prints six decimals — the same conversion the adapter sends to a live controller, in the same file, so the export cannot drift from what the robot would be told. A tool pointing straight down at the deck is rx = π, which is the 3.141593 above.
The cell frame
Poses are expressed in the base frame of the default cell layout, and every number in it is editable configuration rather than a constant of nature:
pallet origin (700, -400, 0) mm infeed pick (-500, 300, 900) mm home (0, 0, 1200) mm approach clearance 120 mm above a placement retreat clearance 120 mm after release traverse height 1500 mm between picks speeds 1 traverse, 0.35 on approach (fractions)
If your cell is not laid out this way — and it is not — these are what you change. The arithmetic that turns a placement into an approach, a descent, a release and a retreat does not change with them.
What the exporter refuses
It recomputes the plan’s hash and re-derives its verdict from its geometry before writing a single pose. A document whose contents no longer match its recorded hash is refused; so is one whose recorded verdict its geometry does not support — the digest is unkeyed, so anyone who can edit a plan can reseal it, and only re-running the validator catches that. An inadmissible plan is refused outright. The one thing an export must never do is turn a defect into coordinates.
What it is not
It is not a program: no gripper I/O, no safety configuration, no controller preamble. It is not an authorization — that belongs to the safety gate, which mints a capability token inside the controlling process, recomputes both hashes itself and has no override parameter. And it is not evidence that any of this has run on a physical arm; no adapter in this project has. Commissioning a cell from this file is an integrator’s job, under their risk assessment.
The placement CSV is the same data without the cell frame, for a controller that is not a UR. Both formats come from the paid API and, unmetered, from the open-source CLI: palletizer export plan.json --format urscript.
Upload your own SKU CSV and get a validated, sealed plan in the browser.
The engine is Apache-2.0 and unmetered on your own machines — what the hosted plans add is a signature only this service can make, state it keeps for you, and compute on its hardware.