[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

Re: [Orekit Developers] Attitude class : conventions, problems, solutions and improvements



Anxionnat Julien <Julien.Anxionnat@cnes.fr> a écrit :

Hello,

Hi Julien,


I'm working for the CNES, where I'm in charge of the attitudes and kinematics subjects for the Sirius project. (I'm a co-worker of Yannick Tanguy who appears regularly on this mailing-list.) So, I'm gonna speak about attitude, rotations and quaternions, cause we encounter several problems...


I'm sure this subject has provoked numerous discussions, but it's a pretty hard problem for us. All our kinematic and guidance algorithms are based on the most-used international convention : "The rotation r where theta is the angle of the rotation and u the axis of the rotation is represented by the quaternion Q = ( cos(theta/2) , sin(theta/2).u )." Accordingly, we have v' = q.v.q* where v' yields the vector v rotated by the angle theta aroud the axis u. Badly it's not the convention in Commons Math. Okay, we have to compose with it.

The reason for this design choice is explained in the Apache Commons Math documentation (see <http://commons.apache.org/math/apidocs/org/apache/commons/math3/geometry/euclidean/threed/Rotation.html>). The rotation is considered here as a vectorial operator. In most geometry applications, when we consider a 45 degrees rotation around Z axis, we consider the image of a vector initially aligned with +X would be between +X and +Y, i.e. we consider the *vector* has moved by +45 degrees in the trigonometric direction.

In attitude, rotations represent *frames* rotation, not vectors rotation. In this specific field of application. So if we consider a +45 degrees frame rotation around Z, the of a vector initially aligned with +X would be between +X and -Y (not +Y), i.e. it is exactly the opposite of the other convention.

Apache Commons Math is a general purpose library, not a library dedicated to a specific field like attitude. So it was decided to stock with the most general geometry convention and not the specific attitude convention.

As you work in the attitude field, you can consider this is an awkward convention. Just remember other people use rotations who do not work in the attitude field.

(For information, we discussed with CM community few months ago to create a Quaternion class in CM and to modify the constructors and the getters of the Rotation class to manage the two conventions : "CCSDS" (above) and "Classical" (the "original"). If desired, I could attach our code of this modified Rotation class.)

For those interested, the thread can be read here:
  <http://commons.markmail.org/thread/adntgonwy3eamqjg>


I guess that's the reason why the rotation representing the attitude in Orekit is also the inverse of the most-used convention : all references and recommandations give the attitude as the representation of the orientation of the satellite frame relative to the reference frame. And it turns out that the Orekit getRotation() returns the rotation from the sat frame to the ref frame...

No. The rotation returned by Orekit transforms vectors from the inertial frame to the spacecraft frame. Just look at all the test cases. If for example you want to check the observing direction of the spacecraft Z axis in the inertial frame, you do something along this line:

  Vector3D zInInertialFrame =
     state.getAttitude().getRotation().applyInverseTo(Vector3D.PLUS_K);

The important part here is we must apply the *inverse* of the rotation to go from spacecraft frame to inertial frame.

I think the confusion you experience is you don't think of rotations as vectorial operators, which is the convention used by Apache Commons Math. Since in Orekit we directly use the Apache Commons Math class without any translation layer, we get this behaviour.

With a getQx(), admittedly the quaternion is "good conventioned", but it isn't pretty clean. In this state, we cannot reuse this package for our guidance applications.


So we have a proposition to improve the actual attitudes package (adding some kinematic and guidance algorithms) and also to clarify the direction of the rotation (and make it more user-friendly) :

1. Creation of "KinematicElements" class with attributes :
- attitude : Rotation [= rotation from R to S = rotation which transforms the axis of R frame into the axis of the S frame]
- spin : Vector3D [= angular velocity of S relative to R, expressed in S]
- acceleration : Vector3D
- jerk : Vector3D
- snap : Vector3D
=> It's the user (or the using class) of these elements who manage the concerned frames. The jerk is the derivative of the angular acceleration, and the snap the derivative of the jerk. These derivation orders are needed by our kinematic algorithms. Of course, they'll be optional.

This is interesting. Note that about three weeks ago, a new AngularCoordinates class has been added to Orekit (see <https://www.orekit.org/forge/projects/orekit/repository/revisions/017880506b284a6727fc920418ee42303aaad839>). This class packs a rotation and its first derivative. It is now used both by Attitude and by Transform (and therefore Frame) classes.

Note however that the first derivative is useful for both transforms, frames and attitude, but the higher order derivatives would be useful only for attitude. So I would suggest a layered approach extending what was done with AngularCoordinates (the name can be changed, of course, but it was chosen this way for consistency with PVCoordinates). We would have three layers:

  - Apache Commons Math Rotation
    (existing)
  - Orekit AngularCoordinates
    (existing, contains a Rotation and add first derivative)
  - Orekit KinematicElements (or better DynamicsElements)
    (new, contains a AngularCoordinates and add second and third derivatives)
  - Orekit Attitude
    (existing but modified to use KinematicElements/DynamicsElements
     instead of AngularCoordinates)


2. Changes in Attitude class :
- turning getRotation() to @deprecated,

I don't buy this. As explained in the example above, this method is useful as is and in fact is used in many places.

- creating getRotationSatFrameToRefFrame() to substitute it,

It's just getRotation().getInverse(), but we can add this if you really wants.

- turning getSpin() to @deprecated,
- suppressing the attitude and spin attributes,

This has been done as part of introducing AngularCoordinates

- creating the attribute kinematic of type KinematicElements (which represents the kinematic of sat frame relative to the ref frame),

If we replace AngularCoordinates with KinematicElements/DynamicsElements, it makes sense, sure.

- creating the getters getKinematicElements() and getKinematicElements(order : int).

I'm not really a big fan of the order paremeter. It seems awkward and breaks strong typing. It will also introduce lots of "if/then" statements in user code, which will not really protect agains anything. I would prefer to simply say Rotation has no derivatives, AngularCoordinates has first derivatives, KinematicElements/DynamicsElements has higher order derivatives. It is always possible to convert from low order to high order by setting zero derivatives, and it is always possible to convert from high order to low order by simply ignoring derivatives.

Note also that as part of the changes in AngularCoordinates/Transform/Frames and the continuing changes being implemented right now for thread safety, we have introduced a general interpolation feature which can use any derivative orders. The general feature is used in a more specific way with AngularCoordinates in which case we use first derivative in the interpolation if desired (we interpolate on modified Rodrigues vector, not quaternion or original Gibbs/Rodrigues vector). It would be nice to have KinematicElements/DynamicsElements also use this and use higher order derivatives in the interpolation.

Luc


What do you think about that ?


Best regards,
Julien Anxionnat





----------------------------------------------------------------
This message was sent using IMP, the Internet Messaging Program.