Satellite pass prediction and contact window computation
0
fork

Configure Feed

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

Remove renamed packages, add new CCSDS standards

Remove ocaml-ccsds-122 and ocaml-ccsds-123 (renamed to ocaml-idc and
ocaml-hcomp). Add ocaml-csts, ocaml-mal, ocaml-spacefibre packages.
Update ocaml-xmlt, ocaml-contact, ocaml-crypto (pure AES + JS stubs).

+21 -21
+14 -14
lib/contact.mli
··· 7 7 let tle = Sgp4.parse_tle_string tle_str |> Result.get_ok in 8 8 let la = Contact.ground_station ~lat:34.05 ~lon:(-118.25) ~alt:0.071 in 9 9 let passes = Contact.predict tle la ~duration_days:3 in 10 - List.iter (fun p -> 11 - Printf.printf "%s max_el=%.1f deg dur=%.0fs\n" 12 - p.aos_epoch p.max_elevation p.duration) 10 + List.iter 11 + (fun p -> 12 + Printf.printf "%s max_el=%.1f deg dur=%.0fs\n" p.aos_epoch 13 + p.max_elevation p.duration) 13 14 passes 14 15 ]} *) 15 16 ··· 31 32 (** {1 Ground station} *) 32 33 33 34 val ground_station : lat:float -> lon:float -> alt:float -> ground_station 34 - (** [ground_station ~lat ~lon ~alt] creates a ground station. 35 - [lat] in degrees (positive north), [lon] in degrees (positive east), 36 - [alt] in km above WGS-84 ellipsoid. *) 35 + (** [ground_station ~lat ~lon ~alt] creates a ground station. [lat] in degrees 36 + (positive north), [lon] in degrees (positive east), [alt] in km above WGS-84 37 + ellipsoid. *) 37 38 38 39 (** {1 Pass prediction} *) 39 40 ··· 44 45 ground_station -> 45 46 duration_days:float -> 46 47 pass list 47 - (** [predict tle gs ~duration_days] predicts all passes of the satellite 48 - over the ground station within [duration_days] from the TLE epoch. 48 + (** [predict tle gs ~duration_days] predicts all passes of the satellite over 49 + the ground station within [duration_days] from the TLE epoch. 49 50 50 - [min_elevation] is the minimum peak elevation in degrees for a pass 51 - to be included (default: 5.0). 51 + [min_elevation] is the minimum peak elevation in degrees for a pass to be 52 + included (default: 5.0). 52 53 53 54 [step] is the time step in seconds for the scan (default: 30.0). 54 55 55 56 Returns passes sorted by AOS time. *) 56 57 57 - val elevation : 58 - Sgp4.tle -> ground_station -> float -> float option 58 + val elevation : Sgp4.tle -> ground_station -> float -> float option 59 59 (** [elevation tle gs unix_t] computes the elevation angle in degrees of the 60 - satellite as seen from the ground station at Unix time [unix_t]. 61 - Returns [None] on propagation error. *) 60 + satellite as seen from the ground station at Unix time [unix_t]. Returns 61 + [None] on propagation error. *) 62 62 63 63 (** {1 Pretty-printing} *) 64 64
+7 -7
test/test.ml
··· 1 1 (** Tests for ocaml-contact. 2 2 3 - GMAT reference: station_contacts_report.txt from GMAT R2026a shows 4 - 14 contact windows from LA (34.05 N, 241.75 E) over 3 days for an 5 - ISS-like orbit. Our predictions should find a similar number of passes 6 - with comparable timing. 3 + GMAT reference: station_contacts_report.txt from GMAT R2026a shows 14 4 + contact windows from LA (34.05 N, 241.75 E) over 3 days for an ISS-like 5 + orbit. Our predictions should find a similar number of passes with 6 + comparable timing. 7 7 8 8 Source: GMAT R2026a, station_contacts.script. *) 9 9 ··· 33 33 (* GMAT found 14 passes. Our SGP4-based prediction may differ slightly 34 34 (different force model, different elevation threshold) but should be 35 35 in the same ballpark: 10-18 passes. *) 36 - Alcotest.(check bool) "reasonable pass count" true 36 + Alcotest.(check bool) 37 + "reasonable pass count" true 37 38 (List.length passes >= 8 && List.length passes <= 20) 38 39 39 40 let test_pass_properties () = ··· 62 63 | Some el -> 63 64 Printf.printf " Elevation at epoch: %.1f deg\n" el; 64 65 (* Should be a valid angle *) 65 - Alcotest.(check bool) "valid elevation" true 66 - (el >= -90.0 && el <= 90.0) 66 + Alcotest.(check bool) "valid elevation" true (el >= -90.0 && el <= 90.0) 67 67 68 68 let test_no_passes_wrong_inclination () = 69 69 (* An equatorial satellite (0 deg inclination) should never pass over