1 #ifndef SimTK_SimTKCOMMON_ROTATION_H_
2 #define SimTK_SimTKCOMMON_ROTATION_H_
46 template <
class P>
class Rotation_;
165 Rotation_(
BodyOrSpaceType bodyOrSpace,
RealP angle1,
const CoordinateAxis& axis1,
RealP angle2,
const CoordinateAxis& axis2,
RealP angle3,
const CoordinateAxis& axis3 ) {
setRotationFromThreeAnglesThreeAxes(bodyOrSpace,angle1,axis1,angle2,axis2,angle3,axis3); }
255 for(
int i=0; i<=2; i++ )
for(
int j=0; j<=2; j++ )
256 {
RealP absDiff = std::fabs(A[i][j] - B[i][j]);
257 if( absDiff > maxDiff ) maxDiff = absDiff; }
314 {
Mat33P& R = *
this; R=m;
return *
this; }
316 {
Mat33P& R = *
this; R(colj)=uvecj.
asVec3();
return *
this; }
334 const RealP s0s1=s[0]*s[1], s2c0=s[2]*c[0], c0c2=c[0]*c[2], nc1= -c[1];
336 R =
Mat33P( c[1]*c[2] , s[2]*nc1 , s[1] ,
337 s2c0 + s0s1*c[2] , c0c2 - s0s1*s[2] , s[0]*nc1 ,
338 s[0]*s[2] - s[1]*c0c2 , s[0]*c[2] + s[1]*s2c0 , c[0]*c[1] );
348 const RealP s1 = std::sin(q[1]), c1 = std::cos(q[1]);
349 const RealP s2 = std::sin(q[2]), c2 = std::cos(q[2]);
351 const RealP s2oc1 = s2*ooc1, c2oc1 = c2*ooc1;
353 const Mat33P E( 0, s2oc1 , c2oc1 ,
355 1, s1*s2oc1 , s1*c2oc1 );
362 const RealP s1 = std::sin(q[1]), c1 = std::cos(q[1]);
363 const RealP s2 = std::sin(q[2]), c2 = std::cos(q[2]);
365 const Mat33P Einv( -s1 , 0 , 1 ,
378 const RealP s1 = std::sin(q[1]), c1 = std::cos(q[1]);
379 const RealP s2 = std::sin(q[2]), c2 = std::cos(q[2]);
380 const RealP ooc1 = 1/c1;
381 const RealP s2oc1 = s2*ooc1, c2oc1 = c2*ooc1, s1oc1 = s1*ooc1;
383 const Mat33P E( 0 , s2oc1 , c2oc1 ,
385 1 , s1*s2oc1 , s1*c2oc1 );
386 const Vec3P qdot = E * w_PB_B;
388 const RealP t = qdot[1]*s1oc1;
389 const RealP a = t*s2oc1 + qdot[2]*c2oc1;
390 const RealP b = t*c2oc1 - qdot[2]*s2oc1;
392 const Mat33P Edot( 0 , a , b ,
393 0 , -qdot[2]*s2 , -qdot[2]*c2 ,
394 0 , s1*a + qdot[1]*s2 , s1*b + qdot[1]*c2 );
396 return E*wdot_PB_B + Edot*w_PB_B;
414 (
Vec3P(0, std::cos(q[1]), std::cos(q[2])),
415 Vec3P(0, std::sin(q[1]), std::sin(q[2])));
424 const RealP s1 = sq[1], c1 = cq[1];
425 const RealP s2 = sq[2], c2 = cq[2];
426 const RealP ooc1 = 1/c1;
427 const RealP s2oc1 = s2*ooc1, c2oc1 = c2*ooc1;
429 return Mat33P( c2oc1 , -s2oc1 , 0,
431 -s1*c2oc1 , s1*s2oc1, 1 );
450 (
Vec3P(std::cos(q[0]), std::cos(q[1]), 0),
451 Vec3P(std::sin(q[0]), std::sin(q[1]), 0));
461 const RealP s0 = sq[0], c0 = cq[0];
462 const RealP s1 = sq[1], c1 = cq[1];
463 const RealP ooc1 = 1/c1;
464 const RealP s0oc1 = s0*ooc1, c0oc1 = c0*ooc1;
466 return Mat33P( 1 , s1*s0oc1 , -s1*c0oc1,
468 0 , -s0oc1 , c0oc1 );
482 const RealP s0 = sinxy[0], c0 = cosxy[0];
483 const RealP s1 = sinxy[1];
484 const RealP w0 = w_PB[0], w1 = w_PB[1], w2 = w_PB[2];
486 const RealP t = (s0*w1-c0*w2)*oocosy;
487 return Vec3P( w0 + t*s1, c0*w1 + s0*w2, -t );
498 const RealP s0 = sinxy[0], c0 = cosxy[0];
499 const RealP s1 = sinxy[1];
500 const RealP q0 = q[0], q1 = q[1], q2 = q[2];
502 const RealP t = (q0*s1-q2) * oocosy;
503 return Vec3P( q0, c0*q1 + t*s0, s0*q1 - t*c0 );
539 const RealP s1 = sinxy[1], c1 = cosxy[1];
540 const RealP q0 = qdot[0], q1 = qdot[1], q2 = qdot[2];
545 const RealP q1oc1 = q1*oocosy;
546 const Vec3P NDotw((q0*s1-q2)*q1oc1,
560 const RealP s0 = sinxy[0], c0 = cosxy[0];
561 const RealP s1 = sinxy[1], c1 = cosxy[1];
562 const RealP q0 = qdot[0], q1 = qdot[1], q2 = qdot[2];
563 const RealP c1q2 = c1*q2;
565 return Vec3P( q0 + s1*q2,
576 const RealP s0 = sinxy[0], c0 = cosxy[0];
577 const RealP s1 = sinxy[1], c1 = cosxy[1];
578 const RealP w0 = v_P[0], w1 = v_P[1], w2 = v_P[2];
582 s1*w0 - s0*c1*w1 + c0*c1*w2);
599 (
Vec3P(0, std::cos(q[1]), std::cos(q[2])),
600 Vec3P(0, std::sin(q[1]), std::sin(q[2])),
612 const RealP s1 = sq[1], c1 = cq[1];
613 const RealP s2 = sq[2], c2 = cq[2];
614 const RealP ooc1 = 1/c1;
615 const RealP s2oc1 = s2*ooc1, c2oc1 = c2*ooc1;
617 const RealP t = qdot[1]*s1*ooc1;
618 const RealP a = t*s2oc1 + qdot[2]*c2oc1;
619 const RealP b = t*c2oc1 - qdot[2]*s2oc1;
621 return Mat33P( b , -a , 0,
622 qdot[2]*c2 , -qdot[2]*s2 , 0,
623 -(s1*b + qdot[1]*c2) , s1*a + qdot[1]*s2 , 0 );
639 const RealP cy = std::cos(q[1]);
641 (
Vec2P(std::cos(q[0]), cy),
642 Vec2P(std::sin(q[0]), std::sin(q[1])),
652 const RealP s0 = sq[0], c0 = cq[0];
653 const RealP s1 = sq[1], c1 = cq[1];
654 const RealP s0oc1 = s0*ooc1, c0oc1 = c0*ooc1;
656 const RealP t = qdot[1]*s1*ooc1;
657 const RealP a = t*s0oc1 + qdot[0]*c0oc1;
658 const RealP b = t*c0oc1 - qdot[0]*s0oc1;
660 return Mat33P( 0, s1*a + qdot[1]*s0, -(s1*b + qdot[1]*c0),
661 0, -qdot[0]*s0 , qdot[0]*c0 ,
677 (
Vec3P(0, std::cos(q[1]), std::cos(q[2])),
678 Vec3P(0, std::sin(q[1]), std::sin(q[2])));
688 const RealP s1 = sq[1], c1 = cq[1];
689 const RealP s2 = sq[2], c2 = cq[2];
691 return Mat33P( c1*c2 , s2 , 0 ,
707 (
Vec3P(std::cos(q[0]), std::cos(q[1]), 0),
708 Vec3P(std::sin(q[0]), std::sin(q[1]), 0));
718 const RealP s0 = sq[0], c0 = cq[0];
719 const RealP s1 = sq[1], c1 = cq[1];
721 return Mat33P( 1 , 0 , s1 ,
737 (
Vec3P(0, std::cos(q[1]), std::cos(q[2])),
738 Vec3P(0, std::sin(q[1]), std::sin(q[2])),
760 (
Vec3P(0, std::cos(q[1]), std::cos(q[2])),
761 Vec3P(0, std::sin(q[1]), std::sin(q[2])),
786 (
Vec3P(0, std::cos(q[1]), std::cos(q[2])),
787 Vec3P(0, std::sin(q[1]), std::sin(q[2])),
802 const Vec3P qdot = N * w_PB_B;
805 return N*wdot_PB_B + NDot*w_PB_B;
815 const RealP ne1 = -e[1], ne2 = -e[2], ne3 = -e[3];
816 return Mat43P( ne1, ne2, ne3,
829 const Vec4P ed = qdot/2;
830 const RealP ned1 = -ed[1], ned2 = -ed[2], ned3 = -ed[3];
831 return Mat43P( ned1, ned2, ned3,
847 const RealP ne1 = -e[1], ne2 = -e[2], ne3 = -e[3];
848 return Mat34P(ne1, e[0], ne3, e[2],
849 ne2, e[3], e[0], ne1,
850 ne3, ne2, e[1], e[0]);
879 const Vec4P qdot = N*w_PB_P;
882 return N*wdot_PB_P + NDot*w_PB_P;
895 const Vec4P Nb = N*b_PB;
909 :
Mat33P( xx,xy,xz, yx,yy,yz, zx,zy,zz ) {}
920 SimTK_SimTKCOMMON_EXPORT Vec3P convertTwoAxesBodyFixedRotationToThreeAngles(
const CoordinateAxis& axis1,
const CoordinateAxis& axis2 )
const;
921 SimTK_SimTKCOMMON_EXPORT Vec3P convertThreeAxesBodyFixedRotationToThreeAngles(
const CoordinateAxis& axis1,
const CoordinateAxis& axis2,
const CoordinateAxis& axis3 )
const;
929 static Mat33P calcQBlockForBodyXYZInBodyFrame(
const Vec3P& a)
932 static Mat33P calcQInvBlockForBodyXYZInBodyFrame(
const Vec3P& a)
935 static Mat<4,3,P> calcUnnormalizedQBlockForQuaternion(
const Vec4P& q)
938 static Mat<3,4,P> calcUnnormalizedQInvBlockForQuaternion(
const Vec4P& q)
941 static Vec3P convertAngVelToBodyFixed123Dot(
const Vec3P& q,
const Vec3P& w_PB_B)
944 static Vec3P convertBodyFixed123DotToAngVel(
const Vec3P& q,
const Vec3P& qdot)
947 static Vec3P convertAngVelDotToBodyFixed123DotDot
984 static Rotation_ aboutYThenNewX(
const RealP& yInRad,
const RealP& xInRad) {
return aboutXThenOldY(xInRad, yInRad); }
985 static Rotation_ aboutXThenNewZ(
const RealP& xInRad,
const RealP& zInRad) {
return aboutZThenOldX(zInRad, xInRad); }
986 static Rotation_ aboutZThenNewX(
const RealP& zInRad,
const RealP& xInRad) {
return aboutXThenOldZ(xInRad, zInRad); }
987 static Rotation_ aboutYThenNewZ(
const RealP& yInRad,
const RealP& zInRad) {
return aboutZThenOldY(zInRad, yInRad); }
988 static Rotation_ aboutZThenNewY(
const RealP& zInRad,
const RealP& yInRad) {
return aboutYThenOldZ(yInRad, zInRad); }
1119 operator<<(std::ostream&, const Rotation_<P>&);
1122 operator<<(std::ostream&, const InverseRotation_<P>&);
1128 template <
class P,
int S>
inline UnitVec<P,1>
1130 template <
class P,
int S>
inline UnitRow<P,1>
1132 template <
class P,
int S>
inline UnitVec<P,1>
1134 template <
class P,
int S>
inline UnitRow<P,1>
1139 template <
class P>
inline
1156 template <
class P>
inline Rotation_<P>
1158 template <
class P>
inline Rotation_<P>
1160 template <
class P>
inline Rotation_<P>
1167 template <
class P>
inline Rotation_<P>
1169 template <
class P>
inline Rotation_<P>
1171 template <
class P>
inline Rotation_<P>
1173 template <
class P>
inline Rotation_<P>
1182 #endif // SimTK_SimTKCOMMON_ROTATION_H_