Orbit Data Messages (CCSDS 502.0-B-3)
0
fork

Configure Feed

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

odm: rename test_vectors→test_oem, extract opm helpers (E001/E005/E605)

Rename test_vectors.ml to test_oem.ml so it covers the OEM library
module (was missing test_oem.ml). Extract write_header/metadata/state/
spacecraft/covariance/maneuver helpers from to_string (was 79 lines).
Pull maneuver_of_table and consume_pair out of parse_maneuvers to drop
nesting depth from 5 to 3.

+77 -65
+75 -62
lib/opm.ml
··· 254 254 cz_dot_z_dot = float_or "CZ_DOT_Z_DOT" 0.0 pairs; 255 255 } 256 256 257 + let maneuver_of_table cur = 258 + let get k = try Hashtbl.find cur k with Not_found -> "" in 259 + let getf k = float_or_zero (get k) in 260 + let epoch = 261 + match Kvn.parse_epoch (get "MAN_EPOCH_IGNITION") with 262 + | Some t -> t 263 + | None -> Ptime.epoch 264 + in 265 + { 266 + man_epoch_ignition = epoch; 267 + man_duration = getf "MAN_DURATION"; 268 + man_delta_mass = getf "MAN_DELTA_MASS"; 269 + man_ref_frame = get "MAN_REF_FRAME"; 270 + man_dv_1 = getf "MAN_DV_1"; 271 + man_dv_2 = getf "MAN_DV_2"; 272 + man_dv_3 = getf "MAN_DV_3"; 273 + } 274 + 275 + let is_man_key k = String.length k >= 4 && String.sub k 0 4 = "MAN_" 276 + 277 + let consume_pair mans cur (k, v) = 278 + if not (is_man_key k) then () 279 + else begin 280 + if k = "MAN_EPOCH_IGNITION" && Hashtbl.mem cur "MAN_EPOCH_IGNITION" then begin 281 + mans := maneuver_of_table cur :: !mans; 282 + Hashtbl.clear cur 283 + end; 284 + Hashtbl.replace cur k v 285 + end 286 + 257 287 let parse_maneuvers pairs = 258 288 (* Collect all MAN_EPOCH_IGNITION entries; each starts a new maneuver. 259 289 Since KVN pairs are in order, we group maneuver fields by scanning 260 290 for the epoch keyword. *) 261 291 let mans = ref [] in 262 292 let cur = Hashtbl.create 8 in 263 - let flush () = 264 - if Hashtbl.mem cur "MAN_EPOCH_IGNITION" then begin 265 - let get k = try Hashtbl.find cur k with Not_found -> "" in 266 - let getf k = float_or_zero (get k) in 267 - let epoch = 268 - match Kvn.parse_epoch (get "MAN_EPOCH_IGNITION") with 269 - | Some t -> t 270 - | None -> Ptime.epoch 271 - in 272 - mans := 273 - { 274 - man_epoch_ignition = epoch; 275 - man_duration = getf "MAN_DURATION"; 276 - man_delta_mass = getf "MAN_DELTA_MASS"; 277 - man_ref_frame = get "MAN_REF_FRAME"; 278 - man_dv_1 = getf "MAN_DV_1"; 279 - man_dv_2 = getf "MAN_DV_2"; 280 - man_dv_3 = getf "MAN_DV_3"; 281 - } 282 - :: !mans; 283 - Hashtbl.clear cur 284 - end 285 - in 286 - List.iter 287 - (fun (k, v) -> 288 - if String.length k >= 4 && String.sub k 0 4 = "MAN_" then begin 289 - if k = "MAN_EPOCH_IGNITION" && Hashtbl.mem cur "MAN_EPOCH_IGNITION" then 290 - flush (); 291 - Hashtbl.replace cur k v 292 - end) 293 - pairs; 294 - flush (); 293 + List.iter (consume_pair mans cur) pairs; 294 + if Hashtbl.mem cur "MAN_EPOCH_IGNITION" then 295 + mans := maneuver_of_table cur :: !mans; 295 296 List.rev !mans 296 297 297 298 let of_string s = ··· 344 345 fmt_epoch buf t; 345 346 Buffer.add_char buf '\n' 346 347 347 - let to_string opm = 348 - let buf = Buffer.create 1024 in 349 - kv buf "CCSDS_OPM_VERS" opm.header.version; 350 - kv buf "CREATION_DATE" opm.header.creation_date; 351 - kv buf "ORIGINATOR" opm.header.originator; 352 - Buffer.add_char buf '\n'; 353 - kv buf "OBJECT_NAME" opm.metadata.object_name; 354 - kv buf "OBJECT_ID" opm.metadata.object_id; 355 - kv buf "CENTER_NAME" opm.metadata.center_name; 356 - kv buf "REF_FRAME" opm.metadata.ref_frame; 357 - kv buf "TIME_SYSTEM" opm.metadata.time_system; 358 - Buffer.add_char buf '\n'; 359 - kv_epoch buf "EPOCH" opm.epoch; 360 - (match opm.state with 348 + let write_header buf header = 349 + kv buf "CCSDS_OPM_VERS" header.version; 350 + kv buf "CREATION_DATE" header.creation_date; 351 + kv buf "ORIGINATOR" header.originator; 352 + Buffer.add_char buf '\n' 353 + 354 + let write_metadata buf m = 355 + kv buf "OBJECT_NAME" m.object_name; 356 + kv buf "OBJECT_ID" m.object_id; 357 + kv buf "CENTER_NAME" m.center_name; 358 + kv buf "REF_FRAME" m.ref_frame; 359 + kv buf "TIME_SYSTEM" m.time_system; 360 + Buffer.add_char buf '\n' 361 + 362 + let write_state buf = function 361 363 | Cartesian c -> 362 364 kvf buf "X" c.x; 363 365 kvf buf "Y" c.y; ··· 373 375 kvf buf "ARG_OF_PERICENTER" ke.arg_of_pericenter; 374 376 kvf_opt buf "TRUE_ANOMALY" ke.true_anomaly; 375 377 kvf_opt buf "MEAN_ANOMALY" ke.mean_anomaly; 376 - kvf_opt buf "GM" ke.gm); 377 - (match opm.spacecraft with 378 + kvf_opt buf "GM" ke.gm 379 + 380 + let write_spacecraft buf = function 378 381 | None -> () 379 382 | Some sp -> 380 383 Buffer.add_char buf '\n'; ··· 382 385 kvf_opt buf "SOLAR_RAD_AREA" sp.solar_rad_area; 383 386 kvf_opt buf "SOLAR_RAD_COEFF" sp.solar_rad_coeff; 384 387 kvf_opt buf "DRAG_AREA" sp.drag_area; 385 - kvf_opt buf "DRAG_COEFF" sp.drag_coeff); 386 - (match opm.covariance with 388 + kvf_opt buf "DRAG_COEFF" sp.drag_coeff 389 + 390 + let write_covariance buf = function 387 391 | None -> () 388 392 | Some c -> 389 393 Buffer.add_char buf '\n'; ··· 410 414 kvf buf "CZ_DOT_Z" c.cz_dot_z; 411 415 kvf buf "CZ_DOT_X_DOT" c.cz_dot_x_dot; 412 416 kvf buf "CZ_DOT_Y_DOT" c.cz_dot_y_dot; 413 - kvf buf "CZ_DOT_Z_DOT" c.cz_dot_z_dot); 414 - List.iter 415 - (fun man -> 416 - Buffer.add_char buf '\n'; 417 - kv_epoch buf "MAN_EPOCH_IGNITION" man.man_epoch_ignition; 418 - kvf buf "MAN_DURATION" man.man_duration; 419 - kvf buf "MAN_DELTA_MASS" man.man_delta_mass; 420 - kv buf "MAN_REF_FRAME" man.man_ref_frame; 421 - kvf buf "MAN_DV_1" man.man_dv_1; 422 - kvf buf "MAN_DV_2" man.man_dv_2; 423 - kvf buf "MAN_DV_3" man.man_dv_3) 424 - opm.maneuvers; 417 + kvf buf "CZ_DOT_Z_DOT" c.cz_dot_z_dot 418 + 419 + let write_maneuver buf man = 420 + Buffer.add_char buf '\n'; 421 + kv_epoch buf "MAN_EPOCH_IGNITION" man.man_epoch_ignition; 422 + kvf buf "MAN_DURATION" man.man_duration; 423 + kvf buf "MAN_DELTA_MASS" man.man_delta_mass; 424 + kv buf "MAN_REF_FRAME" man.man_ref_frame; 425 + kvf buf "MAN_DV_1" man.man_dv_1; 426 + kvf buf "MAN_DV_2" man.man_dv_2; 427 + kvf buf "MAN_DV_3" man.man_dv_3 428 + 429 + let to_string opm = 430 + let buf = Buffer.create 1024 in 431 + write_header buf opm.header; 432 + write_metadata buf opm.metadata; 433 + kv_epoch buf "EPOCH" opm.epoch; 434 + write_state buf opm.state; 435 + write_spacecraft buf opm.spacecraft; 436 + write_covariance buf opm.covariance; 437 + List.iter (write_maneuver buf) opm.maneuvers; 425 438 Buffer.contents buf 426 439 427 440 (* ------------------------------------------------------------------ *)
+1 -2
test/test.ml
··· 1 - let () = 2 - Alcotest.run "odm" [ Test_odm.suite; Test_opm.suite; Test_vectors.suite ] 1 + let () = Alcotest.run "odm" [ Test_odm.suite; Test_opm.suite; Test_oem.suite ]
+1 -1
test/test_vectors.ml test/test_oem.ml
··· 194 194 Alcotest.failf "GEO velocity %.2f km/s out of range" v) 195 195 196 196 let suite = 197 - ( "vectors", 197 + ( "oem", 198 198 valid_v2_samples () @ real_orbit_samples () @ invalid_samples () 199 199 @ [ 200 200 Alcotest.test_case "LEO orbit checks" `Quick leo_orbit_checks;
test/test_vectors.mli test/test_oem.mli