56 #ifndef NDT__NDT_OPTIMIZATION_PROBLEM_HPP_ 57 #define NDT__NDT_OPTIMIZATION_PROBLEM_HPP_ 66 #include <experimental/optional> 68 #include <Eigen/Geometry> 77 namespace localization
82 template<
typename ScalarT>
86 if (std::isnan(p) || p > ScalarT{1.0} || p < ScalarT{0.0}) {
96 template<
typename MapT,
99 EigenPose<Real>, 1U, 6U, common::optimization::EigenComparator>
129 : m_scan_ref(scan), m_map_ref(map)
137 Eigen::Transform<float64_t, 3, Eigen::Affine, Eigen::ColMajor> transform;
138 transform.setIdentity();
144 std::experimental::optional<GradientAngleParameters> grad_params;
147 std::experimental::optional<HessianAngleParameters> hessian_params;
151 const AngleParameters angle_params{x};
155 grad_params.emplace(angle_params);
159 hessian_params.emplace(angle_params);
163 for (
const auto & pt : m_scan_ref) {
168 point_gradient.setZero();
169 point_gradient.block<3, 3>(0, 0).setIdentity();
170 compute_point_gradients(grad_params.value(), pt, point_gradient);
173 point_hessian.setZero();
174 compute_point_hessians(hessian_params.value(), pt, point_hessian);
178 const Point pt_trans = transform * pt;
179 const auto & cells = m_map_ref.cell(pt_trans);
181 for (
const auto & cell : cells) {
182 const Point pt_trans_norm = pt_trans - cell.centroid();
185 const auto & inv_cov = cell.inverse_covariance();
187 Real e_x_cov_x = std::exp(
188 -m_gauss_d2 * pt_trans_norm.dot(
189 inv_cov * pt_trans_norm) / 2.0);
192 score += -m_gauss_d1 * e_x_cov_x;
196 const auto d2_e_x_cov_x = m_gauss_d2 * e_x_cov_x;
206 const auto d1_d2_e_x_cov_x = m_gauss_d1 * d2_e_x_cov_x;
208 for (
auto i = 0U; i < jacobian.rows(); ++i) {
209 const Point cov_dxd_pi = inv_cov * point_gradient.col(i);
211 jacobian(i) += pt_trans_norm.dot(cov_dxd_pi) * d1_d2_e_x_cov_x;
214 for (
auto j = 0U; j < hessian.cols(); ++j) {
215 hessian(i, j) += d1_d2_e_x_cov_x * (-m_gauss_d2 * pt_trans_norm.dot(cov_dxd_pi) *
216 pt_trans_norm.dot(inv_cov * point_gradient.col(j)) +
217 pt_trans_norm.dot(inv_cov * point_hessian.block<3, 1>(3 * i, j)) +
218 point_gradient.col(j).dot(cov_dxd_pi));
239 struct AngleParameters
242 static constexpr
auto approx_thresh{10e-5};
243 AngleParameters() =
delete;
246 if (std::fabs(pose(3)) < approx_thresh) {
250 cx = std::cos(pose(3));
251 sx = std::sin(pose(3));
254 if (std::fabs(pose(4)) < approx_thresh) {
258 cy = std::cos(pose(4));
259 sy = std::sin(pose(4));
262 if (std::fabs(pose(5)) < approx_thresh) {
266 cz = std::cos(pose(5));
267 sz = std::sin(pose(5));
280 struct GradientAngleParameters
283 GradientAngleParameters() =
delete;
284 explicit GradientAngleParameters(
const AngleParameters & params)
286 j_ang_a(0) = -params.sx * params.sz + params.cx * params.sy * params.cz;
287 j_ang_a(1) = -params.sx * params.cz - params.cx * params.sy * params.sz;
288 j_ang_a(2) = -params.cx * params.cy;
290 j_ang_b(0) = params.cx * params.sz + params.sx * params.sy * params.cz;
291 j_ang_b(1) = params.cx * params.cz - params.sx * params.sy * params.sz;
292 j_ang_b(2) = -params.sx * params.cy;
294 j_ang_c(0) = -params.sy * params.cz;
295 j_ang_c(1) = params.sy * params.sz;
296 j_ang_c(2) = params.cy;
298 j_ang_d(0) = params.sx * params.cy * params.cz;
299 j_ang_d(1) = -params.sx * params.cy * params.sz;
300 j_ang_d(2) = params.sx * params.sy;
302 j_ang_e(0) = -params.cx * params.cy * params.cz;
303 j_ang_e(1) = params.cx * params.cy * params.sz;
304 j_ang_e(2) = -params.cx * params.sy;
306 j_ang_f(0) = -params.cy * params.sz;
307 j_ang_f(1) = -params.cy * params.cz;
310 j_ang_g(0) = params.cx * params.cz - params.sx * params.sy * params.sz;
311 j_ang_g(1) = -params.cx * params.sz - params.sx * params.sy * params.cz;
314 j_ang_h(0) = params.sx * params.cz + params.cx * params.sy * params.sz;
315 j_ang_h(1) = params.cx * params.sy * params.cz - params.sx * params.sz;
319 Point j_ang_a, j_ang_b, j_ang_c, j_ang_d, j_ang_e, j_ang_f, j_ang_g, j_ang_h;
323 struct HessianAngleParameters
326 HessianAngleParameters() =
delete;
327 explicit HessianAngleParameters(
const AngleParameters & params)
329 h_ang_a2(0) = -params.cx * params.sz - params.sx * params.sy * params.cz;
330 h_ang_a2(1) = -params.cx * params.cz + params.sx * params.sy * params.sz;
331 h_ang_a2(2) = params.sx * params.cy;
333 h_ang_a3(0) = -params.sx * params.sz + params.cx * params.sy * params.cz;
334 h_ang_a3(1) = -params.cx * params.sy * params.sz - params.sx * params.cz;
335 h_ang_a3(2) = -params.cx * params.cy;
337 h_ang_b2(0) = params.cx * params.cy * params.cz;
338 h_ang_b2(1) = -params.cx * params.cy * params.sz;
339 h_ang_b2(2) = params.cx * params.sy;
341 h_ang_b3(0) = params.sx * params.cy * params.cz;
342 h_ang_b3(1) = -params.sx * params.cy * params.sz;
343 h_ang_b3(2) = params.sx * params.sy;
345 h_ang_c2(0) = -params.sx * params.cz - params.cx * params.sy * params.sz;
346 h_ang_c2(1) = params.sx * params.sz - params.cx * params.sy * params.cz;
349 h_ang_c3(0) = params.cx * params.cz - params.sx * params.sy * params.sz;
350 h_ang_c3(1) = -params.sx * params.sy * params.cz - params.cx * params.sz;
353 h_ang_d1(0) = -params.cy * params.cz;
354 h_ang_d1(1) = params.cy * params.sz;
355 h_ang_d1(2) = params.sy;
357 h_ang_d2(0) = -params.sx * params.sy * params.cz;
358 h_ang_d2(1) = params.sx * params.sy * params.sz;
359 h_ang_d2(2) = params.sx * params.cy;
361 h_ang_d3(0) = params.cx * params.sy * params.cz;
362 h_ang_d3(1) = -params.cx * params.sy * params.sz;
363 h_ang_d3(2) = -params.cx * params.cy;
365 h_ang_e1(0) = params.sy * params.sz;
366 h_ang_e1(1) = params.sy * params.cz;
369 h_ang_e2(0) = -params.sx * params.cy * params.sz;
370 h_ang_e2(1) = -params.sx * params.cy * params.cz;
373 h_ang_e3(0) = params.cx * params.cy * params.sz;
374 h_ang_e3(1) = params.cx * params.cy * params.cz;
377 h_ang_f1(0) = -params.cy * params.cz;
378 h_ang_f1(1) = params.cy * params.sz;
381 h_ang_f2(0) = -params.cx * params.sz - params.sx * params.sy * params.cz;
382 h_ang_f2(1) = -params.cx * params.cz + params.sx * params.sy * params.sz;
385 h_ang_f3(0) = -params.sx * params.sz + params.cx * params.sy * params.cz;
386 h_ang_f3(1) = -params.cx * params.sy * params.sz - params.sx * params.cz;
390 Point h_ang_a2, h_ang_a3,
393 h_ang_d1, h_ang_d2, h_ang_d3,
394 h_ang_e1, h_ang_e2, h_ang_e3,
395 h_ang_f1, h_ang_f2, h_ang_f3;
398 void compute_point_gradients(
399 const GradientAngleParameters & params,
403 point_gradient(1, 3) = x.dot(params.j_ang_a);
404 point_gradient(2, 3) = x.dot(params.j_ang_b);
405 point_gradient(0, 4) = x.dot(params.j_ang_c);
406 point_gradient(1, 4) = x.dot(params.j_ang_d);
407 point_gradient(2, 4) = x.dot(params.j_ang_e);
408 point_gradient(0, 5) = x.dot(params.j_ang_f);
409 point_gradient(1, 5) = x.dot(params.j_ang_g);
410 point_gradient(2, 5) = x.dot(params.j_ang_h);
413 void compute_point_hessians(
414 const HessianAngleParameters & params,
418 const Point a{0.0, x.dot(params.h_ang_a2), x.dot(params.h_ang_a3)};
419 const Point b{0.0, x.dot(params.h_ang_b2), x.dot(params.h_ang_b3)};
420 const Point c{0.0, x.dot(params.h_ang_c2), x.dot(params.h_ang_c3)};
421 const Point d{x.dot(params.h_ang_d1), x.dot(params.h_ang_d2),
422 x.dot(params.h_ang_d3)};
423 const Point e{x.dot(params.h_ang_e1), x.dot(params.h_ang_e2),
424 x.dot(params.h_ang_e3)};
425 const Point f{x.dot(params.h_ang_f1), x.dot(params.h_ang_f2),
426 x.dot(params.h_ang_f3)};
428 point_hessian.block<3, 1>(9, 3) =
a;
429 point_hessian.block<3, 1>(12, 3) = b;
430 point_hessian.block<3, 1>(15, 3) = c;
431 point_hessian.block<3, 1>(9, 4) = b;
432 point_hessian.block<3, 1>(12, 4) = d;
433 point_hessian.block<3, 1>(15, 4) = e;
434 point_hessian.block<3, 1>(9, 5) = c;
435 point_hessian.block<3, 1>(12, 5) = e;
436 point_hessian.block<3, 1>(15, 5) =
f;
442 void init(
Real outlier_ratio)
445 throw std::domain_error(
"Outlier ratio must be between 0 and 1");
447 const auto c_size = m_map_ref.cell_size();
451 const auto gauss_c1 = 10.0 * (1.0 - outlier_ratio);
452 const auto gauss_c2 = outlier_ratio /
static_cast<Real>(c_size.x * c_size.y * c_size.z);
453 const auto gauss_d3 = -std::log(gauss_c2);
454 m_gauss_d1 = -std::log(gauss_c1 + gauss_c2) - gauss_d3;
456 std::log((-std::log(gauss_c1 * std::exp(-0.5) + gauss_c2) - gauss_d3) / m_gauss_d1);
460 const Scan & m_scan_ref;
461 const Map & m_map_ref;
463 Real m_gauss_d1{0.0};
464 Real m_gauss_d2{0.0};
467 template<
typename MapT>
475 #endif // NDT__NDT_OPTIMIZATION_PROBLEM_HPP_ autoware::common::types::float64_t Value
Definition: optimization_problem.hpp:118
This constraint expresses the map interface requirements for the localizer.
Definition: ndt/include/ndt/constraints.hpp:65
double float64_t
Definition: types.hpp:37
bool8_t is_valid_probability(ScalarT p)
Definition: ndt_optimization_problem.hpp:83
Definition: common/optimization/include/optimization/utils.hpp:38
DifferentialEquation f
Definition: kinematic_bicycle.snippet.hpp:44
Definition: ndt_scan.hpp:99
Eigen::Matrix< Value, NumVars, NumVars > Hessian
Definition: optimization_problem.hpp:120
Eigen::Matrix< Value, NumVars, NumJacobianCols > Jacobian
Definition: optimization_problem.hpp:119
Eigen::Vector3d Point
Definition: ndt_optimization_problem.hpp:111
Real outlier_ratio() const noexcept
Definition: ndt_config.hpp:65
void jacobian(const DomainValue &x, JacobianRef out)
Definition: optimization_problem.hpp:69
Eigen::Matrix< T, 6U, 1U > EigenPose
Definition: localization/ndt/include/ndt/utils.hpp:83
bool bool8_t
Definition: types.hpp:33
Definition: optimization_problem.hpp:332
Config class for p2d optimziation problem.
Definition: ndt_config.hpp:54
This file includes common type definition.
EigenPose< Real > DomainValue
Definition: optimization_problem.hpp:117
Definition: ndt_optimization_problem.hpp:98
bool8_t score() const noexcept
Definition: utils.cpp:47
P2DNDTObjective(const P2DNDTScan &scan, const Map &map, const P2DNDTOptimizationConfig config)
Definition: ndt_optimization_problem.hpp:127
Requires
Definition: ndt/include/ndt/constraints.hpp:29
float64_t Real
Definition: ndt_common.hpp:39
void evaluate_(const DomainValue &x, const ComputeMode &mode)
Definition: ndt_optimization_problem.hpp:134
typename ExpressionT::DomainValue DomainValue
Definition: ndt_optimization_problem.hpp:105
a
Definition: catr_diff.py:22
DifferentialState x
Definition: kinematic_bicycle.snippet.hpp:28
Definition: optimization_problem.hpp:109
MapT Map
Definition: ndt_optimization_problem.hpp:109
typename ExpressionT::Hessian Hessian
Definition: ndt_optimization_problem.hpp:108
void set_hessian(const HessianRef &hessian)
Definition: optimization_problem.hpp:173
typename ExpressionT::Value Value
Definition: ndt_optimization_problem.hpp:106
bool8_t jacobian() const noexcept
Definition: utils.cpp:48
void set_score(Value score)
Definition: optimization_problem.hpp:163
typename ExpressionT::Jacobian Jacobian
Definition: ndt_optimization_problem.hpp:107
bool8_t hessian() const noexcept
Definition: utils.cpp:49
Eigen::Matrix< float64_t, 3, 6 > PointGrad
Definition: ndt_optimization_problem.hpp:114
void set_jacobian(const JacobianRef &jacobian)
Definition: optimization_problem.hpp:168
void hessian(const DomainValue &x, HessianRef out)
Definition: optimization_problem.hpp:77
Eigen::Matrix< float64_t, 18, 6 > PointHessian
Definition: ndt_optimization_problem.hpp:115
Generic equality comparison functor for eigen matrices.
Definition: common/optimization/include/optimization/utils.hpp:86
This file defines the lanelet2_map_provider_node class.
Definition: quick_sort.hpp:24