Warehouse Robot Control Platform
Update  /  18 October 2026 Warehouse Robot Control Platform
Platform update

One floor, three layers, nothing taking a step unless it is told it may

Our warehouse robot platform now runs end to end on a simulated site: a dashboard for operators, an edge server that drives the floor, and the devices themselves. This post shows what it does, how it keeps people and machines safe, and what we have run to prove it.

1,700
automated tests
Covering every layer, from the devices to the dashboard.
25
fault types
Each one can be struck on demand and has a test of how the platform reacts.
~100 ms
fleet pause
Every robot held. The limit we set is 1 second.
1,000
devices on one edge
State reaches the cloud at p95 81 ms, against a 500 ms limit.
The system

Three layers, one shared language

The platform controls a fleet of forklifts, robot arms, conveyors and cameras in a warehouse. It is built as three layers that talk only through defined interfaces, so each can be replaced or upgraded on its own.

L1Cloud

Dashboard and cloud service

What operators, supervisors and maintenance staff see. A live floor map, alarms, commands, history and analytics across several sites, signed in through an identity provider with seven roles.

Site to cloud · NATS and protobuf · each site is a leaf node of the cloud hub · state, alarms, commands, safety records
L2Edge

The edge: the robot server

Runs on site. It admits devices, keeps the live picture of the floor, publishes the permit to operate, routes the forklifts without collisions, turns what the cameras see into pallet jobs, and survives the loss of a node or of the WAN.

Edge to devices · NRP (our protocol), VDA 5050, plain JSON over MQTT, OPC UA, RTSP · mTLS with enrolled certificates
L3Devices

The devices and the world they stand in

An agent on every machine and a physical simulation around them: geometry, batteries, radio dead zones, people walking the aisles, MuJoCo arm physics and rendered camera pictures. Robots, shapes and instructions are data in YAML packs, not code.

How it works

What happens when an operator pauses the fleet

One action touches every layer. This is the path a fleet pause takes, and the one we time.

  1. Operator presses Pause

    Sent as the signed-in person, with an idempotency key so a retry never acts twice. Resuming asks for a step-up sign-in.

    sent once, as a named person
  2. Cloud records it

    The request is written to the audit trail in Postgres with who, what and when, then sent to the site.

    audit + lifecycle
  3. Edge takes it north to south

    The command service passes it to the safety supervisor. The stop goes out before the store is waited for, so a slow disk never delays it.

    no wait on storage
  4. Permit withdrawn

    The supervisor marks every device held in the next permit. Vehicles on VDA 5050 get a pause order, one by one.

    permit every 500 ms
  5. Devices hold

    Every device is in HOLD and the dashboard shows who is held and why. Resuming the fleet needs a second person.

    measured ~100 ms · limit 1 s
Features

What each part can do today

L1

Dashboard

  • Live floor map at 10 Hz, with staleness and device flags: held for, signal quality, presence.
  • Alarm console in the ISA-18.2 style: first-out, suppressed counts, acknowledge by a person. 300 alarms in 60 s block the browser for less than 50 ms at a time.
  • Commands to one device or the fleet, with every terminal state shown: done, rejected, expired, failed, cancelled.
  • Multi-site with each site behind its own WAN. A 10-minute outage replays with zero duplicate, out-of-order or missing rows.
  • History and analytics over 30 days: OEE, MTBF, MTTR, throughput, daily CSV report, 2-hour incident replay, maintenance tickets raised from motor and battery alarms.
  • Configuration, maps and OTA rolled out ring by ring and halted by a rollback.
  • Digital twin in Unity, live video over WebRTC, and an interface in English and Japanese.
L2

Edge

  • Five protocols admitted at one door, with devices enrolled over EST and let in over mTLS.
  • Safety supervisor that publishes the permit to operate and applies nine supervisory rules.
  • Traffic control by reservation: over 8 simulated hours and 6,826 journeys, no two forklifts ever overlapped.
  • Missions: pallets seen by the cameras become jobs, forklifts are matched to stations and sent to charge when idle. 96 to 103% of what the stations could take.
  • Raw camera vision finds pallets, unknown slots and askew pallets. 240 of 240 empty slots and 120 of 120 pallet types read right on test scenes.
  • High availability: three nodes, a leader by lease. When the leader is killed, another serves after about 5 s.
  • Edge to cloud over a leaf node, safety records first, each once and in order.
L3

Devices and world

  • Device agent speaking NRP, VDA 5050 or JSON over MQTT, with a write-ahead log so safety events survive a power cut.
  • A world with physics: bodies, forks, belts, batteries, a hall's radio with roaming gaps and dead zones, and people.
  • MuJoCo arm cell, checked against an independent arm model.
  • Perception: labelled picture sets from a seed, byte for byte repeatable. Pose within 3 cm and 2 degrees.
  • Hardware in the loop: the same device agent that ships on a machine runs against a simulated I/O bench.
  • Definition packs: add a robot, a shape or an instruction in YAML. A floor scrubber was added this way.
  • 3D view of the floor in Foxglove or a browser, at 10 Hz.
On screen

The running system, captured

Screenshots taken on 18 October 2026 with all three layers running together: the simulated floor, the edge, and the cloud and dashboard. We struck the faults on purpose and cleared them afterwards. The yellow labels are ours; everything else is what the screens showed.

3D viewer

The simulated world drawn in the browser, and streamed to Foxglove or Lichtblick as well. Here a person has stepped into arm-01's cell (F24) and agf-03's E-stop is pressed (F01). The panel on the left lists what is struck, what is held and what is offline.

1Live link to the world, 10 updates a second2Faults struck now: F24 person in the cell, F01 E-stop3Held by its own agent: arm-01 waits for a reset4arm-01 red: protective stop, person in cell5agf-03 in red: E-stop pressed6Radio dead zone (pink) behind a 6 m rack7Pallets in inbound slots
  1. Live link to the world, 10 updates a second
  2. Faults struck now: F24 person in the cell, F01 E-stop
  3. Held by its own agent: arm-01 waits for a reset
  4. arm-01 red: protective stop, person in cell
  5. agf-03 in red: E-stop pressed
  6. Radio dead zone (pink) behind a 6 m rack
  7. Pallets in inbound slots
The 3D viewer in a browser. The same live stream opens in Foxglove.

Physical simulation

What camera cam-01 sees, rendered by the world from a seed: 6 m up, 9.4 mm of floor per pixel, with sunlight, shadows, lens blur and sensor noise. Each picture comes with its depth, a segmentation and instance masks, and the true pose of every pallet. The edge's pallet detector is held to that truth, within 3 cm and 2 degrees.

1Pallet 0.40 m off its slot, turned 10.3°2Shrink-wrapped pallet, square in slot-a23Painted slot outline4A forklift (AGF-1600) driving into view5Shadows from a sun at 268°, 449 lux
  1. Pallet 0.40 m off its slot, turned 10.3°
  2. Shrink-wrapped pallet, square in slot-a2
  3. Painted slot outline
  4. A forklift (AGF-1600) driving into view
  5. Shadows from a sun at 268°, 449 lux
Depth picture of the same frame: nearer surfaces brighter.Depth
Segmentation of the same frame: pallets in yellow, the forklift in orange.Segmentation
Instance mask of the same frame: one colour per pallet.Instances
One frame of a generated picture set. The same seed gives the same pictures, byte for byte.

Device management

Every device on the site, live, in one list. Each class reports what matters for it, and a class the dashboard has never seen is shown from the factsheet the device sends. The registry is the edge's own record of what it has in service.

1LIVE: the site streams; LOST greys every row2Filter by class3Forklift: battery, load, job, motor4Arm: boxes left, cycles, picks5Camera: slots occupied6Conveyor PLC, over OPC UA7Unknown class, from factsheet8Age, judged by each device's period
  1. LIVE: the site streams; LOST greys every row
  2. Filter by class
  3. Forklift: battery, load, job, motor
  4. Arm: boxes left, cycles, picks
  5. Camera: slots occupied
  6. Conveyor PLC, over OPC UA
  7. Unknown class, from factsheet
  8. Age, judged by each device's period
Devices, signed in as an operator: 8 forklifts, 2 arms, 3 cameras, 2 conveyor PLCs and an environment sensor.
1Served by the edge: revision 22Model and serial3Older firmware4Link, as the edge sees it
  1. Served by the edge: revision 2
  2. Model and serial
  3. Older firmware
  4. Link, as the edge sees it
Registry, served by the edge. A device added here stays OFFLINE until it connects.

Live floor map

The floor from the site package, with every vehicle moving as the site reports it. Arms, conveyors and cameras stand where the package puts them, filled while they work.

1Forklift, pointing where it heads2Arm: filled while it works3Conveyor: filled while it runs4Camera, between the two slots it watches5Inbound slot6No Wi-Fi coverage7Charger
  1. Forklift, pointing where it heads
  2. Arm: filled while it works
  3. Conveyor: filled while it runs
  4. Camera, between the two slots it watches
  5. Inbound slot
  6. No Wi-Fi coverage
  7. Charger
Live map of the simulated warehouse with no fault on the floor.

Fault tolerance

An E-stop on agf-03 (F01) and a radio dead zone on agf-04 (F05), struck through the edge. agf-04 never looks live while it is silent: it greys out with the age of its last position. The edge declares it LOST and keeps its reserved floor until it reports again (rule R1).

1agf-03 in red: E-stop pressed2agf-04 in a dead zone: greyed, aged 4 s3Alarm count4Arms keep working
  1. agf-03 in red: E-stop pressed
  2. agf-04 in a dead zone: greyed, aged 4 s
  3. Alarm count
  4. Arms keep working
Live map a few seconds after the two faults were struck.
1Someone entered arm-01's cell2The supervisory rule behind it3Came back twice: counted once4The station goes down with its arm5Device back: the alarm waits for a person6Acknowledged by a person, under their name
  1. Someone entered arm-01's cell
  2. The supervisory rule behind it
  3. Came back twice: counted once
  4. The station goes down with its arm
  5. Device back: the alarm waits for a person
  6. Acknowledged by a person, under their name
Alarm console about a minute later, after F24 put a person in arm-01's cell. agf-04 is back, and its alarm stays until someone acknowledges it.
Safety

Devices must be told they may move

Most systems stop a robot when something goes wrong. This one inverts it. A machine starts new motion only while it holds a fresh permit, so silence from the server is itself a stop.

The permit to operate

The edge sends a permit every 500 ms. A permit is valid for one second on the device's own clock, and it names any device that is held. If permits stop, because the edge crashed, the broker went down or the network was cut, every supervised device holds within a second of the last one.

A permit from an older epoch is ignored, so a frozen leader that wakes up after a takeover cannot send a machine on its way. The highest epoch seen is kept across a loss of power.

0 s1 s2 s3 s time on the device's clock permit sent at 0 s, valid to 1 s last permit, sent at 1.5 s edge lost at 1.5 s ALL DEVICES HOLD a blip shorter than 500 ms on the bus is let pass: it costs at most one more permit
R1

A device goes silent

Alarm raised, nothing is sent to it, and a forklift keeps its reserved floor until it is heard again.

R2

Forklift off its reservation

Over 0.5 m outside what is reserved: it and its neighbours are held until an operator places it, even through a restart.

R3

Station interlock

An arm is held first. The forklift is released into the station only when the arm's own state shows the hold.

R4

Person in a robot cell

A light curtain or laser scanner sees someone: the arm is held within one permit, about 150 ms, and stays held until the guard is reset.

R5

Vehicle lost its position

Localization score under 0.6: paused until it is back at 0.8. An operator can vouch for it for 5 minutes at most.

R6

Clock off by 100 ms

Alarm raised and the device's data is ordered by when it arrived, not by what it claims.

R7

Bus not healthy for 500 ms

The permit is withdrawn and everything that needs one holds.

R8

Traffic controller silent 5 s

Every vehicle it routes is paused, and released only by the supervisor that paused it.

R9

A device reports a safety stop

A P0 alarm stands until the device says it is over. Nothing is dispatched to it meanwhile.

Stored before acknowledged

Safety events and events are written durably before the edge confirms them. A device keeps its own write-ahead log and resends until the edge confirms. No safety event was lost in the storm, failover and outage runs listed below.

Fenced leadership

A three-node edge elects one leader by lease. Two never serve at once. A frozen leader that wakes stops its edge before it sends anything.

People and permission

Seven roles. Step-up sign-in before a resume, a second person before a fleet resume, and every command in an audit trail with an idempotency key.

Trusted devices, signed changes

Devices enrol over EST and connect with mTLS. Configuration bundles are signed with cosign keys (ECDSA P-256), proven on probation and rolled back if a device does not come up healthy.

People and motion

F01E-stop F02person in path F03localization F15frozen sensor F24person in cell

Machines

F06vacuum lossF07double pickF08conveyor jam F13motor over-tempF14ageing battery

Pallets and cameras

F09camera obstructedF10low confidenceF11pallet askewF12pocket blocked

Network, power and software

F04roaming gapF05dead zoneF16duplicatesF17malformed F18clock skewF19rebootF20log stormF21older firmware F22cert near expiryF23broker failoverF25power blip

Each fault above can be struck on the simulated floor on demand, and a test checks what the edge does against the simulator's ground truth. Two more, a state stall and a failed update, are tested the same way.

Standards

Built on public standards, not private formats

Where an industry standard exists we use it, so vendors' vehicles, tools and viewers work without translation.

VDA 5050Vehicle orders and state for forklifts, including third-party makes. Four vendor profiles are played by the simulator.
OPC UAConveyor PLCs, served and read as real OPC UA nodes.
ISA-18.2Alarm life cycle: raised, acknowledged by a person, cleared. First-out and suppression shown.
EST and mTLSDevice enrolment, certificate renewal at two thirds of life, revocation.
OIDCOperator sign-in through an identity provider, roles read again every 10 minutes.
cosign, ECDSA P-256Signature over the manifest of every configuration bundle.
Protobuf and NATSSite to cloud, with JetStream mirrors and leaf nodes for outages.
MQTT and RTSPEdge to devices, and raw camera streams.
WebRTC (WHEP)Camera pictures in the browser.
MCAP, glTF, URDFRun recordings, site models and robot descriptions for the twin and 3D views.
LIFLayout Interchange Format: forklift lane layouts imported as they come.
FoxgloveThe floor streamed at 10 Hz to a 3D panel.
Speed

Each limit we set, and how much of it we use

Every row has a limit written down before the test. The bar shows the worst figure we measured as a share of that limit. All were measured in simulation on a single machine.

Worst measured figure, as a share of its limit

Shorter is better. Every bar ends well before 100%.
Fleet pause to all devices heldlimit 1 s
~100 ms10% of limit
Device change on screenlimit 1 s
97 ms9.7% of limit
Command acknowledged, 1,000 devicesp95, limit 300 ms
30 ms10% of limit
State reaches the cloud, 1,000 devicesp95, limit 500 ms
81 ms16% of limit
Device to digital twinp95, limit 1 s
135 ms13.5% of limit
Device to screen, 500 operator sessionsp95, about 560,000 states a second, limit 500 ms
153 ms31% of limit
Analytics over 30 days, three sitesslowest query (OEE), p95 limit 1 s
205 ms20.5% of limit
0%25%50%75%100% of limit
worst measuredroom left under the limit

Recovery is measured in seconds, not milliseconds: a reboot storm of 120 devices is fully back in about 3 s (limit 30 s). At 1,000 devices all return 29.3 s after the storm. After the leader is killed, another member serves after about 5 s and every device is back ONLINE 9 to 10 s after the kill.

Proof

How many tests, and what they check

The automated tests behind the platform, and what they check.

1,700
automated tests
Across the edge, the devices, the cloud, the dashboard and the digital twin.
27
fault types, one test each
Every fault in the catalog, plus two more.

Tests by area

The edge has the most tests, because it holds the safety logic.
The edgesafety, traffic, missions, availability
841
Interfaces between layersevery implementation checked the same way
257
Devices and worldagents, physics, perception
256
Cloud servicecommands, history, analytics, roles
118
Dashboard logiclive state, alarms, commands
124
Dashboard in a real browserend to end, including video
43
Digital twinfeed, scene and playback
32
Dashboard componentseach screen part in every state
29
All

Between layers

  • The interfaces between layers hold on every implementation: the simulator, the edge and the devices, including over TLS.
  • Signed configuration bundles verify end to end, from the cloud to the edge.
  • Message formats, scenario files and site packages stay valid.
L1

Dashboard and cloud

  • Live state reaches the screen in time, and 300 alarms in a minute do not freeze the page.
  • Commands reach every terminal state and each one renders. Step-up and second-person rules are enforced.
  • Outages: a 10-minute WAN cut replays with no duplicate, out-of-order or missing rows.
  • Analytics, roles, audit trail, bundles and maps behave as specified. Every widget is checked in its live, stale, lost, empty and alarm-flood states.
  • The Unity twin reads the feed exactly as the Go side writes it.
L2

The edge

  • Every fault is struck and the edge's response is measured against the simulator's ground truth.
  • Safety: the fleet pause, the permit, the nine supervisory rules, holds that survive a restart or takeover.
  • Traffic and missions: no two forklifts overlap, no deadlock lasts a minute, pallets become jobs.
  • Availability: leader killed, cut off, wrong clock, full disk. Never two leaders, nothing lost.
  • Protocols and vision: five protocols, certificates, and the detector against rendered scenes.
L3

Devices and world

  • The device interface on every device agent, however the agents are deployed.
  • Physics and invariants checked at every control period of simulated shifts.
  • Timing trials that must keep time to 50 ms, and agents killed without warning.
  • Perception: the same seed gives the same pictures byte for byte, pose within 3 cm and 2 degrees.
  • The arm on MuJoCo agrees with an independent model, and the device agent is exercised against a simulated I/O bench.
Recorded long runWhat it didResult
Traffic, 8 simulated hours20 forklifts, 6,826 journeys on a larger simulated site0 footprint overlaps · longest deadlock 10.9 s
A full shift at 20x speedThe edge and the simulated floor as separate systems: 149 pallets arrived, 22,381 m driven, 2,500 routes0 safety violations · 0 orders resent
72-hour WAN outage438 safety events, 8,760 events and 291,610 telemetry samples held back, then replayedEach once, in order, safety first · 10 runs of 10 passed
Reboot storm, 1,000 devicesEvery device power-cycled at onceAll back in 29.3 s · no safety event lost
Leader killed without warningThree edge nodes, then the new leader frozen past its leaseSuccessor in 3.4 to 7.7 s · never two leaders · woken leader stands by
Eight-hour mixed-vendor shiftForklifts of two vendor profiles on one floor21.0 pallets/h through the peak · none of 3,169 routes cancelled
Eight days of floor time192 hours of operation, run at 20x speedNo leak · 4,293 pallets
Operator load500 dashboard sessions each following every device of three sitesp95 153 ms against a 500 ms limit

Counts are of tests, not of checks: one test can cover several cases.

Where we stand

What this is not yet

All of the figures above come from simulation. No physical robot has run on the platform yet.

No hardware yet

Devices, people, radio and physics are simulated. A real machine's I/O is exercised only on a simulated bench. On a real floor the cell's own safety circuit acts first; our hold is the second layer.