Setting Attitude Provider to a BoundedPropagator

Hi Forum,

I am trying to simulate and compare multiple attitude modes of a spacecraft.

So I have a Numerical propagator (set to ephemeris mode) which I use to propagate and get the BoundedPropagator (using getGeneratedEphemeris() method). Then I change the attitude provider of the BoundedPropagator by calling setAttitudeProvider(). However, I noticed that the BoundedPropagator that I get has the same attitude provider as my numerical propagator and I am not able to change it even after calling setAttitudeProvider(). Is this expected?

After a quick look, it seems like a bug to me.

Could you try the following:

  • remove the final' in the declaration of attitudeProviderinorg.orekit.propagation.integration.StateMapper`
    (line 43)
  • in the same StateMapper class, add a new method
    /** Set attitude provider.
     * @param attitudeProvider attitude provider
     */
    public void setAttitudeProvider(final AttitudeProvider attitudeProvider) {
        this.attitudeProvider = attitudeProvider;
    }
  • in class org.orekit.propagation.integration.IntegratedEphemeris add a method:
    /** {@inheritDoc} */
    @Override
    public void setAttitudeProvider(final AttitudeProvider attitudeProvider) {
        super.setAttitudeProvider(attitudeProvider);
        mapper.setAttitudeProvider(attitudeProvider);
    }

If this works, then open a bug report with a reference to this topic

@luc, I have tried to incorporate your suggestion but I ended up with a NullPointerException. I am attaching the changes I did and the stacktrace to debug,

Try to protect line 220 in IntegratedEphemeris.java so the method reads:

/** {@inheritDoc} */
    @Override
    public void setAttitudeProvider(final AttitudeProvider attitudeProvider) {
        super.setAttitudeProvider(attitudeProvider);
        if (mapper != null) {
            // at construction, the mapper is not set yet
            // but if attitude provider is changed afterwards, it must be changed in the mapper too
            mapper.setAttitudeProvider(attitudeProvider);
        }
    }

@luc, That seems to just work fine, Thank you.

I’ll go ahead and open a bug report linking this discussion.

Meanwhile, I wanna understand if there is a way to get a copy of the BoundedPropagator object so I can work on multiple ephemeris concurrently. What I am looking for is,

    ephemeris_1 = propagator.getGeneratedEphemeris()
    ephemeris_2 = propagator.getGeneratedEphemeris()
    ephemeris_1.setAttitudeProvider(sun_pointing)
    ephemeris_2.setAttitudeProvider(nadir_pointing)

Is it possible to get a copy of the Generated ephemeris?

There is no straightforward way to do this, and it would involve some changes in Hipparchus too. The rationale is that for integrated ephemeris, what is stored in the ephemeris are all the step interpolators generated by the ODE integrator for each step, and all these interpolators are specific to each integrator (Runge Kutta, Dormand Prince, Gragg Bulirsch Stoer, Adams Bashforth, Adams Moulton and more…).

What you may try is a trick to serialize and deserialize in memory. I am not sure it will work in all cases, as some parts may be non-serializable. Here is a code snippet that may help:

    ByteArrayOutputStream bosEphem = new ByteArrayOutputStream();
    ObjectOutputStream    oosEphem = new ObjectOutputStream(bosEphem);
    oosEphem.writeObject(originalEphem);
    ByteArrayInputStream  bisEphem = new ByteArrayInputStream(bosEphem.toByteArray());
    ObjectInputStream     oisEphem = new ObjectInputStream(bisEphem);
    BoundedPropagator deserializedEphem  = (BoundedPropagator) oisEphem.readObject();

You may use try-with-resource to wrap the various streams and close them properly.

Luc’s trick will work but will also use double the memory since ephemeris will be stored twice in memory.

It might be possible to create a new Propagator instance (that can have separate attitude, event detectors, step handlers, etc.) from the same underlying ephemeris data since the ephemeris data can’t be modified. Gowtham, if memory is an issue for you or you would like a more official API you can create a feature request for this.

Another trick that might work is to create several AggregateBoundedPropagator from a single generated ephemeris. They should use the same backing data in memory and be able to have separate attitude providers.