Custom Force Model Interface

Perfect. Thanks again for taking the time to share all this info! I will take a look at those.

I have a couple of follow up questions:

  1. You recommended to use AbstractPythonForceModel, but it seems from this post (Wrong and missing methods in PythonAbstractForceModel (#458) · Issues · Orekit Labs / Orekit Python Wrapper · GitLab) that it no longer exists in since Orekit v12. Moreover I can only find PythonForceModel in org.orekit.forces. Should I be looking for AbstractPythonForceModel elsewhere? EDIT: I can see that you are answering my questions before I can finish writing them- this is what I call a responsive community :rofl:

  2. Looking at the code you provided and the example of how to subclass a Java class in Python here (cell 14 and 15 of this notebook).
    I have been trying to make a very simple dummy force model as follows:

class CustomForceModel(PythonForceModel):

    def __init__(self):
        super().__init__()

    def init(self):
        pass
    
    def acceleration(self, spacecraftState):
        """
            Compute simple acceleration.

        """
        acceleration = Vector3D(1, 0, 0)
        return acceleration
    
    def getParametersDrivers(self):
        pass
    
    def getEventDetectors(self):
        super().getEventDetectors()

However, I am getting the following error- which seems like similar issue to the one raised here
I simply took the code below from the tutorial you showed me and added the force model:

minStep = 0.001
maxstep = 1000.0
initStep = 60.0
positionTolerance = 1.0 
tolerances = NumericalPropagator.tolerances(positionTolerance, 
                                            initialOrbit, 
                                            initialOrbit.getType())
integrator = DormandPrince853Integrator(minStep, maxstep, 
    JArray_double.cast_(tolerances[0]),  # Double array of doubles needs to be casted in Python
    JArray_double.cast_(tolerances[1]))
integrator.setInitialStepSize(initStep)
satellite_mass = 100.0  # The models need a spacecraft mass, unit kg.
initialState = SpacecraftState(initialOrbit, satellite_mass) 
propagator_num = NumericalPropagator(integrator)
propagator_num.setOrbitType(OrbitType.CARTESIAN)
propagator_num.setInitialState(initialState)
gravityProvider = GravityFieldFactory.getNormalizedProvider(10, 10)
propagator_num.addForceModel(HolmesFeatherstoneAttractionModel(FramesFactory.getITRF(IERSConventions.IERS_2010, True), gravityProvider))
customForceModel = CustomForceModel()
propagator_num.addForceModel(customForceModel)
end_state = propagator_num.propagate(initialDate, initialDate.shiftedBy(3600.0 * 1))
end_state
---------------------------------------------------------------------------
JavaError                                 Traceback (most recent call last)
Cell In[40], line 1
----> 1 end_state = propagator_num.propagate(initialDate, initialDate.shiftedBy(3600.0 * 1))
      2 end_state
      4 #<SpacecraftState: SpacecraftState{orbit=Cartesian parameters: {P(3448526.581483817, 244918.37251755025, -5864890.887030139), V(6464.092116094485, 1251.1535044696986, 3907.265608060511)}, attitude=org.orekit.attitudes.Attitude@3bae64d0, mass=100.0, additional={}, additionalDot={}}>

JavaError: <super: <class 'JavaError'>, <JavaError object>>
    Java stacktrace:
java.lang.NullPointerException
	at org.orekit.propagation.events.EventDetectorsProvider.getEventDetectors(EventDetectorsProvider.java:85)
	at org.orekit.forces.ForceModel.getEventDetectors(ForceModel.java:101)
	at org.orekit.propagation.numerical.NumericalPropagator$Main.<init>(NumericalPropagator.java:914)
	at org.orekit.propagation.numerical.NumericalPropagator.getMainStateEquations(NumericalPropagator.java:890)
	at org.orekit.propagation.integration.AbstractIntegratedPropagator.createODE(AbstractIntegratedPropagator.java:598)
	at org.orekit.propagation.integration.AbstractIntegratedPropagator.integrateDynamics(AbstractIntegratedPropagator.java:471)
	at org.orekit.propagation.integration.AbstractIntegratedPropagator.propagate(AbstractIntegratedPropagator.java:424)

Do you know if I should be initialising the getEventDetectors as part of my force model? I have tried with/without and simply writing pass in the body. I have also tried defining all the functions with pass but I always get this error…

Apologies for the lengthy reply and thanks again for all your help so far.

Best regards,
Charles