599 Matrix4 transformation_matrix = gicp_->base_transformation_;
600 gicp_->applyState(transformation_matrix, x);
601 const Eigen::Matrix4f transformation_matrix_float =
602 transformation_matrix.template cast<float>();
603 const Eigen::Matrix4f base_transformation_float =
604 gicp_->base_transformation_.template cast<float>();
609 Eigen::Matrix3d dR_dPhi;
610 Eigen::Matrix3d dR_dTheta;
611 Eigen::Matrix3d dR_dPsi;
612 gicp_->getRDerivatives(x[3], x[4], x[5], dR_dPhi, dR_dTheta, dR_dPsi);
613 Eigen::Matrix3d ddR_dPhi_dPhi;
614 Eigen::Matrix3d ddR_dPhi_dTheta;
615 Eigen::Matrix3d ddR_dPhi_dPsi;
616 Eigen::Matrix3d ddR_dTheta_dTheta;
617 Eigen::Matrix3d ddR_dTheta_dPsi;
618 Eigen::Matrix3d ddR_dPsi_dPsi;
619 gicp_->getR2ndDerivatives(x[3],
628 Eigen::Matrix3d dCost_dR_T = Eigen::Matrix3d::Zero();
629 Eigen::Matrix3d dCost_dR_T1 = Eigen::Matrix3d::Zero();
630 Eigen::Matrix3d dCost_dR_T2 = Eigen::Matrix3d::Zero();
631 Eigen::Matrix3d dCost_dR_T3 = Eigen::Matrix3d::Zero();
632 Eigen::Matrix3d dCost_dR_T1b = Eigen::Matrix3d::Zero();
633 Eigen::Matrix3d dCost_dR_T2b = Eigen::Matrix3d::Zero();
634 Eigen::Matrix3d dCost_dR_T3b = Eigen::Matrix3d::Zero();
635 Eigen::Matrix3d hessian_rot_phi = Eigen::Matrix3d::Zero();
636 Eigen::Matrix3d hessian_rot_theta = Eigen::Matrix3d::Zero();
637 Eigen::Matrix3d hessian_rot_psi = Eigen::Matrix3d::Zero();
638 Eigen::Matrix<double, 9, 6> hessian_rot_tmp = Eigen::Matrix<double, 9, 6>::Zero();
640 int m =
static_cast<int>(gicp_->tmp_idx_src_->size());
641 for (
int i = 0; i < m; ++i) {
643 const auto& src_idx = (*gicp_->tmp_idx_src_)[i];
647 (*gicp_->tmp_tgt_)[(*gicp_->tmp_idx_tgt_)[i]].getVector4fMap();
648 Eigen::Vector4f p_trans_src(transformation_matrix_float * p_src);
651 const Eigen::Vector3d d(p_trans_src[0] - p_tgt[0],
652 p_trans_src[1] - p_tgt[1],
653 p_trans_src[2] - p_tgt[2]);
654 const Eigen::Matrix3d& M = gicp_->mahalanobis(src_idx);
655 const Eigen::Vector3d Md(M * d);
656 gradient.head<3>() += Md;
657 hessian.topLeftCorner<3, 3>() += M;
658 p_trans_src.noalias() = base_transformation_float * p_src;
659 const Eigen::Vector3d p_base_src(p_trans_src[0], p_trans_src[1], p_trans_src[2]);
660 dCost_dR_T.noalias() += p_base_src * Md.transpose();
661 dCost_dR_T1b += p_base_src[0] * M;
662 dCost_dR_T2b += p_base_src[1] * M;
663 dCost_dR_T3b += p_base_src[2] * M;
664 hessian_rot_tmp.noalias() +=
665 Eigen::Map<const Eigen::Matrix<double, 9, 1>>{M.data()} *
666 (Eigen::Matrix<double, 1, 6>() << p_base_src[0] * p_base_src[0],
667 p_base_src[0] * p_base_src[1],
668 p_base_src[0] * p_base_src[2],
669 p_base_src[1] * p_base_src[1],
670 p_base_src[1] * p_base_src[2],
671 p_base_src[2] * p_base_src[2])
674 gradient.head<3>() *= 2.0 / m;
675 dCost_dR_T *= 2.0 / m;
676 gicp_->computeRDerivative(x, dCost_dR_T, gradient);
677 hessian.topLeftCorner<3, 3>() *= 2.0 / m;
679 dCost_dR_T1.row(0) = dCost_dR_T1b.col(0);
680 dCost_dR_T1.row(1) = dCost_dR_T2b.col(0);
681 dCost_dR_T1.row(2) = dCost_dR_T3b.col(0);
682 dCost_dR_T2.row(0) = dCost_dR_T1b.col(1);
683 dCost_dR_T2.row(1) = dCost_dR_T2b.col(1);
684 dCost_dR_T2.row(2) = dCost_dR_T3b.col(1);
685 dCost_dR_T3.row(0) = dCost_dR_T1b.col(2);
686 dCost_dR_T3.row(1) = dCost_dR_T2b.col(2);
687 dCost_dR_T3.row(2) = dCost_dR_T3b.col(2);
688 dCost_dR_T1 *= 2.0 / m;
689 dCost_dR_T2 *= 2.0 / m;
690 dCost_dR_T3 *= 2.0 / m;
691 hessian(3, 0) = (dR_dPhi * dCost_dR_T1).trace();
692 hessian(4, 0) = (dR_dTheta * dCost_dR_T1).trace();
693 hessian(5, 0) = (dR_dPsi * dCost_dR_T1).trace();
694 hessian(3, 1) = (dR_dPhi * dCost_dR_T2).trace();
695 hessian(4, 1) = (dR_dTheta * dCost_dR_T2).trace();
696 hessian(5, 1) = (dR_dPsi * dCost_dR_T2).trace();
697 hessian(3, 2) = (dR_dPhi * dCost_dR_T3).trace();
698 hessian(4, 2) = (dR_dTheta * dCost_dR_T3).trace();
699 hessian(5, 2) = (dR_dPsi * dCost_dR_T3).trace();
700 hessian.block<3, 3>(0, 3) = hessian.block<3, 3>(3, 0).transpose();
702 int lookup[3][3] = {{0, 1, 2}, {1, 3, 4}, {2, 4, 5}};
703 for (
int l = 0; l < 3; ++l) {
704 for (
int i = 0; i < 3; ++i) {
705 double phi_tmp = 0.0, theta_tmp = 0.0, psi_tmp = 0.0;
706 for (
int j = 0; j < 3; ++j) {
707 for (
int k = 0; k < 3; ++k) {
708 phi_tmp += hessian_rot_tmp(3 * j + i, lookup[l][k]) * dR_dPhi(j, k);
709 theta_tmp += hessian_rot_tmp(3 * j + i, lookup[l][k]) * dR_dTheta(j, k);
710 psi_tmp += hessian_rot_tmp(3 * j + i, lookup[l][k]) * dR_dPsi(j, k);
713 hessian_rot_phi(i, l) = phi_tmp;
714 hessian_rot_theta(i, l) = theta_tmp;
715 hessian_rot_psi(i, l) = psi_tmp;
718 hessian_rot_phi *= 2.0 / m;
719 hessian_rot_theta *= 2.0 / m;
720 hessian_rot_psi *= 2.0 / m;
721 hessian(3, 3) = (dR_dPhi.transpose() * hessian_rot_phi).trace() +
722 (ddR_dPhi_dPhi * dCost_dR_T).trace();
723 hessian(3, 4) = (dR_dPhi.transpose() * hessian_rot_theta).trace() +
724 (ddR_dPhi_dTheta * dCost_dR_T).trace();
725 hessian(3, 5) = (dR_dPhi.transpose() * hessian_rot_psi).trace() +
726 (ddR_dPhi_dPsi * dCost_dR_T).trace();
727 hessian(4, 4) = (dR_dTheta.transpose() * hessian_rot_theta).trace() +
728 (ddR_dTheta_dTheta * dCost_dR_T).trace();
729 hessian(4, 5) = (dR_dTheta.transpose() * hessian_rot_psi).trace() +
730 (ddR_dTheta_dPsi * dCost_dR_T).trace();
731 hessian(5, 5) = (dR_dPsi.transpose() * hessian_rot_psi).trace() +
732 (ddR_dPsi_dPsi * dCost_dR_T).trace();
733 hessian(4, 3) = hessian(3, 4);
734 hessian(5, 3) = hessian(3, 5);
735 hessian(5, 4) = hessian(4, 5);