Swarm-SLAM  1.0.0
C-SLAM Framework
decentralized_pgo.h
Go to the documentation of this file.
1 #ifndef _DECENTRALIZED_PGO_H_
2 #define _DECENTRALIZED_PGO_H_
3 
4 #include <rclcpp/rclcpp.hpp>
5 
6 #include <gtsam/geometry/Pose3.h>
7 #include <gtsam/inference/Key.h>
8 #include <gtsam/inference/LabeledSymbol.h>
9 #include <gtsam/linear/NoiseModel.h>
10 #include <gtsam/nonlinear/GncOptimizer.h>
11 #include <gtsam/nonlinear/NonlinearFactorGraph.h>
12 #include <gtsam/nonlinear/Values.h>
13 #include <gtsam/slam/BetweenFactor.h>
14 
15 #include <cslam_common_interfaces/msg/keyframe_odom.hpp>
16 #include <cslam_common_interfaces/msg/optimization_result.hpp>
17 #include <cslam_common_interfaces/msg/optimizer_state.hpp>
18 #include <cslam_common_interfaces/msg/reference_frames.hpp>
19 #include <cslam_common_interfaces/msg/robot_ids_and_origin.hpp>
20 #include <cslam_common_interfaces/msg/inter_robot_loop_closure.hpp>
21 #include <cslam_common_interfaces/msg/intra_robot_loop_closure.hpp>
22 
23 #include <geometry_msgs/msg/transform_stamped.hpp>
24 #include <geometry_msgs/msg/pose_stamped.hpp>
25 #include <std_msgs/msg/string.hpp>
26 #include <std_msgs/msg/u_int32.hpp>
27 
28 #include <tf2_ros/transform_broadcaster.h>
29 
30 #include <chrono>
31 #include <future>
32 #include <gtsam/slam/dataset.h>
33 #include <list>
34 #include <thread>
35 
39 
40 namespace cslam
41 {
42 
55  {
62  };
63 
65  {
66  public:
72  DecentralizedPGO(std::shared_ptr<rclcpp::Node> &node);
74 
80  void odometry_callback(
81  const cslam_common_interfaces::msg::KeyframeOdom::ConstSharedPtr msg);
82 
89  const cslam_common_interfaces::msg::InterRobotLoopClosure::
90  ConstSharedPtr msg);
91 
98  const cslam_common_interfaces::msg::IntraRobotLoopClosure::
99  ConstSharedPtr msg);
100 
107  const cslam_common_interfaces::msg::RobotIdsAndOrigin::ConstSharedPtr
108  msg);
109 
115  cslam_common_interfaces::msg::PoseGraph fill_pose_graph_msg();
116 
122  cslam_common_interfaces::msg::PoseGraph fill_pose_graph_msg(const cslam_common_interfaces::msg::RobotIds &msg);
123 
130  const cslam_common_interfaces::msg::RobotIds::ConstSharedPtr msg);
131 
137  void pose_graph_callback(
138  const cslam_common_interfaces::msg::PoseGraph::ConstSharedPtr msg);
139 
146  const cslam_common_interfaces::msg::OptimizationResult::ConstSharedPtr
147  msg);
148 
155  const std_msgs::msg::String::ConstSharedPtr msg);
156 
162  void optimization_callback();
163 
169 
174  void update_transform_to_origin(const gtsam::Pose3 &pose);
175 
180  void broadcast_tf_callback();
181 
186  void start_optimization();
187 
193 
199 
205 
210  void start_waiting();
211 
216  bool check_waiting_timeout();
217 
222  void end_waiting();
223 
228  bool is_waiting();
229 
234  std::map<unsigned int, bool> connected_robot_pose_graph();
235 
240  std::pair<gtsam::NonlinearFactorGraph::shared_ptr, gtsam::Values::shared_ptr>
242 
247  void share_optimized_estimates(const gtsam::Values &estimates);
248 
254 
259  void visualization_callback();
260 
268  bool is_optimizer();
269 
277  gtsam::Values optimize(const gtsam::NonlinearFactorGraph::shared_ptr &graph,
278  const gtsam::Values::shared_ptr &initial);
279 
285 
286  private:
287  std::shared_ptr<rclcpp::Node> node_;
288 
289  unsigned int max_nb_robots_, robot_id_, optimization_count_;
290  bool enable_logs_;
291 
292  unsigned int pose_graph_optimization_start_period_ms_,
293  pose_graph_optimization_loop_period_ms_,
294  visualization_period_ms_;
295 
296  bool enable_visualization_;
297 
298  gtsam::SharedNoiseModel default_noise_model_;
299  float rotation_default_noise_std_, translation_default_noise_std_;
300 
301  gtsam::NonlinearFactorGraph::shared_ptr pose_graph_;
302  gtsam::Values::shared_ptr current_pose_estimates_;
303  gtsam::Values::shared_ptr odometry_pose_estimates_;
304 
305  std::map<unsigned int, std::pair<gtsam::NonlinearFactorGraph::shared_ptr,
306  gtsam::Values::shared_ptr>>
307  other_robots_graph_and_estimates_;
308 
309  gtsam::Pose3 latest_local_pose_, local_pose_at_latest_optimization_,
310  tentative_local_pose_at_latest_optimization_, latest_optimized_pose_;
311  gtsam::LabeledSymbol latest_local_symbol_;
312 
313  bool enable_pose_timestamps_recording_;
314 
315  std::map<std::pair<unsigned int, unsigned int>,
316  std::vector<gtsam::BetweenFactor<gtsam::Pose3>>>
317  inter_robot_loop_closures_;
318 
319  rclcpp::Subscription<cslam_common_interfaces::msg::KeyframeOdom>::SharedPtr
320  odometry_subscriber_;
321 
322  rclcpp::Subscription<
323  cslam_common_interfaces::msg::InterRobotLoopClosure>::SharedPtr
324  inter_robot_loop_closure_subscriber_;
325 
326  rclcpp::Subscription<
327  cslam_common_interfaces::msg::IntraRobotLoopClosure>::SharedPtr
328  intra_robot_loop_closure_subscriber_;
329 
330  rclcpp::Publisher<cslam_common_interfaces::msg::OptimizationResult>::SharedPtr
331  debug_optimization_result_publisher_;
332 
333  rclcpp::Subscription<cslam_common_interfaces::msg::OptimizationResult>::
334  SharedPtr optimized_estimates_subscriber_;
335 
336  rclcpp::Publisher<geometry_msgs::msg::PoseStamped>::SharedPtr
337  optimized_pose_estimate_publisher_;
338 
339  std::map<unsigned int,
340  rclcpp::Publisher<
341  cslam_common_interfaces::msg::OptimizationResult>::SharedPtr>
342  optimized_estimates_publishers_;
343 
344  rclcpp::TimerBase::SharedPtr optimization_timer_, optimization_loop_timer_;
345 
346  rclcpp::Publisher<std_msgs::msg::String>::SharedPtr
347  get_current_neighbors_publisher_;
348 
349  rclcpp::Subscription<cslam_common_interfaces::msg::RobotIdsAndOrigin>::
350  SharedPtr current_neighbors_subscriber_;
351 
352  std::map<unsigned int,
353  rclcpp::Publisher<cslam_common_interfaces::msg::RobotIds>::SharedPtr>
354  get_pose_graph_publishers_;
355 
356  std::map<unsigned int, bool> received_pose_graphs_;
357 
358  std::set<unsigned int> connected_robots_;
359 
360  std::map<unsigned int, std::vector<unsigned int>>
361  received_pose_graphs_connectivity_;
362 
363  rclcpp::Subscription<cslam_common_interfaces::msg::RobotIds>::SharedPtr
364  get_pose_graph_subscriber_;
365 
366  rclcpp::Subscription<cslam_common_interfaces::msg::PoseGraph>::SharedPtr
367  pose_graph_subscriber_;
368 
369  rclcpp::Subscription<std_msgs::msg::String>::SharedPtr
370  write_current_estimates_subscriber_;
371 
372  rclcpp::Publisher<cslam_common_interfaces::msg::PoseGraph>::SharedPtr
373  pose_graph_publisher_;
374 
375  rclcpp::Publisher<cslam_common_interfaces::msg::PoseGraph>::SharedPtr
376  visualization_pose_graph_publisher_;
377 
378  cslam_common_interfaces::msg::RobotIdsAndOrigin current_neighbors_ids_;
379 
380  OptimizerState optimizer_state_;
381 
382  std::future<gtsam::Values> optimization_result_;
383 
384  gtsam::GraphAndValues aggregate_pose_graph_;
385 
386  rclcpp::Publisher<cslam_common_interfaces::msg::OptimizerState>::SharedPtr
387  optimizer_state_publisher_;
388 
389  bool is_waiting_;
390 
391  std::string log_folder_;
392 
393  rclcpp::Time start_waiting_time_;
394  rclcpp::Duration max_waiting_time_sec_;
395 
396  unsigned int origin_robot_id_;
397  double heartbeat_period_sec_;
398  rclcpp::Publisher<std_msgs::msg::UInt32>::SharedPtr heartbeat_publisher_;
399 
400  std::unique_ptr<tf2_ros::TransformBroadcaster> tf_broadcaster_;
401 
402  rclcpp::TimerBase::SharedPtr heartbeat_timer_, tf_broadcaster_timer_,
403  visualization_timer_;
404 
405  geometry_msgs::msg::TransformStamped origin_to_first_pose_;
406 
407  bool enable_broadcast_tf_frames_;
408 
409  rclcpp::Publisher<cslam_common_interfaces::msg::ReferenceFrames>::SharedPtr
410  reference_frame_per_robot_publisher_;
411 
412  std::shared_ptr<Logger> logger_;
413 
414  std::map<unsigned int, sensor_msgs::msg::NavSatFix> gps_data_;
415  bool enable_gps_recording_;
416 
417  bool enable_simulated_rendezvous_;
418  std::shared_ptr<SimulatedRendezVous> sim_rdv_;
419  };
420 } // namespace cslam
421 #endif
void write_current_estimates_callback(const std_msgs::msg::String::ConstSharedPtr msg)
Prints current estimates.
void pose_graph_callback(const cslam_common_interfaces::msg::PoseGraph::ConstSharedPtr msg)
Receives pose graph.
bool is_optimizer()
Check if the local robot is the optimizer according to the specified priority rule Default priority r...
void check_result_and_finish_optimization()
Check if the optimization is finished.
void optimized_estimates_callback(const cslam_common_interfaces::msg::OptimizationResult::ConstSharedPtr msg)
Receives estimates from the optimizer.
void end_waiting()
End waiting.
void heartbeat_timer_callback()
Publish heartbeat message periodically.
void optimization_callback()
Starts pose graph optimization process every X ms (defined in config)
void inter_robot_loop_closure_callback(const cslam_common_interfaces::msg::InterRobotLoopClosure::ConstSharedPtr msg)
Receives inter-robot loop closures.
void visualization_callback()
Publish heartbeat message periodically.
bool is_waiting()
Check if waiting.
void start_optimization()
Performs pose graph optimization.
cslam_common_interfaces::msg::PoseGraph fill_pose_graph_msg()
Fill a PoseGraph message with the local data.
void optimization_loop_callback()
Step execution of the optimization State Machine.
void get_pose_graph_callback(const cslam_common_interfaces::msg::RobotIds::ConstSharedPtr msg)
Receives request for pose graph.
void odometry_callback(const cslam_common_interfaces::msg::KeyframeOdom::ConstSharedPtr msg)
Receives odometry msg + keyframe id.
void resquest_current_neighbors()
Request to check the current neighbors.
bool check_waiting_timeout()
Check waiting timeout.
bool check_received_pose_graphs()
Check if received all pose graphs.
void intra_robot_loop_closure_callback(const cslam_common_interfaces::msg::IntraRobotLoopClosure::ConstSharedPtr msg)
Receives intra-robot loop closures.
void share_optimized_estimates(const gtsam::Values &estimates)
Shares optimizes estimates with the robots concerned.
std::map< unsigned int, bool > connected_robot_pose_graph()
Breadth First Seach to check connectivity.
std::pair< gtsam::NonlinearFactorGraph::shared_ptr, gtsam::Values::shared_ptr > aggregate_pose_graphs()
Put all connected pose graphs into one.
void reinitialize_received_pose_graphs()
Sets received pose graphs to false.
DecentralizedPGO(std::shared_ptr< rclcpp::Node > &node)
Initialization of parameters and ROS 2 objects.
void update_transform_to_origin(const gtsam::Pose3 &pose)
Update transform to origin.
void start_waiting()
Start waiting.
gtsam::Values optimize(const gtsam::NonlinearFactorGraph::shared_ptr &graph, const gtsam::Values::shared_ptr &initial)
Pose graph optimization function.
void current_neighbors_callback(const cslam_common_interfaces::msg::RobotIdsAndOrigin::ConstSharedPtr msg)
Receives current neighbors.
void broadcast_tf_callback()
Broadcast tf to current origin point.
Definition: __init__.py:1
OptimizerState
State of the Pose Graph Optimization node.
@ START_OPTIMIZATION
@ POSEGRAPH_COLLECTION
@ WAITING_FOR_NEIGHBORS_INFO
@ WAITING_FOR_NEIGHBORS_POSEGRAPHS