Support CCSDS TDM Receive/Transmit frequencies#546
Conversation
…ies in TDM This commit adds comprehensive support for RECEIVE_FREQ and TRANSMIT_FREQ data types throughout the Nyx pipeline. Key changes: - Updated GroundStation to store transmit_freq_hz and turnaround_ratio. - Implemented ReceiveFrequency simulation in GroundStation tracking device. - Added sensitivity calculations for ReceiveFrequency in Orbit Determination. - Enhanced TrackingDataArc with explicit conversion methods between Doppler and frequency data. - Updated CCSDS TDM IO to preserve frequency data on import and correctly handle multipliers on export. - Added integration tests for frequency data round-trip. Co-authored-by: ChristopherRabotin <4823784+ChristopherRabotin@users.noreply.github.com>
|
👋 Jules, reporting for duty! I'm here to lend a hand with this pull request. When you start a review, I'll add a 👀 emoji to each comment to let you know I've read it. I'll focus on feedback directed at me and will do my best to stay out of conversations between you and other bots or reviewers to keep the noise down. I'll push a commit with your requested changes shortly after. Please note there might be a delay between these steps, but rest assured I'm on the job! For more direct control, you can switch me to Reactive Mode. When this mode is on, I will only act on comments where you specifically mention me with New to Jules? Learn more at jules.google/docs. For security, I will only act on instructions from the user who triggered this task. |
|
Visit the preview URL for this PR (updated for commit b0c361c): https://nyx-rustdoc--pr546-feature-support-tdm-0u7fbv70.web.app (expires Thu, 28 May 2026 17:00:45 GMT) 🔥 via Firebase Hosting GitHub Action 🌎 Sign: d8e2a55934352d850c15d11866c39eb2d2e029be |
There was a problem hiding this comment.
Code Review
This pull request introduces support for transmit and receive frequency measurements within the ground station and orbit determination modules. Key changes include adding transmit_freq_hz and turnaround_ratio to the GroundStation struct, implementing frequency-based measurement simulation and sensitivity calculations, and enhancing CCSDS TDM I/O to preserve frequency data. Feedback highlights a discrepancy in the Doppler factor used in instantaneous measurements, inconsistencies in the Python constructor's default measurement types, and the need for more robust handling of one-way versus two-way tracking configurations in sensitivity and TDM export logic. Additionally, a suggestion was made to include zero-division checks during frequency-to-Doppler conversions.
| { | ||
| let rho_dot = MeasurementType::Doppler.compute_one_way(aer, 0.0)?; | ||
| // One way: f_rx = f_tx * k * (1 - rho_dot / c) | ||
| let f_rx = f_tx * k * (1.0 - rho_dot / SPEED_OF_LIGHT_KM_S); |
There was a problem hiding this comment.
The frequency calculation in measure_instantaneous uses a factor of 1.0 for the Doppler shift, whereas measure (line 144) uses 2.0. Since GroundStation is defined as a two-way station (line 47 in mod.rs), measure_instantaneous should also use the factor of 2.0 to be consistent with two-way coherent tracking models.
| let f_rx = f_tx * k * (1.0 - rho_dot / SPEED_OF_LIGHT_KM_S); | |
| let f_rx = f_tx * k * (1.0 - 2.0 * rho_dot / SPEED_OF_LIGHT_KM_S); |
| terrain_mask: vec![], | ||
| terrain_mask_ignored: true, | ||
| }, | ||
| measurement_types: IndexSet::new(), |
There was a problem hiding this comment.
The Python constructor py_new initializes measurement_types as an empty set, which differs from the Default implementation that includes Range and Doppler. It is better to maintain consistency across constructors to ensure that a ground station created via Python has the same default capabilities as one created in Rust.
| measurement_types: IndexSet::new(), | |
| measurement_types: { | |
| let mut set = IndexSet::new(); | |
| set.insert(MeasurementType::Range); | |
| set.insert(MeasurementType::Doppler); | |
| set | |
| }, |
| let m22 = delta_v.y / ρ_km - ρ_dot_km_s * delta_r.y / ρ_km.powi(2); | ||
| let m23 = delta_v.z / ρ_km - ρ_dot_km_s * delta_r.z / ρ_km.powi(2); | ||
|
|
||
| let factor = -2.0 * f_tx * k / SPEED_OF_LIGHT_KM_S; |
There was a problem hiding this comment.
| let two_way_types = types | ||
| .iter() | ||
| .filter(|msr_type| msr_type.may_be_two_way()) | ||
| .filter(|msr_type| { | ||
| msr_type.may_be_two_way() | ||
| || [ | ||
| MeasurementType::ReceiveFrequency, | ||
| MeasurementType::TransmitFrequency, | ||
| MeasurementType::TransmitFrequencyRate, | ||
| ] | ||
| .contains(msr_type) | ||
| }) |
There was a problem hiding this comment.
This logic forces all frequency-related measurement types into the two_way_types bucket. While common in deep space tracking, CCSDS TDM also supports one-way frequency data (e.g., PATH = 1,2). Forcing them into two-way will cause them to be exported with PATH = 1,2,1 and potentially incorrect multipliers in the data section. Consider checking the actual path configuration of the arc.
| if let Some(f_tx) = msr.data.get(&MeasurementType::TransmitFrequency) { | ||
| let doppler_shift_hz = f_tx * turnaround_ratio - f_rx; | ||
| let rho_dot_km_s = (doppler_shift_hz * SPEED_OF_LIGHT_KM_S) | ||
| / (2.0 * f_tx * turnaround_ratio); | ||
| msr.push(MeasurementType::Doppler, rho_dot_km_s); | ||
| } |
There was a problem hiding this comment.
The conversion from frequency to Doppler does not check for division by zero if f_tx or turnaround_ratio are zero. Adding a check improves robustness against invalid or corrupted tracking data.
if let Some(f_tx) = msr.data.get(&MeasurementType::TransmitFrequency) {
if f_tx.abs() > f64::EPSILON && turnaround_ratio.abs() > f64::EPSILON {
let doppler_shift_hz = f_tx * turnaround_ratio - f_rx;
let rho_dot_km_s = (doppler_shift_hz * SPEED_OF_LIGHT_KM_S)
/ (2.0 * f_tx * turnaround_ratio);
msr.push(MeasurementType::Doppler, rho_dot_km_s);
}
}
Codecov Report❌ Patch coverage is Additional details and impacted files@@ Coverage Diff @@
## master #546 +/- ##
==========================================
- Coverage 79.01% 78.31% -0.71%
==========================================
Files 103 103
Lines 16645 16774 +129
==========================================
- Hits 13152 13136 -16
- Misses 3493 3638 +145 ☔ View full report in Codecov by Sentry. 🚀 New features to boost your workflow:
|
Implemented full support for CCSDS TDM frequency data types (RECEIVE_FREQ, TRANSMIT_FREQ).
This includes simulation, sensitivity calculations for OD, and high-fidelity TDM export/import.
GroundStation now supports optional transmit frequency and turnaround ratio parameters.
TrackingDataArc provides new helper methods for batch conversion between Doppler (km/s) and frequency (Hz) units.
Fixes #392
PR created automatically by Jules for task 14184810549512038715 started by @ChristopherRabotin