00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024
00025
00026
00027
00028
00029
00030
00031 #ifndef EULER_TANSFORMATION_MATRICES
00032 #define EULER_TANSFORMATION_MATRICES
00033
00034 #include <armadillo>
00035
00036 class EulerTransformationMatrices {
00037 public:
00038
00044 static void create_zxz_matrix(double phi, double theta, double psi, arma::mat& matrix) {
00045 double c_phi = cos(phi);
00046 double s_phi = sin(phi);
00047 double c_theta = cos(theta);
00048 double s_theta = sin(theta);
00049 double c_psi = cos(psi);
00050 double s_psi = sin(psi);
00051
00052
00053 if (matrix.n_cols < 3 || matrix.n_rows < 3)
00054 matrix.set_size(3, 3);
00055
00056 matrix(0, 0) = c_phi * c_psi - s_phi * c_theta * s_psi;
00057 matrix(0, 1) = -c_phi * s_psi - s_phi * c_theta * c_psi;
00058 matrix(0, 2) = s_phi * s_theta;
00059
00060 matrix(1, 0) = s_phi * c_psi + c_phi * c_theta * s_psi;
00061 matrix(1, 1) = -s_phi * s_psi + c_phi * c_theta * c_psi;
00062 matrix(1, 2) = -c_phi * s_theta;
00063
00064 matrix(2, 0) = s_theta * s_psi;
00065 matrix(2, 1) = s_theta * c_psi;
00066 matrix(2, 2) = c_theta;
00067
00068 }
00069
00075 static void create_zxz_matrix(double x, double y, double z, double phi, double theta, double psi, arma::mat& matrix) {
00076 double c_phi = cos(phi);
00077 double s_phi = sin(phi);
00078 double c_theta = cos(theta);
00079 double s_theta = sin(theta);
00080 double c_psi = cos(psi);
00081 double s_psi = sin(psi);
00082
00083
00084 if (matrix.n_cols < 4 || matrix.n_rows < 4) {
00085 matrix.set_size(4, 4);
00086 matrix.zeros();
00087 }
00088
00089 matrix(0, 0) = c_phi * c_psi - s_phi * c_theta * s_psi;
00090 matrix(0, 1) = -c_phi * s_psi - s_phi * c_theta * c_psi;
00091 matrix(0, 2) = s_phi * s_theta;
00092 matrix(0, 3) = x;
00093
00094 matrix(1, 0) = s_phi * c_psi + c_phi * c_theta * s_psi;
00095 matrix(1, 1) = -s_phi * s_psi + c_phi * c_theta * c_psi;
00096 matrix(1, 2) = -c_phi * s_theta;
00097 matrix(1, 3) = y;
00098
00099 matrix(2, 0) = s_theta * s_psi;
00100 matrix(2, 1) = s_theta * c_psi;
00101 matrix(2, 2) = c_theta;
00102 matrix(2, 3) = z;
00103
00104 matrix(3, 3) = 1;
00105
00106 }
00107
00113 static void create_zyx_matrix(double phi, double theta, double psi, arma::mat& matrix) {
00114 double c_phi = cos(phi);
00115 double s_phi = sin(phi);
00116 double c_theta = cos(theta);
00117 double s_theta = sin(theta);
00118 double c_psi = cos(psi);
00119 double s_psi = sin(psi);
00120
00121
00122 if (matrix.n_cols < 3 || matrix.n_rows < 3)
00123 matrix.set_size(3, 3);
00124
00125 matrix(0, 0) = c_theta * c_phi;
00126 matrix(0, 1) = -c_psi * s_phi + s_psi * s_theta * c_phi;
00127 matrix(0, 2) = s_psi * s_phi + c_psi * s_theta * c_phi;
00128
00129 matrix(1, 0) = c_theta * s_phi;
00130 matrix(1, 1) = c_psi * c_phi + s_psi * s_theta * s_phi;
00131 matrix(1, 2) = -s_psi * c_phi + c_psi * s_theta * s_phi;
00132
00133 matrix(2, 0) = -s_theta;
00134 matrix(2, 1) = s_psi * c_theta;
00135 matrix(2, 2) = c_psi * c_theta;
00136 }
00137
00143 static void create_zyx_matrix(double x, double y, double z, double phi, double theta, double psi, arma::mat& matrix) {
00144 double c_phi = cos(phi);
00145 double s_phi = sin(phi);
00146 double c_theta = cos(theta);
00147 double s_theta = sin(theta);
00148 double c_psi = cos(psi);
00149 double s_psi = sin(psi);
00150
00151
00152 if (matrix.n_cols < 4 || matrix.n_rows < 4) {
00153 matrix.set_size(4, 4);
00154 matrix.zeros();
00155 }
00156 matrix(0, 0) = c_theta * c_phi;
00157 matrix(0, 1) = -c_psi * s_phi + s_psi * s_theta * c_phi;
00158 matrix(0, 2) = s_psi * s_phi + c_psi * s_theta * c_phi;
00159 matrix(0, 3) = x;
00160
00161 matrix(1, 0) = c_theta * s_phi;
00162 matrix(1, 1) = c_psi * c_phi + s_psi * s_theta * s_phi;
00163 matrix(1, 2) = -s_psi * c_phi + c_psi * s_theta * s_phi;
00164 matrix(1, 3) = y;
00165
00166 matrix(2, 0) = -s_theta;
00167 matrix(2, 1) = s_psi * c_theta;
00168 matrix(2, 2) = c_psi * c_theta;
00169 matrix(2, 3) = z;
00170
00171 matrix(3, 3) = 1;
00172 }
00173
00174 static void zxz_to_zyx_angles(const double in_a, const double in_e, const double in_r, double& out_a, double& out_e, double& out_r) {
00175
00176 arma::mat r(3, 3);
00177 EulerTransformationMatrices::create_zxz_matrix(in_a, in_e, in_r, r);
00178
00179
00180 out_e = atan2(-r(2, 0), hypot(r(0, 0), r(1, 0)));
00181
00182
00183 if (fabs(r(2, 1)) + fabs(r(2, 2)) < 10 * std::numeric_limits<double>::epsilon()) {
00184 out_r = 0.0;
00185 if (out_e > 0)
00186 out_a = -atan2(-r(1, 2), r(0, 2));
00187 else
00188 out_a = atan2(-r(1, 2), -r(0, 2));
00189 } else {
00190 out_r = atan2(r(2, 1), r(2, 2));
00191 out_a = atan2(r(1, 0), r(0, 0));
00192 }
00193 }
00194
00195 static void zyx_to_zxz_angles(const double in_a, const double in_e, const double in_r, double& out_a, double& out_e, double& out_r) {
00196
00197 arma::mat r(3, 3);
00198 EulerTransformationMatrices::create_zyx_matrix(in_a, in_e, in_r, r);
00199
00200 out_e = acos(r(2, 2));
00201
00202 if (fabs(sin(out_e)) > 1E-8) {
00203 out_r = atan2(r(2, 0) / sin(out_e), r(2, 1) / sin(out_e));
00204 out_a = -atan2(r(0, 2) / sin(out_e), r(1, 2) / sin(out_e)) + M_PI;
00205 } else {
00206 out_a = 0;
00207 out_r = atan2(r(1, 0), r(1, 1)) + M_PI;
00208 }
00209 }
00210
00211 static void zyx_from_matrix(const arma::mat& matrix, double& out_x, double& out_y, double& out_z, double& out_azimuth, double& out_elevation, double& out_roll) {
00212 double azimuth, elevation, roll;
00213
00214
00215 elevation = atan2(-matrix(2, 0), hypot(matrix(0, 0), matrix(1, 0)));
00216
00217
00218 if ((fabs(matrix(2, 1)) + fabs(matrix(2, 2))) < 10 * std::numeric_limits<double>::epsilon()) {
00219 roll = 0.0;
00220 if (elevation > 0)
00221 azimuth = -atan2(-matrix(1, 2), matrix(0, 2));
00222 else
00223 azimuth = atan2(-matrix(1, 2), -matrix(0, 2));
00224 } else {
00225 roll = atan2(matrix(2, 1), matrix(2, 2));
00226 azimuth = atan2(matrix(1, 0), matrix(0, 0));
00227 }
00228
00229 out_x = matrix(0, 3);
00230 out_y = matrix(1, 3);
00231 out_z = matrix(2, 3);
00232 out_azimuth = azimuth;
00233 out_elevation = elevation;
00234 out_roll = roll;
00235 }
00236 };
00237
00238 #endif