Transform between two reference frames

I am recently working with the Transform class and there is a point that I am not sure to fully understand when generating a transformation between two reference frames.

Given two different reference frames it’s possible to create a Transform by means of the method getTransformTo(…) of the class Frame. In the general case of two references frames A and B, I can generate this transform with the call Transform transf = refA.getTransformTo(refB).

Once the Transform is obtained I can call the associated getter “getRotation()” and “getRotationRate()”. Looking at the javadoc, I understand that:

  • the result of the “getRotationRate()” call should return the angular velocity of refB with respect to refA expressed in the “refB”. Could you please confirm?
  • I am not sure about the result returned by the call to “getRotation()” : is it the rotation that allows to transform a vector from refB to refA or the inverse? At the beginning I thought that the rotation returned by “transform.getRotation()” was the rotation allowing to transform a vector expressed in the refA to the refB but I am realising that maybe it’s the inverse (cfr the description reported by the javadoc of Transform in the associated class for the example of rotations). Do you know something more about that to clarify me?

Hi @NicNat, welcome to the community

Yes. One way to check this simply is to use some straightforward and well undestood frames. You could for example use something like:

Frame eme2000 = FramesFactory.getEME2000();
Frame itrf    = FramesFactory.getITRF(IERSConventions.IERS_2010, true);
System.out.println(eme2000.getTransformTo(itrf, t0).getRotationRate());

The result should be something close to {-0; -0.0000000001; 0.0000729212}, it may vary very slightly depending on the date and the EOP, but basically it shows Earth rotation about +Z axis.

It is the inverse. The semantic is more explicit if you look at the transform itself rather than the underlying rotation. You call refA.getTransformTo(refB), so you transform vectors or positions, or positions velocities expressed with respect to frame A into the same thing but expressed with respect to frame B. So if for example both following statements will give the same results:

    Transform t = eme2000.getTransformTo(itrf, t0);
    System.out.println(t.transformVector(Vector3D.PLUS_I));
    System.out.println(t.getRotation().applyTo(Vector3D.PLUS_I));

In most cases, using the higher level Transform is much clearer than looking at the underlying implementation details with more mathematical meanings. It cannot be avoided in some cases (for example when combining rotations in complex attitude models), but some care is needed in these cases.

Another thing to take care about is velocity composition. Transform.transformPVCoordinates does include velocity composition, so if you go from an inertial frame to an Earth frame, you get the velocity with respect to Earth, not inertial velocity simply rotated. One way to check this is looking at a geostationary satellite. Its velocity with respect to inertial frame is about 3075m/s eastwards. IF you convert it to itrf using transformPVCoordinates, you will get a velocity close to 0 as the satellite barely moves with respect to Earth, you will not get a 3075m/s vector with an orientation in Earth frame. If you need this (perhaps for exchange data between two different systems), then you should separately transform position and velocity, and for the velocity transform use transformVector, hiding to the library the fact the vector is really a velocity and hence preventing it to use velocity composition.

Ok! Everything is clear now, thanks for these clarifications, @luc !