Getting ephemerides for a CelestialBody always returns Earth's ephemerides

Hi!

I’ve written some code to get the PVCoordinates of a planet at a given time. This works great for Earth but, for some reason, returns Earth’s position regardless of what body I ask for. I’ve loaded a more complete lnxp1550.430 file into my orekit-data folder which I can confirm is being read, so I don’t think that’s the issue, but it shouldn’t matter anyway since I’m not querying for dates very far into the future.

Here’s a simplified version of the code I’m running, made a bit more verbose in places for clarity:

int secondsInDay = 24 * 60 * 60;

// convert Julian Date (2024-Apr-09) to TDB time
Double julianDate = 2460409.5;
int julianDay = julianDate.intValue();
double seconds = (julianDate - julianDay) * secondsInDay;
AbsoluteDate absDate = AbsoluteDate.createJDDate(julianDay, seconds, TimeScalesFactory.getTDB());

// Get Frame
Frame eclipticFrame = FramesFactory.getEcliptic(IERSConventions.IERS_2010);

// Initialise Ephemerides Loader
JPLEphemeridesLoader ephemeridesLoader = new JPLEphemeridesLoader(DEFAULT_DE_SUPPORTED_NAMES, JPLEphemeridesLoader.EphemerisType.SOLAR_SYSTEM_BARYCENTER);

// Get 3 bodies
CelestialBody venus = ephemeridesLoader.loadCelestialBody(CelestialBodyFactory.VENUS);
CelestialBody earth = ephemeridesLoader.loadCelestialBody(CelestialBodyFactory.EARTH);
CelestialBody mars = ephemeridesLoader.loadCelestialBody(CelestialBodyFactory.MARS);

// Get their positions
Vector3D venusPosition = venus.getPVCoordinates(absDate, eclipticFrame).getPosition();
Vector3D earthPosition = earth.getPVCoordinates(absDate, eclipticFrame).getPosition();
Vector3D marsPosition = mars.getPVCoordinates(absDate, eclipticFrame).getPosition();

The issue when I run this code is that all bodies have the same position, and the position matches the JPL Horizons data for Earth at that time! It’s like Orekit can’t find the CelestialBody and then silently falls back to Earth, or something.

Would love to find out what I’m doing wrong here.

Thanks a million!

Hello @decmurphy,

Out of pure interest I tried to debug the code snippet and got the same result as you.

I put a breakpoint after the definition of the Celestial bodies first; All of the attraction coeffients (gm parameter of each celestial body instance) were the same and equal to the Sun’s attraction coefficient. I thought this might not be normal, because the definition of a Celestial body with the default loader (i.e. CelestialBodyFactory.getEarth()) gave the correct attraction coefficient for Earth (or any other body’s), and not the Sun’s Barycenter.

The reason why the attraction coefficient of all bodies is equal to the Sun’s Barycenter coefficient is because you have defined the EphemerisType as SOLAR_BARYCENTER, and the call of the function loadCelestialBody is actually computing the attraction coefficient (gm) of the ephemeris corresponding to the solar barycenter and using that to define the gm for every Celestial Body wished to be loaded (getLoadedGravitationalCoefficient(generateType), in the defintion of loadCelestialBody function)

It is not clear to me if this is the true intention of the function, or if this is unwanted.

If this is intended, then you might need to create one loader per celestial body and then load again the body by calling the function loadCelestialBody(JPLEphemeridesLoader.EphemerisType.VENUS). Please see the code snippet below. This way, you get the body created with the same attraction coefficient as if you would call CelestialBodyFactory.getVenus().

Just replace the instantiation of the JPL loader and body creation with the following snippet, only for Venus, and similar for other bodies.

  // Initialise Ephemerides Loader
  JPLEphemeridesLoader venusEphemeridesLoader = new JPLEphemeridesLoader(
  		JPLEphemeridesLoader.DEFAULT_DE_SUPPORTED_NAMES,
  		JPLEphemeridesLoader.EphemerisType.VENUS);

  CelestialBody venus = venusEphemeridesLoader.loadCelestialBody("VENUS");

  // Get their positions
  Vector3D venusPosition = venus.getPVCoordinates(absDate, eclipticFrame).getPosition();

Has there been a resolution to this?

I find that if I use EphemerisType.EARTH for the loader, the position I get for Earth is 0s. This is what I would expect for an earth-centric coordinate system. (I’m not sure what to make of EphemerisType.VENUS yielding Venus distances greater than 1 au.) I would expect that using SOLAR_SYSTEM_BARYCENTER would be the right thing to do if I want positions in solar system barycentric coordinates.

I do find that the distance from the Sun to the Earth agrees with another source I have when I use EphemerisType.SUN. But when I try to get the distance for any other planet I still get the Earth’s values.

Hi @dlindhol,

Welcome to the Orekit community !

Using the JPLEphemeridesLoader with SOLAR_SYSTEM_BARYCENTER tells indeed the loader to load the ephemeris of the solar system barycenter (SSB). It doesn’t give an indication on the frame used for the positions.
If you want SSB centered inertial position of Venus at a given date you can use the ICRF frame.

Example:

CelestialBody venus = CelestialBodyFactory.getVenus();
Frame icrf = FramesFactory.getICRF();
Vector3D venusPosition = venus.getPVCoordinates(date, icrf).getPosition();

Maxime

Thanks, Maxime! Doing that without the loaders makes much more sense. I am a bit overwhelmed by the Frame possibilities. What I really want is a heliocentric coordinate system so I can compute planetary distances from the sun and relative angle between two planets. I suppose I can use this barycentric frame and do some vector math.

Doug

You’re welcome @dlindhol,

If you want the sun and not the barycenter you can also use CelestialBody sun = CelestialBodyFactory.getSun() and then Frame sunFrame = sun.getInertiallyOrientedFrame() instead of ICRF.