extract_polygon_primitives_auxiliary.cpp
Go to the documentation of this file.
00001 /**************************************************************************************************
00002  Software License Agreement (BSD License)
00003 
00004  Copyright (c) 2011-2013, LAR toolkit developers - University of Aveiro - http://lars.mec.ua.pt
00005  All rights reserved.
00006 
00007  Redistribution and use in source and binary forms, with or without modification, are permitted
00008  provided that the following conditions are met:
00009 
00010   *Redistributions of source code must retain the above copyright notice, this list of
00011    conditions and the following disclaimer.
00012   *Redistributions in binary form must reproduce the above copyright notice, this list of
00013    conditions and the following disclaimer in the documentation and/or other materials provided
00014    with the distribution.
00015   *Neither the name of the University of Aveiro nor the names of its contributors may be used to
00016    endorse or promote products derived from this software without specific prior written permission.
00017  
00018  THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR
00019  IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND
00020  FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR
00021  CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
00022  DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
00023  DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER
00024  IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
00025  OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
00026 ***************************************************************************************************/
00036 #ifndef _extract_polygon_primitives_AUXILIARY_CPP_
00037 #define _extract_polygon_primitives_AUXILIARY_CPP_
00038 
00039 
00040 #include "extract_polygon_primitives.h"
00041 
00049 int get_vehicle_position(ros::NodeHandle *pn, tf::TransformListener* listener, tf::StampedTransform* vehicle_tf, ros::Time* t)
00050 {
00051         ros::spinOnce();
00052         bool cont=true;
00053 
00054         while(cont && pn->ok())
00055         {
00056                 cont=false;
00057                 //Find the tf /world to vehicle at timestamp of velodyne date receival
00058                 try
00059                 {
00060                         //listener->lookupTransform("/tf_vehicle", "/world", *t, *vehicle_tf);
00061                         listener->lookupTransform("/world", "/tf_vehicle", ros::Time(0), *vehicle_tf);
00062                 }
00063                 catch (tf::TransformException ex)
00064                 {
00065                         ROS_ERROR("%s",ex.what());
00066                         cont = true;
00067                         ros::Duration(0.1).sleep();
00068                 }
00069         }
00070 
00071         return 1;
00072 }
00073 
00081 int save_pc_PointNormal_to_pcd(pcl::PointCloud<pcl::PointXYZ>* pc_in, pcl::PointCloud<pcl::Normal>* normals_in, std::string name)
00082 {
00083         pcl::PointCloud<pcl::PointNormal> pc; 
00084         pcl::concatenateFields (*pc_in, *normals_in, pc);
00085         sensor_msgs::PointCloud2 msg;
00086         pcl::toROSMsg(pc, msg);
00087         pcl::io::savePCDFile(name.c_str(), msg);
00088         return 1;
00089 }
00090 
00103 int compute_normals(pcl::PointCloud<pcl::PointXYZ>* pc_in, float vx, float vy, float vz, float radius, int K, pcl::PointCloud<pcl::Normal>* pc_out)
00104 {
00105         ros::Time t = ros::Time::now();
00106         // Compute the normals for the cloud_to_procesvs
00107         pcl::NormalEstimation<pcl::PointXYZ, pcl::Normal> ne; // Create the normal estimation obje
00108         //pcl::KdTreeFLANN<pcl::PointXYZ>::Ptr tree (new pcl::KdTreeFLANN<pcl::PointXYZ> ()); //tree to compute normals
00109 //      pcl::KdTreeFLANN<pcl::PointXYZ>::Ptr tree (new pcl::KdTreeFLANN<pcl::PointXYZ> ()); //tree to compute normals
00110         pcl::search::KdTree<pcl::PointXYZ>::Ptr tree (new pcl::search::KdTree<pcl::PointXYZ>); //tree to compute normals
00111 
00112         ne.setSearchMethod(tree);
00113         ne.setViewPoint(vx,vy,vz);      
00114         ne.setInputCloud(pc_in->makeShared());
00115 
00116         if (K==0)
00117                 ne.setRadiusSearch(radius);
00118         else if (radius==0)
00119                 ne.setKSearch(K);
00120         else
00121         {
00122                 ROS_ERROR("Cannot compute normals. Either radius=%f or K=%d must be 0, so that one is selected", radius, K);
00123                 return 0;
00124         }
00125 
00126         ne.compute(*pc_out);
00127 
00128         for (size_t i=0; i<pc_out->points.size(); ++i)
00129         {
00130                 pcl::flipNormalTowardsViewpoint( pc_in->points[i], vx,vy,vz,pc_out->points[i].normal[0],  pc_out->points[i].normal[1],pc_out->points[i].normal[2]);
00131         }
00132 
00133         ROS_INFO("Estimated normals in %f secs. pc_in with %ld points. radius=%f K=%d", (ros::Time::now() -t).toSec(), pc_in->points.size(), radius, K);
00134         return 1;
00135 }
00136 
00137 void filter_uncoherent_points(pcl::PointCloud<pcl::PointXYZ>::Ptr pcin, pcl::PointCloud<pcl::PointXYZ> *pcout, pcl::PointCloud<pcl::PointXYZ>* pcelim,  pcl::PointCloud<pcl::Normal>::Ptr n ,double radius, float vx, float vy, float vz)
00138 {
00139         pcl::PointCloud<pcl::PointNormal>::Ptr tmp_in = pcl::PointCloud<pcl::PointNormal>::Ptr(new pcl::PointCloud<pcl::PointNormal>)  ; 
00140         pcl::concatenateFields(*pcin, *n, *tmp_in);
00141         pcl::PointCloud<pcl::PointNormal>::Ptr tmp_out = pcl::PointCloud<pcl::PointNormal>::Ptr(new pcl::PointCloud<pcl::PointNormal>); 
00142         pcl::PointCloud<pcl::PointNormal>::Ptr tmp_elim = pcl::PointCloud<pcl::PointNormal>::Ptr(new pcl::PointCloud<pcl::PointNormal>); 
00143 
00144         ros::Time t = ros::Time::now();
00145         filter_uncoherent_points(tmp_in, radius, tmp_out, tmp_elim, vx, vy, vz);
00146 
00147         pcout->points.erase(pcout->points.begin(), pcout->points.end());
00148         for (size_t i=0; i< tmp_out->points.size(); i++)
00149         {
00150                 pcl::PointXYZ pt(tmp_out->points[i].x, tmp_out->points[i].y, tmp_out->points[i].z);     
00151                 pcout->points.push_back(pt);
00152         }
00153 
00154         pcout->height = 1; //1 since its and unordered pc
00155         pcout->is_dense=0;
00156         pcout->header.frame_id = pcin->header.frame_id;
00157         pcout->width = pcout->points.size();
00158 
00159         pcelim->points.erase(pcelim->points.begin(), pcelim->points.end());
00160         for (size_t i=0; i< tmp_elim->points.size(); i++)
00161         {
00162                 pcl::PointXYZ pt(tmp_elim->points[i].x, tmp_elim->points[i].y, tmp_elim->points[i].z);  
00163                 pcelim->points.push_back(pt);
00164         }
00165 
00166         pcelim->height = 1; //1 since its and unordered pc
00167         pcelim->is_dense=0;
00168         pcelim->header.frame_id = pcin->header.frame_id;
00169         pcelim->width = pcelim->points.size();
00170 
00171 
00172         ROS_INFO("Normal orientation entropy filter: pts in %ld pts out %ld removed %ld, (in %f secs)",pcin->points.size(), pcout->points.size(), pcelim->points.size(), (ros::Time::now() -t).toSec());
00173         tmp_in.reset();
00174         tmp_out.reset();
00175         tmp_elim.reset();
00176 }
00177 
00178 void get_limits(double mean, double std, double factor, double *high, double *low)
00179 {
00180         (*high) = mean + factor*std;
00181         (*low) = mean - factor*std;
00182 }
00183 
00184 //void draw_markers(int k, btQuaternion* q_avg, std::vector<btQuaternion>* qv, pcl::PointCloud<pcl::PointNormal>::Ptr pc, std::vector<int>* pointIdxRadiusSearch)
00185 //{
00186 //static ros::Publisher markerarray_pub = pn->advertise<visualization_msgs::MarkerArray>("/Marker_neighbours", 1);
00187 
00188 //static size_t total_normals=0;
00189 //std::vector<visualization_msgs::Marker> marker_vec;
00190 //geometry_msgs::Point p;
00191 //std_msgs::ColorRGBA color;
00192 //visualization_msgs::Marker msg;
00193 
00195 //msg.header.frame_id = std::string("/world");
00196 //msg.header.stamp = ros::Time::now();
00197 //msg.ns = "K"; msg.id = 0;
00198 //msg.action = visualization_msgs::Marker::ADD;
00199 //msg.pose.orientation.w = 1.0;
00200 //msg.type = visualization_msgs::Marker::SPHERE;
00201 //msg.pose.position.x = pc->points[k].x;
00202 //msg.pose.position.y = pc->points[k].y;
00203 //msg.pose.position.z = pc->points[k].z;
00204 //ROS_INFO("Position x=%f y=%f z=%f",msg.pose.position.x, msg.pose.position.y, msg.pose.position.z);
00205 //msg.scale.x = 5; msg.scale.y = 5; msg.scale.z = 5; 
00206 //msg.color.r = 0; msg.color.g = 0; msg.color.b = 0.3; msg.color.a = 0.2;
00207 //marker_vec.push_back(msg);
00208 
00210 //msg.header.frame_id = std::string("/world");
00211 //msg.header.stamp = ros::Time::now();
00212 //msg.ns = "neighbors"; msg.id = 0;
00213 //msg.action = visualization_msgs::Marker::ADD;
00214 //msg.pose.position.x = 0; msg.pose.position.y = 0; msg.pose.position.z = 0; 
00215 //msg.pose.orientation.x = 0;   msg.pose.orientation.y = 0;     msg.pose.orientation.z = 0; msg.pose.orientation.w = 1.0;
00216 //msg.type = visualization_msgs::Marker::POINTS;
00217 //msg.scale.x = 0.03; msg.scale.y = 0.03; msg.scale.z = 0.03; 
00218 //msg.color.r = 0; msg.color.g = 0; msg.color.b = 1; msg.color.a = 1;
00219 
00220 //msg.points.erase(msg.points.begin(), msg.points.end());
00221 //for (size_t i = 0; i<qv->size(); i++)
00222 //{
00223 //p.x = pc->points[pointIdxRadiusSearch->at(i)].x;
00224 //p.y = pc->points[pointIdxRadiusSearch->at(i)].y;
00225 //p.z = pc->points[pointIdxRadiusSearch->at(i)].z;
00226 //msg.points.push_back(p);
00227 //}
00228 //marker_vec.push_back(msg);
00229 
00231 //msg.header.frame_id = std::string("/world");
00232 //msg.header.stamp = ros::Time::now();
00233 //msg.ns = "mean";
00234 //msg.action = visualization_msgs::Marker::ADD;
00235 //msg.pose.position.x = 0; msg.pose.position.y = 0; msg.pose.position.z = 0; 
00236 //msg.pose.orientation.x = 0;   msg.pose.orientation.y = 0;     msg.pose.orientation.z = 0; msg.pose.orientation.w = 1.0;
00237 //msg.type = visualization_msgs::Marker::ARROW;
00238 //msg.id = 0;
00239 //msg.scale.x = 0.08; msg.scale.y = 0.2; 
00240 //msg.color.r = 1; msg.color.g = 0;     msg.color.b = 0.3;      msg.color.a = 0.6;
00241 //msg.points.erase(msg.points.begin(), msg.points.end());       
00242 
00243 //p.x = pc->points[k].x; p.y = pc->points[k].y; p.z = pc->points[k].z;
00244 //msg.points.push_back(p);
00245 //p.x = pc->points[k].x + (*q_avg)[0]; p.y = pc->points[k].y + (*q_avg)[1]; p.z = pc->points[k].z + (*q_avg)[2];
00246 //msg.points.push_back(p);
00247 //marker_vec.push_back(msg);
00248 
00250 //msg.header.frame_id = std::string("/world");
00251 //msg.header.stamp = ros::Time::now();
00252 //msg.ns = "n_normals";
00253 //msg.action = visualization_msgs::Marker::ADD;
00254 //msg.pose.position.x = 0; msg.pose.position.y = 0; msg.pose.position.z = 0; 
00255 //msg.pose.orientation.x = 0;   msg.pose.orientation.y = 0;     msg.pose.orientation.z = 0; msg.pose.orientation.w = 1.0;
00256 //msg.type = visualization_msgs::Marker::ARROW;
00257 //msg.scale.x = 0.01;//arrow shaft radius
00258 //msg.scale.y = 0.05; //arrow head radius
00259 //msg.color.r = 0; msg.color.g = 1; msg.color.b = 0.3; msg.color.a = 0.3;
00260 
00261 //for (size_t i = 0; i < qv->size (); ++i)
00262 //{
00263 //msg.points.erase(msg.points.begin(), msg.points.end());       
00264 //msg.id = i;
00265 //p.x = pc->points[k].x;
00266 //p.y = pc->points[k].y;
00267 //p.z = pc->points[k].z;
00268 //msg.points.push_back(p);
00269 
00270 //p.x = pc->points[k].x + (*qv)[i][0];
00271 //p.y = pc->points[k].y + (*qv)[i][1];
00272 //p.z = pc->points[k].z + (*qv)[i][2];
00273 //msg.points.push_back(p);
00274 //marker_vec.push_back(msg);
00275 //}
00276 
00278 //for (size_t i = qv->size(); i <total_normals; ++i)
00279 //{
00280 //msg.type = visualization_msgs::Marker::ARROW;
00281 //msg.id = i;
00282 //msg.ns = "n_normals";
00283 //msg.action = visualization_msgs::Marker::DELETE;
00284 //marker_vec.push_back(msg);
00285 //}
00286 //total_normals = qv->size();
00287 
00289 //visualization_msgs::MarkerArray marker_array_msg;
00290 //ROS_INFO("marker_vec = %ld",marker_vec.size());
00291 //marker_array_msg.set_markers_vec(marker_vec); 
00292 //markerarray_pub.publish(marker_array_msg);    
00293 //ros::spinOnce();
00294 
00295 
00296 //}
00297 
00298 void filter_uncoherent_points(pcl::PointCloud<pcl::PointNormal>::Ptr pc, double radius, pcl::PointCloud<pcl::PointNormal>::Ptr pcout, pcl::PointCloud<pcl::PointNormal>::Ptr pcelim, float vx, float vy, float vz)
00299 {
00300         bool cont=true;
00301         //initialize a kdtree to pc
00302         pcl::KdTreeFLANN<pcl::PointNormal> kdtree;
00303         kdtree.setInputCloud(pc);
00304 
00305         //make sure pcout has no points
00306         pcout->points.erase(pcout->points.begin(), pcout->points.end());
00307         pcelim->points.erase(pcelim->points.begin(), pcelim->points.end());
00308         //_______________________________________________________
00309         //cycle all points an do the test for each      
00310         for (int k=0; k< (int)pc->points.size(); k++)
00311         {
00312                 std::vector<int> pointIdxRadiusSearch;
00313                 std::vector<float> pointRadiusSquaredDistance;
00314                 std::vector<Eigen::Vector4f> ev_v; //list of quaternions from the normals of each neighbor
00315                 Eigen::Vector4f ev_k;
00316                 std::vector<float> angle_to_avg_v;
00317                 double mean, std;
00318                 //int acc=1; //an accumulator to compute the ratio
00319 
00320                 if(     kdtree.radiusSearch(pc->points[k], radius, pointIdxRadiusSearch, pointRadiusSquaredDistance) <= 0)
00321                 {
00322                         ROS_INFO("pt %d error in kdtree",k);
00323                 }
00324                 else
00325                 {
00326                         //_______________________________________________________
00327                         ev_k[0] = pc->points[k].normal[0]; 
00328                         ev_k[1] = pc->points[k].normal[1]; 
00329                         ev_k[2] = pc->points[k].normal[2]; 
00330                         ev_k[3] = 0;
00331 
00332                         //_______________________________________________________
00333                         for (size_t i = 0; i < pointIdxRadiusSearch.size (); ++i) 
00334                         {
00335                                 pcl::flipNormalTowardsViewpoint(pc->points[k], vx, vy, vz, pc->points[pointIdxRadiusSearch[i]].normal[0], pc->points[pointIdxRadiusSearch[i]].normal[1], pc->points[pointIdxRadiusSearch[i]].normal[2]);
00336                                 Eigen::Vector4f ev; 
00337                                 ev[0] = pc->points[pointIdxRadiusSearch[i]].normal[0]; 
00338                                 ev[1] = pc->points[pointIdxRadiusSearch[i]].normal[1]; 
00339                                 ev[2] = pc->points[pointIdxRadiusSearch[i]].normal[2]; 
00340                                 ev[3] = 0;
00341                                 ev_v.push_back(ev);
00342                         }
00343 
00344                         //_______________________________________________________
00345                         Eigen::Vector4f ev_avg; 
00346                         float x_acc=0, y_acc=0, z_acc=0;
00347                         for (size_t i = 0; i<ev_v.size(); i++) //cycle all neighbor quaternions and use slerp with dynamic weight
00348                         {
00349                                 x_acc += ev_v[i][0];
00350                                 y_acc += ev_v[i][1];
00351                                 z_acc += ev_v[i][2];
00352                         }
00353 
00354                         ev_avg[0] = x_acc/(double)ev_v.size();
00355                         ev_avg[1] = y_acc/(double)ev_v.size();
00356                         ev_avg[2] = z_acc/(double)ev_v.size();
00357                         ev_avg[3] = 0;
00358 
00359                         double norm = sqrt(ev_avg[0]*ev_avg[0] + ev_avg[1]*ev_avg[1] + ev_avg[2]*ev_avg[2]);
00360                         ev_avg[0] = ev_avg[0]/norm;
00361                         ev_avg[1] = ev_avg[1]/norm;
00362                         ev_avg[2] = ev_avg[2]/norm;
00363 
00364                         //______________________________________________________
00365                         //Check if normals must be flipped
00366                         std::vector<Eigen::Vector4f> ev_v2; 
00367                         std::vector<bool> ev_is_fliped; 
00368 
00369                         for (size_t i = 0; i<ev_v.size(); i++) //cycle all neighbor quaternions and use slerp with dynamic weight
00370                         {
00371                                 double angle_straight = ((float)(pcl::getAngle3D(ev_avg, ev_v[i])*180.0/M_PI));
00372                                 Eigen::Vector4f ev_fliped; 
00373                                 ev_fliped[0] = -ev_v[i][0];
00374                                 ev_fliped[1] = -ev_v[i][1];
00375                                 ev_fliped[2] = -ev_v[i][2];
00376                                 ev_fliped[3] = -ev_v[i][3];
00377                                 double angle_fliped = ((float)(pcl::getAngle3D(ev_avg, ev_fliped)*180.0/M_PI));
00378 
00379                                 if (fabs(angle_straight) < fabs(angle_fliped))
00380                                 {
00381                                         ev_v2.push_back(ev_v[i]);       
00382                                         ev_is_fliped.push_back(false);
00383                                 }
00384                                 else
00385                                 {
00386                                         ev_v2.push_back(ev_fliped);     
00387                                         ev_is_fliped.push_back(true);
00388                                 }
00389 
00390                         }
00391 
00392                         //_______________________________________________________
00393                         //Recompute the average after fliping vectors
00394                         Eigen::Vector4f ev2_avg; 
00395                         x_acc=0, y_acc=0, z_acc=0;
00396                         for (size_t i = 0; i<ev_v2.size(); i++) //cycle all neighbor quaternions and use slerp with dynamic weight
00397                         {
00398                                 x_acc += ev_v2[i][0];
00399                                 y_acc += ev_v2[i][1];
00400                                 z_acc += ev_v2[i][2];
00401                         }
00402 
00403                         ev2_avg[0] = x_acc/(double)ev_v2.size();
00404                         ev2_avg[1] = y_acc/(double)ev_v2.size();
00405                         ev2_avg[2] = z_acc/(double)ev_v2.size();
00406                         ev2_avg[3] = 0;
00407 
00408                         norm = sqrt(ev2_avg[0]*ev2_avg[0] + ev2_avg[1]*ev2_avg[1] + ev2_avg[2]*ev2_avg[2]);
00409                         ev2_avg[0] = ev2_avg[0]/norm;
00410                         ev2_avg[1] = ev2_avg[1]/norm;
00411                         ev2_avg[2] = ev2_avg[2]/norm;
00412 
00413                         //_______________________________________________________
00414                         //Get eigen vectors from quaternions
00415                         for (size_t i = 0; i<ev_v2.size(); i++)
00416                         {
00417                                 angle_to_avg_v.push_back((float)(pcl::getAngle3D(ev2_avg, ev_v2[i])*180.0/M_PI));
00418                         }
00419 
00420                         //_______________________________________________________
00421                         //Get mean and standard deviation from the eigen vectors
00422                         pcl::getMeanStd(angle_to_avg_v, mean, std);
00423                         //double angle_to_avg = (float)(pcl::getAngle3D( ev2_avg, ev_k)*180.0/M_PI); 
00424 
00425                         if(std>25 || mean>35)
00426                         {
00427                                 pcelim->points.push_back(pc->points[k]);
00428                         }
00429                         else
00430                         {
00431                                 pcout->points.push_back(pc->points[k]);
00432                         }
00433 
00434                         //  ______________________________________
00435                         //  |                                    |
00436                         //  |                   Draw markers                     |
00437                         //  |____________________________________|
00438                         if(k%1100==0 && cont &&0)
00439                         {
00440 
00441                                 //ROS_INFO("q_avg = %f %f %f %f",q_avg[0], q_avg[1], q_avg[2], q_avg[3]);
00442                                 ROS_INFO("Point %d has %ld neighbors",k,ev_v.size());
00443                                 for (size_t i = 0; i<ev_v.size(); i++)
00444                                 {
00445                                         ROS_INFO("Neighbor %ld has %f (degrees)", i, angle_to_avg_v[i]);
00446                                 }
00447                                 ROS_INFO("Angle to Average Mean = %f std = %f",mean, std);
00448 
00449                                 draw_markers(k, &ev2_avg, &ev_v2, pc, &pointIdxRadiusSearch, &ev_avg, &ev_is_fliped);
00450 
00451                                 printf("olaolaola!\n");
00452                                 char ola[1024];
00453                                 int ret = scanf("%s",ola);  ret++;
00454                                 if (ola[0]=='q') exit(0);
00455                                 else if (ola[0]=='c') cont=false;
00456 
00457 
00458                         }
00459 
00460 
00461 
00462                 }
00463         }
00464 
00465         ROS_INFO("pcin =%d points", (int) pc->points.size());
00466         ROS_INFO("pcout =%d points", (int) pcout->points.size());
00467 }
00468 
00469 void draw_markers(int k, Eigen::Vector4f* q_avg, std::vector<Eigen::Vector4f>* qv, pcl::PointCloud<pcl::PointNormal>::Ptr pc, std::vector<int>* pointIdxRadiusSearch, Eigen::Vector4f* q_avg0, std::vector<bool>* is_fliped)
00470 {
00471         static ros::Publisher markerarray_pub = pn->advertise<visualization_msgs::MarkerArray>("/Marker_neighbours", 1);
00472 
00473         static size_t total_normals=0;
00474         //std::vector<visualization_msgs::Marker> marker_vec;
00475         geometry_msgs::Point p;
00476         std_msgs::ColorRGBA color;
00477         visualization_msgs::Marker msg;
00478         visualization_msgs::MarkerArray marker_vec;
00479 
00480 
00481         //Draw the K point
00482         msg.header.frame_id = std::string("/world");
00483         msg.header.stamp = ros::Time::now();
00484         msg.ns = "K"; msg.id = 0;
00485         msg.action = visualization_msgs::Marker::ADD;
00486         msg.pose.orientation.w = 1.0;
00487         msg.type = visualization_msgs::Marker::SPHERE;
00488         msg.pose.position.x = pc->points[k].x;
00489         msg.pose.position.y = pc->points[k].y;
00490         msg.pose.position.z = pc->points[k].z;
00491         msg.scale.x = 5; msg.scale.y = 5; msg.scale.z = 5; 
00492         msg.color.r = 0; msg.color.g = 0; msg.color.b = 0.3; msg.color.a = 0.2;
00493         marker_vec.markers.push_back(msg);
00494 
00495         //Draw the neighbor points
00496         msg.header.frame_id = std::string("/world");
00497         msg.header.stamp = ros::Time::now();
00498         msg.ns = "neighbors"; msg.id = 0;
00499         msg.action = visualization_msgs::Marker::ADD;
00500         msg.pose.position.x = 0; msg.pose.position.y = 0; msg.pose.position.z = 0; 
00501         msg.pose.orientation.x = 0;     msg.pose.orientation.y = 0;     msg.pose.orientation.z = 0; msg.pose.orientation.w = 1.0;
00502         msg.type = visualization_msgs::Marker::POINTS;
00503         msg.scale.x = 0.03; msg.scale.y = 0.03; msg.scale.z = 0.03; 
00504         msg.color.r = 0; msg.color.g = 0; msg.color.b = 1; msg.color.a = 1;
00505 
00506         msg.points.erase(msg.points.begin(), msg.points.end());
00507         for (size_t i = 0; i<qv->size(); i++)
00508         {
00509                 p.x = pc->points[pointIdxRadiusSearch->at(i)].x;
00510                 p.y = pc->points[pointIdxRadiusSearch->at(i)].y;
00511                 p.z = pc->points[pointIdxRadiusSearch->at(i)].z;
00512                 msg.points.push_back(p);
00513         }
00514         marker_vec.markers.push_back(msg);
00515 
00516         //Draw an arrow with the iteration0 mean orientation
00517         msg.header.frame_id = std::string("/world");
00518         msg.header.stamp = ros::Time::now();
00519         msg.ns = "it0_mean";
00520         msg.action = visualization_msgs::Marker::ADD;
00521         msg.pose.position.x = 0; msg.pose.position.y = 0; msg.pose.position.z = 0; 
00522         msg.pose.orientation.x = 0;     msg.pose.orientation.y = 0;     msg.pose.orientation.z = 0; msg.pose.orientation.w = 1.0;
00523         msg.type = visualization_msgs::Marker::ARROW;
00524         msg.id = 0;
00525         msg.scale.x = 0.08; msg.scale.y = 0.2; 
00526         msg.color.r = 0; msg.color.g = 0.2;     msg.color.b = 0.7;      msg.color.a = 0.6;
00527         msg.points.erase(msg.points.begin(), msg.points.end()); 
00528 
00529         p.x = pc->points[k].x; p.y = pc->points[k].y; p.z = pc->points[k].z;
00530         msg.points.push_back(p);
00531         p.x = pc->points[k].x + (*q_avg0)[0]; p.y = pc->points[k].y + (*q_avg0)[1]; p.z = pc->points[k].z + (*q_avg0)[2];
00532         msg.points.push_back(p);
00533         marker_vec.markers.push_back(msg);
00534 
00535         //Draw an arrow with the mean orientation
00536         msg.header.frame_id = std::string("/world");
00537         msg.header.stamp = ros::Time::now();
00538         msg.ns = "mean";
00539         msg.action = visualization_msgs::Marker::ADD;
00540         msg.pose.position.x = 0; msg.pose.position.y = 0; msg.pose.position.z = 0; 
00541         msg.pose.orientation.x = 0;     msg.pose.orientation.y = 0;     msg.pose.orientation.z = 0; msg.pose.orientation.w = 1.0;
00542         msg.type = visualization_msgs::Marker::ARROW;
00543         msg.id = 0;
00544         msg.scale.x = 0.08; msg.scale.y = 0.2; 
00545         msg.color.r = 1; msg.color.g = 0;       msg.color.b = 0.3;      msg.color.a = 0.6;
00546         msg.points.erase(msg.points.begin(), msg.points.end()); 
00547 
00548         p.x = pc->points[k].x; p.y = pc->points[k].y; p.z = pc->points[k].z;
00549         msg.points.push_back(p);
00550         p.x = pc->points[k].x + (*q_avg)[0]; p.y = pc->points[k].y + (*q_avg)[1]; p.z = pc->points[k].z + (*q_avg)[2];
00551         msg.points.push_back(p);
00552         marker_vec.markers.push_back(msg);
00553 
00554         //Draw the neighbors normals
00555         msg.header.frame_id = std::string("/world");
00556         msg.header.stamp = ros::Time::now();
00557         msg.ns = "n_normals";
00558         msg.action = visualization_msgs::Marker::ADD;
00559         msg.pose.position.x = 0; msg.pose.position.y = 0; msg.pose.position.z = 0; 
00560         msg.pose.orientation.x = 0;     msg.pose.orientation.y = 0;     msg.pose.orientation.z = 0; msg.pose.orientation.w = 1.0;
00561         msg.type = visualization_msgs::Marker::ARROW;
00562         msg.scale.x = 0.01;//arrow shaft radius
00563         msg.scale.y = 0.05; //arrow head radius
00564 
00565         for (size_t i = 0; i < qv->size (); ++i)
00566         {
00567                 if ((*is_fliped)[i]==true)
00568                 {
00569                         msg.color.r = 9; msg.color.g = 0; msg.color.b = 0.0; msg.color.a = 0.3;
00570                 }
00571                 else
00572                 {
00573                         msg.color.r = 0; msg.color.g = 1; msg.color.b = 0.3; msg.color.a = 0.3;
00574                 }
00575 
00576                 msg.points.erase(msg.points.begin(), msg.points.end()); 
00577                 msg.id = i;
00578                 p.x = pc->points[k].x;
00579                 p.y = pc->points[k].y;
00580                 p.z = pc->points[k].z;
00581                 msg.points.push_back(p);
00582 
00583                 p.x = pc->points[k].x + (*qv)[i][0];
00584                 p.y = pc->points[k].y + (*qv)[i][1];
00585                 p.z = pc->points[k].z + (*qv)[i][2];
00586                 msg.points.push_back(p);
00587                 marker_vec.markers.push_back(msg);
00588         }
00589 
00590         //Remove excessive markers
00591         for (size_t i = qv->size(); i <total_normals; ++i)
00592         {
00593                 msg.type = visualization_msgs::Marker::ARROW;
00594                 msg.id = i;
00595                 msg.ns = "n_normals";
00596                 msg.action = visualization_msgs::Marker::DELETE;
00597                 marker_vec.markers.push_back(msg);
00598         }
00599         total_normals = qv->size();
00600 
00601         //Send the marker array msg to rviz
00602                 markerarray_pub.publish(marker_vec);    
00603         ros::spinOnce();
00604 
00605 
00606 }
00607 
00608 //void filter_uncoherent_points(pcl::PointCloud<pcl::PointNormal>::Ptr pc, double radius, pcl::PointCloud<pcl::PointNormal>::Ptr pcout, float vx, float vy, float vz)
00609 //{
00611 //pcl::KdTreeFLANN<pcl::PointNormal> kdtree;
00612 //kdtree.setInputCloud(pc);
00613 
00614 
00616 //pcout->points.erase(pcout->points.begin(), pcout->points.end());
00617 
00618 //ROS_INFO("pcin =%d points", (int) pc->points.size());
00619 
00622 //for (int k=0; k< (int)pc->points.size(); k++)
00623 //{
00624 //std::vector<int> pointIdxRadiusSearch;
00625 //std::vector<float> pointRadiusSquaredDistance;
00626 //std::vector<btQuaternion> qv; //list of quaternions from the normals of each neighbor
00627 //std::vector<float> angle_to_avg_v;
00628 //double mean, std;
00629 //int acc=1; //an accumulator to compute the ratio
00630 
00631 //if(   kdtree.radiusSearch(pc->points[k], radius, pointIdxRadiusSearch, pointRadiusSquaredDistance) <= 0)
00632 //{
00633 //ROS_INFO("pt %d error in kdtree",k);
00634 //}
00635 //else
00636 //{
00639 //btQuaternion q_value(pc->points[k].normal[0], pc->points[k].normal[1], pc->points[k].normal[2], 0);
00640 //q_value.normalize();
00641 //Eigen::Vector4f ev_value; 
00642 //ev_value[0] = q_value[0]; ev_value[1] = q_value[1];   ev_value[2] = q_value[2]; ev_value[3] = q_value[3];
00643 
00646 //for (size_t i = 0; i < pointIdxRadiusSearch.size (); ++i) 
00647 //{
00648 //pcl::flipNormalTowardsViewpoint(pc->points[k], vx, vy, vz, pc->points[pointIdxRadiusSearch[i]].normal[0], pc->points[pointIdxRadiusSearch[i]].normal[1], pc->points[pointIdxRadiusSearch[i]].normal[2]);
00649 //btQuaternion q(pc->points[pointIdxRadiusSearch[i]].normal[0], pc->points[pointIdxRadiusSearch[i]].normal[1], pc->points[pointIdxRadiusSearch[i]].normal[2], 0);
00650 //q.normalize();
00651 //qv.push_back(q);
00652 //}
00653 
00654 
00657 //btQuaternion q_avg(qv[0]); //initialize the average quaternion as the first quaternion on the list
00658 
00659 //for (size_t i = 1; i<qv.size(); i++) //cycle all neighbor quaternions and use slerp with dynamic weight
00660 //{
00661 //if (k%100==0)
00662 //{
00663 //std::vector<int> partial_pointIdxRadiusSearch;
00664 //std::vector<btQuaternion> partial_qv; 
00665 //for (size_t j = 0; j<=i; ++j) 
00666 //{
00667 //partial_pointIdxRadiusSearch.push_back(pointIdxRadiusSearch[j]);
00668 //partial_qv.push_back(qv[j]);
00669 //}
00670 
00671 //draw_markers(k, &q_avg, &partial_qv, pc, &partial_pointIdxRadiusSearch);
00672 
00673 //printf("olaolaola!\n");
00674 //char ola[1024];
00675 //scanf("%s",ola);  
00676 //if (ola[0]=='q') exit(0);
00677 //}
00678 
00679 //double ratio = 1-(double)acc/((double)acc+1);
00680 //q_avg = slerp(q_avg, qv[i], ratio);
00681 //acc++;
00682 //}
00683 
00686 //Eigen::Vector4f ev_avg; 
00687 //ev_avg[0] = q_avg[0]; ev_avg[1] = q_avg[1]; ev_avg[2] = q_avg[2]; ev_avg[3] = q_avg[3];
00688 
00689 //for (size_t i = 0; i<qv.size(); i++)
00690 //{
00691 //Eigen::Vector4f v; 
00692 //v[0] = qv[i][0]; v[1] = qv[i][1]; v[2] = qv[i][2]; v[3] = qv[i][3];
00693 //angle_to_avg_v.push_back((float)(pcl::getAngle3D(ev_avg, v)*180.0/M_PI));
00694 //}
00695 
00698 //pcl::getMeanStd(angle_to_avg_v, mean, std);
00699 //double angle_to_avg = (float)(pcl::getAngle3D( ev_avg, ev_value)*180.0/M_PI); 
00700 
00702 
00703 
00704 //if( fabs(angle_to_avg - mean) < std)
00705 //{
00706 
00707 //}
00708 //else
00709 //{
00710 //pcout->points.push_back(pc->points[k]);
00711 //}
00712 
00713 
00715 //btQuaternion q0(pc->points[k].normal[0], pc->points[k].normal[1], pc->points[k].normal[2], 0);
00716 //q0.normalize();
00717 //Eigen::Vector4f v; 
00718 //v[0] = q0[0];
00719 //v[1] = q0[1];
00720 //v[2] = q0[2];
00721 //v[3] = q0[3];
00722 
00723 //float val = (float)pcl::getAngle3D(ev_avg, v);
00724 //double f=0.3;
00725 
00726 
00731 //if(k%100==0 )
00732 //{
00733 
00734 //ROS_INFO("q_avg = %f %f %f %f",q_avg[0], q_avg[1], q_avg[2], q_avg[3]);
00735 //ROS_INFO("Point %d has %ld neighbors",k,qv.size());
00736 //for (size_t i = 0; i<qv.size(); i++)
00737 //{
00738 //ROS_INFO("Neighbor %ld Angle to Average Quat is %f (degrees)", i, angle_to_avg_v[i]);
00739 //}
00740 //ROS_INFO("Angle to Average Mean = %f std = %f",mean, std);
00741 
00742 //draw_markers(k, &q_avg, &qv, pc, &pointIdxRadiusSearch);
00743 
00744 //printf("olaolaola!\n");
00745 //char ola[1024];
00746 //scanf("%s",ola);  
00747 //if (ola[0]=='q') exit(0);
00748 
00749 
00750 //}
00751 
00752 
00753 
00754 
00759 
00765 
00766 //}
00767 //}
00768 
00769 //ROS_INFO("pcin =%d points", (int) pc->points.size());
00770 //ROS_INFO("pcout =%d points", (int) pcout->points.size());
00771 //}
00772 
00773 
00774 //int erase_old_markers(std::vector<visualization_msgs::Marker>* marker_vec, unsigned int from, unsigned int to, std::string namesp)
00775 //{
00776 //for (unsigned int j=from; j<to; j++) //erase old markers
00777 //{
00778 //visualization_msgs::Marker msg; //declare the msg 
00779 //msg.header.frame_id = data.frames.global_name;
00780 //msg.header.stamp = ros::Time::now();
00781 //msg.ns = namesp.c_str();
00782 //msg.id = j;
00783 //msg.action = visualization_msgs::Marker::DELETE;
00784 //marker_vec->push_back(msg);
00785 //}     
00786 //return 1;
00787 //}
00788 
00789 
00790 #endif
00791 


polygon_primitives_extraction
Author(s): Miguel Oliveira
autogenerated on Thu Nov 20 2014 11:35:55