Collision Avoidance Maneuver design for conjunction assessment
0
fork

Configure Feed

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

Simplify public APIs for odm, collision, and cam

odm: Add Odm.position_at — queries position across all segments in one
call. No need to manually iterate segments or convert epochs.

collision: Add Collision.assess — one-call CDM risk assessment returning
Pc, miss distance, relative velocity, and risk level (Critical/High/
Watch/Low enum). encounter/pc_foster/pc_chan/pc_max remain available for
custom workflows.

cam: Add Cam.avoid — one-call CDM avoidance. Takes a CDM and time-to-burn,
returns the minimum maneuver to reduce Pc below threshold (default 1e-5).
Extracts conjunction geometry from CDM automatically.

+69 -21
+31
lib/cam.ml
··· 180 180 in 181 181 List.sort (fun a b -> Float.compare a.pc_after b.pc_after) results 182 182 183 + (* {1 Simple API} *) 184 + 185 + let avoid ?(hbr = 0.015) ?(target_pc = 1e-5) ?(direction = `Tangential) 186 + (cdm : Cdm.t) ~dt = 187 + let miss_vec = 188 + Vec3.sub cdm.obj2.state.pos cdm.obj1.state.pos 189 + in 190 + let r_hat, t_hat, n_hat = 191 + let rn = Vec3.length cdm.obj1.state.pos in 192 + let r = Vec3.scale (1.0 /. rn) cdm.obj1.state.pos in 193 + let h = Vec3.cross cdm.obj1.state.pos cdm.obj1.state.vel in 194 + let hn = Vec3.length h in 195 + let n = Vec3.scale (1.0 /. hn) h in 196 + let t = Vec3.cross n r in 197 + (r, t, n) 198 + in 199 + let miss_r = Vec3.dot miss_vec r_hat *. 1000.0 in 200 + let miss_t = Vec3.dot miss_vec t_hat *. 1000.0 in 201 + let miss_n = Vec3.dot miss_vec n_hat *. 1000.0 in 202 + let sigma_r = sqrt cdm.obj1.cov.cr_r +. sqrt cdm.obj2.cov.cr_r in 203 + let sigma_t = sqrt cdm.obj1.cov.ct_t +. sqrt cdm.obj2.cov.ct_t in 204 + let hbr_m = hbr *. 1000.0 in 205 + match 206 + min_dv ~miss_r ~miss_t ~miss_n ~sigma_r ~sigma_t ~hbr:hbr_m ~dt ~target_pc 207 + () 208 + with 209 + | None -> None 210 + | Some dv -> 211 + let m = { dt; dv; direction } in 212 + Some (evaluate ~miss_r ~miss_t ~miss_n ~sigma_r ~sigma_t ~hbr:hbr_m m) 213 + 183 214 (* {1 Pretty-printing} *) 184 215 185 216 let pp_direction ppf = function
+38 -21
lib/cam.mli
··· 1 1 (** Collision Avoidance Maneuver (CAM) design. 2 2 3 - Computes impulsive burns to mitigate conjunction risk. When satellite state 4 - vectors are provided, uses Kepler propagation to predict the post-maneuver 5 - trajectory. Falls back to a linear approximation ([dv * dt]) when only miss 6 - distances are available. *) 3 + {2 Quick start} 4 + 5 + {[ 6 + (* Find the minimum burn to make a conjunction safe *) 7 + let cdm = ... in 8 + match Cam.avoid cdm ~dt:21600.0 with 9 + | Some result -> 10 + Printf.printf "Burn %.2f m/s, Pc drops from %e to %e\n" 11 + result.delta_v result.pc_before result.pc_after 12 + | None -> 13 + Printf.printf "Cannot reduce Pc below threshold\n" 14 + ]} 15 + 16 + Uses Kepler propagation when satellite state vectors are available, 17 + linear approximation otherwise. *) 7 18 8 19 (** {1 Types} *) 9 20 ··· 27 38 } 28 39 (** Result of evaluating a maneuver. *) 29 40 30 - (** {1 Maneuver evaluation} *) 41 + (** {1 Simple API} *) 42 + 43 + val avoid : 44 + ?hbr:float -> 45 + ?target_pc:float -> 46 + ?direction:direction -> 47 + Cdm.t -> 48 + dt:float -> 49 + result option 50 + (** [avoid cdm ~dt] finds the minimum tangential burn at [dt] seconds before 51 + TCA that reduces Pc below [target_pc]. 52 + 53 + Defaults: [hbr] = 0.015 km (15 m), [target_pc] = 1e-5, 54 + [direction] = [`Tangential]. 55 + 56 + Returns [None] if the conjunction is already safe or if no burn can achieve 57 + the target. *) 58 + 59 + (** {1 Detailed API} *) 31 60 32 61 val evaluate : 33 62 miss_r:float -> ··· 43 72 result 44 73 (** [evaluate ~miss_r ~miss_t ~miss_n ~sigma_r ~sigma_t ~hbr m] evaluates a 45 74 proposed maneuver [m]. Miss components in meters, sigma in meters, HBR in 46 - meters. 47 - 48 - When [~burn_pos], [~burn_vel], and [~secondary_pos_tca] are provided (all in 49 - km, km/s), uses Kepler propagation to compute the post-maneuver miss 50 - distance. Otherwise falls back to the linear approximation ([dv * dt]). *) 75 + meters. When state vectors are provided (km, km/s), uses Kepler 76 + propagation. *) 51 77 52 78 val min_dv : 53 79 miss_r:float -> ··· 63 89 target_pc:float -> 64 90 unit -> 65 91 float option 66 - (** [min_dv ... ~dt ~target_pc] finds the minimum delta-v (m/s) for a tangential 67 - burn at [dt] seconds before TCA that achieves [target_pc] or lower. Returns 68 - [None] if impossible. Uses bisection search. When state vectors are 69 - provided, uses Kepler propagation. *) 92 + (** Find minimum delta-v for a tangential burn achieving [target_pc]. *) 70 93 71 94 val screen : 72 95 miss_r:float -> ··· 82 105 dt:float -> 83 106 unit -> 84 107 result list 85 - (** [screen ... ~dv_options ~dt] evaluates multiple delta-v options and returns 86 - results sorted by [pc_after] ascending. *) 108 + (** Evaluate multiple delta-v options, sorted by post-maneuver Pc. *) 87 109 88 110 (** {1 Pretty-printing} *) 89 111 90 112 val pp_direction : direction Fmt.t 91 - (** Pretty-print a burn direction. *) 92 - 93 113 val pp_maneuver : maneuver Fmt.t 94 - (** Pretty-print a maneuver. *) 95 - 96 114 val pp : result Fmt.t 97 - (** Pretty-print a maneuver evaluation result. *)