# 4.2. Setting up Observation Models¶

## 4.2.1. Observation Types¶

Tudat supports a diverse set of observation types, which are defined in the ObservableType enum. Below, we provide a list of observable types, with a brief description, as well as the set of link end types that they require:

• one_way_range Range (in meters) between two link ends. Observable has size 1. Requires transmitter and receiver link ends.

• angular_position Right ascension and declination (in radians) of one link end (the transmitter) as observed by other link end (the receiver) as measured in the base frame in which the states of the link ends are defined. Observable has size 2. Requires transmitter and receiver link ends.

• position_observable Three-dimensional position of link end (in m) as measured in base the frame in which the state of the link end is defined. Observable has size 3 (x, y and z components). Requires observed_body link end, which directly defines the body of which an observation is taken. Note that this observable is not realized in practice, but is typically used for testing or analysis purposes. It does not use a light-time calculation.

• one_way_doppler Doppler effect of a signal (dimensionless) between two link ends. Observable has size 1. The value approximately requal to the range-rate between the link ends, divided by c. The full model one-way Doppler observable $$h_{D(1),AB}$$ from link end A to link end B is computed from:

$h_{D(1),AB}=\frac{d\tau_{A}}{dt_{A}}\frac{t_{A}}{dt_{B}}\frac{dt_{B}}{d\tau_{B}}-1$

where $$t$$ and $$\tau$$ denote coordinate anr proper time. The one-way Doppler requires transmitter and receiver link ends.

• two_way_doppler The combined effect from two one-way Doppler effects: one from link end $$A$$ to link end $$B$$, and one from $$B$$ to $$C$$, computed as:

$h_{D(2),ABC}=(h_{D(1),AB}+1)(h_{D(1),BC}+1)-1$

The two-way Doppler requires transmitter, reflector1 and receiver link ends ($$A$$, $$B$$ and $$C$$ in the above example).

• one_way_differenced_range Doppler observable as it is typically obtained in interplanetary tracking in so-called ‘closed-loop’ mode (in m/s) between two link ends. Observable has size 1. The value is computed from the averaged range-rate over some integration time (see below). Requires transmitter and receiver link ends.

• n_way_range Accumulated range (in meters) over any number of signal paths, may be used for two-way range (as in SLR or deep space tracking), as well as more exotic situations where more than 2 signal paths are used in generating the observable (as was the case for, for instance, the SELENE mission) Observable has size 1. The value is computed accumulating the light-time (multiplied by c) with any retransmission delays that the user defines (see below) Requires transmitter, receiver, as well as reflector1, reflector2reflectorX for X+1 signal paths (when only a transmitter and receiver are defined the observation is identical to a one_way_range).

## 4.2.2. Observation Settings¶

The settings for most obsevation model types are provided to an object of the ObservationSettings class, which takes the type of observable, the Light-time Corrections and observation biases Observation Biases. For some observation models, however, specific additional information is required, and a dedicated ObservationSettings derived class is created. Below the input to these classes is discussed in detail.

class ObservationSettings
An ObservationSettings is created as follows:
std::shared_ptr< ObservationSettings > observationSettings =
std::make_shared< ObservationSettings >(
observableType, lightTimeCorrectionsList, biasSettings );


where:

• observableType

ObservableType that defines the type of observable. An ObservationSettings object may be created directly for the following obsevable types:

• one_way_range
• n_way_range (for zero retransmission time)
• angular_position
• position_observable
• one_way_doppler (when using $$d\tau/dt=1$$ for both link ends)
• two_way_doppler (when using $$d\tau/dt=1$$ for all link ends)
• lightTimeCorrectionsList

A list of light-time corrections of type std::vector< std::shared_ptr<'LightTimeCorrectionSettings > > that are used to compute the light-time between the link ends, see Light-time Corrections.

• biasSettings

An object that defines the settings for an observation bias, of type std::shared_ptr< ObservationBiasSettings >, see Observation Biases.

Note that the light-time correction and bias settings are empty by default, so that:

std::shared_ptr< ObservationSettings > observationSettings =
std::make_shared< ObservationSettings >( observableType );


and:

std::shared_ptr< ObservationSettings > observationSettings =
std::make_shared< ObservationSettings >(
observableType, lightTimeCorrectionsList );


may be used as well to create an observation model without light-time corrections or biases (in the case of the former) and no biases (in the case of the latter).

Additionally, a second constructor is provided that takes a single light-time correction setting, instead of a list, as its second argument. So, you may substitute the input of type std::vector< std::shared_ptr< LightTimeCorrectionSettings > > by an input of type std::shared_ptr< LightTimeCorrectionSettings >, in which case you can set only a single light-time correction.

class OneWayDifferencedRangeRateObservationSettings

The OneWayDifferencedRangeRateObservationSettings class is used to define settings for one-way differenced range observables (typically termed one-way Doppler in the deep-space tracking community). An object of this type is created as follows, similar to an ObservationSettings object:

std::shared_ptr< OneWayDifferencedRangeRateObservationSettings > observationSettings =
std::make_shared< OneWayDifferencedRangeRateObservationSettings >(
integrationTimeFunction, lightTimeCorrectionsList, biasSettings );


where no input on the type of observable is given (it is one_way_differenced_range by default). The new input is:

• integrationTimeFunction

std::function< double( const double ) > that returns the integration time of the observable as a function of observation time (function input). In many cases, the integration time will be constant, and you may use a lambda expression, so for a constant 60 s integration time:

std::function< double( const double ) > integrationTimeFunction =
[ = ]( const double ){ return 60.0; };


As is the case for the ObservationSettings class, the second and third constructor arguments are optional, and the second argument may be either a std::vector of std::shared_ptr< LightTimeCorrectionSettings >, or a single such object.

class NWayRangeObservationSettings

The NWayRangeObservationSettings class is used to define settings for n-way range observables. An object of this type is created as follows:

std::shared_ptr< NWayRangeObservationSettings > observationSettings =
std::make_shared< NWayRangeObservationSettings >(
oneWayRangeObsevationSettings, retransmissionTimesFunction, biasSettings );


where no input on the type of observable is given (it is n_way_range by default). The bias settings input is handled in the same way as for the ObservationSettings class (and is again empty by default). The other input arguments are:

• oneWayRangeObsevationSettings

A std::vector< std::shared_ptr< ObservationSettings > > list, that has the observation settings for each leg of the n-way link. Note that the observable type of each of the ObservationSettings in this list must be one_way_range.

• retransmissionTimesFunction

A std::function< std::vector< double >( const double ) > list that returns the retransmission time at each of the intermediate link ends. For instance, for a Graz station -> LRO -> Matera station n-way-range observable, there may be some delay between LRO receiving the signal from Graz, and retransmitting the signal to Matera. The retransmissionTimesFunction list returns this delay as a function of the observation time at the retransmitting link end. As was the case for the integration time in the OneWayDifferencedRangeRateObservationSettings class, you can use lambda expression to define constant retransmission delay. When providing an empty std::vector, no retransmission delay is assumed.

class OneWayDopperObservationSettings

The OneWayDopperObservationSettings class is used to define settings for one-way Doppler observables. Here, the term Doppler is used in the instantaneous sense, and is distinct from what is typically termed Doppler in the deep-space tracking community, which is defined by the OneWayDifferencedRangeRateObservationSettings class. An object of the OneWayDopperObservationSettings type is created as follows:

std::shared_ptr< OneWayDopperObservationSettings > observationSettings =
std::make_shared< OneWayDopperObservationSettings >(


where:

• lightTimeCorrectionsList

A list of light-time corrections of type std::vector< std::shared_ptr<'LightTimeCorrectionSettings > > that are used to compute the light-time between the link ends, see Light-time Corrections.

• transmitterProperTimeRateSettings

An object that defines the settings for the proper time rate $$d\tau/dt$$ of the transmitter, of type std::shared_ptr< DopplerProperTimeRateSettings >, see Proper-time Rate Settings.

• receiverProperTimeRateSettings

An object that defines the settings for the proper time rate $$d\tau/dt$$ of the transmitter, of type std::shared_ptr< DopplerProperTimeRateSettings >, see Proper-time Rate Settings.

• biasSettings

An object that defines the settings for an observation bias, of type std::shared_ptr< ObservationBiasSettings >, see Observation Biases.

class TwoWayDopperObservationSettings

The TwoWayDopperObservationSettings class is used to define settings for two-way Doppler observables:

std::shared_ptr< TwoWayDopperObservationSettings > observationSettings =
std::make_shared< TwoWayDopperObservationSettings >(


where:

• uplinkOneWayDopplerSettings

An object that defines the settings for uplink one-way Doppler, of type std::shared_ptr< OneWayDopperObservationSettings >

• downlinkOneWayDopplerSettings

An object that defines the settings for uplink one-way Doppler, of type std::shared_ptr< OneWayDopperObservationSettings >

• biasSettings

An object that defines the settings for an observation bias, of type std::shared_ptr< ObservationBiasSettings >, see Observation Biases.

### 4.2.2.1. Proper-time Rate Settings¶

When creating a one- or two-way Doppler model, the user can provide settings for the proper time rate model at the link ends, which is handled by the DopplerProperTimeRateSettings class. Each type of proper-time rate model has its own dedicated derived class, which are described below.

class DirectFirstOrderDopplerProperTimeRateSettings

The DirectFirstOrderDopplerProperTimeRateSettings class is derived from DopplerProperTimeRateSettings and defines the proper time rate due to a single static point mass. In this sense, the term ‘static’ indicates that the motion of the body causing a change in proper time rate is not incorporated in the model. An object of this type is created as:

std::shared_ptr< DirectFirstOrderDopplerProperTimeRateSettings > properTimeRateSettings =
std::make_shared< DirectFirstOrderDopplerProperTimeRateSettings >(
bodyName );


where:

• bodyName

An std::string that defines the name of the body that whose mass is causing a proper time rate.

As an example, a one-way Doppler model, where the Earth’s mass is used to perturtb the transmitting station’s proper time rate, and the Moon’s mass the receiver’s proper time rate would be by creating OneWayDopperObservationSettings as follows:

std::shared_ptr< DopplerProperTimeRateSettings > transmitterProperTimeRateSettings =
std::make_shared< DirectFirstOrderDopplerProperTimeRateSettings >( "Earth" );
std::make_shared< DirectFirstOrderDopplerProperTimeRateSettings >( "Moon" );
std::shared_ptr< OneWayDopperObservationSettings > observationSettings =
std::make_shared< OneWayDopperObservationSettings >(
std::vector< std::shared_ptr< LightTimeCorrectionSettings > >, transmitterProperTimeRateSettings, receiverProperTimeRateSettings );


For a case where no light-time corrections, and no observation bias, is used

## 4.2.3. Light-time Corrections¶

When computing the basic light-time between two link ends, the Euclidean distance between them is computed for a signal travelling at exactly c (the speed of light in vacuum). However, various effects must in reality be accounted for to compute the true light time. Tudat currently supports:

• First-order relativistic light-time correction: the correction to the light time of a (set of) stationary point masses, computed up to $$c^{-2}$$ according to general relativity.

As is the case with many other models, a base class settings object is provided LightTimeCorrectionSettings. Specific light-time corrections are defined in derived classes:

class FirstOrderRelativisticLightTimeCorrectionSettings

The FirstOrderRelativisticLightTimeCorrectionSettings defines settings for a first-order relativistic correction to the light-time, as formulated by e.g. Moyer (2000). The class is created by:

std::shared_ptr< FirstOrderRelativisticLightTimeCorrectionSettings > lightTimeCorrectionSettings =
std::make_shared< FirstOrderRelativisticLightTimeCorrectionSettings >(
perturbingBodies );


The input is:

• perturbingBodies

A std::vector< std::string > containing the names of the bodies due to which the light-time correction is to be taken into account.

Note

One ambiguity in the model is the time at which the states of the perturbing bodies are evaluated. We distinguish two cases: one where the perturbing body contains one of link ends, and one where it does not. In the case where the perturbing body contains a link end (for instance perturbation due to Earth gravity field, with one of the link ends being an Earth-based station), the time at which the Earth’s state is evaluated equals the transmission time if Earth acts as transmitter, and reception time if Earth acts as receiver. In other cases, where the perturbing body is not involved in the link ends, its state is evaluated at the midpoint time between transmitter and receiver.

## 4.2.4. Observation Biases¶

Real observations in reality often differ (slightly) from the physical ideal value due to for instance instrumental effects at the link ends. Part of these effects influence the observation in a predictable manner, and can be modelled deterministically. It is these deterministic effects that we collectively term observation biases in Tudat. The stochastic errors are not used as part of the observation model in Tudat, but can be incorporated when simulating observations.

In Tudat, the following types of biases are currently incorporated, where $$h$$ is the physically ideal observation, and $$\tilde{h}$$ is the biases version of the observable.

• Relative bias $$K_{r}$$, which influences the observable as:

$\tilde{h}=h(1+K_{r})$

For an observable with size greater than 1, $$K_{r}$$ is a vector and the multiplication is component-wise.

• Absolute bias $$K_{a}$$, which influences the observable as:

$\tilde{h}=h+K_{a}$

For an observable with size greater than 1, $$K_{a}$$ is a vector and the multiplication is component-wise.

• A combined bias, which is computed from any number of the above bias types combined. Note that each contribution of the combined bias is computed from the unbiased observable, so when applying both a relative and absolute bias, we get:

$\tilde{h}=h+K_{a}+hK_{r}$

And, crucially:

$\tilde{h}\neq (h+K_{a})(1+K_{r})$

As discussed above, the biases are created by passing a ObservationBiasSettings (or derived class) object to the ObservationSettings (or derived class) constructor. Each bias type has a dedicated derived class of ObservationBiasSettings, which are defined as follows:

class ConstantObservationBiasSettings

The ConstantObservationBiasSettings class is used to define settings for an absolute bias $$K_{a}$$ and is created by:

std::shared_ptr< ConstantObservationBiasSettings > observationBiasSettings =
std::make_shared< ConstantObservationBiasSettings >(
observationBias );


The input is:

• observationBias

An Eigen::VectorXd of the same size as the observable (see AAAAA) containing the values of the vector $$K_{a}$$.

class ConstantRelativeObservationBiasSettings

The ConstantRelativeObservationBiasSettings class is used to define settings for an absolute bias $$K_{r}$$ and is created by:

std::shared_ptr< ConstantRelativeObservationBiasSettings > observationBiasSettings =
std::make_shared< ConstantRelativeObservationBiasSettings >(
observationBias );


The input is:

• observationBias

An Eigen::VectorXd of the same size as the observable (see AAAAA) containing the values of the vector $$K_{r}$$.

class MultipleObservationBiasSettings

The MultipleObservationBiasSettings class is used to define settings for a combined bias, that is composed of multiple bias models.

std::shared_ptr< MultipleObservationBiasSettings > observationBiasSettings =
std::make_shared< MultipleObservationBiasSettings >(
biasSettingsList );


The input is:

• biasSettingsList

A std::vector< std::shared_ptr< ObservationBiasSettings > > list containing the bias models to be applied.