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 
00036 
00037 #include "../include/DepthImage_to_Laserscan.h"
00038 
00039 using namespace iav_depthimage_to_laserscan;
00040 
00041   
00042 DepthImage_to_Laserscan::DepthImage_to_Laserscan() {
00043 }
00044 
00045 DepthImage_to_Laserscan::~DepthImage_to_Laserscan() {
00046 }
00047 
00048 
00049 
00050 
00051 
00052 
00053 
00054 
00055 
00056 
00057 
00058 
00059 
00060 
00061 bool DepthImage_to_Laserscan::use_point(float new_value, float old_value, float range_min, float range_max) {  
00062   
00063   bool new_finite = std::isfinite(new_value);
00064   bool old_finite = std::isfinite(old_value);
00065   
00066   
00067   if(!new_finite && !old_finite){ 
00068     if(!isnan(new_value)){ 
00069       return true;
00070     }
00071     return false; 
00072   }
00073   
00074   
00075   bool range_check = range_min <= new_value && new_value <= range_max;
00076   if(!range_check){
00077     return false;
00078   }
00079   
00080   if(!old_finite){ 
00081     return true;
00082   }
00083   
00084   
00085   bool shorter_check = new_value < old_value;
00086   return shorter_check;
00087 }
00088 
00089 
00090 
00091 
00092 
00093 
00094 
00095 
00096 
00097 
00098  
00099 
00100 sensor_msgs::LaserScanPtr DepthImage_to_Laserscan::convert_msg(const sensor_msgs::ImageConstPtr& depth_msg, const CParam& Param, const LSParam& lsparam) 
00101 {
00102   
00103   sensor_msgs::LaserScanPtr scan_msg(new sensor_msgs::LaserScan());
00104   scan_msg->header = depth_msg->header;
00105 
00106   
00107   if(lsparam.laser_output_frame_id.length() > 0){
00108      scan_msg->header.frame_id = lsparam.laser_output_frame_id;
00109   }
00110 
00111   
00112   uint32_t ranges_size = lsparam.laser_rays - 1;
00113   scan_msg->ranges.assign(ranges_size, std::numeric_limits<float>::quiet_NaN());
00114 
00115   scan_msg->angle_min = lsparam.laser_min_angle;
00116   scan_msg->angle_max = lsparam.laser_max_angle;
00117   scan_msg->angle_increment = (scan_msg->angle_max - scan_msg->angle_min) / (scan_msg->ranges.size() - 1);;
00118   scan_msg->time_increment = 0.0;
00119   scan_msg->scan_time = 0;
00120   scan_msg->range_min = lsparam.laser_min_range;
00121   scan_msg->range_max = lsparam.laser_max_range;
00122   
00123   if (depth_msg->encoding == sensor_msgs::image_encodings::TYPE_16UC1)
00124   {
00125      convert_dtl<uint16_t>(depth_msg, Param, lsparam, scan_msg);
00126   }
00127   else if (depth_msg->encoding == sensor_msgs::image_encodings::TYPE_32FC1)
00128   {
00129      convert_dtl<float>(depth_msg, Param, lsparam, scan_msg);
00130   }     
00131   else
00132   {
00133     std::stringstream ss;
00134     ss << "Depth image has unsupported encoding: " << depth_msg->encoding;
00135     throw std::runtime_error(ss.str());
00136   }
00137   
00138   return scan_msg;
00139 
00140 }
00141 
00142 
00143 
00144 
00145 
00146 
00147 
00148 
00149 
00150 
00151 
00152 
00153 template<typename T>
00154 void DepthImage_to_Laserscan::convert_dtl(const sensor_msgs::ImageConstPtr& depth_msg, const CParam& Param, const LSParam& lsparam, const sensor_msgs::LaserScanPtr& scan_msg) 
00155 {
00156 
00157   double r; 
00158   T depth; 
00159   double d; 
00160   int index; 
00161 
00162   
00163   int i_start = 0;
00164   int i_stop = 0;
00165 
00166   
00167   float cam_resolution = Param.cam_image_width/Param.cam_AOV_h;
00168   float laser_resolution = lsparam.laser_rays/(lsparam.laser_max_angle - lsparam.laser_min_angle);
00169 
00170   
00171   const T* depth_row = reinterpret_cast<const T*>(&depth_msg->data[0]);
00172   int row_step = depth_msg->step / sizeof(T);
00173 
00174   
00175   for (int i=0; i < scan_msg->ranges.size(); i++) scan_msg->ranges[i] = scan_msg->range_max;
00176 
00177   
00178   for(int row = 0; row < Param.cam_image_height; row++, depth_row += row_step) {
00179      
00180      for(int col = 0; col < Param.cam_image_width; col++) {
00181         depth = depth_row[col];
00182         d = depth * 0.001f - Param.cam_offset; 
00183         index = Param.cam_index[col];
00184    
00185         
00186         if((Param.cam_min_distances[row] <= d) && (d <= Param.cam_max_distances [row])) {
00187            r = d/Param.cam_cos_h[col];
00188            
00189            
00190            if(use_point(r, scan_msg->ranges[index], lsparam.laser_min_range, lsparam.laser_max_range)) { 
00191         
00192               
00193               if ((cam_resolution < laser_resolution) && (col < Param.cam_image_width - 1))
00194               {
00195                  
00196                  i_stop = Param.cam_index[col];
00197                  i_start = Param.cam_index[col+1];
00198                  
00199                  for (int i=i_start; i <= i_stop; i++) scan_msg->ranges[i] = r;
00200               }
00201               else
00202               {
00203                  
00204                  scan_msg->ranges[index] = r;
00205               }
00206            }
00207         }
00208      }
00209   }
00210 }