box_filter.cpp
Go to the documentation of this file.
00001 /*
00002  *  Software License Agreement (BSD License)
00003  *
00004  *  Robot Operating System code by the University of Osnabrück
00005  *  Copyright (c) 2015, University of Osnabrück
00006  *  All rights reserved.
00007  *
00008  *  Redistribution and use in source and binary forms, with or without
00009  *  modification, are permitted provided that the following conditions
00010  *  are met:
00011  *
00012  *   1. Redistributions of source code must retain the above 
00013  *      copyright notice, this list of conditions and the following
00014  *      disclaimer.
00015  *
00016  *   2. Redistributions in binary form must reproduce the above 
00017  *      copyright notice, this list of conditions and the following
00018  *      disclaimer in the documentation and/or other materials provided
00019  *      with the distribution.
00020  *
00021  *   3. Neither the name of the copyright holder nor the names of its
00022  *      contributors may be used to endorse or promote products derived
00023  *      from this software without specific prior written permission.
00024  *
00025  *
00026  *  THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
00027  *  "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
00028  *  TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
00029  *  PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR
00030  *  CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
00031  *  EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
00032  *  PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;
00033  *  OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
00034  *  WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
00035  *  OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF 
00036  *  ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
00037  *
00038  *
00039  *
00040  *  box_filter.cpp
00041  *
00042  *  author: Sebastian Pütz <spuetz@uni-osnabrueck.de>
00043  */
00044 
00045 #include "laser_filters/box_filter.h"
00046 #include <ros/ros.h>
00047 
00048 laser_filters::LaserScanBoxFilter::LaserScanBoxFilter(){
00049 
00050 }
00051 
00052 bool laser_filters::LaserScanBoxFilter::configure(){
00053   up_and_running_ = true;
00054   double min_x, min_y, min_z, max_x, max_y, max_z;
00055   bool box_frame_set = getParam("box_frame", box_frame_);
00056   bool x_max_set = getParam("max_x", max_x);
00057   bool y_max_set = getParam("max_y", max_y);
00058   bool z_max_set = getParam("max_z", max_z);
00059   bool x_min_set = getParam("min_x", min_x);
00060   bool y_min_set = getParam("min_y", min_y);
00061   bool z_min_set = getParam("min_z", min_z);
00062   
00063   max_.setX(max_x);
00064   max_.setY(max_y);
00065   max_.setZ(max_z);
00066   min_.setX(min_x);
00067   min_.setY(min_y);
00068   min_.setZ(min_z);
00069   
00070   if(!box_frame_set){
00071     ROS_ERROR("box_frame is not set!");
00072   }
00073   if(!x_max_set){
00074     ROS_ERROR("max_x is not set!");
00075   }
00076   if(!y_max_set){
00077     ROS_ERROR("max_y is not set!");
00078   }
00079   if(!z_max_set){
00080     ROS_ERROR("max_z is not set!");
00081   }
00082   if(!x_min_set){
00083     ROS_ERROR("min_x is not set!");
00084   }
00085   if(!y_min_set){
00086     ROS_ERROR("min_y is not set!");
00087   }
00088   if(!z_min_set){
00089     ROS_ERROR("min_z is not set!");
00090   }
00091 
00092   return box_frame_set && x_max_set && y_max_set && z_max_set &&
00093     x_min_set && y_min_set && z_min_set;
00094 
00095 }
00096 
00097 bool laser_filters::LaserScanBoxFilter::update(
00098     const sensor_msgs::LaserScan& input_scan,
00099     sensor_msgs::LaserScan &output_scan)
00100 {
00101   output_scan = input_scan;
00102   sensor_msgs::PointCloud2 laser_cloud;
00103   
00104   std::string error_msg;
00105 
00106   bool success = tf_.waitForTransform(
00107     box_frame_,
00108     input_scan.header.frame_id,
00109     input_scan.header.stamp + ros::Duration().fromSec(input_scan.ranges.size()*input_scan.time_increment),
00110     ros::Duration(1.0),
00111     ros::Duration(0.01),
00112     &error_msg
00113   );
00114   if(!success){
00115     ROS_WARN("Could not get transform, irgnoring laser scan! %s", error_msg.c_str());
00116     return false;
00117   }
00118 
00119   try{
00120     projector_.transformLaserScanToPointCloud(box_frame_, input_scan, laser_cloud, tf_);
00121   }
00122   catch(tf::TransformException& ex){
00123     if(up_and_running_){
00124       ROS_WARN_THROTTLE(1, "Dropping Scan: Tansform unavailable %s", ex.what());
00125       return true;
00126     }
00127     else
00128     {
00129       ROS_INFO_THROTTLE(.3, "Ignoring Scan: Waiting for TF");
00130     }
00131     return false;
00132   }
00133   const int i_idx_c = sensor_msgs::getPointCloud2FieldIndex(laser_cloud, "index");
00134   const int x_idx_c = sensor_msgs::getPointCloud2FieldIndex(laser_cloud, "x");
00135   const int y_idx_c = sensor_msgs::getPointCloud2FieldIndex(laser_cloud, "y");
00136   const int z_idx_c = sensor_msgs::getPointCloud2FieldIndex(laser_cloud, "z");
00137 
00138   if(i_idx_c == -1 || x_idx_c == -1 || y_idx_c == -1 || z_idx_c == -1){
00139       ROS_INFO_THROTTLE(.3, "x, y, z and index fields are required, skipping scan");
00140 
00141   }
00142 
00143 
00144   const int i_idx_offset = laser_cloud.fields[i_idx_c].offset;
00145   const int x_idx_offset = laser_cloud.fields[x_idx_c].offset;
00146   const int y_idx_offset = laser_cloud.fields[y_idx_c].offset;
00147   const int z_idx_offset = laser_cloud.fields[z_idx_c].offset;
00148 
00149   const int pstep = laser_cloud.point_step;
00150   const long int pcount = laser_cloud.width * laser_cloud.height;
00151   const long int limit = pstep * pcount;
00152 
00153   int i_idx, x_idx, y_idx, z_idx;  
00154   for(
00155     i_idx = i_idx_offset,
00156     x_idx = x_idx_offset,
00157     y_idx = y_idx_offset,
00158     z_idx = z_idx_offset;
00159 
00160     x_idx < limit;
00161 
00162     i_idx += pstep,
00163     x_idx += pstep,
00164     y_idx += pstep,
00165     z_idx += pstep)
00166   {
00167 
00168     // TODO works only for float data types and with an index field
00169     // I'm working on it, see https://github.com/ros/common_msgs/pull/78 
00170     float x = *((float*)(&laser_cloud.data[x_idx]));
00171     float y = *((float*)(&laser_cloud.data[y_idx]));
00172     float z = *((float*)(&laser_cloud.data[z_idx]));
00173     int index = *((int*)(&laser_cloud.data[i_idx]));
00174 
00175     tf::Point point(x, y, z);
00176 
00177     if(inBox(point)){
00178       output_scan.ranges[index] = std::numeric_limits<float>::quiet_NaN();
00179     }
00180   }
00181   up_and_running_ = true;
00182   return true;
00183 }
00184 
00185 bool laser_filters::LaserScanBoxFilter::inBox(tf::Point &point){
00186   return
00187     point.x() < max_.x() && point.x() > min_.x() && 
00188     point.y() < max_.y() && point.y() > min_.y() &&
00189     point.z() < max_.z() && point.z() > min_.z();
00190 }
00191 


laser_filters
Author(s): Tully Foote
autogenerated on Sat Sep 9 2017 02:57:38