42 if (
const auto node_ptr = node.lock()) {
44 rclcpp::CallbackGroupType::Reentrant);
48 this->_params_.slam_optimization_period_ <= 0.0) {
49 RCLCPP_INFO(rclcpp::get_logger(
"slam"),
"Optimization is synchronous");
50 }
else if (
const auto node_ptr = node.lock()) {
52 std::chrono::milliseconds(
54 [
this]() { this->_asynchronous_optimization_routine(); }, this->_reentrant_group_);
55 RCLCPP_INFO(rclcpp::get_logger(
"slam"),
"Optimization timer created with period %f seconds",
59 RCLCPP_ERROR(rclcpp::get_logger(
"slam"),
60 "Failed to create optimization timer, node is not valid");
65 const std::shared_ptr<PoseUpdater> pose_updater,
66 const std::shared_ptr<GraphSLAMInstance> graph_slam_instance,
bool force_update) {
67 if (pose_updater->pose_ready_for_graph_update() || force_update) {
70 graph_slam_instance->process_new_pose(
72 pose_updater->get_pose_difference_noise(), pose_updater->get_last_pose(),
73 pose_updater->get_last_pose_update());
75 pose_updater->update_pose(
76 pose_updater->get_last_pose());
84 std::unique_lock lock(this->
_mutex_);
85 RCLCPP_DEBUG(rclcpp::get_logger(
"slam"),
"add_odometry - Mutex accessed");
86 rclcpp::Time start_time, motion_model_time, factor_graph_time;
89 MotionData odometry_data(std::make_shared<Eigen::VectorXd>(3),
90 std::make_shared<Eigen::VectorXd>(3), odometry.
timestamp);
95 start_time = rclcpp::Clock().now();
98 RCLCPP_DEBUG(rclcpp::get_logger(
"slam"),
99 "add_odometry - Optimization under way, pushing motion data");
102 motion_model_time = rclcpp::Clock().now();
103 RCLCPP_DEBUG(rclcpp::get_logger(
"slam"),
"add_odometry - Pose updated");
108 factor_graph_time = rclcpp::Clock().now();
109 RCLCPP_DEBUG(rclcpp::get_logger(
"slam"),
"add_odometry - Factors added? %d", added_factors);
115 this->
_execution_times_->at(9) = (motion_model_time - start_time).seconds() * 1000.0;
116 this->
_execution_times_->at(10) = (factor_graph_time - motion_model_time).seconds() * 1000.0;
117 RCLCPP_DEBUG(rclcpp::get_logger(
"slam"),
"add_odometry - Mutex unlocked");
121 RCLCPP_DEBUG(rclcpp::get_logger(
"slam"),
"add_velocities - Mutex waiting to lock");
122 std::unique_lock lock(this->
_mutex_);
123 RCLCPP_DEBUG(rclcpp::get_logger(
"slam"),
"add_velocities - Mutex accessed");
124 rclcpp::Time start_time, motion_model_time, factor_graph_time;
127 MotionData velocities_data(std::make_shared<Eigen::VectorXd>(4),
128 std::make_shared<Eigen::VectorXd>(4), velocities.
timestamp_);
135 start_time = rclcpp::Clock().now();
138 RCLCPP_DEBUG(rclcpp::get_logger(
"slam"),
139 "add_velocities - Optimization under way, pushing motion data");
144 motion_model_time = rclcpp::Clock().now();
145 RCLCPP_DEBUG(rclcpp::get_logger(
"slam"),
"add_velocities - Pose updated: (%f, %f, %f)",
146 this->
_pose_updater_->get_last_pose()(0), this->_pose_updater_->get_last_pose()(1),
147 this->_pose_updater_->get_last_pose()(2));
152 factor_graph_time = rclcpp::Clock().now();
153 RCLCPP_DEBUG(rclcpp::get_logger(
"slam"),
"add_velocities - Factors added? %d", added_factors);
159 this->
_execution_times_->at(9) = (motion_model_time - start_time).seconds() * 1000.0;
160 this->
_execution_times_->at(10) = (factor_graph_time - motion_model_time).seconds() * 1000.0;
161 RCLCPP_DEBUG(rclcpp::get_logger(
"slam"),
"add_velocities - Mutex unlocked");
169 rclcpp::Time cones_timestamp) {
179 rclcpp::Time start_time, initialization_time, covariance_time, association_time,
180 factor_graph_time, optimization_time;
181 start_time = rclcpp::Clock().now();
182 Eigen::VectorXd observations(cones.size() * 2);
183 Eigen::VectorXd observations_confidences(cones.size());
184 Eigen::VectorXd observations_global(cones.size() * 2);
185 Eigen::VectorXd landmarks, state;
186 Eigen::Vector3d pose;
187 Eigen::MatrixXd covariance;
188 for (
unsigned int i = 0; i < cones.size(); i++) {
190 observations(i * 2) = cones[i].position.x;
191 observations(i * 2 + 1) = cones[i].position.y;
192 observations_confidences(i) = cones[i].certainty;
196 RCLCPP_DEBUG(rclcpp::get_logger(
"slam"),
"add_observations - Shared mutex accessed");
197 const std::shared_lock lock(this->
_mutex_);
199 landmarks = state.segment(3, state.size() - 3);
201 Eigen::Vector3d adjusted_pose = this->
_pose_updater_->get_pose_at_timestamp(
203 observations_global =
205 initialization_time = rclcpp::Clock().now();
207 covariance_time = rclcpp::Clock().now();
209 RCLCPP_INFO(rclcpp::get_logger(
"slam"),
"add_observations - State and covariance obtained");
210 Eigen::VectorXi associations;
211 Eigen::VectorXd filtered_new_observations;
213 RCLCPP_DEBUG(rclcpp::get_logger(
"slam"),
214 "add_observations - Mutex locked - association/filter/loop-closure/graph update");
215 std::unique_lock uniq_lock(this->
_mutex_);
219 landmarks, observations_global, covariance,
220 observations_confidences);
224 association_time = rclcpp::Clock().now();
225 RCLCPP_DEBUG(rclcpp::get_logger(
"slam"),
"add_observations - Associations calculated");
227 RCLCPP_INFO(rclcpp::get_logger(
"slam"),
"add_observations - Associations:");
231 observations_global, observations_confidences, associations);
232 RCLCPP_INFO(rclcpp::get_logger(
"slam"),
"add_observations - Filtered new observations");
236 _loop_closure_->detect(pose, landmarks, associations, observations);
237 if (result.detected) {
241 RCLCPP_INFO(rclcpp::get_logger(
"slam"),
242 "add_observations - First lap detected, locking landmarks");
245 RCLCPP_INFO(rclcpp::get_logger(
"slam"),
"Lap counter: %d",
lap_counter_);
247 RCLCPP_INFO(rclcpp::get_logger(
"slam"),
"add_observations - Loop closure checked");
250 ObservationData observation_data(std::make_shared<Eigen::VectorXd>(observations),
251 std::make_shared<Eigen::VectorXi>(associations),
252 std::make_shared<Eigen::VectorXd>(observations_global),
253 std::make_shared<Eigen::VectorXd>(observations_confidences),
257 RCLCPP_INFO(rclcpp::get_logger(
"slam"),
258 "add_observations - Optimization under way, pushing observation data");
267 RCLCPP_INFO(rclcpp::get_logger(
"slam"),
"add_observations - Factors added to graph");
268 factor_graph_time = rclcpp::Clock().now();
269 RCLCPP_DEBUG(rclcpp::get_logger(
"slam"),
"add_observations - Mutex unlocked - Factors added");
275 RCLCPP_DEBUG(rclcpp::get_logger(
"slam"),
"add_observations - Mutex locked - optimizing graph");
276 std::unique_lock uniq_lock(this->
_mutex_);
278 optimization_time = rclcpp::Clock().now();
280 RCLCPP_DEBUG(rclcpp::get_logger(
"slam"),
"add_observations - Mutex unlocked - graph optimized");
282 RCLCPP_INFO(rclcpp::get_logger(
"slam"),
"add_observations - Graph optimized if needed");
288 this->
_execution_times_->at(3) = (covariance_time - initialization_time).seconds() * 1000.0;
289 this->
_execution_times_->at(2) = (association_time - covariance_time).seconds() * 1000.0;
290 this->
_execution_times_->at(4) = (factor_graph_time - association_time).seconds() * 1000.0;
292 this->
_execution_times_->at(5) = (optimization_time - factor_graph_time).seconds() * 1000.0;
302 rclcpp::Time start_time = rclcpp::Clock().now();
305 std::shared_ptr<GraphSLAMInstance> graph_slam_instance_copy;
306 std::shared_ptr<PoseUpdater> pose_updater_copy;
308 const std::shared_lock lock(this->
_mutex_);
309 RCLCPP_DEBUG(rclcpp::get_logger(
"slam"),
310 "_asynchronous_optimization_routine - Shared mutex accessed");
318 std::unique_lock lock(this->
_mutex_);
321 rclcpp::Time initialization_time = rclcpp::Clock().now();
324 RCLCPP_DEBUG(rclcpp::get_logger(
"slam"),
325 "_asynchronous_optimization_routine - Starting optimization");
326 graph_slam_instance_copy->optimize();
328 RCLCPP_DEBUG(rclcpp::get_logger(
"slam"),
"_asynchronous_optimization_routine - Graph optimized");
329 rclcpp::Time optimization_time = rclcpp::Clock().now();
333 std::unique_lock lock(this->
_mutex_);
335 RCLCPP_DEBUG(rclcpp::get_logger(
"slam"),
"_asynchronous_optimization_routine - Mutex locked");
336 while (this->
_motion_data_queue_.size() > 0 || this->_observation_data_queue_.size() > 0) {
337 RCLCPP_DEBUG(rclcpp::get_logger(
"slam"),
338 "_asynchronous_optimization_routine - Rebuilding graph, motion data queue size: "
339 "%ld, observation data queue size: %ld",
346 std::shared_ptr<V2PMotionModel> motion_model_ptr =
357 graph_slam_instance_copy);
365 rclcpp::Time end_time = rclcpp::Clock().now();
368 (optimization_time - initialization_time).seconds() * 1000.0;
370 (initialization_time - start_time).seconds() * 1000.0;
372 (end_time - optimization_time).seconds() * 1000.0;
374 (end_time - start_time).seconds() * 1000.0;
376 RCLCPP_DEBUG(rclcpp::get_logger(
"slam"),
377 "_asynchronous_optimization_routine - Mutex unlocked - Graph updated");
383 const std::shared_lock lock(this->
_mutex_);
384 rclcpp::Time current_time = rclcpp::Clock().now();
386 std::vector<common_lib::structures::Cone> map_estimate;
389 for (
auto it = graph_values.begin(); it != graph_values.end(); ++it) {
391 if (gtsam::Symbol(it->key).chr() ==
'l') {
395 gtsam::Point2 landmark = it->value.cast<gtsam::Point2>();
400 landmark_position, common_lib::competition_logic::Color::UNKNOWN, 1.0,
404 rclcpp::Time end_time = rclcpp::Clock().now();
405 RCLCPP_DEBUG(rclcpp::get_logger(
"slam"),
"get_map_estimate - Time: %f ms",
406 (end_time - current_time).seconds() * 1000.0);