Ionosphere free LC

Hi @bcazabonne,

I have used OneWayGNSSPhase or OneWayGNSSRange and have GNSS measurement of a LEO receiver. I need to combine them by using the ionosphere-free combination. Can you please give an example of how to use IonosphereFreeCombination and combine two, e.g., OneWayGNSSRange measurements? I appreciate it.

Best regards
Amir

Hi @AmirAllahvirdi,

The combination of measurements does not depends on the nature of the measurement (Range, Phase, OneWayRange, OneWayPhase, etc.). You must use ObservationData objects to perform the combination of measurements. Each observation in a Rinex file corresponds to an ObservationData when parsing the Rinex file in Orekit. Theforefore, ObservationData are used to build the measurements and they can be combined to build combined measurements.

Please note that the combination of measurements can be performed only if:

  1. You have different observations at different frequencies for a same epoch (e.g. C1 and C2).
  2. And the signal code of the observations is the same. For instance, an iono-free combination cannot be performed between C1 and P2 observations.

If I assume a GPS satellite as emitter of the observations, something like that could answer your question:

    // Satellite system
    final SatelliteSystem system = SatelliteSystem.GPS;

    // Initialize the ionosphere-free combination
    final IonosphereFreeCombination ifComb = MeasurementCombinationFactory.getIonosphereFreeCombination(system);

    // Time scale
    final TimeScale utc = TimeScalesFactory.getUTC();

    // LEO satellite
    final ObservableSatellite receiver = new ObservableSatellite(0);

    // Initialize two random observations
    final AbsoluteDate epoch = new AbsoluteDate("2007-09-27T00:00:00.000", utc);
    final ObservationData obs1 = new ObservationData(ObservationType.C1, 21579415.208, 3, 7);
    final ObservationData obs2 = new ObservationData(ObservationType.C2, 21579420.972, 3, 7);

    // Perform the combination of measurements
    final CombinedObservationData combined = ifComb.combine(obs1, obs2);

    // Build a "ionosphere-free" OneWayGNSSRange measurement
    final OneWayGNSSRange measurement = new OneWayGNSSRange(remote, dtRemote,
                                                            epoch, combined.getValue(),
                                                            1.0, 1.0, receiver);

Here you have a ionosphere-free measurement. Therefore, you don’t need to add a ionosphere measurement modifier to the measurement.

It is also possible to perform the combination of measurements directly on an ObservationDataSet (i.e. list of ObservationData at a same epoch and for a single satellite). The advantage of doing that is that the different verifications (different frequency, same signal code, etc.) is done internally by the algorithm of combination of measurements. At the end, you have a CombinedObservationDataSet containing all the possible ionosphere-free combination of measurements for the given data set. The getMeasurementType() method of CombinedObservationData allow you to know the nature of the combined measurement (Range, Phase, etc.). Here a small example:

    // Read the Rinex file
    final RinexLoader loader = new RinexLoader(...);

    // Loop on observation data set
    for (final ObservationDataSet observationDataSet : loader.getObservationDataSets()) {

        // Initialise a ionosphere-free combination of measurements
        final IonosphereFreeCombination ifComb = MeasurementCombinationFactory.getIonosphereFreeCombination(system);

        final CombinedObservationDataSet combinedDataSet = ifComb.combine(observationDataSet);

        for (final CombinedObservationData cod : combinedDataSet.getObservationData()) {

            // If Range
            if (cod.getMeasurementType() == MeasurementType.PSEUDO_RANGE) {
                // Initialize a OneWayGNSSRange
            } else if (cod.getMeasurementType() == MeasurementType.CARRIER_PHASE) {
                // Initialize a OneWayGNSSPhase
        }

    }

Best regards,
Bryan

1 Like

Thank you @bcazabonne

Dear @bcazabonne

I have extracted the ionosphere-free combination of the GNSS code and phase measurements. At each epoch, I want to estimate the orbit (position and velocity), propagation (SRP and drag coefficients and 3 polynomial accelerations), and measurement (receiver clock offset and ambiguities) parameters. All of the estimated drivers are set to “true”.

Now I want to run the EKF: First, the Kalman filter is built (similar to AbstractOrbitDetermination.java. Then, all measurements in each epoch are processed by calling processMeasurements. I checked the KalmanEstimator.java, it processes the observation one by one in estimationStep. Is it correct for GNSS observations?

Imagine that in one epoch, we have 20 IF code and phase measurements. So we have 6 (orbit) + 5 (propagation) + 1 (clock offset) + 10 (ambiguities) that should be estimated. 6 orbital parameters are integrated from the initial orbit, and the others should be estimated, right? I guess at each epoch, it should process all measurements to estimate all unknown parameters. I know the theory, but I can not implement it in Java. Can you please help me with this matter? I appreciate it. (Please note that I followed KalmanNumericalOrbitDetermination you provided in the tutorials)

Best regards
Amir

Hi @AmirAllahvirdi

Please note that we will add in 10.3 version a new implementation for empirical forces. I allows estimating different empirical coefficients for each day or each orbit or each “what you want”. The new implementation is available in develop branch in org.orekit.forces.empirical package.

Using EKF is a good solution since you have to reinitialize ambiguity drivers each cycle slips.

Questions: Because you have different measurements for a same epoch, are you using MultiplexedMeasurement class in order to take advantage of the diversity of the measurement at same epoch?

EKF must estimated all the parameters. In that case, the size of your state vector is equal to 22.

That’s probably here that you will take advantage of the MultiplexedMeasurement class. That class allows regrouping all the measurements at same epoch into one measurement. The dimension of that measurement is equal to the number of observations at same epoch.

Best regards,
Bryan

Dear @bcazabonne,

Thank you. I checked the MultiplexedMeasurement class, and have a question:

After using this class, Why the modifiers are empty? In this case, how can I apply modifiers to the measurements in the Kalman filter?

Regards,
Amir

In reality they are present, but not a the MultiplexedMeasurement level.

Because you can have different modifiers for measurements in a same multiplexed measurement, the modifiers are not associated to the multiplexed measurement but to the measurements inside the multiplexed measurement. That’s why if you call multiplexedMeasurement.getModifiers() you have an empty list.

For instance, considering a Range and a Phase measurement at a given epoch, you will build your MultiplexedMeasurement with the two previous. As you don’t want to consider a PhaseAmbiguityModifier for the Range measurement, that’s why the modifiers are not at the MultiplexedMeasurement level but at the measurement level (i.e. here the PhaseAmbiguityModifier is associated with the Phase measurement).

If you look at the MultiplexedMeasurement class

    for (int i = 0; i < observedMeasurements.size(); ++i) {

        // filter states involved in the current measurement
        ...

        // perform evaluation
        final EstimatedMeasurement<?> eI = observedMeasurements.get(i).estimate(iteration, evaluation, filteredStates);
        estimatedMeasurements.add(eI);

        // extract results
        ...

        // extract states
        ...

    }

You can see that, for each observed measurement inside the multiplexed measurement, the corresponding .estimate(...) method is called. Therefore, the observed measurement modifiers are applied.

Best regards,
Bryan

1 Like