diff --git a/.agent/work-plans/issue-85/progress.md b/.agent/work-plans/issue-85/progress.md new file mode 100644 index 0000000..47a6574 --- /dev/null +++ b/.agent/work-plans/issue-85/progress.md @@ -0,0 +1,21 @@ +--- +issue: 85 +--- + +# Issue #85 — default import_bag bathy output to Processed layer + --bathy-layer flag + +## Local Review (Pre-Push) +**Status**: complete +**When**: 2026-06-28 15:51 +00:00 +**By**: Claude Code Agent (Claude Opus) +**Verdict**: changes-requested + +**Branch**: feature/issue-85 at `e937d40` +**Mode**: pre-push +**Depth**: Light (reason: 34 lines, 1 file, no override-trigger files, no Deep triggers) +**Must-fix**: 1 | **Suggestions**: 1 +**Round**: 1 | **Ship**: continue — lone must-fix is a one-line stale-comment correction; no design/correctness concerns, re-review should clear + +### Findings +- [ ] (must-fix) Backscatter-block comment still says "The bathy layer above is Draft" but bathy now defaults to Processed — stale/self-contradicting after this diff — `cube_bathymetry/src/import_bag_main.cpp:761` +- [ ] (suggestion) "Saved … layer" ternary labels any non-Processed layer as "draft"; fragile if Chart ever becomes selectable — `cube_bathymetry/src/import_bag_main.cpp:752` diff --git a/cube_bathymetry/src/import_bag_main.cpp b/cube_bathymetry/src/import_bag_main.cpp index 1fd959a..3d865b8 100644 --- a/cube_bathymetry/src/import_bag_main.cpp +++ b/cube_bathymetry/src/import_bag_main.cpp @@ -68,6 +68,9 @@ { std::cout << "usage: import_bag [options] -o " "-d [ ...]\n"; + std::cout << " --bathy-layer draft|processed: bathymetry store layer for this " + "import (default processed: the off-boat CUBE re-run is authoritative; the live " + "node writes draft. #85)\n"; std::cout << " -o : Output bathymetry-store directory (created if " "needed)\n"; std::cout << " --bs-store : Also write an MBES backscatter store layer " @@ -274,6 +277,7 @@ int main(int argc, char * argv[]) std::vector bagfile_names; std::string store_dir; std::string bs_store_dir; // optional: MBES backscatter store output (#80) + std::string bathy_layer_str = "processed"; // bathy target layer (#85): draft|processed std::string detections_topic; // required std::string odom_topic; // optional: nav_msgs/Odometry for per-ping vessel speed double resolution = 1.0; @@ -312,6 +316,8 @@ int main(int argc, char * argv[]) usage(); } else if (*arg == "-o") { store_dir = next_value("-o"); + } else if (*arg == "--bathy-layer") { + bathy_layer_str = next_value("--bathy-layer"); } else if (*arg == "--bs-store") { bs_store_dir = next_value("--bs-store"); } else if (*arg == "-d") { @@ -370,6 +376,19 @@ int main(int argc, char * argv[]) usage(); } + // Bathy target layer (#85). The off-boat CUBE re-run is the authoritative product + // (the live node writes Draft), so this defaults to Processed; --bathy-layer draft + // overrides (e.g. to seed a draft from a bag). + marine_bathymetry_store::SourceLayer bathy_layer = + marine_bathymetry_store::SourceLayer::Processed; + if (bathy_layer_str == "draft") { + bathy_layer = marine_bathymetry_store::SourceLayer::Draft; + } else if (bathy_layer_str != "processed") { + std::cerr << "error: --bathy-layer must be 'draft' or 'processed' (got '" + << bathy_layer_str << "')\n"; + usage(); + } + std::cout << "Detections topic: " << detections_topic << " (offline projection, vessel_speed = NaN)" << std::endl; std::cout << "Store dir: " << store_dir << std::endl; @@ -722,24 +741,23 @@ int main(int argc, char * argv[]) "the projector frame overrides and the detections topic." << std::endl; } - // Draft layer: this full-bag CUBE replay merges into the single fused draft - // grid (unh_marine_autonomy#221 — no per-day epochs, newest value wins per - // cell). Off-boat regeneration into the authoritative `processed` layer is a - // separate step. - store.importTiles( - marine_bathymetry_store::SourceLayer::Draft, std::move(tiles)); + // The off-boat full-bag CUBE replay is the authoritative product, so by default it + // lands in the `Processed` layer (#85; --bathy-layer overrides). The live node + // writes the `Draft` layer instead. Single fused grid per layer + // (unh_marine_autonomy#221 — no per-day epochs, newest value wins per cell). + store.importTiles(bathy_layer, std::move(tiles)); std::size_t written = marine_bathymetry_store::save(store, store_dir, ®istry); - std::cout << "Saved " << written << " tiles to " << store_dir << "." << std::endl; + std::cout << "Saved " << written << " tiles to " << store_dir << " (" + << bathy_layer_str << " layer)." << std::endl; // Optional: surface the co-estimated backscatter into an MBES backscatter store - // layer from the SAME CUBE pass (#80). The value is UNCORRECTED -- node.cpp - // emits the identity until the sign-gated angle correction lands (cube#81), - // which then updates both this offline layer and the live tile (#78). Written - // to the PROCESSED layer (operator decision): the offline CUBE re-run is the - // authoritative off-boat product; cube#81 updates corrected values in place. - // The bathy layer above is Draft; the backscatter layer is Processed -- the - // same-pass split is intentional. + // layer from the SAME CUBE pass (#80), written to the Processed layer (the + // off-boat CUBE re-run is the authoritative product). By default the value is + // UNCORRECTED; --backscatter-correction empirical (with a --backscatter-curve) + // applies the per-beam angular-response correction at node-output (cube#81), + // which corrects both this offline layer and the live tile (#78). Bathy (above) + // defaults to the same Processed layer (#85). if (!bs_store_dir.empty()) { std::cout << "Building backscatter store tiles..." << std::endl;