Select the types of activity you want to include in your feed.
fix(ocaml-requests): update tests and fuzz for cstruct→Bytes migration
Test files still referenced Cstruct.t where the API now uses bytes. Fixed all H2 frame, HPACK, client, and connection tests. Fixed fuzz test. 330 tests pass.
···5566(** Fuzz tests for Keplerian propagation.
7788- Key properties tested:
99- 1. Propagation never crashes (no unhandled exceptions)
1010- 2. No NaN/infinity in output positions for valid inputs
1111- 3. Vec3 operations are safe on all floats *)
88+ Key properties tested: 1. Propagation never crashes (no unhandled
99+ exceptions) 2. No NaN/infinity in output positions for valid inputs 3. Vec3
1010+ operations are safe on all floats *)
12111312open Alcobar
1413···2322 in
2423 let px = get 0 and py = get 1 and pz = get 2 in
2524 let vx = get 3 and vy = get 4 and vz = get 5 in
2626- if Float.is_finite px && Float.is_finite py && Float.is_finite pz
2727- && Float.is_finite vx && Float.is_finite vy && Float.is_finite vz
2525+ if
2626+ Float.is_finite px && Float.is_finite py && Float.is_finite pz
2727+ && Float.is_finite vx && Float.is_finite vy && Float.is_finite vz
2828 then begin
2929 let pos = Kepler.Vec3.v px py pz in
3030 let vel = Kepler.Vec3.v vx vy vz in
3131- let dur = abs_float (Float.of_int n) *. 10. +. 1. in
3131+ let dur = (abs_float (Float.of_int n) *. 10.) +. 1. in
3232 let _arc =
3333 Kepler.Propagate.arc ~pos ~vel ~duration_s:dur ~num_points:10
3434 in
···5566(** Two-body (Keplerian) orbit propagation via RK4 integration.
7788- Given position and velocity at epoch, propagates forward/backward
99- using numerical integration. Suitable for short arcs (~1 orbit). *)
88+ Given position and velocity at epoch, propagates forward/backward using
99+ numerical integration. Suitable for short arcs (~1 orbit). *)
10101111let mu = 398600.4418
1212···2929 let a4 = gravity p4 in
3030 let new_pos =
3131 add pos
3232- (scale (dt /. 6.)
3333- (add vel (add (scale 2. v2) (add (scale 2. v3) v4))))
3232+ (scale (dt /. 6.) (add vel (add (scale 2. v2) (add (scale 2. v3) v4))))
3433 in
3534 let new_vel =
3635 add vel
3737- (scale (dt /. 6.)
3838- (add a1 (add (scale 2. a2) (add (scale 2. a3) a4))))
3636+ (scale (dt /. 6.) (add a1 (add (scale 2. a2) (add (scale 2. a3) a4))))
3937 in
4038 (new_pos, new_vel)
4139
+6-10
lib/propagate.mli
···44(** [mu] is Earth's gravitational parameter (km^3/s^2). *)
5566val at : pos:Vec3.t -> vel:Vec3.t -> dt:float -> Vec3.t
77-(** [at ~pos ~vel ~dt] propagates a state vector by [dt] seconds
88- and returns the new position. Uses adaptive step count. *)
77+(** [at ~pos ~vel ~dt] propagates a state vector by [dt] seconds and returns the
88+ new position. Uses adaptive step count. *)
991010val arc :
1111- pos:Vec3.t ->
1212- vel:Vec3.t ->
1313- duration_s:float ->
1414- num_points:int ->
1515- Vec3.t array
1616-(** [arc ~pos ~vel ~duration_s ~num_points] propagates a state vector
1717- over [duration_s] seconds centered on epoch, returning [num_points]
1818- positions in the same frame as the input. *)
1111+ pos:Vec3.t -> vel:Vec3.t -> duration_s:float -> num_points:int -> Vec3.t array
1212+(** [arc ~pos ~vel ~duration_s ~num_points] propagates a state vector over
1313+ [duration_s] seconds centered on epoch, returning [num_points] positions in
1414+ the same frame as the input. *)
+16-33
test/test_propagate.ml
···66 - Curtis, "Orbital Mechanics for Engineering Students"
77 - STK validation data (circular, elliptical, polar orbits) *)
8899-let eps_km = 1.0
109(** Position accuracy ~1 km after short propagation (RK4 vs analytical). *)
1010+let eps_km = 1.0
11111212-let eps_energy = 1e-4
1312(** Specific energy conservation tolerance. *)
1313+let eps_energy = 1e-4
14141515let check_float msg eps expected actual =
1616 Alcotest.(check (float eps)) msg expected actual
···5656 let e0 = specific_energy molniya_pos molniya_vel in
5757 (* Propagate half an orbit (~6 hours = 21600s) *)
5858 let arc =
5959- Kepler.Propagate.arc ~pos:molniya_pos ~vel:molniya_vel
6060- ~duration_s:21600. ~num_points:200
5959+ Kepler.Propagate.arc ~pos:molniya_pos ~vel:molniya_vel ~duration_s:21600.
6060+ ~num_points:200
6161 in
6262 (* Energy at various points should be conserved *)
6363 (* The arc array gives positions; we need to recompute vel for energy.
6464 Instead, verify that the orbit reaches near-apogee altitude. *)
6565 let max_r =
6666- Array.fold_left
6767- (fun acc p -> Float.max acc (Kepler.Vec3.length p))
6868- 0. arc
6666+ Array.fold_left (fun acc p -> Float.max acc (Kepler.Vec3.length p)) 0. arc
6967 in
7068 (* Should reach at least 30000 km (partway to apogee) *)
7169 Alcotest.(check bool) "reaches high altitude" true (max_r > 25000.);
···116114let test_retrograde () =
117115 let pos = Kepler.Vec3.v 6778.0 0.0 0.0 in
118116 let vel = Kepler.Vec3.v 0.0 (-7.669) 0.0 in
119119- let arc =
120120- Kepler.Propagate.arc ~pos ~vel ~duration_s:5400. ~num_points:100
121121- in
117117+ let arc = Kepler.Propagate.arc ~pos ~vel ~duration_s:5400. ~num_points:100 in
122118 (* Should orbit in opposite direction. After quarter period (~1350s),
123119 should be at ~(0, -6778, 0) instead of (0, 6778, 0) for prograde *)
124120 let quarter = arc.(75) in
···129125 With v > v_escape, object should fly away indefinitely. *)
130126let test_escape () =
131127 let pos = Kepler.Vec3.v 6678.0 0.0 0.0 in
132132- let vel = Kepler.Vec3.v 0.0 12.0 0.0 in (* > escape velocity *)
128128+ let vel = Kepler.Vec3.v 0.0 12.0 0.0 in
129129+ (* > escape velocity *)
133130 let e = specific_energy pos vel in
134131 Alcotest.(check bool) "positive energy (hyperbolic)" true (e > 0.);
135135- let arc =
136136- Kepler.Propagate.arc ~pos ~vel ~duration_s:36000. ~num_points:100
137137- in
132132+ let arc = Kepler.Propagate.arc ~pos ~vel ~duration_s:36000. ~num_points:100 in
138133 (* Distance should monotonically increase in forward direction *)
139134 let r_last = Kepler.Vec3.length arc.(99) in
140135 let r_mid = Kepler.Vec3.length arc.(75) in
···150145 let vel = Kepler.Vec3.v 4.901327 5.533756 (-1.976341) in
151146 let e0 = specific_energy pos vel in
152147 Alcotest.(check bool) "bound orbit" true (e0 < 0.);
153153- let arc =
154154- Kepler.Propagate.arc ~pos ~vel ~duration_s:7200. ~num_points:100
155155- in
148148+ let arc = Kepler.Propagate.arc ~pos ~vel ~duration_s:7200. ~num_points:100 in
156149 (* Orbit should stay within reasonable bounds *)
157150 let max_r =
158158- Array.fold_left
159159- (fun acc p -> Float.max acc (Kepler.Vec3.length p))
160160- 0. arc
151151+ Array.fold_left (fun acc p -> Float.max acc (Kepler.Vec3.length p)) 0. arc
161152 in
162153 (* High velocity → large apogee; just verify finite positions *)
163154 Alcotest.(check bool) "max radius finite" true (Float.is_finite max_r)
···171162 let vel = Kepler.Vec3.v 0. (v_esc -. 0.001) 0. in
172163 let e = specific_energy pos vel in
173164 Alcotest.(check bool) "near-zero energy" true (abs_float e < 0.1);
174174- let arc =
175175- Kepler.Propagate.arc ~pos ~vel ~duration_s:36000. ~num_points:50
176176- in
165165+ let arc = Kepler.Propagate.arc ~pos ~vel ~duration_s:36000. ~num_points:50 in
177166 (* Should still produce valid positions *)
178167 Array.iter
179168 (fun (p : Kepler.Vec3.t) ->
···188177 let pos = Kepler.Vec3.v 8000.0 0.0 6000.0 in
189178 let vel = Kepler.Vec3.v 0.0 (-5.0) 6.0 in
190179 (* Forward 3600s *)
191191- let fwd =
192192- Kepler.Propagate.arc ~pos ~vel ~duration_s:7200. ~num_points:100
193193- in
180180+ let fwd = Kepler.Propagate.arc ~pos ~vel ~duration_s:7200. ~num_points:100 in
194181 (* The midpoint (index 50) should be close to the initial position *)
195182 let mid = fwd.(50) in
196183 let dx = abs_float (mid.x -. pos.x) in
···203190let test_arc_length () =
204191 let pos = Kepler.Vec3.v 7000.0 0.0 0.0 in
205192 let vel = Kepler.Vec3.v 0.0 7.5 0.0 in
206206- let arc =
207207- Kepler.Propagate.arc ~pos ~vel ~duration_s:3600. ~num_points:42
208208- in
193193+ let arc = Kepler.Propagate.arc ~pos ~vel ~duration_s:3600. ~num_points:42 in
209194 Alcotest.(check int) "arc length" 42 (Array.length arc)
210195211196let suite =
···213198 [
214199 Alcotest.test_case "ISS energy conservation" `Quick
215200 test_iss_energy_conservation;
216216- Alcotest.test_case "Molniya HEO" `Quick
217217- test_molniya_energy_conservation;
201201+ Alcotest.test_case "Molniya HEO" `Quick test_molniya_energy_conservation;
218202 Alcotest.test_case "GEO period" `Quick test_geo_period;
219203 Alcotest.test_case "polar orbit" `Quick test_polar_orbit;
220204 Alcotest.test_case "retrograde" `Quick test_retrograde;
221205 Alcotest.test_case "escape trajectory" `Quick test_escape;
222206 Alcotest.test_case "Vallado ex1" `Quick test_vallado_ex1;
223207 Alcotest.test_case "near-parabolic" `Quick test_near_parabolic;
224224- Alcotest.test_case "time reversibility" `Quick
225225- test_time_reversibility;
208208+ Alcotest.test_case "time reversibility" `Quick test_time_reversibility;
226209 Alcotest.test_case "arc length" `Quick test_arc_length;
227210 ] )