Muhammad Suleiman Qureshi, robotics and software engineer. My robot is a simulated Unitree Go2 quadruped in MuJoCo, running a supply-courier mission inside the AWS RoboMaker Hospital World. I didn't build the whole stack myself: locomotion comes from an existing convex-MPC Go2 controller, and the MPPI local planner on top of it comes from a paper I first-authored (“MPPI Path Following with Foothold-Quality-Aware Cost for Quadruped Navigation in Unstructured Terrain”). For the hackathon I added everything else: mission autonomy, deterministic path trackers, fault injection, telemetry in RideScan's schema, and the RideScan API integration.
A hospital runs thousands of supply trips a day, pharmacy to ward, lab to diagnostics, most of them walked by staff who could be with patients. A legged courier can take the doors, thresholds and clutter that stop a wheeled robot. But a clinical corridor is an unforgiving place to be autonomous: that route carries blood, medication and sterile supplies past patients and staff, so a courier that stumbles or drops its payload is a safety and contamination incident, not a nuisance. And the failures that matter are rarely dramatic; a knee quietly losing torque, or a battery starting to sag, looks normal right up until it doesn't. What a hospital needs is early warning, catching a courier as it drifts toward failure before it goes down in front of a patient. So I made the mission deliberately boring, the same route every run, so each trip becomes a process that RideScan can score against a known-good baseline.
The integration is a stdlib-only Python client for the RideScan v2.4 API: X-API-KEY auth, robot and mission creation with 409-conflict recovery, multipart upload with order-matched event_times, and async calibrate/process with polling. Telemetry is RideScan's LEGGED_MOBILE CSV schema, all 25 fields at 20 Hz, one telemetry.csv.gz per run. Any Go2 stack can reuse it by writing that schema and pointing the client at a mission.
To follow this, the order matters more than the code. Lock a known-good baseline first: I calibrate on at least 15 clean runs and, since the same seed gives byte-identical telemetry, md5-verify them so “normal” is provable. Give every experiment a fresh mission name, so calibrate and infer train a new model instead of inheriting a stale one. And keep monitoring off the critical path: the upload hook fires only after telemetry is finalized and never raises, and a dry-run mode shows exactly what would be sent before any credentials exist.
The edge case that will bite you is a stochastic controller. My MPPI planner samples rollouts from a random seed, so no two clean runs match and its calibration manifold comes out broad and noisy; RideScan's AI also trains from a random init, and the two compound. So if you monitor MPPI, or any sampling planner, don't trust one calibration: recalibrate at least three times and report the median, calibrate on varied seeds rather than identical runs (identical runs make a model that flags all clean motion), and where you can, drive scoring from a deterministic tracker, which consumes no randomness. A stub server makes all of this testable offline.
Honestly, the data's first lesson was that my own planner was the problem. I calibrated MPPI on 15 byte-identical runs, and clean out-of-sample runs scored 56 to 100, indistinguishable from faults. The anomaly wasn't a fault at all; it was MPPI's own sampling noise, a natural spread of roughly 50 s per trip. The real fix was deterministic path trackers, pure pursuit, Stanley and PD-carrot, which collapsed the clean envelope fifty-fold, to a 1.7 to 3.2 s spread.
From there the scores got useful. With Stanley tracking and the full 25-column feature set, all ten fault mechanisms separate from every clean run with a 2.2 to 2.4x margin, and severity is monotonic in all 42 cells. The scores rank sensibly too, and the torque channels caught faults odometry alone nearly missed.

Figure 1. Unified severity matrix: every fault and severity level against every controller model, scored on RideScan.
One more surprise: RideScan's AI trains from a random init, so a single calibration is a stochastic draw. On deterministic telemetry that is negligible, 1.2 to 4.1 points. On MPPI telemetry, one draw scored a fallen robot at 0.01 and another scored the same run at 42. So every MPPI number I report is a median of three calibrations.

Figure 2. Draw-to-draw score spread on unchanged data: the deterministic trackers are stable, only MPPI is not.
Everything here is simulation, no hardware yet. Mid-hackathon I hit a real platform edge: the staging legged_mobile trainer broke for two days and crashed on every calibration, even a byte-identical replay of a set that trained fine that morning. A two-robot control pinned it server-side, and I worked around it by scoring odometry-only projections under a wheeled_mobile robot until the fix landed.
A few more lessons. File-level scores dilute short anomalies in long normal stretches, so gate on windows, not single scores. And loose tracking quietly kills detection: my pure-pursuit model's wide envelope swallowed six of ten faults, scoring a severe overload at 0.01 while a clean run scored 11.7.
Phase 3 ended with the unified severity matrix below: eight fault mechanisms at three severities each, across three deterministic trackers plus MPPI, all scored on RideScan's real models and published as an interactive dashboard, with Stanley plus varied calibration as the recommended setup.

Figure 3. The full severity matrix, published as the project's interactive dashboard.
The next step is the one I care about most: the same pipeline on a real Go2. The ROS 2 recording path already reproduces the sim telemetry byte-for-byte, so the plumbing is ready.