pointCloudPubliser.cpp
Go to the documentation of this file.
1 //
2 // Created by inspur on 2020/5/13.
3 //
4 
5 #include "pointCloudPublisher.h"
6 #include "unistd.h"
7 #include "DataCache/DataCache.h"
8 #include <octomap/octomap.h>
9 #include <octomap_msgs/Octomap.h>
10 #include <octomap_msgs/conversions.h>
11 #include <octomap_ros/conversions.h>
12 #include "Converter.h"
13 
14 using namespace NS_DataCache;
16 {
17  this->nh = nh;
18  this->SLAM = SLAM;
19  mpPointCloudMapping = SLAM->GetPointCloudMapping();
20  mPointCloudPub = this->nh->advertise<sensor_msgs::PointCloud2>("/orbslam2/pointcloud", 100);
21  mOctomapPub = this->nh->advertise<octomap_msgs::Octomap>("/orbslam2/octomap", 5);
22  mOccupancyMapPub = this->nh->advertise<octomap_msgs::Octomap>("/orbslam2/occupancymap", 5);
23  mOdomPub = this->nh->advertise<nav_msgs::Odometry>("/orbslam2/odometry", 5);
24 
25  mpPointCloudDataCache = mpPointCloudMapping->GetPointCloudDataCache();
26  miPointCloudDataCacheIndex = mpPointCloudMapping->GetPointCloudDataCacheIndex();
27  mpTcwDataCache = this->SLAM->GetTcwDataCache();
28  miTcwDataCacheIndex = this->SLAM->GetTcwDataCacheIndex();
29 
30  PointCloudPublishThread = make_shared<thread>( bind( &PointCloudPublisher::PublishMap, this ) );
31  //OdomPublishThread = make_shared<thread>( bind( &PointCloudPublisher::PublishOdom, this ) );
32 
33 }
35 {
36  int count = 0;
37  //地图类数据发布
38  sensor_msgs::PointCloud2 pointCloud;
39  octomap::Pointcloud octo_cloud;
40  PointCloudMapping::PointCloud tempPointCloud;
41  octomap_msgs::Octomap octomap_msg;
42  // 创建八叉树对象,参数为分辨率,这里设成了0.05
43  octomap::OcTree tree( 0.05 );
44  octomap_msgs::Octomap occupancymap_msg;
45  while(ros::ok())
46  {
47  if (RET_SUCCESS == mpPointCloudDataCache->GetDataByIndex(miPointCloudDataCacheIndex,tempPointCloud))
48  {
49  //发布点云
50  toROSMsg(tempPointCloud, pointCloud);
51  pointCloud.header.stamp = ros::Time::now();
52  pointCloud.header.frame_id = "camera_link";
53  cout<<"Publish PointCloud: "<<count<<" 点云个数云:"<<tempPointCloud.points.size()<<endl;
54  mPointCloudPub.publish(pointCloud);
55 
56  //发布octomap
57  for (auto p:tempPointCloud.points)
58  {
59 
60 
61  //去除天空地面
62  if(p.z>1 || p.z<-0.5)
63  {
64  continue;
65  }
66  // 将点云里的点插入到octomap中
67  tree.updateNode( octomap::point3d(p.x, p.y, p.z), true );
68  }
69  // 更新octomap
70  tree.updateInnerOccupancy();
71  //fullMapToMsg负责转换成message
72  octomap_msgs::fullMapToMsg(tree, octomap_msg);
73  octomap_msg.header.frame_id = "camera_link";
74  octomap_msg.header.stamp = ros::Time::now();
75  mOctomapPub.publish(octomap_msg);
76 
77  //发布occupancymap
78  octomap_msgs::binaryMapToMsg(tree, occupancymap_msg);
79  occupancymap_msg.header.frame_id = "camera_link";
80  occupancymap_msg.header.stamp = ros::Time::now();
81  occupancymap_msg.id = 1;
82  occupancymap_msg.binary = 1;
83  occupancymap_msg.resolution = tree.getResolution();
84  mOccupancyMapPub.publish(octomap_msg);
85  }
86 
87  count++;
88  usleep(10);
89  }
90 }
91 
93 {
94  publish_tf = true;
95  world_frame_id = "odom";
96  base_frame_id = "base_link";
97  camera_frame_id = "camera_link";
98  ros::Rate rate(20);
99  bool warn_flag = false;
100  float x, y, z, qx, qy, qz, qw;
101  int ret_val;
102  tf::Transform sensordata_tf, output_tf;
103  tf::StampedTransform odom_trans;
104  nav_msgs::Odometry odom;
105 
106  while (ros::ok())
107  {
108  if (SLAM->GetTrackingState() != 2)
109  {
110  continue;
111  }
112 
113  // ret_val = SLAM->GetlastKeyFrame(x, y, z, qx, qy, qz, qw);
114 
115  // if (ret_val != 0)
116  // continue;
117  // odom.header.stamp = ros::Time::now();
118 
119  unique_lock<mutex> lock(MutexPose);
120  ret_val = getPose(x, y, z, qx, qy, qz, qw);
121  lock.unlock();
122 
123  if (ret_val != 0)
124  continue;
125 
126  sensordata_tf.setOrigin(tf::Vector3(x, y, z));
127  tf::Quaternion q;
128  q.setX(qx);
129  q.setY(qy);
130  q.setZ(qz);
131  q.setW(qw);
132  sensordata_tf.setRotation(q);
133  // ROS_INFO_STREAM(__FILE__ << "(" << __LINE__ << ") Sync time checkpoint:"
134  // << "[" << pose_sync_time << "]");
135 
136  if (get_base_to_camera)
137  {
138  if (warn_flag)
139  {
140  ROS_INFO("Get TF form '%s' to '%s', Publish TF '%s' to '%s'.", base_frame_id.data(), camera_frame_id.data(), world_frame_id.data(), base_frame_id.data());
141  warn_flag = false;
142  }
143 
144  output_tf = base_to_camera * sensordata_tf * camera_to_base;
145 
146  // tf::Quaternion temp = output_tf.getRotation();
147  // temp.normalize();
148  // output_tf.setRotation(temp);
149 
150  odom_trans = tf::StampedTransform(output_tf, pose_sync_time, world_frame_id, base_frame_id);
151  }
152  else
153  {
154  if (!warn_flag)
155  {
156  ROS_WARN("Can`t get TF form '%s' to '%s',Publish TF '%s' to '%s' instead.", base_frame_id.data(), camera_frame_id.data(), world_frame_id.data(), camera_frame_id.data());
157  warn_flag = true;
158  }
159  output_tf = sensordata_tf;
160  odom_trans = tf::StampedTransform(output_tf, pose_sync_time, world_frame_id, camera_frame_id);
161  }
162 
163  if (publish_tf)
164  {
165  tf_broadcaster.sendTransform(odom_trans);
166  }
167 
168  odom.header.stamp = pose_sync_time;
169  odom.header.frame_id = world_frame_id;
170  odom.child_frame_id = odom_trans.child_frame_id_;
171 
172  odom.pose.pose.position.x = output_tf.getOrigin().getX();
173  odom.pose.pose.position.y = output_tf.getOrigin().getY();
174  odom.pose.pose.position.z = output_tf.getOrigin().getZ();
175 
176  odom.pose.pose.orientation.x = output_tf.getRotation().x();
177  odom.pose.pose.orientation.y = output_tf.getRotation().y();
178  odom.pose.pose.orientation.z = output_tf.getRotation().z();
179  odom.pose.pose.orientation.w = output_tf.getRotation().w();
180  odom.pose.covariance[0] = 1e-3;
181  odom.pose.covariance[7] = 1e-3;
182  odom.pose.covariance[14] = 1e-6;
183  odom.pose.covariance[21] = 1e-6;
184  odom.pose.covariance[28] = 1e-6;
185  odom.pose.covariance[35] = 1e-3;
186 
187  // [ 1e-3, 0, 0, 0, 0, 0,
188  // 0, 1e-3, 0, 0, 0, 0,
189  // 0, 0, 1e6, 0, 0, 0,
190  // 0, 0, 0, 1e6, 0, 0,
191  // 0, 0, 0, 0, 1e6, 0,
192  // 0, 0, 0, 0, 0, 1e3 ];
193  mOdomPub.publish(odom);
194 
195  rate.sleep();
196  }
197 }
198 
199 int PointCloudPublisher::getPose(float &x, float &y, float &z, float &qx, float &qy, float &qz, float &qw)
200 {
201  cv::Mat Tcw;
202  if (RET_SUCCESS == mpTcwDataCache->GetDataByIndex(miTcwDataCacheIndex,Tcw))
203  {
204  // pose_sync_time = ros::Time::now();
205  cv::Mat Ow;
206  cv::Mat R = Tcw.rowRange(0, 3).colRange(0, 3);
207  cv::Mat tcw = Tcw.rowRange(0, 3).col(3);
208  cv::Mat Rwc = R.t();
209  Ow = -Rwc * tcw;
210  vector<float> q = ORB_SLAM2::Converter::toQuaternion(R);
211 
212  x = Ow.at<float>(2);
213  y = -Ow.at<float>(0);
214  z = -Ow.at<float>(1);
215  qx = -q[2];
216  qy = q[0];
217  qz = q[1];
218  qw = q[3];
219  // cout << setprecision(7) << " x=" << Ow.at<float>(2) << " y=" << -Ow.at<float>(0) << " z=" << -Ow.at<float>(1)
220  // << " qx=" << q[2] << " qy=" << q[0] << " qz=" << q[1] << " qw=" << q[3] << endl;
221  Tcw.release();
222  }
223  return 0;
224 }
225 
227 {
228  bool warn_flag = false;
229  tf::StampedTransform base_to_camera_tf;
230  while (ros::ok())
231  {
232  // ros::Time t = ros::Time::now();
233  ros::Time t = pose_sync_time;
234  // ROS_INFO_STREAM(__FILE__ << "(" << __LINE__ << ") Sync time checkpoint:"
235  // << "[" << t << "]");
236  // ROS_INFO_STREAM(__FILE__ << "(" << __LINE__ << ") Sync time checkpoint:"
237  // << "[" << pose_sync_time << "]");
238  try
239  {
240  bool ret = tf_listener.waitForTransform(base_frame_id, camera_frame_id, t, ros::Duration(1.0));
241  //ROS_INFO("%s", ret ? "TRUE" : "FALSE");
242  tf_listener.lookupTransform(base_frame_id, camera_frame_id, t, base_to_camera_tf);
243  }
244  catch (tf::TransformException ex)
245  {
246  if (!warn_flag)
247  {
248  ROS_WARN("Could not get initial transform from '%s' to '%s' frame, %s", base_frame_id.data(), camera_frame_id.data(), ex.what());
249  warn_flag = true;
250  }
251  get_base_to_camera = false;
252  continue;
253  }
254  base_to_camera = base_to_camera_tf;
255  camera_to_base = base_to_camera.inverse();
256 
257  warn_flag = false;
258  get_base_to_camera = true;
259  }
260 }
261 
263 {
264  tf::Vector3 tfVec;
265  tf::Matrix3x3 tfR;
266  tf::Quaternion quat;
267  tfVec = tf.getOrigin();
268  cout << "vector from reference frame to to child frame: " << tfVec.getX() << "," << tfVec.getY() << "," << tfVec.getZ() << endl;
269  tfR = tf.getBasis();
270  cout << "orientation of child frame w/rt reference frame: " << endl;
271  tfVec = tfR.getRow(0);
272  cout << tfVec.getX() << "," << tfVec.getY() << "," << tfVec.getZ() << endl;
273  tfVec = tfR.getRow(1);
274  cout << tfVec.getX() << "," << tfVec.getY() << "," << tfVec.getZ() << endl;
275  tfVec = tfR.getRow(2);
276  cout << tfVec.getX() << "," << tfVec.getY() << "," << tfVec.getZ() << endl;
277  quat = tf.getRotation();
278  cout << "quaternion: " << quat.x() << ", " << quat.y() << ", "
279  << quat.z() << ", " << quat.w() << endl;
280 }
281 
283 {
285  cout << "frame_id: " << sTf.frame_id_ << endl;
286  cout << "child_frame_id: " << sTf.child_frame_id_ << endl;
287  tf = get_tf_from_stamped_tf(sTf); //extract the tf from the stamped tf
288  printTf(tf); //and print its components
289 }
290 
292 {
293  tf::Transform tf(sTf.getBasis(), sTf.getOrigin()); //construct a transform using elements of sTf
294  return tf;
295 }
TFSIMD_FORCE_INLINE void setRotation(const Quaternion &q)
PointCloudPublisher(ros::NodeHandle *nh, ORB_SLAM2::System *SLAM)
TFSIMD_FORCE_INLINE Matrix3x3 & getBasis()
void printTf(tf::Transform tf)
int getPose(float &x, float &y, float &z, float &qx, float &qy, float &qz, float &qw)
TFSIMD_FORCE_INLINE const tfScalar & getY() const
static std::vector< float > toQuaternion(const cv::Mat &M)
TFSIMD_FORCE_INLINE const tfScalar & y() const
TFSIMD_FORCE_INLINE const tfScalar & getZ() const
#define ROS_WARN(...)
TFSIMD_FORCE_INLINE const Vector3 & getRow(int i) const
std::string child_frame_id_
#define ROS_INFO(...)
ROSCPP_DECL bool ok()
int32_t GetTcwDataCacheIndex()
TFSIMD_FORCE_INLINE const tfScalar & x() const
Transform inverse() const
Publisher advertise(const std::string &topic, uint32_t queue_size, bool latch=false)
TFSIMD_FORCE_INLINE Vector3 & getOrigin()
TFSIMD_FORCE_INLINE const tfScalar & z() const
bool sleep()
tf::Transform get_tf_from_stamped_tf(tf::StampedTransform sTf)
Quaternion getRotation() const
pcl::PointCloud< PointT > PointCloud
TFSIMD_FORCE_INLINE const tfScalar & getX() const
static Time now()
DataCache< cv::Mat > * GetTcwDataCache()
TFSIMD_FORCE_INLINE void setOrigin(const Vector3 &origin)
std::string frame_id_
shared_ptr< PointCloudMapping > GetPointCloudMapping()
void printStampedTf(tf::StampedTransform sTf)


orb_slam2_with_maps_odom
Author(s): teng zhang
autogenerated on Fri Sep 25 2020 03:24:47