iterative closest points
CEV ICP algorithm library
Loading...
Searching...
No Matches
driver.cpp
Go to the documentation of this file.
1#include "icp/driver.h"
2#include <limits>
3
4namespace icp {
5 ICPDriver::ICPDriver(std::unique_ptr<ICP> icp) {
6 icp_ = std::move(icp);
7 }
8
9 ICPDriver::ConvergenceState ICPDriver::converge(const std::vector<Vector>& a,
10 const std::vector<Vector>& b, RBTransform t) {
11 start_time_ = std::chrono::steady_clock::now();
12 icp_->begin(a, b, t);
13
14 ConvergenceState state{};
15 state.iteration_count = 0;
16 state.cost = icp_->calculate_cost();
17 state.transform = icp_->current_transform();
18
19 std::optional<ConvergenceState> last_state{};
20
21 while (!should_terminate(state, last_state)) {
22 icp_->iterate();
23 last_state = state;
24 state.iteration_count++;
25 state.cost = icp_->calculate_cost();
26 state.transform = icp_->current_transform();
27 }
28
29 return state;
30 }
31
32 bool ICPDriver::should_terminate(ConvergenceState current_state,
33 std::optional<ConvergenceState> last_state) {
34 // absolute conditions based only on current state
35 if (min_iterations_ && current_state.iteration_count < min_iterations_.value()) {
36 return false;
37 }
38
39 if (max_iterations_ && current_state.iteration_count >= max_iterations_.value()) {
40 return true;
41 }
42
43 if (stop_cost_ && current_state.cost < stop_cost_.value()) {
44 return true;
45 }
46
47 if (time_limit_) {
48 auto current_time = std::chrono::steady_clock::now();
49 if (current_time - start_time_ > time_limit_.value()) {
50 return true;
51 }
52 }
53
54 // end if we don't have a last state
55 if (!last_state) {
56 return false;
57 }
58
59 // relative conditions based on progress
60 double delta_cost = current_state.cost - last_state.value().cost;
61 if (absolute_cost_tolerance_ && std::abs(delta_cost) < absolute_cost_tolerance_.value()) {
62 return true;
63 }
64
65 double relative_cost_change = std::abs(delta_cost) / current_state.cost;
66 if (relative_cost_tolerance_ && relative_cost_change < relative_cost_tolerance_.value()) {
67 return true;
68 }
69
70 if (angle_tolerance_rad_ && translation_tolerance_) {
71 icp::Vector prev_rot_vector = last_state.value().transform.rotation * icp::Vector(1, 0);
72 icp::Vector current_rot_vector = current_state.transform.rotation * icp::Vector(1, 0);
73 double dot = prev_rot_vector.dot(current_rot_vector);
74 double angle = std::acos(std::clamp(dot, -1.0, 1.0));
75
76 auto translation = current_state.transform.translation
77 - last_state.value().transform.translation;
78
79 if (angle < angle_tolerance_rad_.value()
80 && translation.norm() < translation_tolerance_.value()) {
81 return true;
82 }
83 }
84
85 return false;
86 }
87
88 void ICPDriver::set_min_iterations(uint64_t min_iterations) {
89 assert(!max_iterations_ || min_iterations <= max_iterations_.value());
90 min_iterations_ = min_iterations;
91 }
92
93 void ICPDriver::set_max_iterations(uint64_t max_iterations) {
94 assert(!min_iterations_ || max_iterations >= min_iterations_.value());
95 max_iterations_ = max_iterations;
96 }
97
98 void ICPDriver::set_stop_cost(double stop_cost) {
99 stop_cost_ = stop_cost;
100 }
101
102 void ICPDriver::set_relative_cost_tolerance(double relative_cost_tolerance) {
103 relative_cost_tolerance_ = relative_cost_tolerance;
104 }
105
106 void ICPDriver::set_absolute_cost_tolerance(double absolute_cost_tolerance) {
107 absolute_cost_tolerance_ = absolute_cost_tolerance;
108 }
109
110 void ICPDriver::set_transform_tolerance(double angle_tolerance, double translation_tolerance) {
111 angle_tolerance_rad_ = angle_tolerance;
112 translation_tolerance_ = translation_tolerance;
113 }
114
115 void ICPDriver::set_time_limit(std::chrono::duration<double> time_limit) {
116 time_limit_ = time_limit;
117 }
118}
void set_min_iterations(uint64_t min_iterations)
Sets the minimum number of iterations to run.
Definition driver.cpp:88
ICPDriver(std::unique_ptr< ICP > icp)
Constructs a new ICPDriver using the given ICP method.
Definition driver.cpp:5
void set_transform_tolerance(double angle_tolerance, double translation_tolerance)
Set the transform tolerance.
Definition driver.cpp:110
void set_absolute_cost_tolerance(double absolute_cost_tolerance)
Set the absolute cost tolerance.
Definition driver.cpp:106
void set_relative_cost_tolerance(double relative_cost_tolerance)
Sets the relative cost tolerance.
Definition driver.cpp:102
void set_time_limit(std::chrono::duration< double > time_limit)
Set the time limit for converge.
Definition driver.cpp:115
void set_stop_cost(double stop_cost)
Sets the cost at which to stop ICP.
Definition driver.cpp:98
void set_max_iterations(uint64_t max_iterations)
Sets the maximum number of iterations to run.
Definition driver.cpp:93
ConvergenceState converge(const std::vector< Vector > &a, const std::vector< Vector > &b, RBTransform t)
Runs ICP to convergence based on the termination conditions set.
Definition driver.cpp:9
Definition driver.h:7
Eigen::Vector2d Vector
Definition geo.h:15
The result of running ICPDriver::converge.
Definition driver.h:15
size_t iteration_count
The number of iterations performed.
Definition driver.h:20
Rigid-body transformation.
Definition geo.h:19