Question About Redesign of Measurements Package

All

As I mentioned a while back, I needed to redesign the TDOA/FDOA classes in estimation/measurements to accept space receivers as well as ground receivers. I have done the core code restructuring work that I needed to do for my own simulations, essentially by creating an abstract class ObservationObject from which ground observers and satellite observers inherit. The code for all the various measurement classes (TDOA, FDOA, Phase, Range, etc.) has been redesigned to simply accept an ObservationObject without needing to know if it’s on the ground or space, with the exception of a few specific types of measurements (specifically AzEl, RaDec, and the GNSS measurement classes) that seem to really only apply to GroundStations or Satellite observers, not both.

However, one of the big questions that has come up in the overall redesign are the ionospheric/tropospheric modifications in estimations/measurements. Right now all of that code assumes the observing object is going to be on the ground. Now that it is possible for the observing object to be in space, I was wondering if you would like me to implement code in the Satellite observation object that would allow the ionospheric and tropospheric modifiers to function with a Satellite observation object as the input, or if you would prefer that this code assume the observer is still a GroundStation by using upcasting.

Thanks

Brianna

In fact, there is a way to use inter-satellite ionospheric effects.
I thought I put that back into Orekit, but it seemed I only did it in a TAS project. I will try to move it there.

The method is pretty straightforward: once you have the two endpoints (emitter and receiver), you transform them in body frame and call OneAxisEllipsoid.lowestAltitudeIntermediate(emitterBody, receiverBody) to get the lowest GeodeticPoint along the signal path. Then you can create a temporary TopocentricFrame for this intermediate point. Once you have this, you split the path in two legs joined at this lowest point. You can compute the ionospheric delay in the two-leg signal path (or one-leg only if lowest point is very close to either emitter or receiver, which typically happens if emitter is a MEO GNSS and receiver is a LEO). The total delay is just the sum of the delays along each leg. The lowest point and topocentric frame are just simple throw-away objects, they do not add too much overhead and this allows to still use the existing API for ionospheric models.

This method could probably be applied to tropospheric effects too as range/range-rate/phase are only based on delays. It would be difficult to do that for angular measurements, but for now we don’t support on-board angular measurements.

But do you want me to add that capability? The reason I asked is because when I was looking at how to go about it for the design, I was concerned that initializing a OneAxisEllipsoid with all the ITRF data would be a significant computational load, and if both emitter and receiver are in space I might be doing a lot of computational work for very little gain.

You are right, but all the ionospheric models I know about are indeed Earth-related, so you can’t avoid the frames conversions.

1 Like

@luc after rethinking my approach I think I’ve hit on a redesign method that actually works quite well. Essentially, it involves adding the OneAxisEllipsoid earth body to the ionospheric/tropospheric models so that it does not need to be introduced by the measurement or by the observing object. Preliminary tests look good, and it should allow the ionospheric/tropospheric models to be applied without prejudice to both ground and space-based measurements (e.g. OneWayGNSSRange).

1 Like

I like the idea.
Does it imply changing the models API or only the loaders API to pass the ellipsoid at load/build time? We can of course change API as we are going to do a major release, so it would be the right time to do it.

I changed IonosphericModel from an interface to a class, modified the constructors to accept a OneAxisEllipsoid input in the child/parent classes and then added a method to retrieve the value to the parent class:

    public KlobucharIonoModel(final OneAxisEllipsoid earth,
                              final double[] alpha,
                              final double[] beta,
                              final TimeScale gps) {
        super(earth);
        this.alpha = alpha.clone();
        this.beta  = beta.clone();
        this.gps = gps;
    }
public abstract class IonosphericModel implements ParameterDriversProvider {

    /** Stores earth data. */
    private final OneAxisEllipsoid earth;

    /** Simple constructor.
     * @param name name of receiver
     * @since 14.0
     */
    public IonosphericModel(final OneAxisEllipsoid earth) {
        this.earth = earth;
    }

    /** Get the earth body shape for earth-frame calculations
     * @return earth body shape
     * @since 14.0
     */
    public final OneAxisEllipsoid getEarth() {
        return earth;
    }

I would prefer to have IonosphericModel still be an interface, and add an AbstractIonosphericModel base class between this interface and the existing models.
The getEarth() could be moved up to the interface level if needed.

1 Like

No problem, that’s easy enough. Just to ask, is there a particular reason you want to preserve IonosphericModel as an interface?

It is a general design choice I often make. It allows for example to have one custom object implement several interfaces at once (but Java doesn’t allow multiple inheritance).

1 Like

Hi,

I think in java it’s good practise to handle Interface at high level. They simply defined the must have capabilities. Implementation details are left to the inheritors. And for unit tests you can just mock them.
So yeah I agree with Luc, we shouldn’t ditch an Interface for an abstract class, if we had the latter we still keep the former.

Cheers,
Romain.

@luc @Serrof what about the tropospheric models? Ionosphere can go up to hundreds of kilometers, so it makes sense that a space-space transfer can be affected. But troposphere doesn’t really go up to more than 15-20 km max. The number of cases affected by the lack of an abstracted tropospheric modifier are going to be pretty slim. In addition, the calculation methods themselves tend to assume your estimated object is in space and the observing object is on the ground (for example, the ModifiedSaastomoinenModel assumes a min elevation of 5 degrees, but for a space-space case the elevation of both space objects with respect to the minimum altitude point would by definition be 0 deg). I can change the code, but do we want to bother?

I agree, and for the project I work on at TAS, I didn’t set up tropospheric corrections for inter-satellite measurements. I think we can safely ignore this case until someone uses Orekit for stratospheric balloons.

For the record, a long time ago someone told us our magnetic field models failed under the surface of Earth: he used Orekit for cave mapping using a magnetometer; we clearly did not anticipate this use case!

1 Like