// Copyright (c) CNES 2008 // // This software is part of CelestLab, a CNES toolbox for Scilab // // This software is governed by the CeCILL license under French law and // abiding by the rules of distribution of free software. You can use, // modify and/ or redistribute the software under the terms of the CeCILL // license as circulated by CEA, CNRS and INRIA at the following URL // 'http://www.cecill.info'. function [angles1,angles2,Inok] = CL_rot_quat2angles(q,naxes) // Quaternion to Euler or Cardan rotation angles // // Calling Sequence // [angles1,angles2,Inok] = CL_rot_quat2angles(q,naxes) // // Description // //

This function computes the rotation angles of the 3 successive elementary rotations // that correspond to a given quaternion.

//

Two solutions (2 sets of angles) are computed (angles1 and angles2).

//

//

The rotations are described by 3 axis numbers: 1=x-axis, 2=y-axis, 3=z-axis. The possible // combinations of axis numbers correspond to:

//

- 6 Cardan rotations (for which all axes are different): XYZ, XZY, YXZ, YZX, ZXY and ZYX;

//

- 6 Euler rotations (for which 2 axes are the same): XYX, XZX, YXY, YZY, ZXZ and ZYZ.

//

//

// //

Notes:

//

1) There solutions are such that:

//

- For Cardan angles, angles1 is the solution for which the second rotation angle is between -pi/2 and pi/2.

//

- For Euler angles, angles1 is the solution for which the second rotation angle is between 0 and pi.

//

//

2) Cardan and Euler angles have singularities.

//

- For Cardan angles, singularities occur when the second angle is close to -pi/2 or +pi/2

//

- For Euler angles, singularities occur when the second angle is close to 0 or pi (which implies that // the identity rotation is always singular for Euler angles!)

//

//

3) The returned angles for cases close to singularities are approximate. // The corresponding indices are returned in Inok.

//
//
// // Parameters // q : Quaternion that defines the rotation (dim N). // naxes : Successive axes numbers : 1=x-axis, 2=y-axis or 3=z-axis (1x3 or 3x1) // angles1 : First set of rotation angles [rad] (3xN) // angles2 : Second set of rotation angles [rad] (3xN) // Inok : Indices for which singularities occur (1xP) // // Authors // CNES - DCT/SB // // See also // CL_rot_angles2quat // CL_rot_angles2matrix // CL_rot_matrix2angles // // Examples // // Cardan angles (XYZ), second rotation angle < %pi/2 // naxes = [1,2,3]; // angles = [0.1;0.4;0.5]; // q = CL_rot_angles2quat(naxes,angles); // [angles1,angles2,Inok] = CL_rot_quat2angles(q,naxes); // angles1 - angles // => 0 // // // Cardan angles (XYZ), second rotation angle > %pi/2 // angles = [0.1;2.4;0.5]; // q = CL_rot_angles2quat(naxes,angles); // [angles1,angles2,Inok] = CL_rot_quat2angles(q,naxes); // angles2 - angles // => 0 // // // Euler angles (ZXZ), second rotation angle close to 0 : singularity // naxes = [3,1,3]; // angles = [0.1;0;0.5]; // q = CL_rot_angles2quat(naxes,angles); // [angles1,angles2,Inok] = CL_rot_quat2angles(q,naxes); // Inok // => not empty // q1 = CL_rot_angles2quat(naxes,angles1); // q1*q' // => identity // // Declarations: // Code: if (typeof(q) <> "CLquat") CL__error("Wrong type of input argument. Quaternion expected"); end [angles1,angles2,Inok] = CL__rot_qM2angles(q,naxes); endfunction