feat(reconcile): sub-solution merger with loop closure validation #29
Reference in New Issue
Block a user
Delete Branch "%!s()"
Deleting a branch is permanent. Although the deleted branch may continue to exist for a short time before it actually gets removed, it CANNOT be undone in most cases. Continue?
Summary
Implement
reconciler.py— merges sub-solutions from all dispatched subproblems into a singleSolveResult, validates kinematic loop closure, and applies minimal-movement preference heuristics.Context
After the dispatcher solves each subproblem independently, the reconciler assembles the global solution. The critical challenge is loop closure: when a biconnected component was decomposed by cutting kinematic loops, the cut-constraint residuals must be checked. The reconciler also implements minimal-movement preference — when multiple valid solutions exist, pick the one closest to the initial configuration. This is the D-Cubed-style heuristic that OndselSolver completely lacks, and is a major source of "obscure solution" complaints.
Depends on: #28 (dispatcher — provides SubproblemResult for each subproblem)
Design
Reconciliation pipeline
part_id → Transformmappings from sub-resultsSolveContextcontaining only the loop-closure constraints and the parts they connect, with all other parts grounded at their solved positions. Dispatch to the numerical backend for a targeted N-R solve using the current placements as warm start.SolveContext.partsand pick the solution with minimal aggregate part displacement:ConstraintDiagnosticlists from all sub-results plus any closure diagnosticsAPI
Tolerance
Loop closure tolerance should match the solver's tolerance (default 1e-9 for position, 1e-7 for angular). These should be configurable but sensible by default.
Tasks
ReconcilerclassSolveResultassembly from sub-resultstests/decomposition/test_reconciler.py:Acceptance criteria
merge()returns a validSolveResultwith all parts accounted for