gazebo_odometry_plugin.cpp
Go to the documentation of this file.
1 /*
2  * Copyright 2015 Fadri Furrer, ASL, ETH Zurich, Switzerland
3  * Copyright 2015 Michael Burri, ASL, ETH Zurich, Switzerland
4  * Copyright 2015 Mina Kamel, ASL, ETH Zurich, Switzerland
5  * Copyright 2015 Janosch Nikolic, ASL, ETH Zurich, Switzerland
6  * Copyright 2015 Markus Achtelik, ASL, ETH Zurich, Switzerland
7  * Copyright 2016 Geoffrey Hunter <gbmhunter@gmail.com>
8  *
9  * Licensed under the Apache License, Version 2.0 (the "License");
10  * you may not use this file except in compliance with the License.
11  * You may obtain a copy of the License at
12  *
13  * http://www.apache.org/licenses/LICENSE-2.0
14 
15  * Unless required by applicable law or agreed to in writing, software
16  * distributed under the License is distributed on an "AS IS" BASIS,
17  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
18  * See the License for the specific language governing permissions and
19  * limitations under the License.
20  */
21 
22 // MODULE
24 
25 // SYSTEM
26 #include <chrono>
27 #include <iostream>
28 
29 // 3RD PARTY
30 #include <opencv2/core/core.hpp>
31 #include <opencv2/highgui/highgui.hpp>
32 
33 // USER
35 #include "ConnectGazeboToRosTopic.pb.h"
36 #include "ConnectRosToGazeboTopic.pb.h"
37 #include "PoseStamped.pb.h"
38 #include "PoseWithCovarianceStamped.pb.h"
39 #include "TransformStamped.pb.h"
40 #include "TransformStampedWithFrameIds.pb.h"
41 #include "Vector3dStamped.pb.h"
42 
43 namespace gazebo {
44 
46 }
47 
48 void GazeboOdometryPlugin::Load(physics::ModelPtr _model,
49  sdf::ElementPtr _sdf) {
50  if (kPrintOnPluginLoad) {
51  gzdbg << __FUNCTION__ << "() called." << std::endl;
52  }
53 
54  // Store the pointer to the model
55  model_ = _model;
56  world_ = model_->GetWorld();
57 
58  SdfVector3 noise_normal_position;
59  SdfVector3 noise_normal_quaternion;
60  SdfVector3 noise_normal_linear_velocity;
61  SdfVector3 noise_normal_angular_velocity;
62  SdfVector3 noise_uniform_position;
63  SdfVector3 noise_uniform_quaternion;
64  SdfVector3 noise_uniform_linear_velocity;
65  SdfVector3 noise_uniform_angular_velocity;
66  const SdfVector3 zeros3(0.0, 0.0, 0.0);
67 
68  odometry_queue_.clear();
69 
70  if (_sdf->HasElement("robotNamespace"))
71  namespace_ = _sdf->GetElement("robotNamespace")->Get<std::string>();
72  else
73  gzerr << "[gazebo_odometry_plugin] Please specify a robotNamespace.\n";
74 
75  node_handle_ = gazebo::transport::NodePtr(new transport::Node());
76 
77  // Initialise with default namespace (typically /gazebo/default/)
78  node_handle_->Init();
79 
80  if (_sdf->HasElement("linkName"))
81  link_name_ = _sdf->GetElement("linkName")->Get<std::string>();
82  else
83  gzerr << "[gazebo_odometry_plugin] Please specify a linkName.\n";
84  link_ = model_->GetLink(link_name_);
85  if (link_ == NULL)
86  gzthrow("[gazebo_odometry_plugin] Couldn't find specified link \""
87  << link_name_ << "\".");
88 
89  if (_sdf->HasElement("covarianceImage")) {
90  std::string image_name =
91  _sdf->GetElement("covarianceImage")->Get<std::string>();
92  covariance_image_ = cv::imread(image_name, cv::IMREAD_GRAYSCALE);
93  if (covariance_image_.data == NULL)
94  gzerr << "loading covariance image " << image_name << " failed"
95  << std::endl;
96  else
97  gzlog << "loading covariance image " << image_name << " successful"
98  << std::endl;
99  }
100 
101  if (_sdf->HasElement("randomEngineSeed")) {
102  random_generator_.seed(
103  _sdf->GetElement("randomEngineSeed")->Get<unsigned int>());
104  } else {
105  random_generator_.seed(
106  std::chrono::system_clock::now().time_since_epoch().count());
107  }
108  getSdfParam<std::string>(_sdf, "poseTopic", pose_pub_topic_, pose_pub_topic_);
109  getSdfParam<std::string>(_sdf, "poseWithCovarianceTopic",
112  getSdfParam<std::string>(_sdf, "positionTopic", position_stamped_pub_topic_,
114  getSdfParam<std::string>(_sdf, "transformTopic", transform_stamped_pub_topic_,
116  getSdfParam<std::string>(_sdf, "odometryTopic", odometry_pub_topic_,
118  getSdfParam<std::string>(_sdf, "parentFrameId", parent_frame_id_,
120  getSdfParam<std::string>(_sdf, "childFrameId", child_frame_id_,
122  getSdfParam<SdfVector3>(_sdf, "noiseNormalPosition", noise_normal_position,
123  zeros3);
124  getSdfParam<SdfVector3>(_sdf, "noiseNormalQuaternion",
125  noise_normal_quaternion, zeros3);
126  getSdfParam<SdfVector3>(_sdf, "noiseNormalLinearVelocity",
127  noise_normal_linear_velocity, zeros3);
128  getSdfParam<SdfVector3>(_sdf, "noiseNormalAngularVelocity",
129  noise_normal_angular_velocity, zeros3);
130  getSdfParam<SdfVector3>(_sdf, "noiseUniformPosition", noise_uniform_position,
131  zeros3);
132  getSdfParam<SdfVector3>(_sdf, "noiseUniformQuaternion",
133  noise_uniform_quaternion, zeros3);
134  getSdfParam<SdfVector3>(_sdf, "noiseUniformLinearVelocity",
135  noise_uniform_linear_velocity, zeros3);
136  getSdfParam<SdfVector3>(_sdf, "noiseUniformAngularVelocity",
137  noise_uniform_angular_velocity, zeros3);
138  getSdfParam<int>(_sdf, "measurementDelay", measurement_delay_,
140  getSdfParam<int>(_sdf, "measurementDivisor", measurement_divisor_,
142  getSdfParam<double>(_sdf, "unknownDelay", unknown_delay_, unknown_delay_);
143  getSdfParam<double>(_sdf, "covarianceImageScale", covariance_image_scale_,
145 
146  parent_link_ = world_->EntityByName(parent_frame_id_);
147  if (parent_link_ == NULL && parent_frame_id_ != kDefaultParentFrameId) {
148  gzthrow("[gazebo_odometry_plugin] Couldn't find specified parent link \""
149  << parent_frame_id_ << "\".");
150  }
151 
152  position_n_[0] = NormalDistribution(0, noise_normal_position.X());
153  position_n_[1] = NormalDistribution(0, noise_normal_position.Y());
154  position_n_[2] = NormalDistribution(0, noise_normal_position.Z());
155 
156  attitude_n_[0] = NormalDistribution(0, noise_normal_quaternion.X());
157  attitude_n_[1] = NormalDistribution(0, noise_normal_quaternion.Y());
158  attitude_n_[2] = NormalDistribution(0, noise_normal_quaternion.Z());
159 
160  linear_velocity_n_[0] =
161  NormalDistribution(0, noise_normal_linear_velocity.X());
162  linear_velocity_n_[1] =
163  NormalDistribution(0, noise_normal_linear_velocity.Y());
164  linear_velocity_n_[2] =
165  NormalDistribution(0, noise_normal_linear_velocity.Z());
166 
168  NormalDistribution(0, noise_normal_angular_velocity.X());
169  angular_velocity_n_[1] =
170  NormalDistribution(0, noise_normal_angular_velocity.Y());
171  angular_velocity_n_[2] =
172  NormalDistribution(0, noise_normal_angular_velocity.Z());
173 
174  position_u_[0] = UniformDistribution(-noise_uniform_position.X(),
175  noise_uniform_position.X());
176  position_u_[1] = UniformDistribution(-noise_uniform_position.Y(),
177  noise_uniform_position.Y());
178  position_u_[2] = UniformDistribution(-noise_uniform_position.Z(),
179  noise_uniform_position.Z());
180 
181  attitude_u_[0] = UniformDistribution(-noise_uniform_quaternion.X(),
182  noise_uniform_quaternion.X());
183  attitude_u_[1] = UniformDistribution(-noise_uniform_quaternion.Y(),
184  noise_uniform_quaternion.Y());
185  attitude_u_[2] = UniformDistribution(-noise_uniform_quaternion.Z(),
186  noise_uniform_quaternion.Z());
187 
189  -noise_uniform_linear_velocity.X(), noise_uniform_linear_velocity.X());
190  linear_velocity_u_[1] = UniformDistribution(
191  -noise_uniform_linear_velocity.Y(), noise_uniform_linear_velocity.Y());
192  linear_velocity_u_[2] = UniformDistribution(
193  -noise_uniform_linear_velocity.Z(), noise_uniform_linear_velocity.Z());
194 
196  -noise_uniform_angular_velocity.X(), noise_uniform_angular_velocity.X());
197  angular_velocity_u_[1] = UniformDistribution(
198  -noise_uniform_angular_velocity.Y(), noise_uniform_angular_velocity.Y());
199  angular_velocity_u_[2] = UniformDistribution(
200  -noise_uniform_angular_velocity.Z(), noise_uniform_angular_velocity.Z());
201 
202  // Fill in covariance. We omit uniform noise here.
203  Eigen::Map<Eigen::Matrix<double, 6, 6> > pose_covariance(
204  pose_covariance_matrix_.data());
205  Eigen::Matrix<double, 6, 1> pose_covd;
206 
207  pose_covd << noise_normal_position.X() * noise_normal_position.X(),
208  noise_normal_position.Y() * noise_normal_position.Y(),
209  noise_normal_position.Z() * noise_normal_position.Z(),
210  noise_normal_quaternion.X() * noise_normal_quaternion.X(),
211  noise_normal_quaternion.Y() * noise_normal_quaternion.Y(),
212  noise_normal_quaternion.Z() * noise_normal_quaternion.Z();
213  pose_covariance = pose_covd.asDiagonal();
214 
215  // Fill in covariance. We omit uniform noise here.
216  Eigen::Map<Eigen::Matrix<double, 6, 6> > twist_covariance(
217  twist_covariance_matrix_.data());
218  Eigen::Matrix<double, 6, 1> twist_covd;
219 
220  twist_covd << noise_normal_linear_velocity.X() *
221  noise_normal_linear_velocity.X(),
222  noise_normal_linear_velocity.Y() * noise_normal_linear_velocity.Y(),
223  noise_normal_linear_velocity.Z() * noise_normal_linear_velocity.Z(),
224  noise_normal_angular_velocity.X() * noise_normal_angular_velocity.X(),
225  noise_normal_angular_velocity.Y() * noise_normal_angular_velocity.Y(),
226  noise_normal_angular_velocity.Z() * noise_normal_angular_velocity.Z();
227  twist_covariance = twist_covd.asDiagonal();
228 
229  // Listen to the update event. This event is broadcast every
230  // simulation iteration.
231  updateConnection_ = event::Events::ConnectWorldUpdateBegin(
232  boost::bind(&GazeboOdometryPlugin::OnUpdate, this, _1));
233 }
234 
235 // This gets called by the world update start event.
236 void GazeboOdometryPlugin::OnUpdate(const common::UpdateInfo& _info) {
237  if (kPrintOnUpdates) {
238  gzdbg << __FUNCTION__ << "() called." << std::endl;
239  }
240 
241  if (!pubs_and_subs_created_) {
243  pubs_and_subs_created_ = true;
244  }
245 
246  // C denotes child frame, P parent frame, and W world frame.
247  // Further C_pose_W_P denotes pose of P wrt. W expressed in C.
248  ignition::math::Pose3d W_pose_W_C = link_->WorldCoGPose();
249  ignition::math::Vector3d C_linear_velocity_W_C = link_->RelativeLinearVel();
250  ignition::math::Vector3d C_angular_velocity_W_C = link_->RelativeAngularVel();
251 
252  ignition::math::Vector3d gazebo_linear_velocity = C_linear_velocity_W_C;
253  ignition::math::Vector3d gazebo_angular_velocity = C_angular_velocity_W_C;
254  ignition::math::Pose3d gazebo_pose = W_pose_W_C;
255 
257  ignition::math::Pose3d W_pose_W_P = parent_link_->WorldPose();
258  ignition::math::Vector3d P_linear_velocity_W_P = parent_link_->RelativeLinearVel();
259  ignition::math::Vector3d P_angular_velocity_W_P =
260  parent_link_->RelativeAngularVel();
261  ignition::math::Pose3d C_pose_P_C_ = W_pose_W_C - W_pose_W_P;
262  ignition::math::Vector3d C_linear_velocity_P_C;
263  // \prescript{}{C}{\dot{r}}_{PC} = -R_{CP}
264  // \cdot \prescript{}{P}{\omega}_{WP} \cross \prescript{}{P}{r}_{PC}
265  // + \prescript{}{C}{v}_{WC}
266  // - R_{CP} \cdot \prescript{}{P}{v}_{WP}
267  C_linear_velocity_P_C =
268  -C_pose_P_C_.Rot().Inverse() *
269  P_angular_velocity_W_P.Cross(C_pose_P_C_.Pos()) +
270  C_linear_velocity_W_C -
271  C_pose_P_C_.Rot().Inverse() * P_linear_velocity_W_P;
272 
273  // \prescript{}{C}{\omega}_{PC} = \prescript{}{C}{\omega}_{WC}
274  // - R_{CP} \cdot \prescript{}{P}{\omega}_{WP}
275  gazebo_angular_velocity =
276  C_angular_velocity_W_C -
277  C_pose_P_C_.Rot().Inverse() * P_angular_velocity_W_P;
278  gazebo_linear_velocity = C_linear_velocity_P_C;
279  gazebo_pose = C_pose_P_C_;
280  }
281 
282  // This flag could be set to false in the following code...
283  bool publish_odometry = true;
284 
285  // First, determine whether we should publish a odometry.
286  if (covariance_image_.data != NULL) {
287  // We have an image.
288 
289  // Image is always centered around the origin:
290  int width = covariance_image_.cols;
291  int height = covariance_image_.rows;
292  int x = static_cast<int>(
293  std::floor(gazebo_pose.Pos().X() / covariance_image_scale_)) +
294  width / 2;
295  int y = static_cast<int>(
296  std::floor(gazebo_pose.Pos().Y() / covariance_image_scale_)) +
297  height / 2;
298 
299  if (x >= 0 && x < width && y >= 0 && y < height) {
300  uint8_t pixel_value = covariance_image_.at<uint8_t>(y, x);
301  if (pixel_value == 0) {
302  publish_odometry = false;
303  // TODO: covariance scaling, according to the intensity values could be
304  // implemented here.
305  }
306  }
307  }
308 
310  gz_geometry_msgs::Odometry odometry;
311  odometry.mutable_header()->set_frame_id(parent_frame_id_);
312  odometry.mutable_header()->mutable_stamp()->set_sec(
313  (world_->SimTime()).sec + static_cast<int32_t>(unknown_delay_));
314  odometry.mutable_header()->mutable_stamp()->set_nsec(
315  (world_->SimTime()).nsec + static_cast<int32_t>(unknown_delay_));
316  odometry.set_child_frame_id(child_frame_id_);
317 
318  odometry.mutable_pose()->mutable_pose()->mutable_position()->set_x(
319  gazebo_pose.Pos().X());
320  odometry.mutable_pose()->mutable_pose()->mutable_position()->set_y(
321  gazebo_pose.Pos().Y());
322  odometry.mutable_pose()->mutable_pose()->mutable_position()->set_z(
323  gazebo_pose.Pos().Z());
324 
325  odometry.mutable_pose()->mutable_pose()->mutable_orientation()->set_x(
326  gazebo_pose.Rot().X());
327  odometry.mutable_pose()->mutable_pose()->mutable_orientation()->set_y(
328  gazebo_pose.Rot().Y());
329  odometry.mutable_pose()->mutable_pose()->mutable_orientation()->set_z(
330  gazebo_pose.Rot().Z());
331  odometry.mutable_pose()->mutable_pose()->mutable_orientation()->set_w(
332  gazebo_pose.Rot().W());
333 
334  odometry.mutable_twist()->mutable_twist()->mutable_linear()->set_x(
335  gazebo_linear_velocity.X());
336  odometry.mutable_twist()->mutable_twist()->mutable_linear()->set_y(
337  gazebo_linear_velocity.Y());
338  odometry.mutable_twist()->mutable_twist()->mutable_linear()->set_z(
339  gazebo_linear_velocity.Z());
340 
341  odometry.mutable_twist()->mutable_twist()->mutable_angular()->set_x(
342  gazebo_angular_velocity.X());
343  odometry.mutable_twist()->mutable_twist()->mutable_angular()->set_y(
344  gazebo_angular_velocity.Y());
345  odometry.mutable_twist()->mutable_twist()->mutable_angular()->set_z(
346  gazebo_angular_velocity.Z());
347 
348  if (publish_odometry)
349  odometry_queue_.push_back(
350  std::make_pair(gazebo_sequence_ + measurement_delay_, odometry));
351  }
352 
353  // Is it time to publish the front element?
354  if (gazebo_sequence_ == odometry_queue_.front().first) {
355  // Copy the odometry message that is on the queue
356  gz_geometry_msgs::Odometry odometry_msg(odometry_queue_.front().second);
357 
358  // Now that we have copied the first element from the queue, remove it.
359  odometry_queue_.pop_front();
360 
361  // Calculate position distortions.
362  Eigen::Vector3d pos_n;
363  pos_n << position_n_[0](random_generator_) +
367 
368  gazebo::msgs::Vector3d* p =
369  odometry_msg.mutable_pose()->mutable_pose()->mutable_position();
370  p->set_x(p->x() + pos_n[0]);
371  p->set_y(p->y() + pos_n[1]);
372  p->set_z(p->z() + pos_n[2]);
373 
374  // Calculate attitude distortions.
375  Eigen::Vector3d theta;
376  theta << attitude_n_[0](random_generator_) +
380  Eigen::Quaterniond q_n = QuaternionFromSmallAngle(theta);
381  q_n.normalize();
382 
383  gazebo::msgs::Quaternion* q_W_L =
384  odometry_msg.mutable_pose()->mutable_pose()->mutable_orientation();
385 
386  Eigen::Quaterniond _q_W_L(q_W_L->w(), q_W_L->x(), q_W_L->y(), q_W_L->z());
387  _q_W_L = _q_W_L * q_n;
388  q_W_L->set_w(_q_W_L.w());
389  q_W_L->set_x(_q_W_L.x());
390  q_W_L->set_y(_q_W_L.y());
391  q_W_L->set_z(_q_W_L.z());
392 
393  // Calculate linear velocity distortions.
394  Eigen::Vector3d linear_velocity_n;
395  linear_velocity_n << linear_velocity_n_[0](random_generator_) +
401 
402  gazebo::msgs::Vector3d* linear_velocity =
403  odometry_msg.mutable_twist()->mutable_twist()->mutable_linear();
404 
405  linear_velocity->set_x(linear_velocity->x() + linear_velocity_n[0]);
406  linear_velocity->set_y(linear_velocity->y() + linear_velocity_n[1]);
407  linear_velocity->set_z(linear_velocity->z() + linear_velocity_n[2]);
408 
409  // Calculate angular velocity distortions.
410  Eigen::Vector3d angular_velocity_n;
411  angular_velocity_n << angular_velocity_n_[0](random_generator_) +
417 
418  gazebo::msgs::Vector3d* angular_velocity =
419  odometry_msg.mutable_twist()->mutable_twist()->mutable_angular();
420 
421  angular_velocity->set_x(angular_velocity->x() + angular_velocity_n[0]);
422  angular_velocity->set_y(angular_velocity->y() + angular_velocity_n[1]);
423  angular_velocity->set_z(angular_velocity->z() + angular_velocity_n[2]);
424 
425  odometry_msg.mutable_pose()->mutable_covariance()->Clear();
426  for (int i = 0; i < pose_covariance_matrix_.size(); i++) {
427  odometry_msg.mutable_pose()->mutable_covariance()->Add(
429  }
430 
431  odometry_msg.mutable_twist()->mutable_covariance()->Clear();
432  for (int i = 0; i < twist_covariance_matrix_.size(); i++) {
433  odometry_msg.mutable_twist()->mutable_covariance()->Add(
435  }
436 
437  // Publish all the topics, for which the topic name is specified.
438  if (pose_pub_->HasConnections()) {
439  pose_pub_->Publish(odometry_msg.pose().pose());
440  }
441 
442  if (pose_with_covariance_stamped_pub_->HasConnections()) {
443  gz_geometry_msgs::PoseWithCovarianceStamped
444  pose_with_covariance_stamped_msg;
445 
446  pose_with_covariance_stamped_msg.mutable_header()->CopyFrom(
447  odometry_msg.header());
448  pose_with_covariance_stamped_msg.mutable_pose_with_covariance()->CopyFrom(
449  odometry_msg.pose());
450 
452  pose_with_covariance_stamped_msg);
453  }
454 
455  if (position_stamped_pub_->HasConnections()) {
456  gz_geometry_msgs::Vector3dStamped position_stamped_msg;
457  position_stamped_msg.mutable_header()->CopyFrom(odometry_msg.header());
458  position_stamped_msg.mutable_position()->CopyFrom(
459  odometry_msg.pose().pose().position());
460 
461  position_stamped_pub_->Publish(position_stamped_msg);
462  }
463 
464  if (transform_stamped_pub_->HasConnections()) {
465  gz_geometry_msgs::TransformStamped transform_stamped_msg;
466 
467  transform_stamped_msg.mutable_header()->CopyFrom(odometry_msg.header());
468  transform_stamped_msg.mutable_transform()->mutable_translation()->set_x(
469  p->x());
470  transform_stamped_msg.mutable_transform()->mutable_translation()->set_y(
471  p->y());
472  transform_stamped_msg.mutable_transform()->mutable_translation()->set_z(
473  p->z());
474  transform_stamped_msg.mutable_transform()->mutable_rotation()->CopyFrom(
475  *q_W_L);
476 
477  transform_stamped_pub_->Publish(transform_stamped_msg);
478  }
479 
480  if (odometry_pub_->HasConnections()) {
481  // DEBUG
482  odometry_pub_->Publish(odometry_msg);
483  }
484 
485  //==============================================//
486  //========= BROADCAST TRANSFORM MSG ============//
487  //==============================================//
488 
489  gz_geometry_msgs::TransformStampedWithFrameIds
490  transform_stamped_with_frame_ids_msg;
491  transform_stamped_with_frame_ids_msg.mutable_header()->CopyFrom(
492  odometry_msg.header());
493  transform_stamped_with_frame_ids_msg.mutable_transform()
494  ->mutable_translation()
495  ->set_x(p->x());
496  transform_stamped_with_frame_ids_msg.mutable_transform()
497  ->mutable_translation()
498  ->set_y(p->y());
499  transform_stamped_with_frame_ids_msg.mutable_transform()
500  ->mutable_translation()
501  ->set_z(p->z());
502  transform_stamped_with_frame_ids_msg.mutable_transform()
503  ->mutable_rotation()
504  ->CopyFrom(*q_W_L);
505  transform_stamped_with_frame_ids_msg.set_parent_frame_id(parent_frame_id_);
506  transform_stamped_with_frame_ids_msg.set_child_frame_id(child_frame_id_);
507 
508  broadcast_transform_pub_->Publish(transform_stamped_with_frame_ids_msg);
509 
510  } // if (gazebo_sequence_ == odometry_queue_.front().first) {
511 
513 }
514 
516  // Create temporary "ConnectGazeboToRosTopic" publisher and message
517  gazebo::transport::PublisherPtr connect_gazebo_to_ros_topic_pub =
518  node_handle_->Advertise<gz_std_msgs::ConnectGazeboToRosTopic>(
519  "~/" + kConnectGazeboToRosSubtopic, 1);
520 
521  gz_std_msgs::ConnectGazeboToRosTopic connect_gazebo_to_ros_topic_msg;
522 
523  // ============================================ //
524  // =============== POSE MSG SETUP ============= //
525  // ============================================ //
526 
527  pose_pub_ = node_handle_->Advertise<gazebo::msgs::Pose>(
528  "~/" + namespace_ + "/" + pose_pub_topic_, 1);
529 
530  connect_gazebo_to_ros_topic_msg.set_gazebo_topic("~/" + namespace_ + "/" +
531  pose_pub_topic_);
532  connect_gazebo_to_ros_topic_msg.set_ros_topic(namespace_ + "/" +
533  pose_pub_topic_);
534  connect_gazebo_to_ros_topic_msg.set_msgtype(
535  gz_std_msgs::ConnectGazeboToRosTopic::POSE);
536  connect_gazebo_to_ros_topic_pub->Publish(connect_gazebo_to_ros_topic_msg,
537  true);
538 
539  // ============================================ //
540  // == POSE WITH COVARIANCE STAMPED MSG SETUP == //
541  // ============================================ //
542 
544  node_handle_->Advertise<gz_geometry_msgs::PoseWithCovarianceStamped>(
546 
547  connect_gazebo_to_ros_topic_msg.set_gazebo_topic(
548  "~/" + namespace_ + "/" + pose_with_covariance_stamped_pub_topic_);
549  connect_gazebo_to_ros_topic_msg.set_ros_topic(
550  namespace_ + "/" + pose_with_covariance_stamped_pub_topic_);
551  connect_gazebo_to_ros_topic_msg.set_msgtype(
552  gz_std_msgs::ConnectGazeboToRosTopic::POSE_WITH_COVARIANCE_STAMPED);
553  connect_gazebo_to_ros_topic_pub->Publish(connect_gazebo_to_ros_topic_msg,
554  true);
555 
556  // ============================================ //
557  // ========= POSITION STAMPED MSG SETUP ======= //
558  // ============================================ //
559 
561  node_handle_->Advertise<gz_geometry_msgs::Vector3dStamped>(
562  "~/" + namespace_ + "/" + position_stamped_pub_topic_, 1);
563 
564  connect_gazebo_to_ros_topic_msg.set_gazebo_topic("~/" + namespace_ + "/" +
565  position_stamped_pub_topic_);
566  connect_gazebo_to_ros_topic_msg.set_ros_topic(namespace_ + "/" +
567  position_stamped_pub_topic_);
568  connect_gazebo_to_ros_topic_msg.set_msgtype(
569  gz_std_msgs::ConnectGazeboToRosTopic::VECTOR_3D_STAMPED);
570  connect_gazebo_to_ros_topic_pub->Publish(connect_gazebo_to_ros_topic_msg,
571  true);
572 
573  // ============================================ //
574  // ============= ODOMETRY MSG SETUP =========== //
575  // ============================================ //
576 
577  odometry_pub_ = node_handle_->Advertise<gz_geometry_msgs::Odometry>(
578  "~/" + namespace_ + "/" + odometry_pub_topic_, 1);
579 
580  connect_gazebo_to_ros_topic_msg.set_gazebo_topic("~/" + namespace_ + "/" +
581  odometry_pub_topic_);
582  connect_gazebo_to_ros_topic_msg.set_ros_topic(namespace_ + "/" +
583  odometry_pub_topic_);
584  connect_gazebo_to_ros_topic_msg.set_msgtype(
585  gz_std_msgs::ConnectGazeboToRosTopic::ODOMETRY);
586  connect_gazebo_to_ros_topic_pub->Publish(connect_gazebo_to_ros_topic_msg,
587  true);
588 
589  // ============================================ //
590  // ======== TRANSFORM STAMPED MSG SETUP ======= //
591  // ============================================ //
592 
594  node_handle_->Advertise<gz_geometry_msgs::TransformStamped>(
595  "~/" + namespace_ + "/" + transform_stamped_pub_topic_, 1);
596 
597  connect_gazebo_to_ros_topic_msg.set_gazebo_topic(
598  "~/" + namespace_ + "/" + transform_stamped_pub_topic_);
599  connect_gazebo_to_ros_topic_msg.set_ros_topic(namespace_ + "/" +
600  transform_stamped_pub_topic_);
601  connect_gazebo_to_ros_topic_msg.set_msgtype(
602  gz_std_msgs::ConnectGazeboToRosTopic::TRANSFORM_STAMPED);
603  connect_gazebo_to_ros_topic_pub->Publish(connect_gazebo_to_ros_topic_msg,
604  true);
605 
606  // ============================================ //
607  // ===== "BROADCAST TRANSFORM" MSG SETUP ===== //
608  // ============================================ //
609 
611  node_handle_->Advertise<gz_geometry_msgs::TransformStampedWithFrameIds>(
612  "~/" + kBroadcastTransformSubtopic, 1);
613 }
614 
616 
617 } // namespace gazebo
UniformDistribution angular_velocity_u_[3]
gazebo::transport::PublisherPtr position_stamped_pub_
gazebo::transport::PublisherPtr transform_stamped_pub_
gazebo::transport::PublisherPtr odometry_pub_
UniformDistribution position_u_[3]
gazebo::transport::PublisherPtr pose_pub_
UniformDistribution linear_velocity_u_[3]
bool pubs_and_subs_created_
Flag that is set to true once CreatePubsAndSubs() is called, used to prevent CreatePubsAndSubs() from...
NormalDistribution linear_velocity_n_[3]
event::ConnectionPtr updateConnection_
Pointer to the update event connection.
static const bool kPrintOnPluginLoad
Definition: common.h:41
Eigen::Quaternion< typename Derived::Scalar > QuaternionFromSmallAngle(const Eigen::MatrixBase< Derived > &theta)
Computes a quaternion from the 3-element small angle approximation theta.
Definition: common.h:187
gazebo::transport::PublisherPtr pose_with_covariance_stamped_pub_
void Load(physics::ModelPtr _model, sdf::ElementPtr _sdf)
NormalDistribution angular_velocity_n_[3]
static const bool kPrintOnUpdates
Definition: common.h:42
void CreatePubsAndSubs()
Creates all required publishers and subscribers, incl. routing of messages to/from ROS if required...
UniformDistribution attitude_u_[3]
std::normal_distribution NormalDistribution
GZ_REGISTER_MODEL_PLUGIN(GazeboRosP3D)
double time_since_epoch()
static const std::string kConnectGazeboToRosSubtopic
Definition: common.h:56
void OnUpdate(const common::UpdateInfo &)
static const std::string kBroadcastTransformSubtopic
Special-case topic for ROS interface plugin to listen to (if present) and broadcast transforms to the...
Definition: common.h:61
gazebo::transport::NodePtr node_handle_
static const std::string kDefaultParentFrameId
std::uniform_real_distribution UniformDistribution
gazebo::transport::PublisherPtr broadcast_transform_pub_
Special-case publisher to publish stamped transforms with frame IDs. The ROS interface plugin (if pre...


rotors_gazebo_plugins
Author(s): Fadri Furrer, Michael Burri, Mina Kamel, Janosch Nikolic, Markus Achtelik
autogenerated on Mon Feb 28 2022 23:39:04