An Orbit Mean-elements Message (OMM) is the CCSDS-standardized representation of TLE/GP data — the same orbital elements traditionally distributed as Two-Line Element sets, in a structured, self-describing format. Data sources like CelesTrak and Space-Track distribute GP data as OMM. The typical workflow is to parse an OMM and initialize an SGP4 propagator.
importbraheasbhfrombrahe.ccsdsimportOMMbh.initialize_eop()# Parse OMMomm=OMM.from_file("test_assets/ccsds/omm/OMMExample1.txt")print(f"Object: {omm.object_name} ({omm.object_id})")print(f"Theory: {omm.mean_element_theory}")print(f"Epoch: {omm.epoch}")# Extract mean elements for SGP4# The epoch string is needed in ISO format for from_omm_elementsd=omm.to_dict()epoch_str=d["mean_elements"]["epoch"]# Initialize SGP propagator from OMM elementsprop=bh.SGPPropagator.from_omm_elements(epoch=epoch_str,mean_motion=omm.mean_motion,eccentricity=omm.eccentricity,inclination=omm.inclination,raan=omm.ra_of_asc_node,arg_of_pericenter=omm.arg_of_pericenter,mean_anomaly=omm.mean_anomaly,norad_id=omm.norad_cat_id,object_name=omm.object_name,object_id=omm.object_id,classification=omm.classification_type,bstar=omm.bstar,mean_motion_dot=omm.mean_motion_dot,mean_motion_ddot=omm.mean_motion_ddot,ephemeris_type=omm.ephemeris_type,element_set_no=omm.element_set_no,rev_at_epoch=omm.rev_at_epoch,)print("\nSGP Propagator created:")print(f" NORAD ID: {prop.norad_id}")print(f" Name: {prop.satellite_name}")print(f" Epoch: {prop.epoch}")# Propagate 1 day forwardtarget=prop.epoch+86400.0state=prop.state(target)print(f"\nState after 1 day ({target}):")print(f" Position: [{state[0]/1e3:.3f}, {state[1]/1e3:.3f}, {state[2]/1e3:.3f}] km")print(f" Velocity: [{state[3]:.3f}, {state[4]:.3f}, {state[5]:.3f}] m/s")# Propagate to several epochsprint("\nState every 6 hours:")forhoursinrange(0,25,6):t=prop.epoch+hours*3600.0s=prop.state(t)r=(s[0]**2+s[1]**2+s[2]**2)**0.5print(f" +{hours:2d}h: r={r/1e3:.1f} km")# State every 6 hours:# + 0h: r=... km# + 6h: r=... km# +12h: r=... km# +18h: r=... km# +24h: r=... km
Parse from file or string, then access metadata, mean elements, and TLE parameters. The message carries two main data sections: mean elements (epoch, mean motion, eccentricity, inclination, RAAN, argument of pericenter, mean anomaly) and TLE parameters (NORAD catalog ID, classification, element set number, revolution count, \(B^*\) drag term, mean motion derivatives):
usebraheasbh;usebrahe::ccsds::OMM;fnmain(){bh::initialize_eop().unwrap();// Parse OMM fileletomm=OMM::from_file("test_assets/ccsds/omm/OMMExample1.txt").unwrap();// Headerprintln!("Format version: {}",omm.header.format_version);println!("Originator: {}",omm.header.originator);println!("Creation date: {}",omm.header.creation_date);// Metadataprintln!("\nObject name: {}",omm.metadata.object_name);println!("Object ID: {}",omm.metadata.object_id);println!("Center name: {}",omm.metadata.center_name);println!("Ref frame: {}",omm.metadata.ref_frame);println!("Time system: {}",omm.metadata.time_system);println!("Mean element theory: {}",omm.metadata.mean_element_theory);// Mean orbital elements (CCSDS/TLE-native units)println!("\nEpoch: {}",omm.mean_elements.epoch);println!("Mean motion: {} rev/day",omm.mean_elements.mean_motion.unwrap_or(0.0));println!("Eccentricity: {}",omm.mean_elements.eccentricity);println!("Inclination: {} deg",omm.mean_elements.inclination);println!("RAAN: {} deg",omm.mean_elements.ra_of_asc_node);println!("Arg of pericenter: {} deg",omm.mean_elements.arg_of_pericenter);println!("Mean anomaly: {} deg",omm.mean_elements.mean_anomaly);println!("GM: {:.4e} m³/s²",omm.mean_elements.gm.unwrap_or(0.0));// TLE parametersifletSome(reftle)=omm.tle_parameters{println!("\nNORAD catalog ID: {}",tle.norad_cat_id.unwrap_or(0));println!("Classification: {}",tle.classification_type.unwrap_or('U'));println!("Ephemeris type: {}",tle.ephemeris_type.unwrap_or(0));println!("Element set no: {}",tle.element_set_no.unwrap_or(0));println!("Rev at epoch: {}",tle.rev_at_epoch.unwrap_or(0));println!("BSTAR: {}",tle.bstar.unwrap_or(0.0));println!("Mean motion dot: {} rev/day²",tle.mean_motion_dot.unwrap_or(0.0));println!("Mean motion ddot: {} rev/day³",tle.mean_motion_ddot.unwrap_or(0.0));}println!("\nParsing completed successfully.");}
Unit Convention for OMM
Mean motion, angles, and TLE drag terms are kept in their CCSDS/TLE-native units (rev/day, degrees, etc.) because these values are needed as-is for TLE generation and SGP4 initialization. Only GM is converted to SI (m\(^3\)/s\(^2\)).
Brahe's GPRecord type — returned by both CelestrakClient and SpaceTrackClient when querying GP data — has a bidirectional relationship with OMM. A GPRecord can be converted to an OMM via to_omm() for CCSDS-compliant export, and an OMM can be converted to a GPRecord via to_gp_record() for use with brahe's ephemeris infrastructure.
This means you can move freely between the two representations: query CelesTrak for a satellite, get a GPRecord, and export it as a standards-compliant OMM file for distribution. Or parse an OMM file received from an external system and convert it to a GPRecord to use the same downstream code you would with a CelesTrak or Space-Track query. Both conversions preserve all shared fields, so switching between formats introduces no data loss.