IO diagnostics · round 2
Plug the rack in and the panel says what is connected, what isn't, and what to check, in plain words. Printer-style utilities wrap your d_* tools, and every button dry-runs first.
io-diagnostics main @ a6853bde (local repo) · drivers on bam_ws claude/traj-tracking-sim-to-real-a3da60 @ bb393a35, not merged ·
live captures 2026-10-22T19:35:23-07:00, real rack, read-only. No button that writes or moves was pressed.
A still from the middle of the video. The video is not in the public copy: its frames show the machine's name and device serials.
Hero: the live dashboard on this PC.
- fdcanusb XXXXXXXX holds CAN 1 / 14 / 15.
- CAN 1 → Run calibration… dry run, showing the exact command and preconditions.
- The confirm modal won't enable until you tick "joint is free".
- Cancel.
- The second adapter XXXXXXXX: "frames never reached the bus" and what to check.
The rack, live
Every button, and what it would run
These are real dry runs through the host (io-diagnostics act … --dry-run) against this PC's adapter and camera. Nothing ran.
Same name = same meaning on every driver (docs/actions-vocabulary-v0.1.md).
| Button | Danger | Exact command its dry run reports | Replaces |
|---|---|---|---|
| Check communication fdcanusb XXXXXXXX | query | py3 -m moteus_servo.diagnostics --bus-lock ~/.cache/rack-commissioning/bus.lock --firmware-cache ~/.cache/moteus-firmware --inventory ~/archive/datasets/bam_rig/rack_inventory diagnose --device /dev/serial/by-id/usb-mjbots_fdcanusb_272813EF-if00 --range 1 126 | d_find + d_triage |
| Check firmware fdcanusb XXXXXXXX | query | py3 -m moteus_servo.diagnostics --bus-lock ~/.cache/rack-commissioning/bus.lock --firmware-cache ~/.cache/moteus-firmware --inventory ~/archive/datasets/bam_rig/rack_inventory diagnose --device /dev/serial/by-id/usb-mjbots_fdcanusb_272813EF-if00 --queries 0 --no-config | |
| Stop all fdcanusb XXXXXXXX | interrupts | py3 ~/bam_ws/src/core/mdp/agent/actuators/moteus_servo/utils/moteus_with_targets.py ~/.local/bin/moteus_tool -t 1,14 --stop --fdcanusb /dev/serial/by-id/usb-mjbots_fdcanusb_272813EF-if00 | d_stop |
| Open console fdcanusb XXXXXXXX | interrupts | py3 ~/bam_ws/src/core/mdp/agent/actuators/moteus_servo/utils/moteus_with_targets.py ~/.local/bin/tview -t 1,14 --fdcanusb /dev/serial/by-id/usb-mjbots_fdcanusb_272813EF-if00 | d_tview |
| Update firmware… fdcanusb XXXXXXXX · CAN 1 | changes | py3 a private note --target 1 --port /dev/serial/by-id/usb-mjbots_fdcanusb_272813EF-if00 --cache-dir ~/.cache/moteus-firmware --tool ~/.local/bin/moteus_tool | the update-moteus-firmware skill |
| Run calibration… fdcanusb XXXXXXXX · CAN 1 | moves | ~/.local/bin/moteus_tool --target 1 --calibrate --fdcanusb /dev/serial/by-id/usb-mjbots_fdcanusb_272813EF-if00 | d_calibrate |
| Update configuration… fdcanusb XXXXXXXX · CAN 1 | changes | ~/.local/bin/moteus_tool --target 1 --restore-config ~/.local/share/moteus-config/can-1.cfg --fdcanusb /dev/serial/by-id/usb-mjbots_fdcanusb_272813EF-if00 | d_config (its script is gone; stock moteus_tool --dump-config / --restore-config) |
| Clear faults fdcanusb XXXXXXXX · CAN 1 | changes | py3 -m moteus_servo.diagnostics --bus-lock ~/.cache/rack-commissioning/bus.lock --firmware-cache ~/.cache/moteus-firmware --inventory ~/archive/datasets/bam_rig/rack_inventory act --device /dev/serial/by-id/usb-mjbots_fdcanusb_272813EF-if00 --action clear_faults --node 1 | |
| Reboot… fdcanusb XXXXXXXX · CAN 1 | interrupts | py3 -m moteus_servo.diagnostics --bus-lock ~/.cache/rack-commissioning/bus.lock --firmware-cache ~/.cache/moteus-firmware --inventory ~/archive/datasets/bam_rig/rack_inventory act --device /dev/serial/by-id/usb-mjbots_fdcanusb_272813EF-if00 --action reboot --node 1 | |
| Change CAN id… fdcanusb XXXXXXXX · CAN 1 | changes | ran in 0.098 s · 1 lines | d_reassign |
| Check communication RealSense D405 · 6036 | query | pyrealsense2.context().query_devices() device.get_info(pyrealsense2.camera_info.<field>) for <field> in (name, serial_number, asic_serial_number, firmware_version, recommended_firmware_version, usb_type_descriptor, physical_port, product_id, product_line, firmware_update_id, connection_type), skipping any the device does not support | |
| Check firmware RealSense D405 · 6036 | query | pyrealsense2.context().query_devices() device.get_info(pyrealsense2.camera_info.<field>) for <field> in (name, serial_number, asic_serial_number, firmware_version, recommended_firmware_version, usb_type_descriptor, physical_port, product_id, product_line, firmware_update_id, connection_type), skipping any the device does not support | |
| Reboot… RealSense D405 · 6036 | interrupts | intel_rgbd.real.RealSenseCamera('XXXXXXXXXXXX').hardware_reset() | |
| Update firmware… RealSense D405 · 6036 | changes | exited 3 after 0.1 s | |
| Run calibration… RealSense D405 · 6036 | changes | pyrealsense2.context().query_devices() device('XXXXXXXXXXXX').as_auto_calibrated_device().run_on_chip_calibration('{"speed": 3, "scan parameter": 0}', 120000) set_calibration_table(table) then write_calibration(), only when |health_before| >= 0.25 and |health_after| < |health_before| | |
| Open console RealSense D405 · 6036 | interrupts | /usr/bin/realsense-viewer |
Five ways to see the entities
All six are live in the bottom-right Structure switcher, on the same live data. P1 is the default because it is literally “fdcanusb → Moteus c1 · CAN 15” plus a Ports toggle for the USB / PCIe detail. The single computer is never a fold in any of them.
Eleven skins, light and dark
The seven you named, plus four of mine:
- ISA-101 HMI: grey, colour only for abnormal. It is the standard behind “quiet when OK”.
- macOS Settings.
- Linear.
- High contrast: AAA.
What the live rack caught
- Our own checks raced for the rack bus lock: one camera reported "lock held". Plugins sharing a gate now queue.
- Config reads failed or garbled values: the inventory and config check read raw streams past the frame guard. Now paced; CAN 1 and 14 read every key and firmware 657b5c5, read-only.
- Firmware 1.1.2 has no
servo.derate_temperature: every board read "unknown". Now "not on this firmware", and derating comes from fault_temperature − temperature_margin. - A silent adapter was blamed on "frames are ACKed": now
FramesNotSentwhen dlec stays 7. - Your
d_*aliases point at a moved folder:src/core/mdp/actuators→src/core/mdp/agent/actuators. d_find --rangere-launched the triage script: fixed.- A silent board printed "MISMATCH kp, ki, kd…": now "NO REPLY".
Decisions
Done and proved
- The live panel shows both adapters, CAN 1 / 14 / 15 and both D405s, with plain-words reasons (captures above, real rack).
- Every utility dry-runs to the exact command (the table above). Gates: 876 tree/skin checks with mutations caught, 118 view-core, 37 utilities, 182 host pytest, 687 moteus_servo, 163 intel_rgbd, 275 rack twin.
Needs you
- Pick a structure and a skin. Default if you say nothing: P1 + Claude.
- XXXXXXXX: unplug its CAN cable at the board end, then press Check communication. The panel says whether the board or the adapter holds the bus.
- CAN 1 now reads ratio 0.1, but the record holds 1. Say “record it” and I run
config-record --can-id 1. CAN 1 motion stays refused until then. - Update configuration has no recorded per-board .cfg files yet, so it refuses with a dump command. Default: I seed them from the 10-10 / 10-19 firmware-run dumps when you say so.
Deliberately not done
- No write or motion button was pressed by any agent: Stop all, firmware, calibration, config and ids are yours to click.
- Nothing is merged; the drivers stay on their branch.