Swarm-SLAM  1.0.0
C-SLAM Framework
gtsam_utils.cpp
Go to the documentation of this file.
2 
3 namespace cslam {
4 
5 geometry_msgs::msg::Pose gtsam_pose_to_msg(const gtsam::Pose3 &pose) {
6  geometry_msgs::msg::Pose msg;
7  msg.position.x = pose.x();
8  msg.position.y = pose.y();
9  msg.position.z = pose.z();
10  auto rotation = pose.rotation().quaternion();
11  msg.orientation.w = rotation[0];
12  msg.orientation.x = rotation[1];
13  msg.orientation.y = rotation[2];
14  msg.orientation.z = rotation[3];
15  return msg;
16 }
17 
18 geometry_msgs::msg::Transform
19 gtsam_pose_to_transform_msg(const gtsam::Pose3 &pose) {
20  geometry_msgs::msg::Transform msg;
21  msg.translation.x = pose.x();
22  msg.translation.y = pose.y();
23  msg.translation.z = pose.z();
24 
25  auto rotation = pose.rotation().quaternion();
26  msg.rotation.w = rotation[0];
27  msg.rotation.x = rotation[1];
28  msg.rotation.y = rotation[2];
29  msg.rotation.z = rotation[3];
30 
31  return msg;
32 }
33 
34 std::vector<cslam_common_interfaces::msg::PoseGraphValue>
35 gtsam_values_to_msg(const gtsam::Values &values) {
36  std::vector<cslam_common_interfaces::msg::PoseGraphValue> poses;
37  for (const auto key_value : values) {
38  auto p = dynamic_cast<const gtsam::GenericValue<gtsam::Pose3> *>(
39  &key_value.value);
40  if (!p)
41  continue;
42  cslam_common_interfaces::msg::PoseGraphValue pose_msg;
43  pose_msg.pose = gtsam_pose_to_msg(p->value());
44  auto key = gtsam::LabeledSymbol(key_value.key);
45  pose_msg.key.robot_id = ROBOT_ID(key.label());
46  pose_msg.key.keyframe_id = key.index();
47 
48  poses.emplace_back(pose_msg);
49  }
50  return poses;
51 }
52 
53 std::vector<cslam_common_interfaces::msg::PoseGraphValue>
54 gtsam_values_to_msg(const gtsam::Values::shared_ptr values) {
55  return gtsam_values_to_msg(*values);
56 }
57 
58 std::vector<cslam_common_interfaces::msg::PoseGraphEdge>
59 gtsam_factors_to_msg(const gtsam::NonlinearFactorGraph &factors) {
60  std::vector<cslam_common_interfaces::msg::PoseGraphEdge> edges;
61  for (const auto &factor_ : factors) {
62  auto factor =
63  boost::dynamic_pointer_cast<gtsam::BetweenFactor<gtsam::Pose3>>(
64  factor_);
65  if (factor) {
66  cslam_common_interfaces::msg::PoseGraphEdge edge_msg;
67 
68  auto key_from = gtsam::LabeledSymbol(factor->key1());
69  auto key_to = gtsam::LabeledSymbol(factor->key2());
70  edge_msg.key_from.robot_id = ROBOT_ID(key_from.label());
71  edge_msg.key_from.keyframe_id = key_from.index();
72  edge_msg.key_to.robot_id = ROBOT_ID(key_to.label());
73  edge_msg.key_to.keyframe_id = key_to.index();
74 
75  edge_msg.measurement = gtsam_pose_to_msg(factor->measured());
76 
77  gtsam::SharedNoiseModel model = factor->noiseModel();
78  auto noise =
79  boost::dynamic_pointer_cast<gtsam::noiseModel::Diagonal>(model);
80  auto sigmas = noise->sigmas();
81  for (unsigned int i = 0; i < 6; i++) {
82  edge_msg.noise_std[i] = sigmas[i];
83  }
84 
85  edges.emplace_back(edge_msg);
86  }
87  }
88  return edges;
89 }
90 
91 std::vector<cslam_common_interfaces::msg::PoseGraphEdge>
92 gtsam_factors_to_msg(const gtsam::NonlinearFactorGraph::shared_ptr factors) {
93  return gtsam_factors_to_msg(*factors);
94 }
95 
96 gtsam::Pose3 transform_msg_to_pose3(const geometry_msgs::msg::Transform &msg) {
97  gtsam::Rot3 rotation(msg.rotation.w, msg.rotation.x, msg.rotation.y,
98  msg.rotation.z);
99  return gtsam::Pose3(
100  rotation, {msg.translation.x, msg.translation.y, msg.translation.z});
101 }
102 
103 gtsam::Pose3 pose_msg_to_gtsam(const geometry_msgs::msg::Pose &pose) {
104  gtsam::Rot3 rotation(pose.orientation.w, pose.orientation.x,
105  pose.orientation.y, pose.orientation.z);
106  return gtsam::Pose3(rotation,
107  {pose.position.x, pose.position.y, pose.position.z});
108 }
109 
110 gtsam::Pose3 odometry_msg_to_pose3(const nav_msgs::msg::Odometry &odom_msg) {
111  return pose_msg_to_gtsam(odom_msg.pose.pose);
112 }
113 
114 gtsam::Values::shared_ptr values_msg_to_gtsam(
115  const std::vector<cslam_common_interfaces::msg::PoseGraphValue> &msg) {
116  auto values = boost::make_shared<gtsam::Values>();
117  for (auto v : msg) {
118  gtsam::Pose3 pose = pose_msg_to_gtsam(v.pose);
119  gtsam::LabeledSymbol symbol(GRAPH_LABEL, ROBOT_LABEL(v.key.robot_id),
120  v.key.keyframe_id);
121  values->insert(symbol, pose);
122  }
123  return values;
124 }
125 
126 gtsam::NonlinearFactorGraph::shared_ptr edges_msg_to_gtsam(
127  const std::vector<cslam_common_interfaces::msg::PoseGraphEdge> &msg) {
128  auto graph = boost::make_shared<gtsam::NonlinearFactorGraph>();
129  for (auto e : msg) {
130  gtsam::Pose3 pose = pose_msg_to_gtsam(e.measurement);
131  gtsam::LabeledSymbol symbol_from(
132  GRAPH_LABEL, ROBOT_LABEL(e.key_from.robot_id), e.key_from.keyframe_id);
133  gtsam::LabeledSymbol symbol_to(GRAPH_LABEL, ROBOT_LABEL(e.key_to.robot_id),
134  e.key_to.keyframe_id);
135 
136  Eigen::VectorXd sigmas(6);
137  sigmas << e.noise_std[0], e.noise_std[1], e.noise_std[2], e.noise_std[3],
138  e.noise_std[4], e.noise_std[5];
139  auto noise_model = gtsam::noiseModel::Diagonal::Sigmas(sigmas);
140 
141  gtsam::BetweenFactor<gtsam::Pose3> factor(symbol_from, symbol_to, pose,
142  noise_model);
143  graph->push_back(factor);
144  }
145  return graph;
146 }
147 
148 } // namespace cslam
#define GRAPH_LABEL
Definition: gtsam_utils.h:20
#define ROBOT_ID(ch)
Definition: gtsam_utils.h:22
#define ROBOT_LABEL(id)
Definition: gtsam_utils.h:21
Definition: __init__.py:1
gtsam::NonlinearFactorGraph::shared_ptr edges_msg_to_gtsam(const std::vector< cslam_common_interfaces::msg::PoseGraphEdge > &edges)
Converts from ROS 2 message to GTSAM.
gtsam::Pose3 odometry_msg_to_pose3(const nav_msgs::msg::Odometry &odom_msg)
Converts odometry message to gtsam::Pose3.
std::vector< cslam_common_interfaces::msg::PoseGraphValue > gtsam_values_to_msg(const gtsam::Values::shared_ptr values)
Converts from GTSAM to ROS 2 message.
Definition: gtsam_utils.cpp:54
gtsam::Pose3 pose_msg_to_gtsam(const geometry_msgs::msg::Pose &pose)
Converts from ROS 2 message to GTSAM.
gtsam::Values::shared_ptr values_msg_to_gtsam(const std::vector< cslam_common_interfaces::msg::PoseGraphValue > &values)
Converts from ROS 2 message to GTSAM.
gtsam::Pose3 transform_msg_to_pose3(const geometry_msgs::msg::Transform &msg)
Converts a transform msg into a gtsam::Pose3.
Definition: gtsam_utils.cpp:96
geometry_msgs::msg::Pose gtsam_pose_to_msg(const gtsam::Pose3 &pose)
Converts from GTSAM to ROS 2 message.
Definition: gtsam_utils.cpp:5
std::vector< cslam_common_interfaces::msg::PoseGraphEdge > gtsam_factors_to_msg(const gtsam::NonlinearFactorGraph::shared_ptr factors)
Converts from GTSAM to ROS 2 message.
Definition: gtsam_utils.cpp:92
geometry_msgs::msg::Transform gtsam_pose_to_transform_msg(const gtsam::Pose3 &pose)
Converts from GTSAM to ROS 2 message.
Definition: gtsam_utils.cpp:19