CelestialBodyPointing to Earth center and perfect circular KeplerianOrbit

Hi team

I have a simple Keplerian orbit, perfectly circular, starting at node.
I add to the KeplerianPropagator an attitude event pointing the center of Earth with +Z (so +k axis).
So pointing vector points the center of Earth at the node.
Here my test:

    AbsoluteDate startDate = Time.getAbsoluteDateFromEpochMilli(1751400000000L);
    AbsoluteDate endDate = startDate.shiftedBy(1000);

    KeplerianOrbit orbit = new KeplerianOrbit(7428000, 0.0, 89.0, 0.0, 0.0, 0.0,
        PositionAngleType.MEAN,
        FramesFactory.getEME2000(),
        Time.getAbsoluteDateFromEpochMilli(1751400000000L),
        EGM96_EARTH_MU);

    //Attitude pointing Earth center with +Z (so +k)
    AttitudeProvider attitude = new CelestialBodyPointed(FramesFactory.getEME2000(),
        CelestialBodyFactory.getEarth(),
        Vector3D.PLUS_I, Vector3D.PLUS_K, Vector3D.PLUS_J);

    //Keplerian propagator
    KeplerianPropagator prop = new KeplerianPropagator(orbit, attitude);

    //Propagate and get last state
    SpacecraftState lastState = prop.propagate(endDate);

    assertEquals(lastState.getDate().durationFrom(endDate), 0, 1e-7);

Where

public static AbsoluteDate getAbsoluteDateFromTimestamp(long timestamp) {
    LocalDateTime utcDate = LocalDateTime.ofInstant(Instant.ofEpochMilli(timestamp), UTC_ZONE_ID);
    val year = utcDate.getYear();
    val month = utcDate.getMonthValue();
    val day = utcDate.getDayOfMonth();
    val hour = utcDate.getHour();
    val minute = utcDate.getMinute();
    val second = utcDate.getSecond();
    val millis = utcDate.getNano() / 1e9;
    return new AbsoluteDate(year, month, day, hour, minute, second, TimeScalesFactory.getUTC()).shiftedBy(millis);

It fails with:

org.hipparchus.exception.MathRuntimeException: cannot normalize a zero norm vector
	at org.hipparchus.geometry.Vector.normalize(Vector.java:102)
	at org.hipparchus.geometry.euclidean.threed.Rotation.<init>(Rotation.java:273)
	at org.orekit.attitudes.CelestialBodyPointed.getAttitude(CelestialBodyPointed.java:125)
	at org.orekit.propagation.analytical.KeplerianPropagator.<init>(KeplerianPropagator.java:105)
	at org.orekit.propagation.analytical.KeplerianPropagator.<init>(KeplerianPropagator.java:75)
	at com.rivadaspace.e2eps.flightdynamics.calculators.OrbitCalculatorTest.testCircularOrbitalParametersPointingEarth(OrbitCalculatorTest.java:346)
	at java.base/java.lang.reflect.Method.invoke(Method.java:580)
	at java.base/java.util.ArrayList.forEach(ArrayList.java:1596)
	at java.base/java.util.ArrayList.forEach(ArrayList.java:1596)

It fails directly at the initialization of the KeplerianPropagator.
Am I doing something wrong ?

Thanks
Alberto

Hi @alberto-ferrero,

Welcome back to the forum!

Here your phasing reference is aligned with the pointing axis a t0.
So Orekit is trying to transform two aligned vectors in J2000 frame (+I, -I) into two perpendicular vectors in S/C frame (+K, +J) with a single rotation… and it fails to do so.
Your phasingCel must never be colinear to your pointing axis. I suggest you use +K instead of +I as the phasing reference since with your inclination the pointing direction should never be aligned with the pole of J2000.

Note that you could also use the BodyCenterPointing attitude provider which is designed to do just what you need :wink:

Cheers,
Maxime

Perfect, indeed it works setting

AttitudeProvider attitude = new CelestialBodyPointed(FramesFactory.getEME2000(),
        CelestialBodyFactory.getEarth(),
        Vector3D.PLUS_K, Vector3D.PLUS_K, Vector3D.PLUS_J);

Thanks for the quick reply :slight_smile: