Propagation CR3BP

Hi all,

I’m trying to use the CR3BP package and I think I’m getting the hang of it but I’m still struggling on some aspects. For now I’ve only reused one of the example indicated by Bryan: PropagationInCR3BP.

From what I understood position and velocity have to be normalized with the characteristic length of the system and so has to be the time (using the orbital period of m2). I’m trying to propagate for 1 day and it seems that my propagation is working fine given the states it prints as it goes but oddly the final state has not changed from the initial state. And I don’t manage to find what I’m missing… Attached the code I’ve been using.

The good thing is that I have a starting point and already now where I should be after a day of propagation. In J2000 I start here:

  • Date: 2026/08/11 21:49:57
  • Position [m]: [-282554776, 117058409, 32929943]
  • Velocity [m/s]: [-694, 43, 80]

And should end somewhere around this point:

  • Date: 2026/08/12 21:49:57
  • Position [m]: [-329114574, 116239320, 38725331]
  • Velocity [m/s]: [-394, -52, 56]

Thank you very much for your help!

Kind regards,

B. (9.3 KB)

ERRATUM: for the velocity I just noticed the normalization should be done with the system parameter vDim.

Hi benoist,

I think what you missed is that the call to propagator.getInitialState() doesn’t return the initial state before the propagation started but the actual spacecraft state of the propagator.
So in the case of your sample code both finalState and propagator.getInitialState() refer to an object containing the same values. That is why it seems your final state hasn’t changed. It has changed but you’re actually comparing it with itself.

I reckon the method getInitialState has a confusing name since it is not the initial but the current state of the propagator that is returned.
This is because the default behavior of the propagator is to reset the initial state to its current value after each call to propagate. See for example this line in the AbstractIntegratedPropagator class.
To avoid this you could set the boolean resetAtEnd to false by calling the method propagator.setResetAtEnd(false) before the propagation happens.


Hi Maxime,

Thanks a lot for this! A bit of a rookie mistake…

I have a question as well on the frames definitions for CR3BP propagation. I’m quite lost with the definition in ua and the rotating frame so I don’t manage to correctly build the transformation between J2000 and CR3BP frames.

I define my initial state as follows:

PVCoordinates initialPVJ2000 = new PVCoordinates(	new Vector3D(-327813119.002316, 116405954.440142, 38535148.2199351), 
							new Vector3D(-404.854767058064, -49.8422335282003, 57.095383473808));
// Transformations J2000 from and to CR3BP
Frame j2000 = FramesFactory.getEME2000();   
final Frame rotatingFrame = syst.getRotatingFrame();
Transform tranformJ2000toCR3BP = j2000.getTransformTo(rotatingFrame, initialDate);
Transform tranformCR3BPtoJ2000 = rotatingFrame.getTransformTo(j2000, initialDate);

// Initial state
PVCoordinates initialPVcr3bp = new PVCoordinates( tranformJ2000toCR3BP.transformPVCoordinates(initialPVJ2000).getPosition().scalarMultiply(1/dDim),
AbsolutePVCoordinates initialAbsPV = new AbsolutePVCoordinates(rotatingFrame, initialDate, initialPVcr3bp);   

I do manage to get the J2000 position from this CR3BP position by using:


But I don’t manage to get the same values on the velocity, I tried several things, none leading to the right result:


Would you or anyone else be able to guide me on how to correctly convert PV between these two frames?

Thank you very much!

Kind regards,



It’s because you perform the final PV transformation with normalized coordinates. You have to use the un-normalized parameters inside the transformPVCoordinates() method in order to have correct kinematic effects during the transformation and thus having correct velocity. Here an example of code using your data:

Define the initial state as (no big difference with your example, I just factorized the code to perform the PV transformation only once):

    // Initial state
    PVCoordinates initialPVcr3bp = tranformJ2000toCR3BP.transformPVCoordinates(initialPVJ2000);

    AbsolutePVCoordinates initialAbsPV = new AbsolutePVCoordinates(rotatingFrame, initialDate, new PVCoordinates(initialPVcr3bp.getPosition().scalarMultiply(1.0 / dDim),
                                                                                                                 initialPVcr3bp.getVelocity().scalarMultiply(1.0 / vDim)));   

Perform the transformation from CR3BP frame to J200 frame as:

    PVCoordinates finalPVInJ2000 = tranformCR3BPtoJ2000.transformPVCoordinates(new PVCoordinates(initialAbsPV.getPosition().scalarMultiply(dDim),

Here the PVCoordinates are un-normalized before the PV transformation. Moreover, I use a PV transformation (not a Vector or a Position transformation) in order to take into account the kinematics effects. The main difference with you example is that here the kinematics effect are computed for un-normalized PV coordinates. That’s why they are well computed and I have the correct velocity after the transformation:

Intial Position: {-327 813 119,002316; 116 405 954,440142; 38 535 148,2199351}
Intial Velocity: {-404,8547670581; -49,8422335282; 57,0953834738}

Position after transformations: {-327 813 119,002316; 116 405 954,4401421; 38 535 148,2199351}
Velocity after transformations: {-404,8547670581; -49,8422335282; 57,0953834738}