Go to the documentation of this file.00001 #include <sys/types.h>
00002 #include <dirent.h>
00003 #include <errno.h>
00004 #include <vector>
00005 #include <string>
00006 #include <iostream>
00007 #include <ros/ros.h>
00008 #include <std_msgs/String.h>
00009 #include <pcl/point_types.h>
00010 #include <pcl_ros/point_cloud.h>
00011 #include <pcl/io/pcd_io.h>
00012
00013 typedef pcl::PointXYZ Point;
00014 typedef pcl::PointCloud<Point> PointCloud;
00015 typedef pcl::PointXYZRGB PointRGB;
00016 typedef pcl::PointCloud<PointRGB> PointCloudRGB;
00017
00018 class PcdPublisher {
00019
00020
00021 ros::NodeHandle nh_;
00022 ros::NodeHandle nh_private_;
00023
00024
00025 ros::Publisher point_cloud_pub_;
00026
00027
00028 ros::WallTimer timer_;
00029
00030
00031 std::string pcd_files_dir_;
00032 std::vector<std::string> pcd_files_;
00033 unsigned int pcd_counter_;
00034
00035 public:
00036
00040 PcdPublisher(std::string pcd_files_dir)
00041 {
00042 int len;
00043 double timer_period;
00044
00045
00046 ros::NodeHandle nh;
00047 ros::NodeHandle nh_private_("~");
00048
00049
00050 nh_private_.param("timer_period", timer_period, 0.1);
00051
00052
00053 pcd_files_dir_ = pcd_files_dir;
00054 pcd_files_ = std::vector<std::string>();
00055 pcd_counter_ = 0;
00056
00057
00058 len = pcd_files_dir_.length();
00059 if (strcmp("/", &(pcd_files_dir_[len - 1])) != 0)
00060 {
00061 pcd_files_dir_ = pcd_files_dir_ + "/";
00062 }
00063
00064
00065 listPcdFiles(pcd_files_dir_, pcd_files_);
00066
00067
00068 point_cloud_pub_ = nh_private_.advertise<PointCloudRGB>("output", 1);
00069
00070
00071 timer_ = nh.createWallTimer(ros::WallDuration(timer_period),
00072 boost::bind(&PcdPublisher::readAndPublish,
00073 this));
00074 ROS_INFO_STREAM("[PcdPublisher:] Timer started!");
00075 }
00076
00077 protected:
00078
00082 int listPcdFiles(std::string dir, std::vector<std::string> &files)
00083 {
00084 int len;
00085 DIR *dp;
00086 struct dirent *dirp;
00087
00088
00089 if((dp = opendir(dir.c_str())) == NULL)
00090 {
00091 std::cout << "Error(" << errno << ") opening " << dir << std::endl;
00092 return errno;
00093 }
00094
00095
00096 while ((dirp = readdir(dp)) != NULL)
00097 {
00098 len = strlen(dirp->d_name);
00099 if (len >= 4)
00100 {
00101 if (strcmp(".pcd", &(dirp->d_name[len - 4])) == 0)
00102 {
00103 files.push_back(dirp->d_name);
00104 }
00105 }
00106 }
00107 closedir(dp);
00108
00109
00110 std::sort(files.begin(), files.end());
00111 return 0;
00112 }
00113
00117 void readAndPublish()
00118 {
00119
00120 if (pcd_counter_ < pcd_files_.size())
00121 {
00122 PointCloud::Ptr cloud(new PointCloud);
00123
00124 if (pcl::io::loadPCDFile<Point>(pcd_files_dir_ + pcd_files_[pcd_counter_], *cloud) == -1)
00125 {
00126 ROS_ERROR_STREAM("Couldn't read file " << pcd_files_dir_ + pcd_files_[pcd_counter_]);
00127 return;
00128 }
00129
00130
00131 PointCloudRGB::Ptr cloud_rgb(new PointCloudRGB);
00132 pcl::copyPointCloud(*cloud, *cloud_rgb);
00133
00134
00135 point_cloud_pub_.publish(cloud_rgb);
00136
00137 ROS_INFO_STREAM("[PcdPublisher:] Published " << cloud->width * cloud->height
00138 << " data points from " << pcd_files_dir_ + pcd_files_[pcd_counter_]);
00139
00140 pcd_counter_++;
00141 }
00142 else
00143 {
00144
00145 timer_.stop();
00146 ROS_INFO_STREAM("[PcdPublisher:] All PCD files processed. Timer stoped!");
00147 }
00148 }
00149 };
00150
00154 int main(int argc, char **argv)
00155 {
00156 ros::init(argc, argv, "pcd_publisher");
00157
00158
00159 std::string pcd_files_dir = argc > 1 ? argv[1] : "data";
00160
00161
00162 PcdPublisher node(pcd_files_dir);
00163 ros::spin();
00164 return 0;
00165 }
00166