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

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



Hello Luc,


It seems you didn't understand my purpose about rotations and quaternions. I'm sorry, I'll try to be more explicit.

First, I'm agree with you, the Rotation class of Commons Math is (and has to be) a vectorial operator. That's the definition. And we don't have any problem with it. I mean : applyTo() is ok for us.

The problem is about its quaternion representation. Commons Math returns :
q0 = cos(theta/2)
q1 = - sin(theta/2).ux
q2 = - sin(theta/2).uy
q3 = - sin(theta/2).uz
(Where theta is the angle of the rotation and u=(ux,uy,uz) the axis of the rotation.)

And all existing litterature (i.e. not only attitude litterature) give :
q0 = cos(theta/2)
q1 = sin(theta/2).ux
q2 = sin(theta/2).uy
q3 = sin(theta/2).uz
(for example : http://en.wikipedia.org/wiki/Quaternions_and_spatial_rotation)

=> That's the first problem.


The second problem is about Attitude.getRotation() Orekit method.

As you said, the "Rotation" returned by Attitude.getRotation() transforms vectors from the ref frame to the sat frame. It's "miss-named" : it's not a rotation, it's a frame transformation.
If this "rotation" was really the rotation from reference frame to the satellite frame, we should have : X_sat = r.applytTo(X_eme2000). And that's why I said that's the inverse of the most-used convention.
I'm not agree with you : to represent attitude, we use the rotation which (really) transforms ref frame into sat frame, and not the frame transformation (which is the rotation from sat frame to ref frame).

That's why I suggested to rename getRotation() in getRotationSatFrameToRefFrame(). And I'm convinced that's a good thing, because it's less confusing.
An other good idea would be to have a getTransform() rather than this confusing getRotation().


And I +1 the three layers you presented :
   - Apache Commons Math Rotation
     (existing)
   - Orekit AngularCoordinates
     (existing, contains a Rotation and add first derivative)
   - Orekit DynamicsElements
     (new, contains a AngularCoordinates and add second and third derivatives)
   - Orekit Attitude
     (existing but modified to use KinematicElements/DynamicsElements
      instead of AngularCoordinates)
It's a good approach.


Julien


-----Message d'origine-----
De : MAISONOBE Luc [mailto:luc.maisonobe@c-s.fr] 
Envoyé : lundi 2 juillet 2012 13:52
À : orekit-developers@orekit.org
Objet : 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.