How to project satellites with attitude to the ground, where attitude means ROLL,PITCH,YAW, and in the order of RPY

First of all,this is my code:
final AbsoluteDate initialDate = new AbsoluteDate(“2023-10-19T18:18:50.000”, TimeScalesFactory.getUTC());
final Vector3D positionECF = new Vector3D(-3443011.0276737823, 5409676.758639811, 2455315.2146701273);
final Vector3D velocityECF = new Vector3D(-4541.811537870899, -4449.90303687951, 3421.5476352639403);
PVCoordinates pvCoordinates = new PVCoordinates(positionECF, velocityECF);
// Inertial frame
final Frame inertialFrame = FramesFactory.getGCRF();
OneAxisEllipsoid earth2 = new OneAxisEllipsoid(Constants.WGS84_EARTH_EQUATORIAL_RADIUS, Constants.WGS84_EARTH_FLATTENING, inertialFrame);

GeodeticPoint satLatLonAlt = earth2.transform(pvCoordinates.getPosition(), FramesFactory.getEME2000(), initialDate);

This is great. I can get the projection points of the satellites.But the Z axis is roughly normal to equator.
My satellite attitude is as follows:
double roll = FastMath.toRadians(39.976486);
double pitch = FastMath.toRadians(0.219314);
double yaw = 0;

The converted ecf should be:
final Vector3D positionECF2 = new Vector3D(-2947453.473909, 5006687.644903, 2622949.033188);

GeodeticPoint is {longitude:120.4854,latitude:24.44};

What should I do? Please help me out. I appreciate it.

1 Like

Hi Samuel, welcome

The simplest way to do this is to use an attitude provider to manage the attitude and a propagator to merge both the orbit and attitude together as time evolves.

The attitude provider would be:

  AttitudeProvider attitudeProvider = new LofOffset(inertialFrame, LOFType.VNC, RotationOrder.XYZ,
                                                    FastMath.toRadians(39.976486),
                                                    FastMath.toRadians( 0.219314),
                                                    FastMath.toRadians( 0.0));

Beware I selected VNC as the base Local Orbital Frame, but it may be something different like LOFType.LVLH_CCSDS

You can register this to any propagator by calling propagator.setAttitudeProvider(attitudeProvider), then, each time you get a SpacecraftState from the propagator (either inside a step handler during the propagation or at the end of the propagation), it will contain both the time-stamped orbit and attitude (and also mass and additional parameters, but you won’t need these).

So assuming state is a SpacecraftState, you can do this:

Transform     inertToBody   = state.getFrame().getTransformTo(earth.getBodyFrame(), state.getDate());
Transform     scToBody      = new Transform(state.getDate(),
                                            state.toTransform().getInverse(),
                                            inertToBody);
Vector3D      position      = scToBody.transformPosition(Vector3D.ZERO);
Vector3D      farAwayAlongZ = scToBody.transformPosition(new Vector3D(1.0e6,
                                                                      Vector3D.PLUS_K);
Line          lineOfSight   = new Line(position, farAwayAlongZ, 1.0e-3);
GeodeticPoint gp            = earth.getIntersectionPoint(lineOfSight, position,
                                                         earth.getBodyFrame(),
                                                         state.getDate());