Sure thing
So what I did is the following.
Build a StateConverter
interface with a public SpacecraftState convert(SpacecraftState s)
method
Create an AttitudeModel
class which implements AdditionalEquations
, AttitudeProvider
and StateConverter
Modify the AbstractIntegratedPropagator
class of Orekit as follows:
1/ Add this method:
private List<StateConverter> stateConverters;
public void addStateConverter(final StateConverter converter) {
stateConverters.add(converter);
}
2/ Modify this method:
private SpacecraftState convert(final ODEStateAndDerivative os) {
SpacecraftState s = stateMapper.mapArrayToState(os.getTime(), os.getPrimaryState(), os.getPrimaryDerivative(), propagationType);
s = updateAdditionalStates(s);
for (int i = 0; i < additionalEquations.size(); ++i) {
final double[] secondary = os.getSecondaryState(i + 1);
s = s.addAdditionalState(additionalEquations.get(i).getName(), secondary);
}
// TODO: use state converters to update spacecraft state with additional equations
for (StateConverter converter : stateConverters) {
s = converter.convert(s);
}
return s;
}
The problem here is that in AttitudeModel
you will need to store the previously integrated attitudes in a structure such as private TreeMap<AbsoluteDate, Attitude> attitudes;
In AttitudeModel
, each call to the convert
method stores the integrated attitude in the TreeMap
.
@Override
public SpacecraftState convert(SpacecraftState state) {
AbsoluteDate date = state.getDate();
double[] attitudeState = state.getAdditionalState(ATTITUDE_MODEL_KEY);
[...]
Attitude attitude = new Attitude(referenceFrame, orientation);
SpacecraftState newState;
if (state.isOrbitDefined()) {
newState = new SpacecraftState(state.getOrbit(), attitude, state.getMass(),
state.getAdditionalStates());
} else {
newState = new SpacecraftState(state.getAbsPVA(), attitude, state.getMass(),
state.getAdditionalStates());
}
// Update attitudes state map
attitudes.put(date, attitude);
return newState;
}
Finally the getAttitude
methods is as follows:
@Override
public Attitude getAttitude(PVCoordinatesProvider pvProv, AbsoluteDate date, Frame frame) {
AbsoluteDate nearestPreviousDate = attitudes.floorKey(date);
Attitude nearestPreviousAttitude = attitudes.get(nearestPreviousDate);
return new Attitude(date, frame, nearestPreviousAttitude.getOrientation());
}
This can probably be greatly improved. One of the downsizes of this implementation is that it prevents any kind of propagation of the attitude model in the future. A getAttitude
call performed by Orekit at a date where the integration has not been performed yet will return a past attitude. I have not found a way to improve this behavior. My guess is that you would need to modify Orekit a bit more deeply to succeed.