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
00039
00040
00041
00042
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
00169
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