16 #include <mrpt/poses/Lie/SE.h>
18 #include <Eigen/Dense>
21 #if defined(MP2P_HAS_TBB)
22 #include <tbb/blocked_range.h>
23 #include <tbb/parallel_reduce.h>
40 "This method requires a linearization point");
55 Eigen::Matrix<double, 6, 1> g = Eigen::Matrix<double, 6, 1>::Zero();
56 Eigen::Matrix<double, 6, 6> H = Eigen::Matrix<double, 6, 6>::Zero();
62 std::size_t cur_point_block_start = 0;
67 const auto dDexpe_de =
68 mrpt::poses::Lie::SE<3>::jacob_dDexpe_de(result.
optimalPose);
70 double errNormSqr = 0;
72 #if defined(MP2P_HAS_TBB)
90 Eigen::Matrix<double, 6, 6> H;
91 Eigen::Matrix<double, 6, 1> g;
94 const auto& [H_tbb_pt2pt, g_tbb_pt2pt] = tbb::parallel_reduce(
96 tbb::blocked_range<size_t>{0, nPt2Pt},
100 [&](
const tbb::blocked_range<size_t>& r, Result
res) -> Result
102 auto& [H_local, g_local] =
res;
103 for (
size_t idx_pt = r.begin(); idx_pt < r.end(); idx_pt++)
107 mrpt::math::CMatrixFixed<double, 3, 12> J1;
108 mrpt::math::CVectorFixedDouble<3> ret =
112 if (has_per_pt_weight)
114 if (idx_pt >= cur_point_block_start +
115 cur_point_block_weights->first)
118 cur_point_block_weights !=
120 ++cur_point_block_weights;
121 cur_point_block_start = idx_pt;
123 w.pt2pt = cur_point_block_weights->second;
127 double weight = w.pt2pt,
128 retSqrNorm = ret.asEigen().squaredNorm();
129 if (robustSqrtWeightFunc)
130 weight *= robustSqrtWeightFunc(retSqrNorm);
133 const Eigen::Vector3d err_i = ret.asEigen();
134 errNormSqr += weight * retSqrNorm;
136 const Eigen::Matrix<double, 3, 6> Ji =
137 J1.asEigen() * dDexpe_de.asEigen();
138 g_local.noalias() += weight * Ji.transpose() * err_i;
139 H_local.noalias() += weight * Ji.transpose() * Ji;
144 [](Result a,
const Result& b) -> Result {
return a + b; });
146 H = std::move(H_tbb_pt2pt);
147 g = std::move(g_tbb_pt2pt);
150 for (
size_t idx_pt = 0; idx_pt < nPt2Pt; idx_pt++)
154 mrpt::math::CMatrixFixed<double, 3, 12> J1;
155 mrpt::math::CVectorFixedDouble<3> ret =
159 if (has_per_pt_weight)
162 cur_point_block_start + cur_point_block_weights->first)
165 ++cur_point_block_weights;
166 cur_point_block_start = idx_pt;
168 w.pt2pt = cur_point_block_weights->second;
172 double weight = w.pt2pt, retSqrNorm = ret.asEigen().squaredNorm();
173 if (robustSqrtWeightFunc)
174 weight *= robustSqrtWeightFunc(retSqrNorm);
177 const Eigen::Vector3d err_i = ret.asEigen();
178 errNormSqr += weight * retSqrNorm;
180 const Eigen::Matrix<double, 3, 6> Ji =
181 J1.asEigen() * dDexpe_de.asEigen();
182 g.noalias() += weight * Ji.transpose() * err_i;
183 H.noalias() += weight * Ji.transpose() * Ji;
188 for (
size_t idx_pt = 0; idx_pt < nPt2Ln; idx_pt++)
192 mrpt::math::CMatrixFixed<double, 3, 12> J1;
193 mrpt::math::CVectorFixedDouble<3> ret =
197 double weight = w.pt2ln, retSqrNorm = ret.asEigen().squaredNorm();
198 if (robustSqrtWeightFunc)
199 weight *= robustSqrtWeightFunc(retSqrNorm);
202 const Eigen::Vector3d err_i = ret.asEigen();
203 errNormSqr += weight * weight * retSqrNorm;
205 const Eigen::Matrix<double, 3, 6> Ji =
206 J1.asEigen() * dDexpe_de.asEigen();
207 g.noalias() += weight * Ji.transpose() * err_i;
208 H.noalias() += weight * Ji.transpose() * Ji;
213 for (
size_t idx_ln = 0; idx_ln < nLn2Ln; idx_ln++)
216 mrpt::math::CMatrixFixed<double, 4, 12> J1;
217 mrpt::math::CVectorFixedDouble<4> ret =
221 double weight = w.ln2ln, retSqrNorm = ret.asEigen().squaredNorm();
222 if (robustSqrtWeightFunc)
223 weight *= robustSqrtWeightFunc(retSqrNorm);
226 const Eigen::Vector4d err_i = ret.asEigen();
227 errNormSqr += weight * weight * retSqrNorm;
229 const Eigen::Matrix<double, 4, 6> Ji =
230 J1.asEigen() * dDexpe_de.asEigen();
231 g.noalias() += weight * Ji.transpose() * err_i;
232 H.noalias() += weight * Ji.transpose() * Ji;
235 #if defined(MP2P_HAS_TBB)
237 const auto& [H_tbb_pt2pl, g_tbb_pt2pl] = tbb::parallel_reduce(
239 tbb::blocked_range<size_t>{0, nPt2Pl},
243 [&](
const tbb::blocked_range<size_t>& r, Result
res) -> Result
245 auto& [H_local, g_local] =
res;
246 for (
size_t idx_pl = r.begin(); idx_pl < r.end(); idx_pl++)
250 mrpt::math::CMatrixFixed<double, 3, 12> J1;
251 mrpt::math::CVectorFixedDouble<3> ret =
255 double weight = w.pt2pl,
256 retSqrNorm = ret.asEigen().squaredNorm();
257 if (robustSqrtWeightFunc)
258 weight *= robustSqrtWeightFunc(retSqrNorm);
261 const Eigen::Vector3d err_i = ret.asEigen();
262 errNormSqr += weight * retSqrNorm;
264 const Eigen::Matrix<double, 3, 6> Ji =
265 J1.asEigen() * dDexpe_de.asEigen();
266 g_local.noalias() += weight * Ji.transpose() * err_i;
267 H_local.noalias() += weight * Ji.transpose() * Ji;
272 [](Result a,
const Result& b) -> Result {
return a + b; });
278 for (
size_t idx_pl = 0; idx_pl < nPt2Pl; idx_pl++)
282 mrpt::math::CMatrixFixed<double, 3, 12> J1;
283 mrpt::math::CVectorFixedDouble<3> ret =
287 double weight = w.pt2pl, retSqrNorm = ret.asEigen().squaredNorm();
288 if (robustSqrtWeightFunc)
289 weight *= robustSqrtWeightFunc(retSqrNorm);
292 const Eigen::Vector3d err_i = ret.asEigen();
293 errNormSqr += weight * weight * retSqrNorm;
295 const Eigen::Matrix<double, 3, 6> Ji =
296 J1.asEigen() * dDexpe_de.asEigen();
297 g.noalias() += weight * Ji.transpose() * err_i;
298 H.noalias() += weight * Ji.transpose() * Ji;
303 for (
size_t idx_pl = 0; idx_pl < nPl2Pl; idx_pl++)
307 mrpt::math::CMatrixFixed<double, 3, 12> J1;
308 mrpt::math::CVectorFixedDouble<3> ret =
312 double weight = w.pl2pl, retSqrNorm = ret.asEigen().squaredNorm();
313 if (robustSqrtWeightFunc)
314 weight *= robustSqrtWeightFunc(retSqrNorm);
316 const Eigen::Vector3d err_i = ret.asEigen();
317 errNormSqr += weight * weight * retSqrNorm;
319 const Eigen::Matrix<double, 3, 6> Ji =
320 J1.asEigen() * dDexpe_de.asEigen();
321 g.noalias() += weight * Ji.transpose() * err_i;
322 H.noalias() += weight * Ji.transpose() * Ji;
326 if (gnParams.
prior.has_value())
328 const auto& priorMean = gnParams.
prior->mean;
329 const auto& priorInf = gnParams.
prior->cov_inv;
336 const mrpt::poses::CPose3D P1invP2 = result.
optimalPose - priorMean;
337 const auto err_i = mrpt::poses::Lie::SE<3>::log(P1invP2);
339 mrpt::math::CMatrixDouble66 df_de2;
341 mrpt::poses::Lie::SE<3>::jacob_dDinvP1invP2_de1e2(
343 mrpt::poses::CPose3D::Identity(),
354 (df_de2.transpose() * priorInf.asEigen()) * err_i.asEigen();
357 (df_de2.transpose() * priorInf.asEigen()) * df_de2.asEigen();
361 const double errNorm = std::sqrt(errNormSqr);
363 if (errNorm <= gnParams.
maxCost)
break;
368 const Eigen::Matrix<double, 6, 1> delta = -H.ldlt().solve(g);
371 const auto dE = mrpt::poses::Lie::SE<3>::exp(
372 mrpt::math::CVectorFixed<double, 6>(delta));
378 std::cout <<
"[P2P GN] iter:" << iter <<
" err:" << errNorm
379 <<
" delta:" << delta.transpose() <<
"\n";
383 if (delta.norm() < gnParams.
minDelta)
break;