laserscan_to_pointcloud.cpp
Go to the documentation of this file.
1 
18 #include <pcl/io/pcd_io.h>
19 #include <pcl/point_types.h>
20 #include "std_msgs/String.h"
21 #include "leica_scanstation_utils/LeicaUtils.h"
23 
25  :nh_(nh)
26 {
27  total_cloud_ = boost::make_shared<PointCloudXYZ>();
28 
29  // Subscribe to the topic where the outline of the object that sees the laser is published
30  sub_ = nh_.subscribe<sensor_msgs::LaserScan>("simulator/scan", 100, &ScanToPointCloud::scanCb, this);
31  filename_sub_ = nh_.subscribe<std_msgs::String>("simulator/filename", 100, &ScanToPointCloud::filenameCb, this);
32 
33  // Create a topic where the point cloud will be published
34  pub_ = nh_.advertise<sensor_msgs::PointCloud2>("simulator/cloud", 100, false);
35 
36  // Publish service so that it can be invoked when requested
38 
39  counter_ = 0;
40  file_name_ = LeicaUtils::getFilePath("scan", ".pcd"); // default
41 }
42 
43 void ScanToPointCloud::filenameCb(const std_msgs::String::ConstPtr& msg)
44 {
45  file_name_ = LeicaUtils::getFilePath(msg->data, ".pcd", counter_);
46  counter_++;
47 }
48 
49 bool ScanToPointCloud::saveCloudCb(std_srvs::Trigger::Request &req, std_srvs::Trigger::Response &res)
50 {
51  ROS_INFO("Saving the point cloud...");
52 
53  // Save the point cloud on the hard disk
54  pcl::io::savePCDFileASCII(file_name_, *total_cloud_);
55  ROS_INFO("Saved %zu data points to %s", total_cloud_->size(), file_name_.c_str());
56 
57  // Reset the cloud after saving it
58  total_cloud_.reset(new PointCloudXYZ);
59  init_cloud_ = true;
60 
61  return true;
62 }
63 
64 void ScanToPointCloud::scanCb(const sensor_msgs::LaserScan::ConstPtr& scan)
65 {
66  // Variables to store the current point cloud and the new chunk
67  sensor_msgs::PointCloud2 cloud,total_cloud_msg;
68 
69  // Pointer to save ros scan info and update total_cloud_
70  PointCloudXYZ::Ptr cloud_pcl;
71  cloud_pcl.reset(new PointCloudXYZ);
72 
73  // Find that the tf you need to relate the frame of the sensor to the world frame exists
75  scan->header.frame_id,
76  "/world",
77  scan->header.stamp + ros::Duration().fromSec(scan->ranges.size()*scan->time_increment),
78  ros::Duration(1.0)))
79  {
80  // Transform the continuous line that sees the laser to a series of points
82 
83  // Convert to PCL is necessary to add new scan data to total_cloud_
84  pcl::fromROSMsg(cloud, *cloud_pcl);
85 
86  // Execute this once
87  if (init_cloud_)
88  {
89  *total_cloud_ = *cloud_pcl;
90  init_cloud_ = false;
91  }
92 
93  // Add the new set of point cloud to the current point cloud
94  *total_cloud_ += *cloud_pcl;
95 
96  // Convert again to ros msg and publish
97  pcl::toROSMsg(*total_cloud_, total_cloud_msg);
98  pub_.publish(total_cloud_msg);
99  }
100 }
101 
102 int main(int argc, char** argv)
103 {
104  // Launch the process of transforming the laser scan into the point cloud
105  ros::init(argc, argv, "ScanToPointCloud");
106  ros::NodeHandle nh;
107 
108  ROS_INFO("tf from laserscan to pointcloud");
109  ScanToPointCloud cloud_converter(nh);
110 
111  ros::spin();
112 
113  return 0;
114 }
PointCloudXYZ::Ptr total_cloud_
Point cloud generated by the Leica.
void publish(const boost::shared_ptr< M > &message) const
Subscriber subscribe(const std::string &topic, uint32_t queue_size, void(T::*fp)(M), T *obj, const TransportHints &transport_hints=TransportHints())
tf::TransformListener tf_listener_
Reference system of the listener.
ScanToPointCloud(ros::NodeHandle nh)
Construct a new Scan To Point Cloud object.
laser_geometry::LaserProjection projector_
Instance of object LaserProjection to transform the laser scan into a point cloud.
ROSCPP_DECL void init(int &argc, char **argv, const std::string &name, uint32_t options=0)
ros::Subscriber sub_
Subscriber for the laser scan.
ServiceServer advertiseService(const std::string &service, bool(T::*srv_func)(MReq &, MRes &), T *obj)
bool init_cloud_
Attaches header info and more to total_cloud_ in the first iteration.
ROSCPP_DECL void spin(Spinner &spinner)
bool waitForTransform(const std::string &target_frame, const std::string &source_frame, const ros::Time &time, const ros::Duration &timeout, const ros::Duration &polling_sleep_duration=ros::Duration(0.01), std::string *error_msg=NULL) const
Duration & fromSec(double t)
ros::Subscriber filename_sub_
Subscriber to receive file name.
#define ROS_INFO(...)
Publisher advertise(const std::string &topic, uint32_t queue_size, bool latch=false)
ros::NodeHandle nh_
Pointer to the ROS node.
bool saveCloudCb(std_srvs::Trigger::Request &req, std_srvs::Trigger::Response &res)
Saves the cloud as .pcd format. The destination folder will be on package leica_scanstation_utils/poi...
void scanCb(const sensor_msgs::LaserScan::ConstPtr &scan)
Callback for adding the new scan to the point cloud.
pcl::PointCloud< pcl::PointXYZ > PointCloudXYZ
ros::Publisher pub_
Publisher for the point cloud.
std::string file_name_
File name to store point cloud scanned.
void filenameCb(const std_msgs::String::ConstPtr &msg)
Callback for read file name in which store point cloud scanned.
void transformLaserScanToPointCloud(const std::string &target_frame, const sensor_msgs::LaserScan &scan_in, sensor_msgs::PointCloud &cloud_out, tf::Transformer &tf, double range_cutoff, int channel_options=channel_option::Default)
ros::ServiceServer store_sub_
Service for saving the point cloud.
int counter_
Count number of scans finished to append on file name.
int main(int argc, char **argv)


leica_gazebo_simulation
Author(s): Ines Lara Sicilia
autogenerated on Mon Feb 22 2021 03:50:48