Skip to content

Latest commit

 

History

History
122 lines (97 loc) · 17 KB

README.md

File metadata and controls

122 lines (97 loc) · 17 KB

Engineering log

Notes for people and agents who pick up this project later: what the system looks like now, how it got there, what was tried and dropped, the measurements behind decisions and the incidents with their root causes. The how-to material (deploying, operating, developing) lives in AGENTS.md, .claude/skills/* and workspaces/forge/README.md; this folder is the history and the reasoning.

Open questions, unresolved problems and on-robot checks: open-issues.md. What to do next: roadmap.md.

Conventions: dates in file names and timestamps are UTC unless marked otherwise; the robot and its owner are in Sydney (AEST, UTC+10, AEDT from 4 October 2026). Commit hashes refer to this repository. Everything after commit b36435d (2026-10-02 00:49 UTC) was uncommitted when these notes were written (2026-10-03); those entries name files instead of commits. Reports referred to as ~/projects/rabbit/data/offline/... are kept outside the repo because they contain maps and data of the flat.

What's next: roadmap.md.

Index

Entry Topic
2025-05-18 hardware and stack history hardware, the move from Raspberry Pi to Jetson, ROS 2 → NATS, state after five months off
2026-10-01 revival and telemetry node rewrite, RoboClaw/INA/IMU telemetry, jetson_clocks, TLS and Chrome
2026-10-01 ZED spatial mapping SDK 5.5, room map, memory, quality tuning, mesh filter, chunk format (superseded)
2026-10-01 driving, nav and safety nav node, missions, swept-arc guard, wall crash, calibration, rear-axle tracking
2026-10-01 exploration and Hybrid A* frontier exploration and the planner kernels
2026-10-01 Forge ClickHouse writer, slabs, MCP, chat agent, anomalies, moving onto the robot
2026-10-01 HUD 3D HUD, chat panel, minimap, voxel map, objects
2026-10-01 lag and Wi-Fi the lag hunt, Wi-Fi drops, TX power
2026-10-01 public access Cloudflare tunnel, access links, HTTP/2
2026-10-01 map resets every map reset or loss and its cause
2026-10-01 deploy and agent workflow deploy script, parallel agent sessions
2026-10-02 Jetson performance clocks, IRQs, headless, the clock-floor incident, OC3, JetPack assessment
2026-10-02 ZED optimisation CPU, GIL, frame rates, depth, GEN_3 keyframe leak, map modes
2026-10-02 nvblox nvblox extension, clearance grid, reflections, debris
2026-10-02 floor estimation floor origin, per-frame floor plane, robot on a table
2026-10-02 route planner rabbit-planner: trips to points, places and objects; replay
2026-10-02 object detector YOLOE in the ZED SDK, filtering, objects in Forge
2026-10-02 voice agent Realtime voice, spoken approvals, robot prompt
2026-10-02 relocalization millimetre poses, false relocalization, give-up rules
2026-10-02 odom/map split nav on continuous odometry
2026-10-02 operator heartbeat removal the HUD is a viewer
2026-10-02 NATS/Docker latency latency audit and NATS settings
2026-10-02 SLAM survey and benchmark cuVSLAM / RTAB-Map vs ZED GEN_3 (in progress)
2026-10-03 motor slew limit smoothing bursty joystick commands
2026-10-03 Forge on Parquet and chDB ClickHouse server replaced by Parquet files and embedded chDB: design, parity, memory
2026-10-03 Jetson diet and Python 3.12 trimming host services, journald, logrotate, image pruning; Python 3.12 patch
2026-10-03 field session boot after a move, recordings, nav safety trips, far-floor phantom obstacles
2026-10-03 power rails battery, motor, servo and Jetson currents from telemetry; the motor buck at its limit, the battery shunt near its range
2026-10-03 Rabbit 2.0 made buildable Pi 4 body: BOM, pinout and buses, fail-safe E-stop, NATS hub + leaf, INA4235 channels and shunts, wiring diagrams
2026-10-03 nav replay offline replay of the day's trips: recovery along the trail, turnaround loops, stuck, IMU thresholds
2026-10-03 full-stack simulator rabbit-sim + local NATS + the real nav/planner/explore on the Mac, end-to-end tests
2026-10-03 observability structured events with reasons and ids, node metrics, start snapshots, events / node_starts / node_metrics / nats_server in Forge
2026-10-03 phase 0 tools INA per-channel shunts and clipped, duty cap 12 V / V_supply, RoboClaw config tool (3 A, NVM), encoder check
2026-10-03 printed mounts Rabbit 2.0 brackets in cad/brackets/: ToF pairs, compliant bumpers with D2F switches, lidar mast (scan plane 230 mm), button pod, rear camera mount, body-PCB clips and grommets; fit checks against the 3-deck stack with the PCB STEP; the USB hub has no place yet
2026-10-03 body PCB deck-2 board for Rabbit 2.0 generated by code (KiCad 10 + Freerouting): Pi, RoboClaw, regulators, fuses, INA4235, PCA9685; stack heights, current paths, DRC clean, JLCPCB outputs
2026-10-03 body PCB review independent pre-order review of rev A: pin-by-pin checks pass; fixed input TVS, ToF and 5 V rail resistance, motor star, stale net classes, ZED cut-out, INA4235 paste, BOM; PCA9685/INA4235 stock blocks JLC assembly; factory-assembly options and rev B lessons
2026-10-03 BLDC drive study why the 37D 70:1 is slow and loud, torque/speed needs per wheel, the motor mount measured in the chassis model, BLDC/brushed/gimbal options, DRV8316 + STM32G4 on the body PCB, regen with a V-mount BMS; report reports/2026-10-03-bldc-drive.md
2026-10-03 BLDC drive mount final BLDC choice (maxon ECX FLAT 22 L + GPX 22 LN 16:1 + ENX 22 MILE; Faulhaber 3216 fallback), new 6061 bracket with its own wheel bearings and an Oldham coupling inside a hollow stub axle, printed test-fit variant, fit check in the widened chassis, wiring to the rev B connectors; cad/drive/
2026-10-10 BLDC drop-in BLDC that fits the existing 37D bracket and wheel hub: Pololu face re-measured from the STEP, JGB37 bare-BLDC makers (Kechen, Chihai), adapter-plate route for maxon GPX 22 UP / Faulhaber 22GPT; report reports/2026-10-10-bldc-drop-in.md
2026-10-10 body PCB rev C RoboClaw removed; deck-2 board (140 × 314 mm, ZED 2i on the nose) with STM32G474 + 2 × DRV8243 for the kit JGB37-520 motors, an eFuse with current readback on every load (10 × TPS25947, 2 × TPS16630, LM5069 motor bus, 2 × ADS7128), 4 × INA238, 6 ToF ports on brackets (mux on Pi I2C6), 3 lidar (XH-5), 8 servo ports, xArm 1S bus, vertical connectors only, Pi 4 on board powered over USB-C; two review rounds; 667 parts, all 159 BOM lines in JLC stock; 8 layers, routing in progress; spec reports/2026-10-10-body-pcb-rev-c.md, project pcb/rabbit-body-c
2026-10-11 rev C bring-up plan step-by-step first power-up of rev C: pre-power resistances (workspaces/bench/pcb-bringup/rail_resistance.py), rails, eFuses, MCU, motors, servos, arm, sensors; expected values with sources; risks P29–P34
2026-10-10 ToF carrier 22 × 18 mm VL53L8CX carrier for the body board's GH-6 ToF ports: 3.3 V alone is not allowed (CORE/IOVDD 1.98 V max), so LP5907 1.8 V with an RC-delayed enable for the DS slew rule and an LSF0204 translator; routed, DRC clean, JLC outputs; port J1 is the HCTL HC-GH-6PLT (GH-compatible, in JLC stock) like the body board's six ToF ports; project pcb/rabbit-tof
2026-10-11 blog SEO rabbit0.dev: a page per post, canonical/hreflang per language, JSON-LD, sitemap, Atom feeds, icons, 404; 640/1280 px previews with a PhotoSwipe lightbox; built in CI, outputs gitignored; dependencies updated
2026-10-03 body software Rabbit 2.0 body written offline: rabbit-lidar (RPLIDAR C1 protocol, timestamps, de-skew), rabbit-tof (VL53L8CX ×4, floor rejection), rabbit-safety (50 Hz arbiter, caps by clearance and input freshness, E-stop line self-test), rabbit-power (shutdown state machine), fake GPIO/serial/ToF backend, lidar/ToF/bumpers in the simulator, nav and planner on the lidar scan, Forge tables, Pi compose and deploy; Raspberry Pi kernels keep GPIO outputs after a crash
2026-10-03 body PCB rev B deck-2 board rev B: STM32G474 + 2× DRV8316 BLDC drive with hardware E-stop and brake chopper, LM74800 soft-latch switch, LM61495 bucks, TPS16630 Jetson eFuse, 4× INA226, SMD fuses, GND_MOT island; everything JLC-stocked and JLC-assembled; Freerouting fed filled pours

lessons.md collects the hard-won rules in one list.

Current state of the system (2026-10-03)

Hardware

Jetson Orin Nano Super 8 GB (MAXN_SUPER, clocks pinned, headless), ZED 2i on USB, RoboClaw 2x30A on the UART, PCA9685 steering servo, INA4235 power monitor, 99 Wh 4S Li-ion pack, Wi-Fi only. Wheel encoders do not count; speed comes from the camera pose. Details in the hardware entry.

Services (workspaces/compose.yaml)

Service Role
nats, nats-init, nats-dashboard message bus; KV bucket rabbit, JetStream LOGS (7 days)
rabbit-zed the only camera process: GEN_3 tracking and relocalization, depth (NEURAL_LIGHT, every 2nd frame), nvblox mapping (C++/CUDA extension), floor estimation, obstacle scan, YOLOE object detection, preview, SVO recording, health
rabbit-nav missions (move, turn, goto, path), path tracking on the rear axle in the odometry frame (curvature feedforward + feedback), swept-footprint collision guard with blind-zone memory, stall and bump trips
rabbit-planner Hybrid A* trips to points, saved places and objects; replanning and recovery
rabbit-explore exploration by expected information gain per metre, through planner trips
rabbit-roboclaw, rabbit-steering motors (electronic differential, slew limiting, kill switch) and the servo
rabbit-ina, rabbit-telemetry power at 50 Hz; Jetson, containers and Wi-Fi at 1 Hz
forge NATS → Parquet writer, compaction, chDB queries, chat/voice agent API, in one process
rabbit-web nginx: the built HUD, /api → chat, /nats → NATS websocket, access-link gate
tunnel Cloudflare tunnel (HTTP/2) to https://live.rabbit0.dev

All rabbit-* nodes share one image with the code bind-mounted; a code change needs a container recreate, not a rebuild.

Main NATS contracts

  • Sensors: rabbit.zed.pose (map pose plus an odom sub-object; floor at y = 0, camera at y ≈ 0.137), rabbit.zed.imu, rabbit.zed.obstacle (48-bin scan over ±60°, obstacles 4–45 cm above a per-frame floor plane), rabbit.zed.objects, rabbit.health.zed (fps, spatial_memory_status, relocalizing, map_mode, map_id, nvblox timings), rabbit.roboclaw, rabbit.ina, rabbit.steering, rabbit.telemetry.
  • Commands: rabbit.cmd.joy (owns the motors for 1 s), rabbit.cmd.drive, rabbit.nav.mission, rabbit.nav.cancel, rabbit.nav.explore, rabbit.planner.goal (request/reply, preview), rabbit.planner.places*, rabbit.zed.wake, rabbit.zed.record.
  • Map: rabbit.map.chunks / rabbit.map.snapshot (mesh blocks, <IIIfff header, int16 mm vertices relative to a per-chunk origin), rabbit.map.grid / .snapshot (int16 mm clearance, 5 cm cells), rabbit.map.save, rabbit.map.reset, rabbit.map.extend (request/reply).
  • State: rabbit.nav.state (10 Hz), rabbit.planner.state, rabbit.explore.state, logs on rabbit.log.<node>.
  • rabbit.operator.heartbeat only raises the idle camera rate; nothing depends on the HUD being open.
  • Rabbit 2.0 body (written and simulated, not deployed): rabbit.lidar.scan (binary rotation, Pi clock), rabbit.tof (per-sensor frames with obstacle points), rabbit.safety.drive / .state / .estop / .reset, rabbit.power.state / .request / .jetson, rabbit.health.lidar / .tof; contracts in log/2026-10-03-body-software.md. nav and the planner already take rabbit.lidar.scan when it appears.

Map and localization pipeline

ZED depth + GEN_3 pose → plausibility filter (millimetre poses, jump gate) → floor estimator → nvblox TSDF/ESDF on the GPU (5 cm voxels, rays clipped at the floor, integration up to 5 m) → mesh blocks for the HUD and the 2D clearance grid for the planner. The SDK area memory (room.area) provides relocalization after restarts; map_mode keeps it in localization by default and extends it only for a new map or exploration (GEN_3 keeps adding keyframes otherwise). Saved state in data/map/: room.area, room.nvblx, room.id, room.ply, archive/ (last 5). Relocalization counts after 10 s of a localized status; it gives up after 3 m of travel or 45 s and starts a new map.

Planner

Hybrid A* (numba) on the clearance grid with asymmetric curvature tables, costs that keep to the middle of gaps, reverse only into mapped space, Dijkstra heuristic; plans in 5–80 ms typically on the Jetson. Trips replan on new obstacles, pose jumps and blocks, back up along their own trail, and hold before long detours. Object goals come from Forge's object memory.

Forge

Parquet files on the robot (one file per table and hour every 10 s, merged hourly), queried in-process with chDB; one container of about 300 MB instead of ClickHouse, writer and chat (600–850 MB). See 2026-10-03 Forge on Parquet and chDB. Slabs, a static SQL gate plus EXPLAIN, a metric graph with investigate, Chronos-2 anomaly detection, MCP tools, a chat agent (OpenAI via the Vercel AI SDK) and a Realtime voice agent, both with approval cards for motion. Every node records its decisions as structured events with a reason, ids and the measured values (events), its start snapshot (node_starts) and its process health (node_metrics); conventions in reports/2026-10-03-observability.md.

HUD

React/three.js at https://jetson.rabbit (LAN) and https://live.rabbit0.dev (access link required): 3D view with a voxel or surface map, minimap, objects, panels with uPlot charts, gamepad/keyboard driving, AI LINK chat with voice.

In progress / open

  • Forge storage cutover to Parquet + chDB is staged but not switched (runbook: reports/2026-10-03-forge-cutover-runbook.md). Until it's done, don't run scripts/deploy.sh without arguments or with forge-*: the working tree's Forge code no longer runs in the old alpine containers. Deploying rabbit-* services is safe. forge-shadow (the new writer) starts on boot.
  • Localization replacement: odometry from cuVSLAM or ZED VIO plus RTAB-Map as the global localizer, being benchmarked on recorded SVOs; ground-truth floor markers and wake-up sessions still to record.
  • Commit the work since b36435d (planner node, nvblox extension, detector, voice, access links, relocalization fixes, odom split).
  • Make rabbit-zed survive an nvblox CUDA out-of-memory.
  • Wi-Fi in the far part of the flat (router RSSI settings, antennas or another card).
  • Actual clocks and OC counters in Forge; Python 3.12; Docker image cleanup; RTC battery and persistent journal.
  • pose Euler angles in Forge: rows recorded before the writer fix of 2026-10-03 hold yaw in pitch_deg, roll in yaw_deg and pitch in roll_deg (ZED euler_deg is rotation about x, y, z in the Y-up frame: pitch, yaw, roll); newer rows are correct.
  • Encoders read 0; the magnetometer is not calibrated.
  • Rabbit 2.0 body software (safety, power, lidar, tof nodes, workspaces/body/) waits for the parts; bring-up checks are open-issues V7–V12.
  • Body PCB rev B (pcb/rabbit-body/, BLDC drive on board) is designed, not ordered; it needs MCU firmware and ina.py for INA226 before it can replace the RoboClaw setup (reports/2026-10-03-body-pcb-rev-b.md §12).