pub struct ObserverState {
pub time: Dt,
pub position: Position,
pub velocity: Velocity,
pub grav_potential_m2_s2: Real,
pub characteristic_length_scale: Real,
}Expand description
A snapshot of an observer’s relativistic state at a specific instant.
ObserverState combines time, position, velocity, and local gravitational
information. It is the main input type used by relativistic light-time
methods in this library.
Fields§
§time: DtThe time of this state.
Any [Scale] is accepted. This time is treated as coordinate time
for light-time calculations.
position: PositionPosition of the observer in meters.
Typically expressed in a barycentric (solar-system barycenter) or heliocentric frame, depending on the application.
velocity: VelocityVelocity of the observer in meters per second.
grav_potential_m2_s2: RealNewtonian gravitational potential Φ at the observer’s location (in m² s⁻²).
This value is usually negative for bound orbits. It should normally include contributions from the Sun and all relevant planets.
characteristic_length_scale: RealCharacteristic length scale (in meters) over which the gravitational field varies significantly at this location.
- Use
0.0(the default) for all solar-system, GNSS, and weak-field applications. - Provide a non-zero value only when working in strong gravitational fields (e.g. near neutron stars or black holes), where the library’s higher-order curvature terms become relevant.
Implementations§
Source§impl ObserverState
impl ObserverState
Sourcepub const fn new(
time: Dt,
position: Position,
velocity: Velocity,
grav_potential_m2_s2: Real,
) -> Self
pub const fn new( time: Dt, position: Position, velocity: Velocity, grav_potential_m2_s2: Real, ) -> Self
Creates a new ObserverState for typical solar-system, GNSS,
or weak-field use.
This is the recommended constructor for most applications.
It sets the characteristic_length_scale to 0.0, which disables
higher-order curvature terms in the proper-time model.
§Parameters
time: The time of the state.position: Position in meters (usually barycentric or heliocentric).velocity: Velocity in m/s.grav_potential_m2_s2: Newtonian gravitational potential Φ at the location (in m²/s²).
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 value indicates how fast a physical clock located at this state
would advance relative to the time used by this ObserverState.
A returned value of 1.0 means the clock advances at the same rate
as the state’s time coordinate. Values are typically slightly different
from 1.0 due to the effects of velocity and gravitational potential.
This rate is computed using the library’s unified proper-time model. It is used internally for light-time corrections and Doppler calculations.
Sourcepub const fn relativistic_clock_rate_ratio(&self, rx: ObserverState) -> Real
pub const fn relativistic_clock_rate_ratio(&self, rx: ObserverState) -> Real
Returns the ratio of proper time rates between the receiver and transmitter for a one-way signal.
This method computes:
ratio = rx.proper_time_rate() / self.proper_time_rate()§Interpretation
- A value of
1.0indicates that both clocks run at the same rate. - A value less than
1.0means the receiver’s clock runs slower than the transmitter’s clock. The receiver will observe a lower frequency than was emitted. - A value greater than
1.0means the receiver’s clock runs faster than the transmitter’s clock. The receiver will observe a higher frequency than was emitted.
The ratio captures the combined effect of special-relativistic time dilation (due to velocity) and general-relativistic gravitational time dilation.
§Typical Usage (One-Way)
This ratio is often combined with the classical kinematic Doppler term to estimate the total one-way frequency shift:
approximate_frequency_shift ≈ ratio * (1 - v_radial / C)where v_radial is the radial velocity (positive when the receiver is
receding).
§Two-Way Usage
For round-trip (two-way) measurements, square the one-way ratio:
let one_way_ratio = transmitter.relativistic_clock_rate_ratio(receiver);
let two_way_ratio = one_way_ratio * one_way_ratio;This pattern is commonly used when correcting two-way Doppler (range-rate) data for relativistic clock effects.
§Limitations
- This method only accounts for the difference in clock rates between the two ends.
- It does not include Shapiro delay or higher-order relativistic effects on signal propagation.
- The combination with classical Doppler shown above is a first-order approximation.
§Parameters
self— Transmitter state at the time of transmission.rx— Receiver state at the approximate time of reception.
§Example
let ratio = transmitter.relativistic_clock_rate_ratio(receiver);
let v_radial = ...; // m/s, positive if receding
let classical_doppler = 1.0 - v_radial / C;
let approx_frequency_shift = ratio * classical_doppler;Sourcepub const fn one_way_relativistic_delay(
&self,
rx: ObserverState,
bodies: &[(Dt, Position)],
) -> Dt
pub const fn one_way_relativistic_delay( &self, rx: ObserverState, bodies: &[(Dt, Position)], ) -> Dt
Computes the combined one-way relativistic correction for a signal traveling from this observer (the transmitter) to a receiver.
This value is the total extra time you should add to the Newtonian
geometric light travel time (distance / speed of light). It includes
two separate relativistic effects:
- The gravitational propagation delay (Shapiro delay) caused by the Sun and other bodies slowing the signal.
- The differential clock-rate correction caused by the transmitter and receiver having slightly different proper-time rates (due to their velocities and gravitational potentials).
In other words, this method gives you propagation delay + clock-rate correction in one convenient call.
Important: This is a convenience method. It is provided so you can
get the full one-way relativistic correction quickly. If you need
strict separation of the two effects (for example, to apply them at
different stages of your calculation), call
Self::shapiro_delay and Self::compute_differential_clock_correction
individually and add the results yourself.
§When to use this method
Use this when you need the complete relativistic correction for one-way light time in a single step — for example when:
- Computing high-precision one-way range or Doppler observables
- Building simplified navigation or orbit determination models
- You want the total effect without manually combining the pieces
§The bodies parameter – which masses to include
Pass a slice of (shapiro_coefficient, body_position) pairs:
shapiro_coefficient: How strong the delay from this body should be. It equals2GM / c³. UseDt::SHAPIRO_SOLARfor the Sun, or [Dt::shapiro_from_grav_param(gm)] for any other body.body_position: Where the center of that body is located at the relevant time.
Important: All positions must be measured the same way
The transmitter position (self.position), the receiver position
(rx.position), and every body_position you provide must all be
measured from the same point in space, and they must all use
the same directions for their X, Y, and Z axes.
For example, if your transmitter position is measured from the center of the solar system, then the receiver and body positions must also be measured from the center of the solar system using the same pointing directions for the coordinate axes.
In most solar-system work, people use positions from JPL ephemerides (which are measured from the center of the solar system).
Pass an empty slice (&[]) to turn off the Shapiro (gravitational)
part of the correction.
§Parameters
rx— Receiver state at the approximate time the signal arrives.bodies— List of bodies that should contribute to the gravitational propagation delay.
§Returns
The total one-way relativistic correction (Shapiro propagation delay
plus differential clock-rate correction), expressed as a Dt in the
same time scale as self.time.
This value should normally be added to the Newtonian geometric light time.
Sourcepub fn iterative_one_way_light_time_to<F>(
&self,
rx_provider: &mut F,
bodies: &[(Dt, Position)],
tolerance: Dt,
max_iter: usize,
) -> (Dt, Dt, ObserverState)
pub fn iterative_one_way_light_time_to<F>( &self, rx_provider: &mut F, bodies: &[(Dt, Position)], tolerance: Dt, max_iter: usize, ) -> (Dt, Dt, ObserverState)
Iteratively solves the one-way light-time equation in coordinate time, including relativistic propagation corrections, until convergence.
This solver computes the receive epoch t_rx such that:
t_rx = t_tx + |r_rx(t_rx) − r_tx(t_tx)| / c + Δt_shapiro(t_tx, t_rx)It performs fixed-point iteration using the propagation delay returned by
Self::shapiro_delay. Clock-rate and proper-time effects
are not included in the iteration; they should be applied separately
when converting between coordinate time and proper time or when forming
observables.
The solver is suitable for high-precision one-way light-time calculations and works with any ephemeris source via the provided closure.
§Parameters
rx_provider— Closure returning the fullObserverStateof the receiver at a given coordinate time.bodies— Slice of(shapiro_coefficient, body_position)pairs controlling the Shapiro contribution. Use&[(Dt::SHAPIRO_SOLAR, sun_pos)]for solar-system work; include additional bodies for higher precision. Pass&[]to disable Shapiro.tolerance— Maximum allowed change in receive time per iteration before declaring convergence (e.g.Dt::from_ns(1, Scale::TAI)).max_iter— Maximum number of iterations. Typical values are 12–20 for solar-system geometries.
§Returns
A tuple (prop_correction, rx_time, final_state) where:
prop_correctionis the converged Shapiro propagation delay,rx_timeis the converged receive time (same scale asself.time),final_stateis the receiver state atrx_time.
Sourcepub fn round_trip_light_time_correction<RxF, TxF>(
&self,
rx_provider: RxF,
tx_provider: TxF,
bodies: &[(Dt, Position)],
tolerance: Dt,
max_iter: usize,
) -> Dt
pub fn round_trip_light_time_correction<RxF, TxF>( &self, rx_provider: RxF, tx_provider: TxF, bodies: &[(Dt, Position)], tolerance: Dt, max_iter: usize, ) -> Dt
Computes the total Shapiro (gravitational propagation) delay for a complete round-trip (two-way) signal.
This method solves the uplink and downlink legs separately and independently using the iterative light-time solver. This approach is more accurate than older combined round-trip formulas when the two ends have significantly different velocities or are in different gravitational environments.
The returned value is the sum of the uplink and downlink Shapiro delays only. It does not include clock-rate or proper-time corrections.
§When to use this method
Use this when you need the total gravitational propagation correction for two-way (round-trip) measurements, for example:
- Two-way range or range-rate (Doppler) data
- Transponded signals from spacecraft
- Any high-precision two-way light-time calculation
For one-way signals, use Self::shapiro_delay or
Self::one_way_relativistic_delay instead.
§How the calculation works
- Solves the uplink leg (from
selfto the remote receiver) using therx_providerclosure. - Obtains the accurate receiver state at the uplink arrival time.
- Solves the downlink leg (from the receiver back to the local
transmitter) using the
tx_providerclosure.
§The bodies parameter – which masses to include
Pass a slice of (shapiro_coefficient, body_position) pairs (the
same slice is used for both legs). See Self::shapiro_delay for
details on how to build this slice.
Important: All states returned by the providers must be consistent with the same reference frame (same origin and same coordinate axes).
§Parameters
rx_provider— Closure that returns the fullObserverStateof the remote receiver (planet, spacecraft, etc.) at any given coordinate time.tx_provider— Closure that returns the fullObserverStateof the local transmitter at any given coordinate time (used only for the downlink leg).bodies— Slice of(shapiro_coefficient, body_position)pairs describing the gravitating bodies.tolerance— Convergence tolerance for each leg’s iterative solver (e.g.Dt::from_ns(1, Scale::TAI)).max_iter— Maximum number of iterations allowed per leg (typical values are 12–20).
§Returns
The total round-trip Shapiro propagation delay (uplink + downlink)
as a Dt, in the same time scale as self.time.
This value should normally be added to the Newtonian geometric round-trip light time. Clock-rate corrections must still be applied separately (e.g. by squaring the one-way clock-rate ratio).
Sourcepub const fn shapiro_delay(
&self,
rx: ObserverState,
bodies: &[(Dt, Position)],
) -> Dt
pub const fn shapiro_delay( &self, rx: ObserverState, bodies: &[(Dt, Position)], ) -> Dt
Computes the one-way gravitational propagation delay (Shapiro delay) caused by massive bodies between this observer (the transmitter) and a receiver.
This value is the extra time a radio signal takes to travel because
gravity from the Sun and planets slightly slows it down. You normally
add this delay to the ordinary geometric light travel time
(distance / speed of light) to get a more accurate total one-way
signal travel time.
Important: This method returns only the gravitational
propagation delay. It does not include clock-rate differences
between the transmitter and receiver caused by velocity or gravity.
Those effects are available separately through
Self::compute_differential_clock_correction,
Self::proper_time_rate, and Self::relativistic_clock_rate_ratio.
§When to use this method
Use this when you need the gravitational (Shapiro) contribution to one-way light time — for example when building high-precision range, Doppler, or orbit determination models.
§The bodies parameter – which masses to include
Pass a slice of (shapiro_coefficient, body_position) pairs:
shapiro_coefficient: How strong the delay from this body should be. It equals2GM / c³. UseDt::SHAPIRO_SOLARfor the Sun, or [Dt::shapiro_from_grav_param(gm)] for any other body.body_position: Where the center of that body is located at the relevant time.
Important: All positions must be measured the same way
The transmitter position (self.position), the receiver position
(rx.position), and every body_position you provide must all be
measured from the same point in space, and they must all use
the same directions for their X, Y, and Z axes.
For example, if the transmitter position is measured from the center of the solar system, then the receiver and body positions must also be measured from the center of the solar system, using the same pointing directions for the coordinate axes.
If the positions come from different measurement systems, the calculated delay will be wrong.
In most solar-system work, people use positions from JPL ephemerides (which are measured from the center of the solar system).
Pass an empty slice (&[]) to turn off Shapiro delay entirely.
§Parameters
rx— Receiver state at the approximate time the signal arrives.bodies— List of bodies that should contribute to the delay.
§Returns
The total one-way Shapiro gravitational propagation delay, in the
same time scale as self.time. This value should normally be
added to the Newtonian geometric light time.
Sourcepub const fn compute_differential_clock_correction(
&self,
rx: ObserverState,
) -> Dt
pub const fn compute_differential_clock_correction( &self, rx: ObserverState, ) -> Dt
Computes the differential proper-time correction between self
(transmitter) and rx (receiver) over the interval between their
time tags.
This returns the difference in proper time advance between the two observers. It does not include Shapiro propagation delay.
The result can be added to the output of Self::shapiro_delay
or Self::iterative_one_way_light_time_to when a combined
relativistic correction (propagation + clock rate) is required.
§Parameters
rx— Receiver state at the approximate time of reception.
§Returns
The differential clock-rate correction (rx_proper_advance − tx_proper_advance).
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<'de> Deserialize<'de> for ObserverState
impl<'de> Deserialize<'de> for ObserverState
Source§fn deserialize<__D>(__deserializer: __D) -> Result<Self, __D::Error>where
__D: Deserializer<'de>,
fn deserialize<__D>(__deserializer: __D) -> Result<Self, __D::Error>where
__D: Deserializer<'de>,
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 ==.