1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64
| void park_martin(std::vector<Eigen::Matrix4d> A, std::vector<Eigen::Matrix4d> B, Eigen::Matrix4d& result) { int dataLength = A.size(); if(dataLength != B.size()) { return; }
Eigen::Matrix3d M = Eigen::Matrix3d::Zero();
for (int i = 0; i < dataLength; i++) { Eigen::Matrix3d Ra = A[i].toMatrix().block<3, 3>(0, 0); Eigen::Matrix3d Rb = B[i].toMatrix().block<3, 3>(0, 0); M += log(Rb) * log(Ra).transpose(); }
Eigen::Matrix3d theta_X = invsqrt(M.transpose() * M) * M.transpose();
Eigen::MatrixXd C(3 * dataLength, 3); Eigen::MatrixXd y(3 * dataLength, 1);
for (int i = 0; i < dataLength; i++) { Eigen::Matrix3d Ra = A[i].toMatrix().block<3, 3>(0, 0); Eigen::Vector3d b_a = A[i].toMatrix().block<3, 1>(0, 3);
Eigen::Matrix3d Rb = B[i].toMatrix().block<3, 3>(0, 0); Eigen::Vector3d b_b = B[i].toMatrix().block<3, 1>(0, 3); C.block<3, 3>(i * 3, 0) = Ra - Eigen::Matrix3d::Identity(); y.block<3, 1>(i * 3, 0) = theta_X * b_b - b_a; } Eigen::Vector3d b_x = (C.transpose() * C).inverse() * C.transpose() * y;
Eigen::Matrix4d result_M = Eigen::Matrix4d::Identity(); result_M.block<3, 3>(0, 0) = theta_X; result_M.block<3, 1>(0, 3) = b_x; result = result_M; }
Eigen::Vector3d DrsToolCalibration::log(Eigen::Matrix3d rotM) { double theta = std::acos((rotM(0, 0) + rotM(1, 1) + rotM(2, 2) - 1.0) / 2.0); return Eigen::Vector3d(rotM(2, 1) - rotM(1, 2), rotM(0, 2) - rotM(2, 0), rotM(1, 0) - rotM(0, 1))* theta / (2 * std::sin(theta)); }
Eigen::Matrix3d DrsToolCalibration::invsqrt(Eigen::Matrix3d rotM) { if (rotM.rows() != rotM.cols()) { return Eigen::MatrixXd(); } Eigen::JacobiSVD<Eigen::MatrixXd> svd(rotM, Eigen::ComputeThinU | Eigen::ComputeThinV); Eigen::VectorXd s = svd.singularValues(); for (int i = 0; i < s.size(); ++i) { if (s(i) <= 0) { break; } } Eigen::VectorXd inv_sqrt_s = s.array().inverse().sqrt(); return svd.matrixU() * inv_sqrt_s.asDiagonal() * svd.matrixV().transpose(); }
|