1 #ifndef _DECENTRALIZED_PGO_H_
2 #define _DECENTRALIZED_PGO_H_
4 #include <rclcpp/rclcpp.hpp>
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>
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>
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>
28 #include <tf2_ros/transform_broadcaster.h>
32 #include <gtsam/slam/dataset.h>
81 const cslam_common_interfaces::msg::KeyframeOdom::ConstSharedPtr msg);
89 const cslam_common_interfaces::msg::InterRobotLoopClosure::
98 const cslam_common_interfaces::msg::IntraRobotLoopClosure::
107 const cslam_common_interfaces::msg::RobotIdsAndOrigin::ConstSharedPtr
122 cslam_common_interfaces::msg::PoseGraph
fill_pose_graph_msg(
const cslam_common_interfaces::msg::RobotIds &msg);
130 const cslam_common_interfaces::msg::RobotIds::ConstSharedPtr msg);
138 const cslam_common_interfaces::msg::PoseGraph::ConstSharedPtr msg);
146 const cslam_common_interfaces::msg::OptimizationResult::ConstSharedPtr
155 const std_msgs::msg::String::ConstSharedPtr msg);
240 std::pair<gtsam::NonlinearFactorGraph::shared_ptr, gtsam::Values::shared_ptr>
277 gtsam::Values
optimize(
const gtsam::NonlinearFactorGraph::shared_ptr &graph,
278 const gtsam::Values::shared_ptr &initial);
287 std::shared_ptr<rclcpp::Node> node_;
289 unsigned int max_nb_robots_, robot_id_, optimization_count_;
292 unsigned int pose_graph_optimization_start_period_ms_,
293 pose_graph_optimization_loop_period_ms_,
294 visualization_period_ms_;
296 bool enable_visualization_;
298 gtsam::SharedNoiseModel default_noise_model_;
299 float rotation_default_noise_std_, translation_default_noise_std_;
301 gtsam::NonlinearFactorGraph::shared_ptr pose_graph_;
302 gtsam::Values::shared_ptr current_pose_estimates_;
303 gtsam::Values::shared_ptr odometry_pose_estimates_;
305 std::map<
unsigned int, std::pair<gtsam::NonlinearFactorGraph::shared_ptr,
306 gtsam::Values::shared_ptr>>
307 other_robots_graph_and_estimates_;
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_;
313 bool enable_pose_timestamps_recording_;
315 std::map<std::pair<unsigned int, unsigned int>,
316 std::vector<gtsam::BetweenFactor<gtsam::Pose3>>>
317 inter_robot_loop_closures_;
319 rclcpp::Subscription<cslam_common_interfaces::msg::KeyframeOdom>::SharedPtr
320 odometry_subscriber_;
322 rclcpp::Subscription<
323 cslam_common_interfaces::msg::InterRobotLoopClosure>::SharedPtr
324 inter_robot_loop_closure_subscriber_;
326 rclcpp::Subscription<
327 cslam_common_interfaces::msg::IntraRobotLoopClosure>::SharedPtr
328 intra_robot_loop_closure_subscriber_;
330 rclcpp::Publisher<cslam_common_interfaces::msg::OptimizationResult>::SharedPtr
331 debug_optimization_result_publisher_;
333 rclcpp::Subscription<cslam_common_interfaces::msg::OptimizationResult>::
334 SharedPtr optimized_estimates_subscriber_;
336 rclcpp::Publisher<geometry_msgs::msg::PoseStamped>::SharedPtr
337 optimized_pose_estimate_publisher_;
339 std::map<
unsigned int,
341 cslam_common_interfaces::msg::OptimizationResult>::SharedPtr>
342 optimized_estimates_publishers_;
344 rclcpp::TimerBase::SharedPtr optimization_timer_, optimization_loop_timer_;
346 rclcpp::Publisher<std_msgs::msg::String>::SharedPtr
347 get_current_neighbors_publisher_;
349 rclcpp::Subscription<cslam_common_interfaces::msg::RobotIdsAndOrigin>::
350 SharedPtr current_neighbors_subscriber_;
352 std::map<
unsigned int,
353 rclcpp::Publisher<cslam_common_interfaces::msg::RobotIds>::SharedPtr>
354 get_pose_graph_publishers_;
356 std::map<unsigned int, bool> received_pose_graphs_;
358 std::set<unsigned int> connected_robots_;
360 std::map<unsigned int, std::vector<unsigned int>>
361 received_pose_graphs_connectivity_;
363 rclcpp::Subscription<cslam_common_interfaces::msg::RobotIds>::SharedPtr
364 get_pose_graph_subscriber_;
366 rclcpp::Subscription<cslam_common_interfaces::msg::PoseGraph>::SharedPtr
367 pose_graph_subscriber_;
369 rclcpp::Subscription<std_msgs::msg::String>::SharedPtr
370 write_current_estimates_subscriber_;
372 rclcpp::Publisher<cslam_common_interfaces::msg::PoseGraph>::SharedPtr
373 pose_graph_publisher_;
375 rclcpp::Publisher<cslam_common_interfaces::msg::PoseGraph>::SharedPtr
376 visualization_pose_graph_publisher_;
378 cslam_common_interfaces::msg::RobotIdsAndOrigin current_neighbors_ids_;
382 std::future<gtsam::Values> optimization_result_;
384 gtsam::GraphAndValues aggregate_pose_graph_;
386 rclcpp::Publisher<cslam_common_interfaces::msg::OptimizerState>::SharedPtr
387 optimizer_state_publisher_;
391 std::string log_folder_;
393 rclcpp::Time start_waiting_time_;
394 rclcpp::Duration max_waiting_time_sec_;
396 unsigned int origin_robot_id_;
397 double heartbeat_period_sec_;
398 rclcpp::Publisher<std_msgs::msg::UInt32>::SharedPtr heartbeat_publisher_;
400 std::unique_ptr<tf2_ros::TransformBroadcaster> tf_broadcaster_;
402 rclcpp::TimerBase::SharedPtr heartbeat_timer_, tf_broadcaster_timer_,
403 visualization_timer_;
405 geometry_msgs::msg::TransformStamped origin_to_first_pose_;
407 bool enable_broadcast_tf_frames_;
409 rclcpp::Publisher<cslam_common_interfaces::msg::ReferenceFrames>::SharedPtr
410 reference_frame_per_robot_publisher_;
412 std::shared_ptr<Logger> logger_;
414 std::map<unsigned int, sensor_msgs::msg::NavSatFix> gps_data_;
415 bool enable_gps_recording_;
417 bool enable_simulated_rendezvous_;
418 std::shared_ptr<SimulatedRendezVous> sim_rdv_;
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.
OptimizerState
State of the Pose Graph Optimization node.
@ WAITING_FOR_NEIGHBORS_INFO
@ WAITING_FOR_NEIGHBORS_POSEGRAPHS