由于课题是做激光雷达定位方向,所以需要在ROS中利用gazebo仿真。发现网上没有讲激光帧仿真数据转换为PCL数据的教程。我就抛砖引玉写一个。其实主要是记录做课题的过程。同时作为自己的第一个CSDN博客!!
主要目的是将sensor_msgs::LaserScan类型转化为sensor_msgs::PointCloud2类型
先贴上这个ROS库的wiki地址:
laser_geometry
简易版本
这个转换也很简单,主要是使用了laser_geometry这个库的函数来进行转换。订阅仿真激光的节点,再套用函数即可。
#include <ros/ros.h>
#include <pcl/point_cloud.h>
#include <pcl/io/pcd_io.h>
#include <pcl_conversions/pcl_conversions.h>
#include <sensor_msgs/PointCloud2.h>
#include <sensor_msgs/PointCloud.h>
#include <sensor_msgs/LaserScan.h>
#include <laser_geometry/laser_geometry.h>
laser_geometry::LaserProjection projector_;
void scanCallback_1 (const sensor_msgs::LaserScan::ConstPtr& scan_in)
{
sensor_msgs::PointCloud2 cloud1;
projector_.projectLaser(*scan_in, cloud1);
// Do something with cloud.
//将激光帧保存为PCD文件
pcl::PointCloud<pcl::PointXYZ> cloud;
pcl::fromROSMsg(cloud1, cloud);
pcl::io::savePCDFileASCII ("test.pcd", cloud);
}
int main (int argc, char **argv)
{
ros::init (argc, argv, "pcl_create");
ros::NodeHandle nh;
//订阅scan话题,这里可以根据自己的话题进行改变
ros::Subscriber laser_scan=nh.subscribe("scan",1000,scanCallback_1);
ros::spin();
return 0;
}
CMake文件中需要依赖roscpp、pcl_conversions、pcl_ros、sensor_msgs、angles、laser_geometry这几个库。
高级版本
另一个函数就是可以将点云转换到另外的TF坐标系下的,需要先构建一个TF监听器,讲上文中的回调函数替换为下面的函数即可。
由于WIKI中写的不是很清楚,这里提醒一下如果将
tf::TransformListener listener_; 这条命令放到回调函数外面的话,会报错You must call ros::init() before creating the first NodeHandle 在此记录。
void scanCallback (const sensor_msgs::LaserScan::ConstPtr& scan_in)
{
tf::TransformListener listener_;
//做判断等待TF变换
if(!listener_.waitForTransform(
scan_in->header.frame_id,
"/base_link",
scan_in->header.stamp + ros::Duration().fromSec(scan_in->ranges.size()*scan_in->time_increment),
ros::Duration(1.0))){
return;
}
sensor_msgs::PointCloud2 cloud1;
projector_.transformLaserScanToPointCloud("/base_link",*scan_in,
cloud1,listener_);
// Do something with cloud.
pcl::PointCloud<pcl::PointXYZ> cloud;
pcl::fromROSMsg(cloud1, cloud);
pcl::io::savePCDFileASCII ("test2.pcd", cloud);
}
两端代码都是将点云储存为PCD文件,当然大家也可以进行其他操作。根据个人需要。
嗯,第一篇博客就这样,主要是技术比较菜,还是要多学习。