Go to the documentation of this file.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 #include "dense_laser_assembler/dense_laser_assembler.h"
00036 
00037 using namespace std;
00038 using namespace dense_laser_assembler;
00039 
00040 DenseLaserAssembler::DenseLaserAssembler(const unsigned int cache_size)
00041   : cache_(&settlerlib::SortedDeque<sensor_msgs::LaserScanConstPtr>::getPtrStamp, "dense_laser_deque")
00042 {
00043   setCacheSize(cache_size);
00044 }
00045 
00046 void DenseLaserAssembler::setCacheSize(const unsigned int cache_size)
00047 {
00048   cache_.setMaxSize(cache_size);
00049 }
00050 
00051 void DenseLaserAssembler::add(const sensor_msgs::LaserScanConstPtr& laser_scan)
00052 {
00053   cache_.add(laser_scan);
00054 }
00055 
00056 bool DenseLaserAssembler::assembleSnapshot(const ros::Time& start, const ros::Time& end, calibration_msgs::DenseLaserSnapshot& snapshot)
00057 {
00058   vector< sensor_msgs::LaserScanConstPtr > scan_vec;
00059   ROS_DEBUG("Assembling snapshot:\n"
00060             "   from: %.2f\n"
00061             "   to:   %.2f\n"
00062             "   duration: %.3f\n",
00063             start.toSec(), end.toSec(), (end-start).toSec());
00064 
00065   scan_vec = cache_.getInterval(start, end);
00066   return flattenScanVec(scan_vec, snapshot);
00067 }
00068 
00069 bool DenseLaserAssembler::flattenScanVec(const std::vector< sensor_msgs::LaserScanConstPtr >& scans,
00070                                          calibration_msgs::DenseLaserSnapshot& snapshot)
00071 {
00072   if (scans.size() == 0)
00073   {
00074     ROS_WARN("Trying to build empty cloud") ;
00075     snapshot.angle_min       = 0.0;
00076     snapshot.angle_max       = 0.0;
00077     snapshot.angle_increment = 0.0;
00078     snapshot.time_increment  = 0.0;
00079     snapshot.range_min       = 0.0;
00080     snapshot.range_max       = 0.0;
00081     snapshot.readings_per_scan = 0;
00082     snapshot.num_scans       = 0;
00083     snapshot.ranges.clear();
00084     snapshot.intensities.clear();
00085     snapshot.scan_start.clear();
00086     return true;
00087   }
00088 
00089   
00090   snapshot.header.stamp = scans[scans.size()-1]->header.stamp;
00091 
00092   
00093   snapshot.header.frame_id = scans[0]->header.frame_id;
00094   snapshot.angle_min       = scans[0]->angle_min;
00095   snapshot.angle_max       = scans[0]->angle_max;
00096   snapshot.angle_increment = scans[0]->angle_increment;
00097   snapshot.time_increment  = scans[0]->time_increment;
00098   snapshot.range_min       = scans[0]->range_min;
00099   snapshot.range_max       = scans[0]->range_max;
00100 
00101   
00102   snapshot.readings_per_scan = scans[0]->ranges.size();
00103   snapshot.num_scans         = scans.size();
00104   const unsigned int& w = snapshot.readings_per_scan;
00105   const unsigned int& h = snapshot.num_scans;
00106 
00107   
00108   for (unsigned int i=0; i<scans.size(); i++)
00109   {
00110     if (!verifyMetadata(snapshot, *scans[i]))
00111     {
00112       ROS_WARN("Metadata doesn't match. It is likely that someone just changed the laser's configuration");
00113       return false ;
00114     }
00115   }
00116 
00117   
00118   snapshot.scan_start.resize(h) ;
00119   snapshot.ranges.resize(w*h) ;
00120   snapshot.intensities.resize(w*h) ;
00121 
00122   const unsigned int range_elem_size     = sizeof(scans[0]->ranges[0]) ;
00123   const unsigned int intensity_elem_size = sizeof(scans[0]->intensities[0]) ;
00124 
00125   
00126   assert(sizeof(snapshot.ranges[0])      == sizeof(scans[0]->ranges[0]));
00127   assert(sizeof(snapshot.intensities[0]) == sizeof(scans[0]->intensities[0]));
00128 
00129   for (unsigned int i=0; i<h; i++)
00130   {
00131     memcpy(&snapshot.ranges[i*w],      &scans[i]->ranges[0],      w*range_elem_size) ;
00132     memcpy(&snapshot.intensities[i*w], &scans[i]->intensities[0], w*intensity_elem_size) ;
00133 
00134     
00135     snapshot.scan_start[i] = scans[i]->header.stamp ;
00136   }
00137 
00138   ROS_DEBUG("Done building snapshot that is [%u rows] x [%u cols]", h, w) ;
00139   ROS_DEBUG("  ranges.size      = %u", snapshot.ranges.size());
00140   ROS_DEBUG("  intensities.size = %u", snapshot.intensities.size());
00141 
00142   return true ;
00143 }
00144 
00145 static const double eps = 1e-9 ;
00146 
00147 #define CHECK(a) \
00148 { \
00149   if ( (snapshot.a - scan.a < -eps) || (snapshot.a - scan.a > eps)) \
00150     return false ; \
00151 }
00152 
00153 bool DenseLaserAssembler::verifyMetadata(const calibration_msgs::DenseLaserSnapshot& snapshot, const sensor_msgs::LaserScan& scan)
00154 {
00155   CHECK(angle_min) ;
00156   CHECK(angle_max) ;
00157   CHECK(angle_increment) ;
00158   CHECK(time_increment) ;
00159   CHECK(range_min) ;
00160   CHECK(range_max) ;
00161 
00162   if (snapshot.header.frame_id.compare(scan.header.frame_id) != 0)
00163     return false ;
00164 
00165   if (snapshot.readings_per_scan != scan.ranges.size())
00166     return false ;
00167   if (snapshot.readings_per_scan != scan.intensities.size())
00168     return false ;
00169 
00170 
00171   return true ;
00172 }