[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 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.

OK, now I understand better.



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).

Well, this is exactly what have right now, so I really don't get your point.

It seems we are completely unable to understand each other by mail. What about getting some face to face explanation, with a white board nearby to draw some sketches full of frames and vectors ?

We'll report back to the list if some change need to be introduced.

Luc

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.






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