41 feq (
double a,
double b) {
42 return fabs (a - b) < 1e-9;
46 qeq (
double *q,
double a,
double b,
double c,
double d)
48 return feq(q[0],a) &&
feq(q[1],b) &&
feq(q[2],c) &&
feq(q[3],d);
52 rpyeq (
double roll,
double pitch,
double yaw,
double r,
double p,
double y)
54 return feq(roll,r) &&
feq(pitch,p) &&
feq(yaw,y);
70 c[0] = a[0]*b[0] - a[1]*b[1] - a[2]*b[2] - a[3]*b[3];
71 c[1] = a[0]*b[1] + a[1]*b[0] + a[2]*b[3] - a[3]*b[2];
72 c[2] = a[0]*b[2] - a[1]*b[3] + a[2]*b[0] + a[3]*b[1];
73 c[3] = a[0]*b[3] + a[1]*b[2] - a[2]*b[1] + a[3]*b[0];
89 double a[4], b[4], c[4];
92 memcpy (b+1, v, 3 *
sizeof (
double));
101 memcpy (v, c+1, 3 *
sizeof (
double));
118 double a[4], b[4], c[4];
121 memcpy (b+1, v, 3 *
sizeof (
double));
130 memcpy (v, c+1, 3 *
sizeof (
double));
136 double x = axis[0], y = axis[1], z = axis[2];
137 double norm = sqrt (x*x + y*y + z*z);
140 q[1] = q[2] = q[3] = 0;
144 double t = sin(theta/2) / norm;
146 q[0] = cos(theta / 2);
155 double halftheta = acos (q[0]);
156 *theta = halftheta * 2;
157 double sinhalftheta = sin (halftheta);
158 if (
feq (halftheta, 0)) {
164 axis[0] = q[1] / sinhalftheta;
165 axis[1] = q[2] / sinhalftheta;
166 axis[2] = q[3] / sinhalftheta;
173 double roll = rpy[0], pitch = rpy[1], yaw = rpy[2];
175 double halfroll = roll / 2;
176 double halfpitch = pitch / 2;
177 double halfyaw = yaw / 2;
179 double sin_r2 = sin (halfroll);
180 double sin_p2 = sin (halfpitch);
181 double sin_y2 = sin (halfyaw);
183 double cos_r2 = cos (halfroll);
184 double cos_p2 = cos (halfpitch);
185 double cos_y2 = cos (halfyaw);
187 q[0] = cos_r2 * cos_p2 * cos_y2 + sin_r2 * sin_p2 * sin_y2;
188 q[1] = sin_r2 * cos_p2 * cos_y2 - cos_r2 * sin_p2 * sin_y2;
189 q[2] = cos_r2 * sin_p2 * cos_y2 + sin_r2 * cos_p2 * sin_y2;
190 q[3] = cos_r2 * cos_p2 * sin_y2 - sin_r2 * sin_p2 * cos_y2;
196 double roll_a = 2 * (q[0]*q[1] + q[2]*q[3]);
197 double roll_b = 1 - 2 * (q[1]*q[1] + q[2]*q[2]);
198 rpy[0] = atan2 (roll_a, roll_b);
200 double pitch_sin = 2 * (q[0]*q[2] - q[3]*q[1]);
201 rpy[1] = asin (pitch_sin);
203 double yaw_a = 2 * (q[0]*q[3] + q[1]*q[2]);
204 double yaw_b = 1 - 2 * (q[2]*q[2] + q[3]*q[3]);
205 rpy[2] = atan2 (yaw_a, yaw_b);
230 double norm = quat[0]*quat[0] + quat[1]*quat[1] + quat[2]*quat[2] +
232 if (fabs(norm) < 1e-10)
236 double x = quat[1]*norm;
237 double y = quat[2]*norm;
238 double z = quat[3]*norm;
239 double w = quat[0]*norm;
252 rot[0] = w2+x2-y2-z2; rot[1] = xy-wz; rot[2] = xz+wy;
253 rot[3] = xy+wz; rot[4] = w2-x2+y2-z2; rot[5] = yz-wx;
254 rot[6] = xz-wy; rot[7] = yz+wx; rot[8] = w2-x2-y2+z2;
291 quat[0] = 0.5*sqrt(rot[0]+rot[4]+rot[8]+1);
293 if (fabs(quat[0]) > 1e-8) {
294 double w4 = 1/4/quat[0];
295 quat[1] = (rot[7]-rot[5]) * w4;
296 quat[2] = (rot[2]-rot[6]) * w4;
297 quat[3] = (rot[3]-rot[1]) * w4;
300 quat[1] = sqrt(fabs(-0.5*(rot[4]+rot[8])));
301 quat[2] = sqrt(fabs(-0.5*(rot[0]+rot[8])));
302 quat[3] = sqrt(fabs(-0.5*(rot[0]+rot[4])));
305 double norm = quat[0]*quat[0] + quat[1]*quat[1] + quat[2]*quat[2] +
307 if (fabs(norm) < 1e-10)
322 #define FAIL_TEST { fprintf(stderr, "rot_quaternion_test failed at line %d\n", \
323 __LINE__); return 0; }
325 fprintf(stderr,
"running quaternion test\n");
327 double rvec[] = { 0, 0, 1 };
330 double roll, pitch, yaw;
337 roll = rpy[0]; pitch = rpy[1]; yaw = rpy[2];
345 fprintf(stderr,
"<%.3f, %.3f, %.3f, %.3f>\n", q[0], q[1], q[2], q[3]);
359 double axis1[] = { 0, 1, 0 };
360 double axis2[] = { 0, 0, 1 };
364 rvec[0] = 0; rvec[1] = 0; rvec[2] = 1;
366 fprintf(stderr,
"by q: [ %.2f, %.2f, %.2f ]\n", rvec[0], rvec[1], rvec[2]);
367 rvec[0] = 0; rvec[1] = 0; rvec[2] = 1;
369 fprintf(stderr,
"by q2: [ %.2f, %.2f, %.2f ]\n", rvec[0], rvec[1], rvec[2]);
370 rvec[0] = 0; rvec[1] = 0; rvec[2] = 1;
372 fprintf(stderr,
"by q*q2: [ %.2f, %.2f, %.2f ]\n",
373 rvec[0], rvec[1], rvec[2]);
374 rvec[0] = 0; rvec[1] = 0; rvec[2] = 1;
377 fprintf(stderr,
"by q2*q: [ %.2f, %.2f, %.2f ]\n",
378 rvec[0], rvec[1], rvec[2]);
384 fprintf(stderr,
"rot_quaternion_test complete\n");
void rot_angle_axis_to_roll_pitch_yaw(double theta, const double axis[3], double rpy[3])
int rot_quat_pos_to_matrix(const double quat[4], const double pos[3], double mat[16])
void rot_quat_mult(double c[4], const double a[4], const double b[4])
rot_quat_mult
void rot_roll_pitch_yaw_to_quat(const double rpy[3], double q[4])
int rot_matrix_to_quat(const double rot[9], double quat[4])
void rot_roll_pitch_yaw_to_angle_axis(const double rpy[3], double *theta, double axis[3])
int rot_quaternion_test()
void rot_quat_rotate_rev(const double rot[4], double v[3])
rot_quat_rotate_rev
header file for rotations.cpp Transformation utilities
static int rpyeq(double roll, double pitch, double yaw, double r, double p, double y)
void rot_quat_to_roll_pitch_yaw(const double q[4], double rpy[3])
static int qeq(double *q, double a, double b, double c, double d)
void rot_quat_to_angle_axis(const double q[4], double *theta, double axis[3])
int rot_quat_to_matrix(const double quat[4], double rot[9])
void rot_quat_rotate(const double rot[4], double v[3])
rot_quat_rotate
static int feq(double a, double b)
void rot_angle_axis_to_quat(double theta, const double axis[3], double q[4])