@@ -541,12 +541,27 @@ void so32quat(const Vector3d &so3, double *q) {
541541 }
542542}
543543void SO32quat (const Matrix3d &SO3, double *q) {
544- Quaterniond q_eigen (SO3);
545- q_eigen.normalize ();
546- q[0 ] = q_eigen.w ();
547- q[1 ] = q_eigen.x ();
548- q[2 ] = q_eigen.y ();
549- q[3 ] = q_eigen.z ();
544+ // Eigen implementation assumes input matrix is strictly orthogonal and is not
545+ // numerically stable sometimes.
546+ Quaterniond q_eigen (SO3);
547+ q_eigen.normalize ();
548+ q[0 ] = q_eigen.w ();
549+ q[1 ] = q_eigen.x ();
550+ q[2 ] = q_eigen.y ();
551+ q[3 ] = q_eigen.z ();
552+ // double r11 = SO3(0,0);
553+ // double r12 = SO3(0,1);
554+ // double r13 = SO3(0,2);
555+ // double r21 = SO3(1,0);
556+ // double r22 = SO3(1,1);
557+ // double r23 = SO3(1,2);
558+ // double r31 = SO3(2,0);
559+ // double r32 = SO3(2,1);
560+ // double r33 = SO3(2,2);
561+ // q1_sq = 0.25*(1.0+r11+r22+r33);
562+ // q2_sq = 0.25*(1.0+r11-r22-r33);
563+ // q3_sq = 0.25*(1.0-r11+r22-r33);
564+ // q4_sq = 0.25*(1.0-r11-r22+r33);
550565}
551566
552567Matrix4d pose2SE3 (const double *pose) {
@@ -881,17 +896,13 @@ CartesianPose::CartesianPose(std::vector<double> pose) {
881896 (*p_)[0 ] = pose[0 ];
882897 (*p_)[1 ] = pose[1 ];
883898 (*p_)[2 ] = pose[2 ];
884- qw_ = pose[3 ];
885- qx_ = pose[4 ];
886- qy_ = pose[5 ];
887- qz_ = pose[6 ];
888899 double norm = sqrt (pose[3 ]*pose[3 ] + pose[4 ]*pose[4 ] + pose[5 ]*pose[5 ]
889900 + pose[6 ]*pose[6 ]);
890901 assert (abs (norm - 1.0 ) < 0.1 );
891- // q_->w() = pose[3]/norm;
892- // q_->x() = pose[4]/norm;
893- // q_->y() = pose[5]/norm;
894- // q_->z() = pose[6]/norm;
902+ qw_ = pose[3 ]/norm;
903+ qx_ = pose[4 ]/norm;
904+ qy_ = pose[5 ]/norm;
905+ qz_ = pose[6 ]/norm;
895906 Eigen::Quaterniond q = Eigen::Quaterniond (qw_, qx_, qy_, qz_);
896907 *R_ = q.toRotationMatrix ();
897908}
@@ -922,6 +933,11 @@ CartesianPose::CartesianPose(const Eigen::MatrixXd &T) {
922933 *p_ = T.block <3 ,1 >(0 ,3 );
923934 *R_ = T.block <3 ,3 >(0 ,0 );
924935 Eigen::Quaterniond q = Eigen::Quaterniond (*R_);
936+ if (fabs (q.norm () - 1 ) > 0.1 ) {
937+ std::cout << " [cpplibrary] Error: input matrix is not orthonormal." << std::endl;
938+ std::cout << " R:\n " << *R_ << std::endl;
939+ std::cout << " R'*R:\n " << R_->transpose ()*(*R_) << std::endl;
940+ }
925941 qw_ = q.w ();
926942 qx_ = q.x ();
927943 qy_ = q.y ();
0 commit comments