#!/usr/bin/env python3 """Publish the cross-backend-consensus result as the recommended deliverable.""" import argparse import json from pathlib import Path def main(): parser = argparse.ArgumentParser(description=__doc__) parser.add_argument("--consensus-extrinsic", required=True) parser.add_argument("--consensus-check", required=True) parser.add_argument("--open3d-extrinsic", required=True) parser.add_argument("--small-extrinsic", required=True) parser.add_argument("--output", required=True) parser.add_argument("--summary", required=True) args = parser.parse_args() consensus = json.loads(Path(args.consensus_extrinsic).read_text(encoding="utf-8-sig")) check = json.loads(Path(args.consensus_check).read_text(encoding="utf-8-sig")) open3d = json.loads(Path(args.open3d_extrinsic).read_text(encoding="utf-8-sig")) small = json.loads(Path(args.small_extrinsic).read_text(encoding="utf-8-sig")) summary = { "recommended_method": "Open3D B gated by Open3D-small_gicp cross-backend agreement", "selection_is_X_independent": True, "second_batch_role": "estimation (dense RTK)", "first_batch_role": "auxiliary check only (sparse RTK)", "consensus": { "translation_m": consensus["translation_m"], "rotation_rpy_deg_xyz": consensus["rotation_rpy_deg_xyz"], "estimation": consensus["estimation"]["residuals"], "bootstrap_std": consensus["bootstrap"]["std"], "batch1_auxiliary": check["metrics"], }, "separate_backend_results": { "open3d_gicp": { "translation_m": open3d["translation_m"], "rotation_rpy_deg_xyz": open3d["rotation_rpy_deg_xyz"], }, "small_gicp": { "translation_m": small["translation_m"], "rotation_rpy_deg_xyz": small["rotation_rpy_deg_xyz"], }, }, "warning": "AX rotation RMS remains about one degree; this is not centimetre-grade absolute certification.", } published = dict(consensus) published["selection"] = { "method": summary["recommended_method"], "selection_is_X_independent": True, "consensus_pair_threshold": "Open3D-small_gicp B delta <= 0.05 m and <= 0.50 deg", "warning": summary["warning"], } Path(args.output).write_text(json.dumps(published, ensure_ascii=False, indent=2), encoding="utf-8") Path(args.summary).write_text(json.dumps(summary, ensure_ascii=False, indent=2), encoding="utf-8") print(json.dumps(summary, ensure_ascii=False, indent=2)) if __name__ == "__main__": main()