Say what you need, and the rack fetches the bin. A full-wall automated storage and retrieval system — 23 feet of motorized gantry, counterweighted to near-zero drive load, voice-controlled from a kiosk at the workbench.
Drag to orbit, right-drag to pan, scroll to zoom. Use the view buttons in the lower-left.
Safety can't route through software. The architecture splits into three tiers — hardware for guaranteed stops, firmware for smooth motion, and Node.js for everything else. If the event loop stalls, the watchdog bites and brakes engage.
| Tier | Where | Latency | Responsibility |
|---|---|---|---|
| T0 — Hardware | Safety relays, e-brakes, enable pins | µs–ms, guaranteed | E-stop chain: light curtain, presence beam, e-stop button, limit switches. Wired directly into motor-enable relay. Software observes, never mediates. |
| T1 — Firmware | Stepper drivers / motion MCU | µs–ms | Step generation, 4-motor Y sync, stall detection, decel ramps. Hardware watchdog — if Node stops petting it (~100ms), motion halts. |
| T2 — Node.js | Raspberry Pi 5 | ~1–50ms, soft | Orchestration state machine, inventory, kiosk UI, voice/AI, telemetry, cable-wheel supervisor. Decides what to do next — never what to do about safety. |
White 4080 T-slot (80mm face vertical) spanning all 276". Doubles as the X-axis rail. 6 spliced 48" sticks, counterweighted via 2:1 reeving — near-zero drive load.
DIY concrete-on-threaded-rod castings hidden in the wall cavity. 2:1 pulley reeving (mandatory — 104" travel in 104" of cavity). Three stations balance the total gantry mass.
Every slot fits the same 27-gal Commander tote. Every axis uses the same NEMA 23 (23HS45-4204S, 425 oz-in). One rail spec, one extractor setting, one spare covers all six.
Bins store hanging by their lips on 2x4-on-edge guide rails capped with UHMW slide strips. Lead-in cuts funnel misaligned bins home. 68 rails, zero shelf hardware.
DIY motorized cable reel in the attic — a printed 18" drum in current-limited torque mode acts as an electronic constant-tension spring. No drag chain, no $3k commercial reel.
X drive is a 3D-printed helical rack bolted along the beam's T-slot. Continuous multi-tooth engagement — quiet, low-slip, printed in teal. 3.7× torque margin.
Node.js (TypeScript) on the Pi 5. The event loop is the point — GPIO interrupts
and CAN frames preempt in-flight command flows as the default model. A move()
is a promise that a curtain-tripped event can reject mid-flight.
SQLite via better-sqlite3. Bin → slot → contents. Full-text search, tags, photos. "Where are the hose clamps?"
Fetch/store cycle: idle → align → finger-enter → lift → extract → transit → deliver → return. Every transition sensor-guarded, every state resumable.
Fastify + WebSocket. Live gantry position on the 27" monitor. Search, request-bin, put-away, big red STOP button.
Mic → STT → Claude tool-use against the inventory. Spoken response over the bench speakers. AirPlay receiver ducks when the system talks.
Headless process exposing the same motion API as real hardware. UI, inventory, and voice develop against it with zero hardware.
Subscribes to every T0 signal and T1 fault. Logs all events. Requires explicit operator re-arm after any trip.
No hardware. Virtual gantry honoring rack.json geometry. Web UI for browse/search/retrieve. SQLite inventory wired up.
One motor, one channel. Homing, jog mode, watchdog, e-brake integration. Prove the motion layer works.
All four Y motors running synced. Level-check routine. Full safety relay chain live including all 16 channel trip switches.
Complete extractor on the beam. Single-slot fetch/store cycle on the bench. Lip-finger choreography validated.
Every bin reachable. Cable-wheel supervisor running. Car-present floor interlock. Delivery to the slab drop zone.
STT → Claude → bin dispatch → spoken confirmation. AirPlay on the bench speakers. The system is the garage's interface.
The rule: T2 decides what to do next. T1 does it smoothly. T0 makes sure nobody gets hurt when either of them is wrong. Nothing a person's safety depends on routes through the OS.