00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024
00025
00026
00027
00028
00029
00030
00031
00032
00033
00034
00035
00036
00037
00038 #include <pcl/pcl_config.h>
00039 #include <pcl/io/pcd_grabber.h>
00040 #include <pcl/point_cloud.h>
00041 #include <pcl/point_types.h>
00042 #include <pcl/io/pcd_io.h>
00043 #include <pcl/io/tar.h>
00044
00045 #ifdef _WIN32
00046 # include <io.h>
00047 # include <windows.h>
00048 # define pcl_open _open
00049 # define pcl_close(fd) _close(fd)
00050 # define pcl_lseek(fd,offset,origin) _lseek(fd,offset,origin)
00051 #else
00052 # include <sys/mman.h>
00053 # define pcl_open open
00054 # define pcl_close(fd) close(fd)
00055 # define pcl_lseek(fd,offset,origin) lseek(fd,offset,origin)
00056 #endif
00057
00060 struct pcl::PCDGrabberBase::PCDGrabberImpl
00061 {
00062 PCDGrabberImpl (pcl::PCDGrabberBase& grabber, const std::string& pcd_path, float frames_per_second, bool repeat);
00063 PCDGrabberImpl (pcl::PCDGrabberBase& grabber, const std::vector<std::string>& pcd_files, float frames_per_second, bool repeat);
00064 void trigger ();
00065 void readAhead ();
00066
00067
00068 int openTARFile (const std::string &file_name);
00069 void closeTARFile ();
00070 bool readTARHeader ();
00071
00072 pcl::PCDGrabberBase& grabber_;
00073 float frames_per_second_;
00074 bool repeat_;
00075 bool running_;
00076 std::vector<std::string> pcd_files_;
00077 std::vector<std::string>::iterator pcd_iterator_;
00078 TimeTrigger time_trigger_;
00079
00080 sensor_msgs::PointCloud2 next_cloud_;
00081 Eigen::Vector4f origin_;
00082 Eigen::Quaternionf orientation_;
00083 bool valid_;
00084
00085
00086 int tar_fd_;
00087 int tar_offset_;
00088 std::string tar_file_;
00089 pcl::io::TARHeader tar_header_;
00090 };
00091
00093 pcl::PCDGrabberBase::PCDGrabberImpl::PCDGrabberImpl (pcl::PCDGrabberBase& grabber, const std::string& pcd_path, float frames_per_second, bool repeat)
00094 : grabber_ (grabber)
00095 , frames_per_second_ (frames_per_second)
00096 , repeat_ (repeat)
00097 , running_ (false)
00098 , pcd_files_ ()
00099 , pcd_iterator_ ()
00100 , time_trigger_ (1.0 / static_cast<double> (std::max (frames_per_second, 0.001f)), boost::bind (&PCDGrabberImpl::trigger, this))
00101 , next_cloud_ ()
00102 , origin_ ()
00103 , orientation_ ()
00104 , valid_ (false)
00105 , tar_fd_ (-1)
00106 , tar_offset_ (0)
00107 , tar_file_ ()
00108 , tar_header_ ()
00109 {
00110 pcd_files_.push_back (pcd_path);
00111 pcd_iterator_ = pcd_files_.begin ();
00112 }
00113
00115 pcl::PCDGrabberBase::PCDGrabberImpl::PCDGrabberImpl (pcl::PCDGrabberBase& grabber, const std::vector<std::string>& pcd_files, float frames_per_second, bool repeat)
00116 : grabber_ (grabber)
00117 , frames_per_second_ (frames_per_second)
00118 , repeat_ (repeat)
00119 , running_ (false)
00120 , pcd_files_ ()
00121 , pcd_iterator_ ()
00122 , time_trigger_ (1.0 / static_cast<double> (std::max (frames_per_second, 0.001f)), boost::bind (&PCDGrabberImpl::trigger, this))
00123 , next_cloud_ ()
00124 , origin_ ()
00125 , orientation_ ()
00126 , valid_ (false)
00127 , tar_fd_ (-1)
00128 , tar_offset_ (0)
00129 , tar_file_ ()
00130 , tar_header_ ()
00131 {
00132 pcd_files_ = pcd_files;
00133 pcd_iterator_ = pcd_files_.begin ();
00134 }
00135
00137 void
00138 pcl::PCDGrabberBase::PCDGrabberImpl::readAhead ()
00139 {
00140 PCDReader reader;
00141 int pcd_version;
00142
00143
00144 if (tar_fd_ != -1)
00145 {
00146 if (!readTARHeader ())
00147 closeTARFile ();
00148 valid_ = (reader.read (tar_file_, next_cloud_, origin_, orientation_, pcd_version, tar_offset_) == 0);
00149 if (!valid_)
00150 closeTARFile ();
00151 else
00152 {
00153 tar_offset_ += (tar_header_.getFileSize ()) + (512 - tar_header_.getFileSize () % 512);
00154 int result = static_cast<int> (pcl_lseek (tar_fd_, tar_offset_, SEEK_SET));
00155 if (result < 0)
00156 closeTARFile ();
00157 }
00158 }
00159
00160 else
00161 {
00162 if (pcd_iterator_ != pcd_files_.end ())
00163 {
00164
00165 valid_ = (reader.read (*pcd_iterator_, next_cloud_, origin_, orientation_, pcd_version) == 0);
00166
00167
00168 if (!valid_)
00169 {
00170 if (openTARFile (*pcd_iterator_) >= 0)
00171 {
00172 if (!readTARHeader ())
00173 closeTARFile ();
00174 tar_file_ = *pcd_iterator_;
00175 valid_ = (reader.read (tar_file_, next_cloud_, origin_, orientation_, pcd_version, tar_offset_) == 0);
00176 if (!valid_)
00177 closeTARFile ();
00178 else
00179 {
00180 tar_offset_ += (tar_header_.getFileSize ()) + (512 - tar_header_.getFileSize () % 512);
00181 int result = static_cast<int> (pcl_lseek (tar_fd_, tar_offset_, SEEK_SET));
00182 if (result < 0)
00183 closeTARFile ();
00184 }
00185 }
00186 }
00187
00188 if (++pcd_iterator_ == pcd_files_.end () && repeat_)
00189 pcd_iterator_ = pcd_files_.begin ();
00190 }
00191 else
00192 valid_ = false;
00193 }
00194 }
00195
00197 bool
00198 pcl::PCDGrabberBase::PCDGrabberImpl::readTARHeader ()
00199 {
00200
00201 int result = static_cast<int> (::read (tar_fd_, reinterpret_cast<char*> (&tar_header_), 512));
00202 if (result == -1)
00203 {
00204 closeTARFile ();
00205 return (false);
00206 }
00207
00208
00209
00210
00211 if (tar_header_.file_type[0] != '0' && tar_header_.file_type[0] != '\0')
00212 {
00213 closeTARFile ();
00214 return (false);
00215 }
00216
00217
00218 if (std::string (tar_header_.ustar).substr (0, 5) != "ustar")
00219 {
00220 closeTARFile ();
00221 return (false);
00222 }
00223
00224 if (tar_header_.getFileSize () == 0)
00225 {
00226 closeTARFile ();
00227 return (false);
00228 }
00229
00230 tar_offset_ += 512;
00231
00232 return (true);
00233 }
00234
00236 void
00237 pcl::PCDGrabberBase::PCDGrabberImpl::closeTARFile ()
00238 {
00239 pcl_close (tar_fd_);
00240 tar_fd_ = -1;
00241 tar_offset_ = 0;
00242 memset (&tar_header_.file_name[0], 0, 512);
00243 }
00244
00246 int
00247 pcl::PCDGrabberBase::PCDGrabberImpl::openTARFile (const std::string &file_name)
00248 {
00249 tar_fd_ = pcl_open (file_name.c_str (), O_RDONLY);
00250 if (tar_fd_ == -1)
00251 return (-1);
00252
00253 return (0);
00254 }
00255
00257 void
00258 pcl::PCDGrabberBase::PCDGrabberImpl::trigger ()
00259 {
00260 if (valid_)
00261 grabber_.publish (next_cloud_,origin_,orientation_);
00262
00263
00264 readAhead ();
00265 }
00266
00269 pcl::PCDGrabberBase::PCDGrabberBase (const std::string& pcd_path, float frames_per_second, bool repeat)
00270 : impl_ (new PCDGrabberImpl (*this, pcd_path, frames_per_second, repeat))
00271 {
00272 }
00273
00275 pcl::PCDGrabberBase::PCDGrabberBase (const std::vector<std::string>& pcd_files, float frames_per_second, bool repeat)
00276 : impl_ (new PCDGrabberImpl (*this, pcd_files, frames_per_second, repeat))
00277 {
00278 }
00279
00281 pcl::PCDGrabberBase::~PCDGrabberBase () throw ()
00282 {
00283 stop ();
00284 delete impl_;
00285 }
00286
00288 void
00289 pcl::PCDGrabberBase::start ()
00290 {
00291 if (impl_->frames_per_second_ > 0)
00292 {
00293 impl_->running_ = true;
00294 impl_->time_trigger_.start ();
00295 }
00296 else
00297 impl_->trigger ();
00298 }
00299
00301 void
00302 pcl::PCDGrabberBase::stop ()
00303 {
00304 if (impl_->frames_per_second_ > 0)
00305 {
00306 impl_->time_trigger_.stop ();
00307 impl_->running_ = false;
00308 }
00309 }
00310
00312 void
00313 pcl::PCDGrabberBase::trigger ()
00314 {
00315 if (impl_->frames_per_second_ > 0)
00316 return;
00317 impl_->trigger ();
00318 }
00319
00321 bool
00322 pcl::PCDGrabberBase::isRunning () const
00323 {
00324 return (impl_->running_);
00325 }
00326
00328 std::string
00329 pcl::PCDGrabberBase::getName () const
00330 {
00331 return ("PCDGrabber");
00332 }
00333
00335 void
00336 pcl::PCDGrabberBase::rewind ()
00337 {
00338 impl_->pcd_iterator_ = impl_->pcd_files_.begin ();
00339 }
00340
00342 float
00343 pcl::PCDGrabberBase::getFramesPerSecond () const
00344 {
00345 return (impl_->frames_per_second_);
00346 }
00347
00349 bool
00350 pcl::PCDGrabberBase::isRepeatOn () const
00351 {
00352 return (impl_->repeat_);
00353 }
00354