Urban canals collect litter faster than volunteers can clear it. The long-term vision is a small amphibious robot that patrols a canal, detects floating litter, collects it, and — non-negotiably — stops for wildlife. But hardware robotics projects usually die the expensive way: you buy parts, discover the physics doesn’t cooperate, and iterate at hardware prices.

Stitch inverts that. The rule I set myself is a twin gate: no hardware spend unlocks until the robot is proven in physics.

The twin

Stitch is a faithful digital twin built in ROS 2 Jazzy and Gazebo Harmonic — a six-package workspace of roughly 2,100 lines of Python covering model generation, a water-world simulation, a thrust mixer, a station-keeping controller, perception, and a unit-tested mission state machine. To pass the gate it has to hold station against a simulated current, detect litter, run the full collection mission, and stop for wildlife — repeatably.

One file drives everything

Every physical parameter lives in one canonical YAML file, and Jinja2 templates generate the robot’s SDF model, the water world, and the ROS–Gazebo bridge from it. Move a thruster or change the hull’s mass and the simulated behaviour changes with zero code edits — and because every value in that file maps to a buyable part, the twin can never drift into physics you couldn’t actually purchase.

Making it move — and hold still

Velocity commands become thrust through a full 6-DOF allocator: /cmd_vel is mapped to six vectored thrusters via the pseudo-inverse of the configuration matrix, clamped to the hardware envelope. On top sits a PID station-keeper with anti-windup that holds position against the simulated water current — the capability the whole mission depends on.

Water is where simulations usually cheat, so Stitch models graded buoyancy, Fossen added-mass hydrodynamics, and solver-stable thruster dynamics. The nastiest bug was a DART-solver instability under sustained thrust — diagnosed and fixed with joint damping, spin-rate caps, and tuned inertia, then verified with a 60-second-per-axis thrust-soak test.

Simulation-only isn’t a caveat here. It’s the method.

Engineered like production, priced like software

The whole twin ships as a headless, multi-arch (arm64/amd64) Docker image that runs GPU-free on both Apple-Silicon and Linux machines. GitHub Actions CI runs 38 pure-logic unit tests on every push — allocation maths, PID behaviour, mission-state transitions, and the SDF/world generators — with no GPU or simulator required.

Steal the method

The twin gate isn’t specific to canal robots. Any hardware idea can be run this way: prove the physics before you spend, keep every physical assumption in one reviewable file, and make the simulation honest enough that passing it means something.

It’s also a self-contained way to learn real robotics — control allocation, PID tuning, hydrodynamics, mission state machines — with nothing to break and nothing to buy. The next milestone isn’t a purchase order; it’s the twin passing its full mission gate, so that when hardware does arrive, the physics is already settled.

Under the hood ROS 2 Jazzy, Gazebo Harmonic / SDF, Python, Jinja2, multi-arch Docker (arm64/amd64), GitHub Actions.