Plan: racing-drone consumes anatomy (ADR 0008, step 2)
Issue: #65. Implemented in 2c (#66). Anatomy’s side: branes-ai/anatomy#1 (2a, the skeleton) and #3 (2b, the move), released as anatomy v0.1.0.
Since anatomy v0.3.0 (anatomy#10), the mobility headers are their own library, branes::anatomy_mobility, with a fifth bridge, anatomy_mobility.hpp. branes::anatomy_sim is now branes::anatomy_mobility_sim. This plan records the v0.1.0 state.
Step 2 of ADR 0008: the framework’s neutral half moved to anatomy. racing-drone now fetches it and keeps only its racing part:
- the course and the gate observations;
- racing’s slots and its
Stack; - its configs and its channel;
- the gate projector, its
Simulator, the scoreboard, and the batch run.
What stays the same:
- Behavior: byte-identical.
- Formats and interfaces: the log format, YAML files, and command lines are unchanged.
Acceptance (from #65, stated before any code)
Section titled “Acceptance (from #65, stated before any code)”- Every test and gate passes in CI. The boundary manifest and its ctest are removed, because the boundary is now a repo boundary.
- Byte-identity:
tools/compare_outputs.shwithgcc-releasegives all 39 files identical to main’s before the split (04343d1).flight_stack’s output is unchanged for the same cases as PR 1d. - Log compatibility: a log written before step 2, by
sitl_b0-gt-pidat 04343d1, replays with--verifyunder the newreplay_b0-gt-pid, and itslog_dumpoutput is byte-identical. - No file listed in the manifest remains in racing-drone. racing-drone fetches anatomy pinned to a commit.
Design
Section titled “Design”- The dependency.
cmake/deps.cmakefetches anatomy at its v0.1.0 commit. It is declared after racing-drone’s own yaml-cpp, reflex and Universal, so where both repos name a dependency, racing-drone’s declaration is the one used. A configure-time check fails if anatomy pins a different reflex commit. - The bridges.
sdk/include/branes/racing/anatomy.hpp,anatomy_glue.hpp,anatomy_sim.hppandanatomy_sweep.hppbring each namespace-scope name of one anatomy library into the matchingbranes::racingnamespace.- Each name gets an explicit using-declaration. Unscoped enums also get
using enum, for their enumerators, and namespace aliases are repeated. - They are generated by
tools/gen_anatomy_bridges.pyfrom Clang’s AST of anatomy’s headers, at the fetched commit, so the lists are complete. Rerun it after an anatomy bump. - Racing code includes the bridge in place of each moved header, and otherwise reads as before.
- Each name gets an explicit using-declaration. Unscoped enums also get
- One bridge per library, not one header. The plan had a single header. But a single header would make racing-drone’s core library include the simulator and the sweep types, and so need reflex and Universal. One bridge per anatomy library keeps each racing target’s dependencies as they were.
- Targets:
branes::racingnow compiles only the course loader, and linksbranes::anatomy.branes::racing_glueis gone; the baselines linkbranes::anatomy_glue.branes::racing_simlinksbranes::anatomy_sim.- The baseline generator includes anatomy’s
composition.cmakethroughANATOMY_CMAKE_DIR. - The slot registry names anatomy’s headers for
ScriptedHopControllerandCascadedPid.
- The YAML helpers. Anatomy does not export its private YAML parsing helpers, and racing’s course loader needs them. racing-drone keeps a copy as
sdk/src/config/yaml_parse.hpp; that was the choice left open in step 1. - Tests:
- racing-drone keeps the racing cases of its mixed tests: the gate codec, the course and racing’s scenario and baseline files, racing’s channel, the gate and course contracts, the gate projector, racing’s
Simulator, and the gate-observation cast. - The neutral cases,
util, the compile-fail test, the neutral-mission tests, and the boundary check moved to anatomy, or were already there. - One test is new:
Simulator::createrejects a scenario without racing’s sim parameters.
- racing-drone keeps the racing cases of its mixed tests: the gate codec, the course and racing’s scenario and baseline files, racing’s channel, the gate and course contracts, the gate projector, racing’s
Results
Section titled “Results”Acceptance:
- Tests: all pass on
gcc-debugand onclang-debug. Anatomy runs 102 tests and racing-drone 132, so 234 across the two repos; racing-drone alone had 217 before the move. - Byte-identity: all 39 files are identical to main’s before the split: 3 SITL logs and 3 replays,
score_log, 12log_dumpfiles, a 20-seedsitl_batch, a 20-seed precision sweep (11 files), and the harnesses’ stdout.flight_stackgives the same output and exit code fornullandb0-gt-pidat 10 cycles, 0 cycles, and an overflowing cycle count. - Log compatibility: the pre-split B0 log replays with
--verify(6000 outputs). The replay log it writes is byte-identical to the pre-split replay log, andlog_dumpof it gives byte-identical files. - Nothing left behind: none of the 53 moved files remains. The three build helpers listed in the manifest (
cmake/compile_all.cmake,warnings.cmake,deps.cmake) were never meant to move: anatomy has its own. - Lint: clang-format 18 (CI’s version) is clean on the 45 changed C++ files.
Departures:
- Four bridge headers, generated, rather than one hand-written header (above).
- The YAML helpers are a copy in racing-drone (above).
- The bad-magic error now reads “not a log (bad magic)” (anatomy 2b). Its test moved to anatomy.