Help with local orbital frames

Hello,

I’m trying to convert to local coordinates, and the results are not what I expect. Either I am doing it incorrectly, or perhaps it is my understanding that is wrong.

I’ve adapted part of the “Frames1” tutorial, and would like to transform the inertial coordinates to local (QSW) coordinates (code attached). The local position is [0, 0, 0] which makes sense, however I am confused by the velocity. The output is:

{
    P(0.0, 0.0, 0.0),
    V(-4.58087505735644E-14, 2.7406831090468774E-12, -1.0937332320046279E-13),
    A(7.983577608881926, 9.855860138878967E-16, 8.083811398051921E-16)
}

Using the description of the QSW frame found here (https://sourceforge.isae.fr/svn/dcas-soft-espace/support/softs/CelestLab/trunk/help/en_US/scilab_en_US_help/Local%20frames.html), I expected velocity_y to be large, because it points in the direction of travel. However, it is very small. Can anyone please shed some light for me?

Thank you,
Zach

LocalCoords.java (1.6 KB)

Hi Zach,
Welcome to the forum.
The LOF being bound to the object in orbit, it is normal that the speed of the object in its own frame is zero (the result you get is only a numerical residual) as is its position. And the acceleration calculated along the radial X-axis corresponds well to the gravitational attraction.
Regards,
Pascal

Adding to what Pascal said. If you need a frame that is aligned with QSW at a particular instant but is fixed w.r.t. another frame, such as the inertial frame, use frame.getFrozenFrame(...). See https://www.orekit.org/site-orekit-latest/apidocs/org/orekit/frames/Frame.html#getFrozenFrame-org.orekit.frames.Frame-org.orekit.time.AbsoluteDate-java.lang.String-

Thank you both for the replies. It is clear my understanding is lacking. Let me be more specific about what I am trying to do since I might be asking the wrong question.

First, I do not understand or appreciate the difference between QSW, RSW (image), UVW, and RIC (link for the last 2).

What I am trying to accomplish is, given 2 states which are assumed to be before and after an on-orbit maneuver, determine the delta-v vector for the maneuver, relative to the object. I thought it might be simple enough that I could transform the states to some frame (or frames), and subtract the velocity vectors. Is that true or am I approaching it incorrectly?

Thank you,
Zach

Hi Zach,

There are no differences between QSW, RSW, USW and RIC frames, just the name of the convention change. There is at least another name for the same frame: LVLH.

In order to find the delta-v vector, you should compute the difference in an inertial frame first, and then project it to another frame if you want. However, there is a distinction between what I call projecting a velocity in a frame and transforming a velocity to a frame. When I write “projecting”, I mean you compute the velocity or velocity difference in some frame 1 (here an inertial frame), and then you apply rotations only so you get this inertial velocity coordinates in another frame, which may not be inertial. When I write “transforming”, I mean you that you compute the velocity in some frame 1 (here an inertial frame), and then you apply both rotation and velocity composition so you get the velocity relative to another frame. They key part is to apply or not apply frame velocity composition. In Orekit, you can do either depending on your needs. If you just want to apply rotation and ignore velocity composition, you call transform.transformVector(v). If you want to apply both rotation and velocity composition, you need to have the position too, so you call transform.transforPVCoordinates(pv).

So in your case, I would suggest this:

  SpacecraftState stateBefore = ...;
  SpacecraftState stateAfter  = ...;
  Vector3D deltaVInInertialFrame = stateAfter.getPVCoordinates().getVelocity().
                                   subtract(stateBefore.getPVCoordinates().getVelocity());
  Transform inertialToSpacecraftFrame = stateBefore.toTransform();
  Vector3D deltaVProjected = inertialToSpacecraftFrame.transformVector(deltaVInInertialFrame);

Beware that the previous code snippet works only if the attitude in the stateBefore object is realistic. If it is realistic, it works regardless of the attitude control you selected when building the propagator that generated this state: it would even work in yaw compensation mode or spin stabilized, or celestial pointing or anything else. So if you need it in QSW, then you should configure the propagator for use LofOffset as the attitude provider, with a LOFType.QSW configuration.