pub struct ObserverState {
pub time: Dt,
pub position: Position,
pub velocity: Velocity,
pub grav_potential_m2_s2: f64,
pub characteristic_length_scale: f64,
}Expand description
A complete relativistic state of an observer (spacecraft, ground station, planet, etc.) at a specific instant.
This is the natural input type for all relativistic light-time calculations in the library. It bundles position, velocity, gravitational potential, and an optional length scale in convenient SI units.
Fields§
§time: DtDt of this state (any [Scale] is accepted).
position: PositionPosition in meters (typically barycentric or heliocentric).
velocity: VelocityVelocity in meters per second.
grav_potential_m2_s2: f64Local gravitational potential Φ in m² s⁻² (negative for bound orbits). Usually the sum of contributions from the Sun and planets.
characteristic_length_scale: f64Characteristic length scale (in meters) over which gravity varies
significantly at the observer’s location.
Pass 0.0 (the default) for all solar-system, GNSS, and weak-field cases.
Implementations§
Source§impl ObserverState
impl ObserverState
Sourcepub const fn new(
time: Dt,
position: Position,
velocity: Velocity,
grav_potential_m2_s2: f64,
) -> Self
pub const fn new( time: Dt, position: Position, velocity: Velocity, grav_potential_m2_s2: f64, ) -> Self
Creates a new state for typical solar-system or GNSS use.
Sourcepub const fn new_strong_field(
time: Dt,
position: Position,
velocity: Velocity,
grav_potential_m2_s2: f64,
characteristic_length_scale: f64,
) -> Self
pub const fn new_strong_field( time: Dt, position: Position, velocity: Velocity, grav_potential_m2_s2: f64, characteristic_length_scale: f64, ) -> Self
Creates a new state when strong-field or gravimeter data is available.
Sourcepub const fn proper_time_rate(&self) -> Real
pub const fn proper_time_rate(&self) -> Real
Returns the instantaneous proper-time rate dτ/dt for this observer.
This is the exact rate at which a real clock at the given position, velocity, and gravitational environment would advance compared to coordinate time. It is used internally by the library for proper-time integration, light-time corrections, and Doppler calculations.
Sourcepub const fn relativistic_clock_doppler_factor(&self, rx: ObserverState) -> Real
pub const fn relativistic_clock_doppler_factor(&self, rx: ObserverState) -> Real
Returns the relativistic clock-rate Doppler factor for a one-way signal sent from this transmitter to the given receiver.
The factor is the ratio of the receiver’s proper-time rate to the transmitter’s proper-time rate. It accounts for the fact that clocks at the two locations run at slightly different speeds due to motion and gravity.
To obtain the full observed frequency shift, multiply this factor by
the classical kinematic Doppler term (1 - v_radial / C), where
v_radial is the line-of-sight component of the relative velocity
(positive when the transmitter and receiver are moving apart).
This value is used for deep-space tracking, GNSS range-rate measurements, and pulsar timing.
§Parameters
self– transmitter state (position, velocity, gravitational potential, and length scale at the moment the signal is sent)rx– receiver state (same information, evaluated at the approximate arrival time)
§Example
use deep_time::{ObserverState, Position, Velocity, Dt};
use deep_time::constants::C;
let tx = ObserverState::new(tx_time, tx_pos, tx_vel, phi);
let rx = ObserverState::new(rx_time, rx_pos, rx_vel, phi);
let factor = tx.relativistic_clock_doppler_factor(rx);
// Full observed frequency shift (example only)
let v_radial = 0.0; // m/s, positive if receding
let classical_doppler = 1.0 - v_radial / C;
let total_frequency_shift = 1.0 * factor * classical_doppler;Sourcepub const fn two_way_relativistic_doppler_factor(
&self,
rx: ObserverState,
) -> Real
pub const fn two_way_relativistic_doppler_factor( &self, rx: ObserverState, ) -> Real
Returns the two-way relativistic clock-rate Doppler factor for round-trip ranging (transmit → receive → immediate transponder reply).
This is the product of the one-way factors for the complete round trip and is the value needed by deep-space networks when correcting measured range-rate data.
Sourcepub const fn one_way_relativistic_delay_to(
&self,
rx: ObserverState,
context: LightContext,
) -> TSpan
pub const fn one_way_relativistic_delay_to( &self, rx: ObserverState, context: LightContext, ) -> TSpan
Computes the total relativistic correction that must be added to the Newtonian
geometric light time (|r_rx − r_tx| / c) for a one-way signal.
This function accounts for two physical effects:
- Differential clock-rate drift between transmitter and receiver (special-relativistic velocity + general-relativistic gravitational time dilation) using the library’s unified master-Lagrangian proper-time model.
- Gravitational (Shapiro) delay caused by spacetime curvature near a central mass.
Use cases include:
- Deep-space tracking and ranging (DSN, ESA, JPL)
- GNSS and satellite navigation
- Pulsar timing arrays
- Laser communication or ranging to distant spacecraft
- Future interstellar missions where signals pass near other stars or black holes
§Parameters
self– the transmitter’s full relativistic state at the moment the signal is sentrx– the receiver’s relativistic state at the approximate arrival timecontext– controls the gravitational (Shapiro) contribution. UseLightContext::SOLARfor solar-system work,LightContext::FLATwhen you want no central-mass delay, orLightContext::from_grav_param(your_gravitational_parameter)for any other star, planet, or black hole.
§Returns
A TSpan (in seconds) to be added to the Newtonian geometric light time.
§Examples
Basic usage for a solar-system one-way light-time correction (e.g. Earth to Mars):
use deep_time::{
ObserverState, Position, Velocity, Dt, TSpan, LightContext,
// Assume you have ephemeris functions or constants available
};
let transmitter = ObserverState::new(
tx_time,
tx_pos,
tx_vel,
tx_potential,
);
let receiver_approx = ObserverState::new(
rx_approx_time,
rx_pos,
rx_vel,
rx_potential,
);
// Use SOLAR for Sun-centered calculations
let correction: TSpan = transmitter
.one_way_relativistic_delay_to(receiver_approx, LightContext::SOLAR);
// The result should be added to the Newtonian geometric delay `r_sep / C`For a custom body (e.g. Jupiter):
let jupiter_context = LightContext::from_grav_param(jupiter_gm); // GM in m³/s²
let correction = tx.one_way_relativistic_delay_to(rx, jupiter_context);§Multi-body and exotic environments
This function models the Shapiro delay from only a single central mass
via the supplied LightContext. For signals that pass near multiple massive
bodies (e.g. two stars, a star and a planet, or a binary black-hole system)
or in highly dynamic/strong-field regimes, the single-body approximation may
not be sufficient.
In those cases consider using [one_way_relativistic_delay_integrated] instead,
which lets you supply your own full spacetime model along the entire path.
Alternatively, you can compute individual Shapiro contributions from each body
(using the helper shapiro_one_way_for_body if you add it) and manually combine
them with the result of this function.
Sourcepub fn iterative_one_way_relativistic_delay_to<F>(
&self,
rx_provider: F,
context: LightContext,
tolerance: TSpan,
max_iter: usize,
) -> (TSpan, Dt)
pub fn iterative_one_way_relativistic_delay_to<F>( &self, rx_provider: F, context: LightContext, tolerance: TSpan, max_iter: usize, ) -> (TSpan, Dt)
Iteratively solves for the true receive time and the corresponding relativistic correction for a one-way signal.
Because the exact arrival time depends on the relativistic correction itself, an iterative approach is required. The function typically converges in 3–5 iterations to sub-nanosecond accuracy, even for outer-solar-system distances.
§Parameters
self– the transmitter’s relativistic state (fixed)rx_provider– a closure that, given a guessed receiveDt, returns the fullObserverStateof the receiver at that time. You usually create this closure by calling your ephemeris/orbit propagator.context– gravitational context (LightContext::SOLAR,LightContext::FLAT, or a custom value). See [one_way_relativistic_delay_to] for details.tolerance– maximum allowed change in receive time between iterations (recommendedTSpan::from_ns(1)or tighter)max_iter– safety limit on the number of iterations (recommended 8–12)
§Returns
A tuple (correction, final_rx_time) where:
correctionis the relativistic delay (same as returned by [one_way_relativistic_delay_to])final_rx_timeis the converged receiveDt
§Examples
use deep_time::{ObserverState, Dt, TSpan, LightContext, Position, Velocity};
let transmitter = ObserverState::new(
tx_time,
tx_pos,
tx_vel,
tx_potential,
);
let (correction, final_rx_time) = transmitter.iterative_one_way_relativistic_delay_to(
|guessed_rx_time| {
// Call your ephemeris / orbit propagator here
let (pos, vel, potential) = get_receiver_state_at(guessed_rx_time);
ObserverState::new(guessed_rx_time, pos, vel, potential)
},
LightContext::SOLAR,
TSpan::from_ns(1), // 1 nanosecond tolerance (recommended)
12, // safety limit (recommended)
);
// `correction` is the total relativistic delay (clock drift + Shapiro)
// to add to the Newtonian geometric light time.
// `final_rx_time` is the accurately converged signal arrival time.Using a custom central body (e.g. near Jupiter) and a tighter tolerance:
let jupiter_gm = 1.26686534e17_f64; // m³/s²
let context = LightContext::from_grav_param(jupiter_gm);
let (correction, rx_time) = tx.iterative_one_way_relativistic_delay_to(
rx_provider, context, TSpan::from_ns(0.1), 10
);Sourcepub const fn one_way_relativistic_delay_integrated(
&self,
rx: ObserverState,
context: LightContext,
samples: &[LocalSpacetime],
) -> TSpan
pub const fn one_way_relativistic_delay_integrated( &self, rx: ObserverState, context: LightContext, samples: &[LocalSpacetime], ) -> TSpan
Computes the relativistic correction using numerical quadrature (Simpson’s rule) of the relative clock-rate offset along the entire straight-line light path.
This is the most accurate method when the clock-rate offset varies continuously along the path (long baselines, interstellar distances, or strong-field regions).
§Parameters
self– the transmitter’s relativistic staterx– the receiver’s relativistic statecontext– gravitational context for the Shapiro delay (see [one_way_relativistic_delay_to])samples– a slice ofLocalSpacetimesnapshots uniformly spaced along the path (λ ∈ [0, 1]). You build this slice by evaluating your spacetime model at several points between transmitter and receiver. Even 9–21 samples give excellent accuracy.
§Returns
A TSpan containing the integrated clock-drift correction plus the Shapiro
delay from the supplied context.
§Example of building samples
let samples: Vec<LocalSpacetime> = (0..=15)
.map(|i| {
let lambda = i as f64 / 15.0;
let point = tx.position.lerp(rx.position, lambda);
let phi_over_c2 = compute_total_potential_at(point); // your model
LocalSpacetime::from_potential_velocity_and_scale(
phi_over_c2,
Velocity::ZERO,
0.0, // weak-field
)
})
.collect();§Examples
Full usage example for high-accuracy one-way light-time correction (e.g. interstellar distances or strong gravitational fields):
use deep_time::{
ObserverState, LocalSpacetime, Position, Velocity, Dt,
TSpan, LightContext,
};
let transmitter = ObserverState::new(
tx_time, tx_pos, tx_vel, tx_potential,
);
let receiver = ObserverState::new(
rx_time, rx_pos, rx_vel, rx_potential,
);
// Build uniformly spaced samples along the straight-line path.
// 9–21 points are usually sufficient; use more for interstellar/strong-field cases.
let samples: Vec<LocalSpacetime> = (0..=21)
.map(|i| {
let lambda = i as f64 / 21.0;
let point = transmitter.position.lerp(receiver.position, lambda);
let phi_over_c2 = compute_total_potential_at(point);
LocalSpacetime::from_potential_velocity_and_scale(
phi_over_c2,
Velocity::ZERO, // light itself carries no rest-mass velocity
0.0, // weak-field approximation
)
})
.collect();
let total_correction: TSpan = transmitter.one_way_relativistic_delay_integrated(
receiver,
LightContext::SOLAR,
&samples,
);
// `total_correction` is the integrated clock-drift + Shapiro delay
// to be added to the Newtonian geometric light time.Using a custom central body (e.g. near another star or planet):
let custom_context = LightContext::from_grav_param(star_gm); // GM in m³/s²
let correction = tx.one_way_relativistic_delay_integrated(
rx, custom_context, &samples
);§Multi-body and exotic environments
This function is the recommended choice when a signal passes near multiple
massive bodies (two or more stars, a star and a planet, binary black holes,
etc.) or when operating in strong gravitational fields or highly dynamic
spacetimes. Because you supply your own LocalSpacetime snapshots, each
sample can incorporate the combined gravitational potential, velocity, and
curvature from every relevant body in your model.
In contrast, the faster [one_way_relativistic_delay_to] function only
supports a single central mass via LightContext. For complex geometries
or high-fidelity simulations, this integrated method provides greater
accuracy and flexibility.
Sourcepub const fn round_trip_relativistic_correction(
&self,
round_trip_measured: TSpan,
rx: ObserverState,
context: LightContext,
) -> TSpan
pub const fn round_trip_relativistic_correction( &self, round_trip_measured: TSpan, rx: ObserverState, context: LightContext, ) -> TSpan
Computes the relativistic correction for a two-way round-trip ranging measurement (transmit → receive → immediate transponder reply).
Deep-space networks measure distance by timing a round-trip signal. This function returns the tiny relativistic adjustment that must be subtracted from the raw measured round-trip time to recover the true geometric distance.
§Parameters
self– the transmitter’s relativistic state at send timeround_trip_measured– the raw measured round-trip duration (in seconds)rx– the receiver’s relativistic state (itstimefield is ignored)context– gravitational context for the Shapiro delay (see [one_way_relativistic_delay_to])
§Returns
A TSpan (in seconds) that must be subtracted from the measured round-trip time.
§Examples
Typical usage for deep-space two-way ranging (e.g. Earth to spacecraft or planet via DSN):
use deep_time::{
ObserverState, Position, Velocity, Dt, TSpan, LightContext,
};
let transmitter = ObserverState::new(
tx_time,
tx_pos,
tx_vel,
tx_potential,
);
// Receiver state at approximate arrival time (its `.time` field is ignored)
let receiver_approx = ObserverState::new(
Dt::default(), // dummy time - will be ignored
rx_pos,
rx_vel,
rx_potential,
);
let relativistic_correction = transmitter.round_trip_relativistic_correction(
measured_round_trip,
receiver_approx,
LightContext::SOLAR,
);
// Correct the measured round-trip time:
let corrected_round_trip = measured_round_trip.sub(relativistic_correction);
// Then the true geometric one-way light time and distance can be computed from
// `corrected_round_trip / 2`.Using a custom gravitational context (e.g. ranging to a probe near Jupiter):
let jupiter_context = LightContext::from_grav_param(jupiter_gm); // GM in m³/s²
let correction = tx.round_trip_relativistic_correction(
measured, rx_approx, jupiter_context
);Trait Implementations§
Source§impl Clone for ObserverState
impl Clone for ObserverState
Source§fn clone(&self) -> ObserverState
fn clone(&self) -> ObserverState
1.0.0 (const: unstable) · Source§fn clone_from(&mut self, source: &Self)
fn clone_from(&mut self, source: &Self)
source. Read moreSource§impl Debug for ObserverState
impl Debug for ObserverState
Source§impl PartialEq for ObserverState
impl PartialEq for ObserverState
Source§fn eq(&self, other: &ObserverState) -> bool
fn eq(&self, other: &ObserverState) -> bool
self and other values to be equal, and is used by ==.