11 start_time_ = std::chrono::steady_clock::now();
16 state.cost = icp_->calculate_cost();
17 state.transform = icp_->current_transform();
19 std::optional<ConvergenceState> last_state{};
21 while (!should_terminate(state, last_state)) {
24 state.iteration_count++;
25 state.cost = icp_->calculate_cost();
26 state.transform = icp_->current_transform();
32 bool ICPDriver::should_terminate(ConvergenceState current_state,
33 std::optional<ConvergenceState> last_state) {
35 if (min_iterations_ && current_state.iteration_count < min_iterations_.value()) {
39 if (max_iterations_ && current_state.iteration_count >= max_iterations_.value()) {
43 if (stop_cost_ && current_state.cost < stop_cost_.value()) {
48 auto current_time = std::chrono::steady_clock::now();
49 if (current_time - start_time_ > time_limit_.value()) {
60 double delta_cost = current_state.cost - last_state.value().cost;
61 if (absolute_cost_tolerance_ && std::abs(delta_cost) < absolute_cost_tolerance_.value()) {
65 double relative_cost_change = std::abs(delta_cost) / current_state.cost;
66 if (relative_cost_tolerance_ && relative_cost_change < relative_cost_tolerance_.value()) {
70 if (angle_tolerance_rad_ && translation_tolerance_) {
73 double dot = prev_rot_vector.dot(current_rot_vector);
74 double angle = std::acos(std::clamp(dot, -1.0, 1.0));
76 auto translation = current_state.transform.translation
77 - last_state.value().transform.translation;
79 if (angle < angle_tolerance_rad_.value()
80 && translation.norm() < translation_tolerance_.value()) {
89 assert(!max_iterations_ || min_iterations <= max_iterations_.value());
90 min_iterations_ = min_iterations;
94 assert(!min_iterations_ || max_iterations >= min_iterations_.value());
95 max_iterations_ = max_iterations;
99 stop_cost_ = stop_cost;
103 relative_cost_tolerance_ = relative_cost_tolerance;
107 absolute_cost_tolerance_ = absolute_cost_tolerance;
111 angle_tolerance_rad_ = angle_tolerance;
112 translation_tolerance_ = translation_tolerance;
116 time_limit_ = time_limit;
void set_min_iterations(uint64_t min_iterations)
Sets the minimum number of iterations to run.
ICPDriver(std::unique_ptr< ICP > icp)
Constructs a new ICPDriver using the given ICP method.
void set_transform_tolerance(double angle_tolerance, double translation_tolerance)
Set the transform tolerance.
void set_absolute_cost_tolerance(double absolute_cost_tolerance)
Set the absolute cost tolerance.
void set_relative_cost_tolerance(double relative_cost_tolerance)
Sets the relative cost tolerance.
void set_time_limit(std::chrono::duration< double > time_limit)
Set the time limit for converge.
void set_stop_cost(double stop_cost)
Sets the cost at which to stop ICP.
void set_max_iterations(uint64_t max_iterations)
Sets the maximum number of iterations to run.
ConvergenceState converge(const std::vector< Vector > &a, const std::vector< Vector > &b, RBTransform t)
Runs ICP to convergence based on the termination conditions set.
The result of running ICPDriver::converge.
size_t iteration_count
The number of iterations performed.