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 #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 }