Finite Maneuvers Overlap

Hello everyone, I am having a bit of a trouble, trying to identify if two (or more) Maneuvers overlap. I am sharing also a chunk of code just to show the problem.

final FactoryManagedFrame eme2000 = FramesFactory.getEME2000();
final AbsoluteDate date = new AbsoluteDate(new DateComponents(2022, 01, 01),
        new TimeComponents(12, 00, 00.000),
        TimeScalesFactory.getUTC());
KeplerianOrbit orbit = new  KeplerianOrbit(6871000, 0.00101606133264409, 
        FastMath.toRadians(50),
        FastMath.toRadians(0), FastMath.toRadians(45),
        FastMath.toRadians(0), PositionAngle.TRUE,
        FramesFactory.getEME2000(), date, Constants.IERS2010_EARTH_MU);
final SpacecraftState initialState = new SpacecraftState(orbit, 250.0);
final OrbitType orbitType = OrbitType.EQUINOCTIAL;
final double[][] tol = NumericalPropagator.tolerances(1.0, orbit, orbitType);
final AdaptiveStepsizeIntegrator integrator =
new DormandPrince853Integrator(0.1,2.0,tol[0],tol[1]);
final NumericalPropagator propagator = new NumericalPropagator(integrator);
propagator.setOrbitType(orbitType);
propagator.setInitialState(initialState);
Vector3D thrustVector = new Vector3D(0,0,10);
AttitudeProvider attitudeOverride = new LofOffset(FramesFactory.getEME2000(), LOFType.VNC);
final AbsoluteDate firingDate = new AbsoluteDate(new DateComponents(2022, 01,
        01),
        new TimeComponents(12, 05, 00.000),
        TimeScalesFactory.getUTC());

final DateDetector start_fire = new DateDetector(firingDate);
final DateDetector end_fire = new DateDetector(firingDate.shiftedBy(15));
final EventBasedManeuverTriggers triggers = new 
        EventBasedManeuverTriggers(start_fire,
        end_fire, false);
final PropulsionModel propulsionModel =
        new BasicConstantThrustPropulsionModel(thrustVector.getNorm(), 150,
        Vector3D.PLUS_I,
        "apogee-engine");
propagator.addForceModel(new Maneuver(attitudeOverride, triggers,
        propulsionModel));

In this case I am adding to the propagator only one maneuver, but, suppose that now I add another maneuver exactly like the first one:

propagator.addForceModel(new Maneuver(attitudeOverride, triggers,
        propulsionModel));

Now, If I have to decide if the maneuvers overlap, is that a simpler way than taking the maneuver triggers and check if the start trigger of the Nth maneuver is located between the start and end trigger of the first maneuver? (The example is with two maneuvers, but let’s suppose to have 100 maneuvers).
Another point, in this case I used date detectors, but what if the detectors to start/end the maneuver are not date detectors? (Consider for example apside detectors).

I hope that is clear what I want to achieve.
Thank you for your support.

Hi @Gabri,

Welcome to the Orekit community !

I think so… :slight_smile: I will try to re-phrase it: “given a sequence of maneuvers that you added by yourself to a propagator, you want to know if any of the maneuvers overlap”.
Is that it ?
If so, I don’t think there is a better method than the one you mentioned for DateDetectors.
For other types of detectors, I think you will have to first run a propagation and store the events dates and then check afterwards if there is any overlap.
The problem here is that the events are gathered on the fly thus there is no way to know a-priori what time exactly they will occur. Plus the first maneuver(s) can change the date of the next one(s).
Example: two tangential thrust, one at perigee and one at the next apogee, the first one will change the triggered date of the second one.

Just a side note: you’re using the EventBasedManeuverTriggers with DateDetector which is risky.
If you look up the Javadoc of EventBasedManeuverTriggers, it is said that it is based on the sign of the g function and thus it is not suited for DateDetector since they can be positive/negative at the same time.

I suggest you use the DateBasedManeuverTriggers instead. It was made to handle this specific case.
With your code:

final DateBasedManeuverTriggers triggers = new DateBasedManeuverTtriggers(start_fire, 15)

Or you could even use the ConstantThrustManeuver class. With your code:

propagator.addForceModel(new ConstantThrustManeuver(start_fire, 15., thrustVector.getNorm(), 150., attitudeOverride, Vector3D.PLUS_I, "apogee-engine")

Hope this helps,
Maxime

Thank you @MaximeJ, I will apply your advice.
By the way, I did not notice the fact of the date detectors, thank you also for that.

@MaximeJ I will avoid using two date detectors with the EventBasedManeuverTriggers, but is it safe to use a DateDetector as a start trigger and an EclipseDetector as an end trigger? Or also in this case they can be both negative/positive at the same time?
Thank you for your help.

Hi @Gabri,

I would avoid it. The problem with the DateDetector is that it is indeed negative before the date and positive afterwards, but it won’t become negative again. So once you passed the firing stop event, the two detectors will become positive.

As I was looking into the tests of EventBasedManeuverTriggers I saw that there are actually some examples of custom detectors (including a DateIntervalDetector) that may actually help you build the detector you need. See the ConfigurableLowThrustManeuverTest class.

Hi @MaximeJ,
this brings another doubt I have right now.
If I chose two general detectors for my start trigger and end trigger of the maneuver, can’t it happen again that the two detectors are both positive/negative? And if so, what should I do?
I am talking in a general case with every one of the detectors already available (not specific for the date detector).
In case I have the case that before the maneuver both detectors are positive/negative, what should I do?

Hi again @Gabri,

Not sure, it could happen yes. What I’ve seen in the test class linked above is something like this:

private ConfigurableLowThrustManeuver buildApogeeManeuver() {

        final ApogeeCenteredIntervalDetector maneuverStartDetector = new ApogeeCenteredIntervalDetector(halfThrustArc,
                PositionAngle.MEAN, new ContinueOnEvent<>());
        final NegateDetector maneuverStopDetector = BooleanDetector.notCombine(maneuverStartDetector);

Here the firing detector is not build from start/end but directly with an interval where you make sure the g function is positive. And the stop-firing is the opposite event.
By the way I think you could write this last as: final NegateDetector maneuverStopDetector = new NegateDetector(maneuverStartDetector);
Doing this lets you have more control on the value of the g function and avoid mistakes.

Maybe @andfio or @Mikael can give you further details on how this trigger exactly works.

Hello @MaximeJ, sorry for the late reply, I was thinking about how to implement something general that can be used safely.
Can you, @andfio and @Mikael take a look at this implementation and tell me if there is something wrong or if it can be used afely without risking any mistakes?
Thank you very much for your help.
Gabri
finite_manoeuvres_propagation_test.zip (10.2 KB)

Hello, sorry for the late answer.
I wanted to look at your code in details but that will be hard to analyze deeply.
Some advices:

  • I do not recommend to update a date detector during the propagation, we failed to have a robust implementation based on it. You may find some very tricky low level issue.
  • I do not recommend to use complex start/stop detectors in propagation (= combination of more than 2 or 3 detectors). We spent a lot of time to debug conception problems as well as low level issues. We end up simplifying everything by using a state machine, and tuning a propagation for each step, using only the required detectors each time.