@@ -188,17 +188,25 @@ class VectorMathT {
188
188
return rotateVectorReverse (v_world, q, assume_unit_quat);
189
189
}
190
190
191
+ static Vector3T transformToBodyFrame (const Vector3T& v_world, const Pose& body_pose, bool assume_unit_quat = true )
192
+ {
193
+ // translate
194
+ Vector3T translated = v_world - body_pose.position ;
195
+ // rotate
196
+ return transformToBodyFrame (translated, body_pose.orientation , assume_unit_quat);
197
+ }
198
+
191
199
static Vector3T transformToWorldFrame (const Vector3T& v_body, const QuaternionT& q, bool assume_unit_quat = true )
192
200
{
193
201
return rotateVector (v_body, q, assume_unit_quat);
194
202
}
195
203
196
- static Vector3T transformToWorldFrame (const Vector3T& v_body, const Pose& pose , bool assume_unit_quat = true )
204
+ static Vector3T transformToWorldFrame (const Vector3T& v_body, const Pose& body_pose , bool assume_unit_quat = true )
197
205
{
198
206
// translate
199
- Vector3T translated = v_body + pose .position ;
207
+ Vector3T translated = v_body + body_pose .position ;
200
208
// rotate
201
- return transformToWorldFrame (translated, pose .orientation , assume_unit_quat);
209
+ return transformToWorldFrame (translated, body_pose .orientation , assume_unit_quat);
202
210
}
203
211
204
212
static QuaternionT negate (const QuaternionT& q)
@@ -226,6 +234,9 @@ class VectorMathT {
226
234
static void toEulerianAngle (const QuaternionT& q
227
235
, RealT& pitch, RealT& roll, RealT& yaw)
228
236
{
237
+ // z-y-x rotation convention (Tait-Bryan angles)
238
+ // http://www.sedris.org/wg8home/Documents/WG80485.pdf
239
+
229
240
RealT ysqr = q.y () * q.y ();
230
241
231
242
// roll (x-axis rotation)
@@ -300,6 +311,9 @@ class VectorMathT {
300
311
// all angles in radians
301
312
static QuaternionT toQuaternion (RealT pitch, RealT roll, RealT yaw)
302
313
{
314
+ // z-y-x rotation convention (Tait-Bryan angles)
315
+ // http://www.sedris.org/wg8home/Documents/WG80485.pdf
316
+
303
317
QuaternionT q;
304
318
RealT t0 = std::cos (yaw * 0 .5f );
305
319
RealT t1 = std::sin (yaw * 0 .5f );
@@ -413,32 +427,122 @@ class VectorMathT {
413
427
* RPY rotates about the fixed axes in the order x-y-z,
414
428
* which is the same as euler angles in the order z-y'-x''.
415
429
*/
416
- static RealT yawFromQuaternion (const QuaternionT& q) {
430
+ static RealT yawFromQuaternion (const QuaternionT& q)
431
+ {
417
432
return atan2 (2.0 * (q.w () * q.z () + q.x () * q.y ()),
418
433
1.0 - 2.0 * (q.y () * q.y () + q.z () * q.z ()));
419
434
}
420
435
421
- static QuaternionT quaternionFromYaw (RealT yaw) {
422
- return QuaternionT (Eigen::AngleAxisd (yaw, Vector3T::UnitZ ()));
436
+ static QuaternionT quaternionFromYaw (RealT yaw)
437
+ {
438
+ return QuaternionT (Eigen::AngleAxis<RealT>(yaw, Vector3T::UnitZ ()));
439
+ }
440
+
441
+ static QuaternionT toQuaternion (const Vector3T& axis, RealT angle)
442
+ {
443
+ // Alternative:
444
+ // auto s = std::sinf(angle / 2);
445
+ // auto u = axis.normalized();
446
+ // return Quaternionr(std::cosf(angle / 2), u.x() * s, u.y() * s, u.z() * s);
447
+
448
+ return QuaternionT (Eigen::AngleAxis<RealT>(angle, axis));
449
+ }
450
+
451
+ // linear interpolate
452
+ static QuaternionT lerp (const QuaternionT& from, const QuaternionT& to, RealT alpha)
453
+ {
454
+ QuaternionT r;
455
+ RealT n_alpha = 1 - alpha;
456
+ r.x = n_alpha * from.x + alpha * to.x ;
457
+ r.y = n_alpha * from.y + alpha * to.y ;
458
+ r.z = n_alpha * from.z + alpha * to.z ;
459
+ r.w = n_alpha * from.w + alpha * to.w ;
460
+ return r.normalized ();
461
+ }
462
+
463
+ // spherical lerp
464
+ static QuaternionT slerp (const QuaternionT& from, const QuaternionT& to, RealT alpha)
465
+ {
466
+ QuaternionT r;
467
+ RealT n_alpha = 1 - alpha;
468
+ RealT Wa, Wb;
469
+ RealT theta = acos (from.x *to.x + from.y *to.y + from.z *to.z + from.w *to.w );
470
+ RealT sn = sin (theta);
471
+ Wa = sin (n_alpha*theta) / sn;
472
+ Wb = sin (alpha*theta) / sn;
473
+ r.x = Wa * from.x + Wb * to.x ;
474
+ r.y = Wa * from.y + Wb * to.y ;
475
+ r.z = Wa * from.z + Wb * to.z ;
476
+ r.w = Wa * from.w + Wb * to.w ;
477
+ return r.normalized ();
478
+ }
479
+
480
+ Vector3T lerp (const Vector3T& from, const Vector3T& to, RealT alpha)
481
+ {
482
+ return (from + alpha * (to - from));
483
+ }
484
+
485
+ Vector3T slerp (const Vector3T& from, const Vector3T& to, RealT alpha)
486
+ {
487
+ RealT dot = from.dot (to);
488
+ dot = Utils::clip<RealT>(dot, -1 , 1 );
489
+ RealT theta = std::acos (dot)*alpha;
490
+ Vector3T relative = (to - from * dot).normalized ();
491
+ return from * std::cos (theta) + relative * std::sin (theta);
492
+ }
493
+
494
+ Vector3T nlerp (const Vector3T& from, const Vector3T& to, float alpha)
495
+ {
496
+ return lerp (from, to, alpha).normalized ();
497
+ }
498
+
499
+ static QuaternionT lookAt (Vector3T sourcePoint, Vector3T destPoint)
500
+ {
501
+ Vector3T toVector = (destPoint - sourcePoint);
502
+
503
+ RealT dot = VectorMath::front ().dot (toVector);
504
+ dot = Utils::clip<RealT>(dot, -1 , 1 );
505
+ RealT ang = std::acosf (dot);
506
+
507
+ Vector3T axis = VectorMath::front ().cross (toVector);
508
+ if (axis == Vector3T::Zero ())
509
+ axis = VectorMath::up ();
510
+ else
511
+ axis = axis.normalized ();
512
+
513
+ return VectorMath::toQuaternion (axis, ang);
423
514
}
424
515
425
516
static const Vector3T front ()
426
517
{
427
518
static Vector3T v (1 , 0 , 0 );
428
519
return v;
429
520
}
430
-
521
+ static const Vector3T back ()
522
+ {
523
+ static Vector3T v (-1 , 0 , 0 );
524
+ return v;
525
+ }
431
526
static const Vector3T down ()
432
527
{
433
528
static Vector3T v (0 , 0 , 1 );
434
529
return v;
435
530
}
436
-
531
+ static const Vector3T up ()
532
+ {
533
+ static Vector3T v (0 , 0 , -1 );
534
+ return v;
535
+ }
437
536
static const Vector3T right ()
438
537
{
439
538
static Vector3T v (0 , 1 , 0 );
440
539
return v;
441
540
}
541
+ static const Vector3T left ()
542
+ {
543
+ static Vector3T v (0 , -1 , 0 );
544
+ return v;
545
+ }
442
546
};
443
547
typedef VectorMathT<Eigen::Vector3d, Eigen::Quaternion<double ,Eigen::DontAlign>, double > VectorMathd;
444
548
typedef VectorMathT<Eigen::Vector3f, Eigen::Quaternion<float ,Eigen::DontAlign>, float > VectorMathf;
0 commit comments