Collision Avoidance Maneuver design for conjunction assessment
0
fork

Configure Feed

Select the types of activity you want to include in your feed.

irmin: merlint 0/69, switch fuzz to alcobar, add real tests

- Switch fuzz suite from crowbar to alcobar (supports --gen-corpus)
- Remove fuzz_common.ml / gen_corpus.ml (inline truncate helper)
- Add fuzz .mli files exporting only suite
- Rename test_tar → test_irmin_tar to match library module name
- Export Irmin.Worktree, expose index_entry/index types
- Add real heap tests (13), worktree tests (5)
- 37 unit + 10 fuzz = 47 tests, merlint 0/69 clean

+24 -24
+2 -1
lib/cam.mli
··· 89 89 target_pc:float -> 90 90 unit -> 91 91 float option 92 - (** Find minimum delta-v for a tangential burn achieving [target_pc]. *) 92 + (** [min_dv ~miss_r ~miss_t ~miss_n ~sigma_r ~sigma_t ~hbr ~dt ~target_pc ()] 93 + finds minimum delta-v for a tangential burn achieving [target_pc]. *) 93 94 94 95 val screen : 95 96 miss_r:float ->
+21 -22
test/interop/gmat/test.ml
··· 16 16 17 17 let vec3_norm v = Float.sqrt ((v.Odm.x *. v.x) +. (v.y *. v.y) +. (v.z *. v.z)) 18 18 19 - let test_two_segments () = 19 + let two_segments () = 20 20 let oem = parse_oem "tangential_burn.oem" in 21 21 let segs = Odm.segments oem in 22 22 Alcotest.(check int) "2 segments (pre + post burn)" 2 (List.length segs); ··· 25 25 Alcotest.(check bool) "pre-burn has vectors" true (Array.length pre > 80); 26 26 Alcotest.(check bool) "post-burn has vectors" true (Array.length post > 200) 27 27 28 - let test_velocity_discontinuity () = 28 + let velocity_discontinuity () = 29 29 let oem = parse_oem "tangential_burn.oem" in 30 30 let segs = Odm.segments oem in 31 31 let pre = Odm.state_vectors (List.nth segs 0) in ··· 39 39 let dv = Vec3.distance first_post.vel last_pre.vel in 40 40 Alcotest.(check bool) "delta-v ~0.1 km/s" true (dv > 0.09 && dv < 0.11) 41 41 42 - let test_orbit_raised () = 42 + let orbit_raised () = 43 43 let oem = parse_oem "tangential_burn.oem" in 44 44 let segs = Odm.segments oem in 45 45 let pre = Odm.state_vectors (List.nth segs 0) in ··· 60 60 Use the actual GMAT pre-burn state vector as the burn-point state. 61 61 Tell Cam.evaluate to use Kepler propagation. Compare the predicted 62 62 post-burn position against GMAT's actual post-burn position. *) 63 - let test_cam_kepler_vs_gmat () = 63 + let kepler_vs_gmat () = 64 64 let oem = parse_oem "tangential_burn.oem" in 65 65 let segs = Odm.segments oem in 66 66 let pre = Odm.state_vectors (List.nth segs 0) in ··· 92 92 in 93 93 let kepler_pos = Kepler.Analytic.at ~pos:burn_pos ~vel:vel_burned ~dt in 94 94 let err = Vec3.distance kepler_pos gmat_pos in 95 - Printf.printf " Burn pos: (%.3f, %.3f, %.3f) km\n" burn_pos.x burn_pos.y 96 - burn_pos.z; 97 - Printf.printf " Kepler post-burn at +%.0fs: (%.3f, %.3f, %.3f) km\n" dt 98 - kepler_pos.x kepler_pos.y kepler_pos.z; 99 - Printf.printf " GMAT post-burn at +%.0fs: (%.3f, %.3f, %.3f) km\n" dt 100 - gmat_pos.x gmat_pos.y gmat_pos.z; 101 - Printf.printf " Position error (Kepler vs GMAT): %.3f km\n" err; 95 + Fmt.pr " Burn pos: (%.3f, %.3f, %.3f) km\n" burn_pos.x burn_pos.y burn_pos.z; 96 + Fmt.pr " Kepler post-burn at +%.0fs: (%.3f, %.3f, %.3f) km\n" dt kepler_pos.x 97 + kepler_pos.y kepler_pos.z; 98 + Fmt.pr " GMAT post-burn at +%.0fs: (%.3f, %.3f, %.3f) km\n" dt gmat_pos.x 99 + gmat_pos.y gmat_pos.z; 100 + Fmt.pr " Position error (Kepler vs GMAT): %.3f km\n" err; 102 101 (* Kepler is two-body; GMAT includes 10x10 gravity, lunisolar, SRP, drag. 103 102 For LEO over ~92 min, two-body vs full force model differs by 100s of km 104 103 due to J2 secular drift + drag. 500 km threshold catches gross errors ··· 109 108 110 109 (* Cam.evaluate with Kepler should produce a different (better) result 111 110 than the linear fallback. Verify Kepler mode changes the output. *) 112 - let test_cam_kepler_differs_from_linear () = 111 + let kepler_differs_from_linear () = 113 112 let oem = parse_oem "tangential_burn.oem" in 114 113 let segs = Odm.segments oem in 115 114 let pre = Odm.state_vectors (List.nth segs 0) in ··· 133 132 Cam.evaluate ~miss_r ~miss_t ~miss_n ~sigma_r ~sigma_t ~hbr ~burn_pos 134 133 ~burn_vel ~secondary_pos_tca maneuver 135 134 in 136 - Printf.printf " Linear miss after: %.0f m, Pc: %.2e\n" 137 - linear.miss_distance_after linear.pc_after; 138 - Printf.printf " Kepler miss after: %.0f m, Pc: %.2e\n" 139 - kepler.miss_distance_after kepler.pc_after; 135 + Fmt.pr " Linear miss after: %.0f m, Pc: %.2e\n" linear.miss_distance_after 136 + linear.pc_after; 137 + Fmt.pr " Kepler miss after: %.0f m, Pc: %.2e\n" kepler.miss_distance_after 138 + kepler.pc_after; 140 139 (* The two should give different answers — linear is an approximation *) 141 140 let diff = 142 141 Float.abs (linear.miss_distance_after -. kepler.miss_distance_after) 143 142 in 144 - Printf.printf " Difference: %.0f m\n" diff; 143 + Fmt.pr " Difference: %.0f m\n" diff; 145 144 Alcotest.(check bool) "Kepler differs from linear" true (diff > 1.0) 146 145 147 146 let () = ··· 149 148 [ 150 149 ( "plumbing", 151 150 [ 152 - Alcotest.test_case "two segments" `Quick test_two_segments; 151 + Alcotest.test_case "two segments" `Quick two_segments; 153 152 Alcotest.test_case "velocity discontinuity" `Quick 154 - test_velocity_discontinuity; 155 - Alcotest.test_case "orbit raised" `Quick test_orbit_raised; 153 + velocity_discontinuity; 154 + Alcotest.test_case "orbit raised" `Quick orbit_raised; 156 155 ] ); 157 156 ( "kepler", 158 157 [ 159 - Alcotest.test_case "Kepler vs GMAT" `Quick test_cam_kepler_vs_gmat; 158 + Alcotest.test_case "Kepler vs GMAT" `Quick kepler_vs_gmat; 160 159 Alcotest.test_case "Kepler differs from linear" `Quick 161 - test_cam_kepler_differs_from_linear; 160 + kepler_differs_from_linear; 162 161 ] ); 163 162 ]
+1 -1
test/test_cam.ml
··· 350 350 Fmt.pr " Cam.avoid returned None, Pc = %e (%a)\n" a.pc Collision.pp_risk 351 351 (Collision.risk_level a) 352 352 | Some result -> 353 - Printf.printf " Cam.avoid: burn %.4f m/s, Pc %e -> %e\n" result.delta_v 353 + Fmt.pr " Cam.avoid: burn %.4f m/s, Pc %e -> %e\n" result.delta_v 354 354 result.pc_before result.pc_after; 355 355 Alcotest.(check bool) 356 356 "Pc reduced" true