ImpulseManeuver on PositionAngle with Python wrapper

Hello everyone, I hope you are well.

I am trying to execute an ImpulseManeuver triggered by a certain PositionAngleDetector near a certain date. I am working with the Orekit Python wrapper. But when I execute my code, I get a NullPointerException on line 150 of EventEnablingPredicateFilter.java

This is very reminiscent of this issue, but not quite the same. In my case, the PositionAngleDetector is wrapped in an EventEnablingPredicateFilter. I have tried the same workaround (running init() explicitely on the detector, in my case the filter) but it does not seem to work.

My guess is that EventEnablingPredicateFilter suffers from an issue similar to the PositionAngleDetector issue that has been fixed.

I have put together a minimal example that reproduces my issue. It can be consulted directly online on mybinder.org:
Binder
Feel free to make changes to the notebook and restart it: mybinder creates a dedicated copy for each visitor.

Any idea for a workaround ?

Hi,

Not that it fixes it but the parameters for def eventIsEnabled should include self/this, (self, state, eventDetector, g). Note you are using “this” in the functioncall. But this does not seem to solve it.

class CloseToDatePredicate(PythonEnablingPredicate):
    def __init__(self, date: AbsoluteDate, tolerance_seconds: float):
        self.date = date
        self.tolerance_seconds = tolerance_seconds

def eventIsEnabled(self, state, eventDetector, g):
    return abs(state.getDate().durationFrom(self.date)) <= self.tolerance_seconds

There is maybe something odd with the predicate. If you print this one gets:
print(predictate)
<CloseToDatePredicate: < null> >

Not sure this is right. Need to continue some other day…

Ah, and when implementing a custom init there needs to be a call to super to get the full class setup:

class CloseToDatePredicate(PythonEnablingPredicate):
    def __init__(self, date: AbsoluteDate, tolerance_seconds: float):
        self.date = date
        self.tolerance_seconds = tolerance_seconds
        super(CloseToDatePredicate, self).__init__()

        
    def eventIsEnabled(self, state, eventDetector, g):
        print(state.getDate())
        return abs(state.getDate().durationFrom(self.date)) <= self.tolerance_seconds

With this it works.

The online notebook through Binder was a really good way to troubleshoot!

Awesome, thank you very much @petrus.hyvonen ! Orekit community support is impressive as always.

I should have insisted more on the Python side of things, since I clearly struggled to put together the subclassing. I had played a bit with the init method and the of_ method as I suspected an issue with the Java generic types. But since the symptom was so similar to issue #663 I jumped to a bad conclusion. I made a false bug accusation, for which I must apologize sincerely !

What would you think of putting the updated example into the Python Wrapper documentation ? I noticed that the basic tutorial has no code sample for interface subclassing. This example is maybe a bit more complex, but I think it is a fairly common use case to implement a maneuver at a certain position angle. I can make the change if you agree.

Binder is indeed very well put together. Maybe we could consider offering the Python Orekit tutorials on it as well ? The main drawback is that, as far as I know, it works only with github repositories.

Thanks again.

After a more thorough check, it turns out I was wrong : binder has an option for custom git repositories.

Yes, the examples in the repo can be executed in the binder. Good for entry level and education, and actually for troubleshooting as well as it is a pretty “clean” environment and can help if one isn’t sure if it is the local installation or a library bug.

I’ve made some updates to the Basics notebook with subclassing, but will look after a more functioning example of it.