v4r_laser_corner_filter_node.cpp
Go to the documentation of this file.
00001 /***************************************************************************
00002  * Copyright (c) 2014 Markus Bader <markus.bader@tuwien.ac.at>
00003  * All rights reserved.
00004  * 
00005  * Redistribution and use in source and binary forms, with or without
00006  * modification, are permitted provided that the following conditions are met:
00007  * 1. Redistributions of source code must retain the above copyright
00008  *    notice, this list of conditions and the following disclaimer.
00009  * 2. Redistributions in binary form must reproduce the above copyright
00010  *    notice, this list of conditions and the following disclaimer in the
00011  *    documentation and/or other materials provided with the distribution.
00012  * 3. All advertising materials mentioning features or use of this software
00013  *    must display the following acknowledgement:
00014  *    This product includes software developed by the TU-Wien.
00015  * 4. Neither the name of the TU-Wien nor the
00016  *    names of its contributors may be used to endorse or promote products
00017  *    derived from this software without specific prior written permission.
00018  * 
00019  * THIS SOFTWARE IS PROVIDED BY Markus Bader ''AS IS'' AND ANY
00020  * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
00021  * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
00022  * DISCLAIMED. IN NO EVENT SHALL Markus Bader BE LIABLE FOR ANY
00023  * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
00024  * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
00025  * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
00026  * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
00027  * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
00028  * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
00029  ***************************************************************************/
00030 
00031 #include "v4r_laser_filter/v4r_laser_corner_filter_node.h"
00032 #include <fstream>
00033 #include <cfloat>
00034 using namespace LaserFilter;
00035 
00036 int main(int argc, char **argv) {
00037 
00038     ros::init(argc, argv, "LaserCornerFilter");
00039     ros::NodeHandle n;
00040     LaserCornerFilterNode my_node(n);
00041     ros::spin();
00042     return 0;
00043 }
00044 
00045 LaserCornerFilterNode::LaserCornerFilterNode ( ros::NodeHandle &n )
00046     :n_ ( n ), n_param_ ( "~" ), callbackCount(0) {
00047     sub_ = n_.subscribe("scan", 1000, &LaserCornerFilterNode::callback, this);
00048     init_marker_visualization();
00049     pub_marker_visualization_ =  n.advertise<visualization_msgs::Marker>("visualization_marker", 10);
00050     pub_marker_posearray_ =  n.advertise<geometry_msgs::PoseArray>("marker", 10);
00051 
00052     reconfigureFnc_ = boost::bind(&LaserCornerFilterNode::callbackParameters, this,  _1, _2);
00053     reconfigureServer_.setCallback(reconfigureFnc_);
00054 }
00055 
00056 void LaserCornerFilterNode::callbackParameters ( v4r_laser_filter::CornerFilterConfig &config, uint32_t level ) {
00057     param_.min_line_length = config.min_line_length;
00058     param_.min_points_on_line = config.min_points_on_line;
00059     param_.normal_angle_threshold = config.normal_angle_threshold;
00060     param_.max_corner_line_differnce = config.max_corner_line_differnce;
00061     param_.max_line_error = config.max_line_error;
00062     param_.max_corner_error = config.max_corner_error;
00063     param_.redefine_corners = config.redefine_corners;
00064     param_.remove_double_detections = config.remove_double_detections;
00065     param_.remove_double_detections_threshold = config.remove_double_detections_threshold;
00066     param_.write_scan = config.write_scan;
00067     param_.read_scan = config.read_scan;
00068 
00069 }
00070 
00071 void LaserCornerFilterNode::callback (const sensor_msgs::LaserScan::ConstPtr& _msg) {
00072 
00073     if(param_.write_scan) LaserFilter::writeScan(param_.scan_filename, *_msg);
00074     if(param_.read_scan)  LaserFilter::readScan(param_.scan_filename, msg_scan_);
00075     else msg_scan_ = *_msg;
00076     msg_scan_.header = _msg->header;
00077 
00078     LaserFilter::copy(msg_scan_, measurments_, beams_);
00079 
00080     lines_.clear();
00081     lines_.reserve(measurments_.size());
00082 
00083 
00084     for( int i = 0; i < measurments_.size() - param_.min_points_on_line; i++) {
00085         for( int j = i+param_.min_points_on_line; j < measurments_.size(); j++) {
00086             float l = cv::norm(measurments_[i]-measurments_[j]);
00087             if(l > param_.min_line_length) {
00088                 lines_.push_back(LineSegment(i, j, measurments_));
00089                 break;
00090             }
00091         }
00092     }
00093     std::vector<Corner> corners_canditates;
00094     Corner corner;
00095     for( int i = 0; i < lines_.size(); i++) {
00096         for( int j = i+1; j < lines_.size(); j++) {
00097             corner.set(lines_[i], lines_[j]);
00098             if( corner.l0.idx.second == corner.l1.idx.first) {
00099                 if(corner.isCorner(param_.normal_angle_threshold, param_.max_corner_line_differnce)) {
00100                     corner.updateError(measurments_);
00101                     if(corner.l0.distances_error > param_.max_line_error) continue;
00102                     if(corner.l1.distances_error > param_.max_line_error) continue;
00103                     if(corner.error > param_.max_corner_error) continue;
00104                     if(param_.redefine_corners) {
00105                       corner.redefine(measurments_);
00106                       if(corner.updateError(measurments_) > param_.max_corner_error) continue;
00107                     }
00108                     corners_canditates.push_back(corner);
00109                 }
00110                 break;
00111             }
00112         }
00113     }
00114     
00115     corners_.clear();
00116     if(param_.remove_double_detections){
00117       int nrOfClusters = 0;
00118       std::vector< int > corner_clusters(corners_canditates.size(), -1);
00119       int corner_clusters_representative = -1;
00120       for(size_t i = 0; i < corners_canditates.size(); i++){
00121         if(corner_clusters[i] >= 0) continue;
00122         corner_clusters[i] = nrOfClusters++;
00123         corner_clusters_representative = i;
00124         for(size_t j = i+1; j < corners_canditates.size(); j++){
00125           if(corner_clusters[j] >= 0) continue;
00126           cv::Vec2f v(corners_canditates[i].point() - corners_canditates[j].point());
00127           float d = norm(v);
00128           if(d < param_.remove_double_detections_threshold){
00129             corner_clusters[j] = corner_clusters[i];
00130             if(corners_canditates[j].error < corners_canditates[i].error){
00131               corner_clusters_representative = j;
00132             }
00133           }
00134         }
00135         corners_.push_back(corners_canditates[corner_clusters_representative]);
00136       }      
00137     } else {
00138       corners_ = corners_canditates;
00139     }
00140     
00141     publish_marker_visualization ();
00142     publish_marker_posearray ();
00143 }
00144 
00145 void LaserCornerFilterNode::init_marker_visualization () {
00146     msg_corner_pose_.header = msg_scan_.header;
00147     msg_corner_pose_.lifetime = ros::Duration(10,0);
00148     msg_corner_pose_.ns = "corners";
00149     msg_corner_pose_.action = visualization_msgs::Marker::ADD;
00150     msg_corner_pose_.pose.orientation.w = 1.0;
00151     msg_corner_pose_.type = visualization_msgs::Marker::LINE_LIST;
00152     msg_corner_pose_.id = 0;
00153     msg_corner_pose_.scale.x = 0.01;
00154     msg_corner_pose_.color.r = 1.0;
00155     msg_corner_pose_.color.g = 1.0;
00156     msg_corner_pose_.color.b = 0.0;
00157     msg_corner_pose_.color.a = 1.0;
00158 
00159 
00160     msg_corner_l0_ = msg_corner_pose_;
00161     msg_corner_l0_.ns = "corners_l0";
00162     msg_corner_l0_.lifetime = ros::Duration(10,0);
00163     msg_corner_l0_.id = 0;
00164     msg_corner_l0_.color.r = 1.0;
00165     msg_corner_l0_.color.g = 0.0;
00166     msg_corner_l0_.color.b = 0.2;
00167 
00168     msg_corner_l1_ = msg_corner_pose_;
00169     msg_corner_l1_.ns = "corners_l1";
00170     msg_corner_l1_.lifetime = ros::Duration(10,0);
00171     msg_corner_l1_.id = 0;
00172     msg_corner_l1_.color.r = 0.0;
00173     msg_corner_l1_.color.g = 1.0;
00174     msg_corner_l1_.color.b = 0.2;
00175 
00176 }
00177 
00178 void LaserCornerFilterNode::publish_marker_visualization () {  
00179     if(pub_marker_visualization_.getNumSubscribers() < 1) return;
00180     geometry_msgs::Point p0, p1;
00181 
00182     msg_corner_pose_.header = msg_scan_.header;
00183     msg_corner_pose_.points.clear();
00184     msg_corner_l0_.header = msg_scan_.header;
00185     msg_corner_l0_.points.clear();
00186     msg_corner_l1_.header = msg_scan_.header;
00187     msg_corner_l1_.points.clear();
00188 
00189 
00190     for(unsigned int i = 0; i < corners_.size(); i++) {
00191         p0.x = corners_[i].x(), p0.y = corners_[i].y();
00192         p1.x = p0.x + cos(corners_[i].angle());
00193         p1.y = p0.y + sin(corners_[i].angle());
00194         msg_corner_pose_.points.push_back(p0);
00195         msg_corner_pose_.points.push_back(p1);
00196 
00197         Line &l0 = corners_[i].l0;
00198         Line &l1 = corners_[i].l1;
00199         p0.x = l0.p0.x, p0.y = l0.p0.y;
00200         p1.x = l0.p1.x, p1.y = l0.p1.y;
00201         msg_corner_l0_.points.push_back(p0);
00202         msg_corner_l0_.points.push_back(p1);
00203         p0.x = l1.p0.x, p0.y = l1.p0.y;
00204         p1.x = l1.p1.x, p1.y = l1.p1.y;
00205         msg_corner_l1_.points.push_back(p0);
00206         msg_corner_l1_.points.push_back(p1);
00207 
00208 
00209     }
00210     pub_marker_visualization_.publish(msg_corner_pose_);
00211     pub_marker_visualization_.publish(msg_corner_l0_);
00212     pub_marker_visualization_.publish(msg_corner_l1_);
00213 
00214 }
00215 
00216 void LaserCornerFilterNode::publish_marker_posearray () {  
00217     if(pub_marker_posearray_.getNumSubscribers() < 1) return;
00218     
00219     
00220     msg_marker_posearray_.header = msg_scan_.header;
00221     msg_marker_posearray_.poses.resize(corners_.size());
00222 
00223     for(unsigned int i = 0; i < corners_.size(); i++) {
00224       msg_marker_posearray_.poses[i].position.x = corners_[i].x();
00225       msg_marker_posearray_.poses[i].position.y = corners_[i].y();
00226       msg_marker_posearray_.poses[i].position.z = 0;
00227       msg_marker_posearray_.poses[i].orientation.x = 0;
00228       msg_marker_posearray_.poses[i].orientation.y = 0;
00229       msg_marker_posearray_.poses[i].orientation.z = sin(corners_[i].angle()/2.0);
00230       msg_marker_posearray_.poses[i].orientation.w = cos(corners_[i].angle()/2.0);      
00231     }
00232     pub_marker_posearray_.publish(msg_marker_posearray_);
00233 
00234 }


v4r_laser_filter
Author(s):
autogenerated on Wed Aug 26 2015 16:41:46