PropagatorsParallelizer

Hi Everyone, I’m starting to get my bearings with Orekit (using python) and am now pushing into more complex scenarios with multiple satellites. I’ve tried using the parallelizer like so:

iniDate = datetime_to_absolutedate(sce.time[0])
finDate = datetime_to_absolutedate(sce.time[1])

propagators = [sce.spacecraft[0].state,
               sce.spacecraft[1].state]

step_handler = MultiSatStepHandler(propagators, iniDate)
master_loop = PropagatorsParallelizer(propagators, step_handler)
master_loop.propagate(iniDate, finDate)

But get a “not implemented” error when calling the MultiSatStepHandler. I’ve also tried calling PropagatorParallelizer without the 2nd argument but that gave me an invalid argument error. Could someone point me in the right direction with an example? Thanks!

Hi @Sydra,

I am a big noob in Python. But I can try to help you.

MultiSatStepHandler is an Orekit Java interface. Therefore, you must implement it. This interface has 2 methods. A default one, init(), that you may not implement and another one that must be implemented handleStep(). That is probably the reason why you have a “not implemented” error. Please note that the implementation of the handleStep() method can be empty. if you don’t want to perform any action at the integration steps (an action can be printing satellites orbits for instance).

To implement the Orekit MultiSatStepHandler class in Python, you will need to implement the Python class PythonMultiSatStepHandler (Python wrapping). Here an example developed by @petrus.hyvonen showing how to implement a Python handler. The example is for a PythonOrekitFixedStepHandler but this is the same method for the PythonMultiSatStepHandler.

Kind regards,
Bryan

1 Like

Hi!

Yes, @Brian is likely on the right path. I haven’t used MutiSatStepHandler (yet but it looks very interesting). In the java test examples (which is a good source of examples) there is for example one java usage like:

      MultiSatStepHandler handler = (interpolators, isLast) -> {
        Vector3D p0 = interpolators.get(0).getCurrentState().getPVCoordinates().getPosition();
        Vector3D p1 = interpolators.get(1).getCurrentState().getPVCoordinates().getPosition();
        Assert.assertEquals(0.0, Vector3D.distance(p0, p1), positionTolerance);
    };

This on-the-fly creation of classes do not exist in Python so a full class needs to be implemented, based on the Python wrapped class PythonMultiStepHandler, where the interface methods marked native needs to be implemented. See

And when looking at that file i realize they are not exposed. Will fix it in short.

This is updated now in the latest version of the python-orekit-wrapper java source, and in build 2 of orekit 10.2 on conda forge (availabel through the “conda install -c conda-forge orekit” command).

Awesome - thank you Petrus! I will take a look this weekend and see if I can make it work :slight_smile:

I updated my orekit install, took another run at this, and did get a little bit further, but … still no cigar. In the code below, PropagatorParallelizer expects a “globalHandler” object as the 2nd input. However, the call to PythonMultiSatStepHandler returns a “FinalizerProxy” object instead, and when trying to create the master_loop I get an invalid argument error. In the error message itself the object types seem to be correct though. Any ideas?

from orekit.pyhelpers import datetime_to_absolutedate
from org.orekit.propagation import PropagatorsParallelizer
from org.orekit.propagation.sampling import PythonMultiSatStepHandler

iniDate = datetime.datetime(2023, 6, 1,  0, 0, 0)
finDate = datetime.datetime(2023, 6, 1, 12, 0, 0)
iniDate = datetime_to_absolutedate(iniDate)
finDate = datetime_to_absolutedate(finDate)

#KeplerianPropagator objects
propagators = [sce.spacecraft[0].state, 
               sce.spacecraft[1].state] 

step_handler = PythonMultiSatStepHandler(propagators, iniDate)
master_loop  = PropagatorsParallelizer(propagators, step_handler)
master_loop.propagate(iniDate, finDate)

I get the following error when defining the master_loop:

master_loop  = PropagatorsParallelizer(propagators, step_handler)
InvalidArgsError: (<class 'org.orekit.propagation.PropagatorsParallelizer'>, '__init__', (
    [<KeplerianPropagator: org.orekit.propagation.analytical.KeplerianPropagator@5460cf3a>,
     <KeplerianPropagator: org.orekit.propagation.analytical.KeplerianPropagator@7e4204e2>], 
    <PythonMultiSatStepHandler: org.orekit.propagation.sampling.PythonMultiSatStepHandler@daae1e8>))

Thanks for the help!

Hi Sydra,

Yes, you need to define your own PythonMultiStepHandler in python, by subclassing this class and implementing the needed methods init(states0, t) and handleStep(interpolators, isLast).

There is a way in java to specify this “inline” where you only specify one of the methods (handleStep in this case), and init is the default implementation. This is not really possible in Python so you need to subclass class

i.e.

  PythonMultiStepHandler():

    init(it(self, states0, t):
     pass
    
   handleStep((self, interpolators, isLast):
       # do something

Regards
/Petrus