6     ROS_INFO (
"HectorStairDetection started");
    49     if(
setup_.compare(std::string(
"argo"))==0){
    83                                           pcl::IndicesClustersPtr cluster_indices, std::vector<int> final_cluster_idx, Eigen::Vector3f base, Eigen::Vector3f point){
    85     geometry_msgs::PoseStamped position_and_orientaion;
    86     Eigen::Vector3f directionStairs;
    88     hector_stair_detection_msgs::PositionAndOrientaion pos_and_orientaion_message;
    89     pos_and_orientaion_message.orientation_of_stairs=position_and_orientaion;
    90     pos_and_orientaion_message.directionX=directionStairs(0);
    91     pos_and_orientaion_message.directionY=directionStairs(1);
    92     pos_and_orientaion_message.directionZ=directionStairs(2);
    95     pcl::PointCloud<pcl::PointXYZ>::Ptr final_stairsCloud(
new pcl::PointCloud<pcl::PointXYZ>);
    96     visualization_msgs::MarkerArray stairs_boarder_marker;
    97     getFinalStairsCloud_and_position(input_surface_cloud->header.frame_id, directionStairs, input_surface_cloud, planeCloud, cluster_indices, final_cluster_idx, final_stairsCloud, stairs_boarder_marker, base);
   106     hector_stair_detection_msgs::BorderAndOrientationOfStairs border_and_orientation_msg;
   107     border_and_orientation_msg.header.frame_id=input_surface_cloud->header.frame_id;
   108     border_and_orientation_msg.border_of_stairs= stairs_boarder_marker;
   109     border_and_orientation_msg.orientation_of_stairs=position_and_orientaion;
   110     border_and_orientation_msg.number_of_points= final_cluster_idx.size();
   111     border_and_orientation_msg.directionX=directionStairs(0);
   112     border_and_orientation_msg.directionY=directionStairs(1);
   113     border_and_orientation_msg.directionZ=directionStairs(2);
   128     Eigen::Vector3f stairs_position= 0.5*(base + point);
   130     position_and_orientaion.header.frame_id=frameID;
   131     position_and_orientaion.pose.position.x=stairs_position(0);
   132     position_and_orientaion.pose.position.y=stairs_position(1);
   133     position_and_orientaion.pose.position.z=stairs_position(2);
   135     if(point(2) >=base(2)){
   136         direction=point-base;
   138         direction=base-point;
   141     float stairs_yaw= 
atan2(direction(1), direction(0));
   142     float staris_pitch= 
atan2(direction(1)*
sin(stairs_yaw)+direction(0)*
cos(stairs_yaw), direction(2))+M_PI_2;
   145     position_and_orientaion.pose.orientation.x=temp.getX();
   146     position_and_orientaion.pose.orientation.y=temp.getY();
   147     position_and_orientaion.pose.orientation.z=temp.getZ();
   148     position_and_orientaion.pose.orientation.w=temp.
getW();
   151 void HectorStairDetection::getFinalStairsCloud_and_position(std::string frameID, Eigen::Vector3f directionS, pcl::PointCloud<pcl::PointNormal>::Ptr &input_surface_cloud, pcl::PointCloud<pcl::PointXYZ>::Ptr &planeCloud, pcl::IndicesClustersPtr cluster_indices, std::vector<int> final_cluster_idx,
   152                                                             pcl::PointCloud<pcl::PointXYZ>::Ptr &final_stairsCloud, visualization_msgs::MarkerArray &stairs_boarder_marker, Eigen::Vector3f base){
   153     int cluster_counter=0;
   155     float maxZ= -FLT_MAX;
   158     final_stairsCloud->header.frame_id=frameID;
   190     for (
int i = 0; i < cluster_indices->size (); ++i){
   191         std::vector<int>::iterator idx_it;
   193         idx_it = find (final_cluster_idx.begin(), final_cluster_idx.end(), cluster_counter);
   194         if (idx_it != final_cluster_idx.end()){
   195             for (
int j = 0; j < (*cluster_indices)[i].indices.size (); ++j){
   197                 tempP.x=input_surface_cloud->points[(*cluster_indices)[i].indices[j]].x;
   198                 tempP.y=input_surface_cloud->points[(*cluster_indices)[i].indices[j]].y;
   199                 tempP.z=input_surface_cloud->points[(*cluster_indices)[i].indices[j]].z;
   200                 final_stairsCloud->points.push_back(tempP);
   213         cluster_counter=cluster_counter+1;
   216     Eigen::Vector3f minStepAVG;
   220     Eigen::Vector3f maxStepAVG;
   226     for (
int j = 0; j < (*cluster_indices)[minZIndex].indices.size (); ++j){
   227         minStepAVG(0)=minStepAVG(0)+input_surface_cloud->points[(*cluster_indices)[minZIndex].indices[j]].x;
   228         minStepAVG(1)=minStepAVG(1)+input_surface_cloud->points[(*cluster_indices)[minZIndex].indices[j]].y;
   229         minStepAVG(2)=minStepAVG(2)+input_surface_cloud->points[(*cluster_indices)[minZIndex].indices[j]].z;
   232     minStepAVG=minStepAVG/(*cluster_indices)[minZIndex].indices.size ();
   234     for (
int j = 0; j < (*cluster_indices)[maxZIndex].indices.size (); ++j){
   235         maxStepAVG(0)=maxStepAVG(0)+input_surface_cloud->points[(*cluster_indices)[maxZIndex].indices[j]].x;
   236         maxStepAVG(1)=maxStepAVG(1)+input_surface_cloud->points[(*cluster_indices)[maxZIndex].indices[j]].y;
   237         maxStepAVG(2)=maxStepAVG(2)+input_surface_cloud->points[(*cluster_indices)[maxZIndex].indices[j]].z;
   240     maxStepAVG=maxStepAVG/(*cluster_indices)[maxZIndex].indices.size ();
   243     for(
int i=0; i<4; i++){
   244         visualization_msgs::Marker marker;
   245         marker.header.frame_id = frameID;
   246         marker.type = visualization_msgs::Marker::SPHERE;
   247         marker.action = visualization_msgs::Marker::ADD;
   248         marker.ns = 
"hector_stair_detection";
   250         if((directionS(0)> 0 && directionS(1) >0) || (directionS(0)< 0 && directionS(1) <0)){
   252                 marker.pose.position.x = minStepAVG(0) - 0.5*
sin(
atan2(directionS(1), directionS(0)));
   253                 marker.pose.position.y = minStepAVG(1) + 0.5*
cos(
atan2(directionS(1), directionS(0)));
   254                 marker.pose.position.z=minStepAVG(2);
   258                 marker.pose.position.x = minStepAVG(0) + 0.5*
sin(
atan2(directionS(1), directionS(0)));
   259                 marker.pose.position.y = minStepAVG(1) - 0.5*
cos(
atan2(directionS(1), directionS(0)));
   260                 marker.pose.position.z=minStepAVG(2);
   264                 marker.pose.position.x = maxStepAVG(0) - 0.5*
sin(
atan2(directionS(1), directionS(0)));
   265                 marker.pose.position.y = maxStepAVG(1) + 0.5*
cos(
atan2(directionS(1), directionS(0)));
   266                 marker.pose.position.z=maxStepAVG(2);
   270                 marker.pose.position.x = maxStepAVG(0) + 0.5*
sin(
atan2(directionS(1), directionS(0)));
   271                 marker.pose.position.y = maxStepAVG(1) - 0.5*
cos(
atan2(directionS(1), directionS(0)));
   272                 marker.pose.position.z=maxStepAVG(2);
   276                 marker.pose.position.x = minStepAVG(0) + 0.5*
sin(
atan2(directionS(1), directionS(0)));
   277                 marker.pose.position.y = minStepAVG(1) + 0.5*
cos(
atan2(directionS(1), directionS(0)));
   278                 marker.pose.position.z=minStepAVG(2);
   282                 marker.pose.position.x = minStepAVG(0) - 0.5*
sin(
atan2(directionS(1), directionS(0)));
   283                 marker.pose.position.y = minStepAVG(1) - 0.5*
cos(
atan2(directionS(1), directionS(0)));
   284                 marker.pose.position.z=minStepAVG(2);
   288                 marker.pose.position.x = maxStepAVG(0) + 0.5*
sin(
atan2(directionS(1), directionS(0)));
   289                 marker.pose.position.y = maxStepAVG(1) + 0.5*
cos(
atan2(directionS(1), directionS(0)));
   290                 marker.pose.position.z=maxStepAVG(2);
   294                 marker.pose.position.x = maxStepAVG(0) - 0.5*
sin(
atan2(directionS(1), directionS(0)));
   295                 marker.pose.position.y = maxStepAVG(1) - 0.5*
cos(
atan2(directionS(1), directionS(0)));
   296                 marker.pose.position.z=maxStepAVG(2);
   300         marker.pose.orientation.x = 0.0;
   301         marker.pose.orientation.y = 0.0;
   302         marker.pose.orientation.z = 0.0;
   303         marker.pose.orientation.w = 1.0;
   304         marker.scale.x = 0.2;
   305         marker.scale.y = 0.2;
   306         marker.scale.z = 0.2;
   307         marker.color.a = 1.0;
   308         marker.color.r = 0.0;
   309         marker.color.g = 1.0;
   310         marker.color.b = 0.0;
   312         stairs_boarder_marker.markers.push_back(marker);
   319     float first_step_z=0.05;
   323     for(
int i=0; i<stairs_boarder_marker.markers.size(); i++){
   324         if(stairs_boarder_marker.markers.at(i).pose.position.z <minZ){
   325             minZ=stairs_boarder_marker.markers.at(i).pose.position.z;
   331     for(
int i=0; i<stairs_boarder_marker.markers.size(); i++){
   332         if(i != minPos1 && stairs_boarder_marker.markers.at(i).pose.position.z <minZ){
   333             minZ=stairs_boarder_marker.markers.at(i).pose.position.z;
   338     stairs_boarder_marker.markers.at(minPos1).pose.position.x=stairs_boarder_marker.markers.at(minPos1).pose.position.x+(first_step_z-stairs_boarder_marker.markers.at(minPos1).pose.position.z)/direction(2)*direction(0);
   339     stairs_boarder_marker.markers.at(minPos1).pose.position.y=stairs_boarder_marker.markers.at(minPos1).pose.position.y+(first_step_z-stairs_boarder_marker.markers.at(minPos1).pose.position.z)/direction(2)*direction(1);
   340     stairs_boarder_marker.markers.at(minPos1).pose.position.z=first_step_z;
   341     stairs_boarder_marker.markers.at(minPos2).pose.position.x=stairs_boarder_marker.markers.at(minPos2).pose.position.x+(first_step_z-stairs_boarder_marker.markers.at(minPos2).pose.position.z)/direction(2)*direction(0);
   342     stairs_boarder_marker.markers.at(minPos2).pose.position.y=stairs_boarder_marker.markers.at(minPos2).pose.position.y+(first_step_z-stairs_boarder_marker.markers.at(minPos2).pose.position.z)/direction(2)*direction(1);
   343     stairs_boarder_marker.markers.at(minPos2).pose.position.z=first_step_z;
   347     Eigen::Vector2f direction1;
   348     Eigen::Vector2f direction2;
   349     Eigen::Vector2f direction3;
   350     Eigen::Vector2f direction4;
   352     direction1=maxXminY-minXminY;
   353     direction2=minXmaxY-minXminY;
   354     direction3=minXminY-maxXminY;
   355     direction4=minXminY-minXmaxY;
   357     float angle1=
acos((directionStairs.dot(direction1))/(directionStairs.norm()*direction1.norm()));
   358     float angle2=
acos((directionStairs.dot(direction2))/(directionStairs.norm()*direction2.norm()));
   359     float angle3=
acos((directionStairs.dot(direction3))/(directionStairs.norm()*direction3.norm()));
   360     float angle4=
acos((directionStairs.dot(direction4))/(directionStairs.norm()*direction4.norm()));
   362     if(angle1>=angle2 && angle1>=angle3 && angle1>=angle4){
   366     if(angle2>=angle1 && angle2>=angle3 && angle2>=angle4){
   370     if(angle3>=angle2 && angle3>=angle1 && angle3>=angle4){
   374     if(angle4>=angle2 && angle4>=angle3 && angle4>=angle1){
   380     ROS_INFO(
"Hector Stair Detection get Surface");
   381     pcl::PointCloud<pcl::PointXYZ>::Ptr processCloud_v1(
new pcl::PointCloud<pcl::PointXYZ>());
   382     pcl::PointCloud<pcl::PointXYZ>::Ptr processCloud_v2(
new pcl::PointCloud<pcl::PointXYZ>());
   386     pcl::PassThrough<pcl::PointXYZ> pass;
   387     pass.setInputCloud(input_cloud);
   388     pass.setFilterFieldName(
"z");
   390     pass.filter(*processCloud_v1);
   404     pcl::VoxelGrid<pcl::PointXYZ> vox;
   405     vox.setInputCloud(processCloud_v1);
   407     vox.setDownsampleAllData(
false);
   408     vox.filter(*processCloud_v2);
   412     pcl::MovingLeastSquares<pcl::PointXYZ, pcl::PointNormal> mls;
   413     mls.setSearchRadius(0.05);
   414     mls.setPolynomialOrder(1);
   415     mls.setComputeNormals(
true);
   416     mls.setInputCloud(processCloud_v2);
   419     point_cloud_mls_normal.reset(
new pcl::PointCloud<pcl::PointNormal>);
   420     mls.process(*point_cloud_mls_normal);
   437     output_cloud->clear();
   438     output_cloud->header.frame_id=input_cloud->header.frame_id;
   440     output_cloud.reset(
new pcl::PointCloud<pcl::PointNormal>(*point_cloud_mls_normal));
   443     std::vector<int> indices;
   444     pcl::removeNaNFromPointCloud(*output_cloud,*output_cloud, indices);
   445     pcl::removeNaNNormalsFromPointCloud(*output_cloud,*output_cloud, indices);
   452 bool customRegionGrowing (
const pcl::PointNormal& point_a, 
const pcl::PointNormal& point_b, 
float squared_distance){
   453     Eigen::Map<const Eigen::Vector3f> point_b_normal = point_b.normal;
   455     Eigen::Vector3f d1(1,0,0);
   456     Eigen::Vector3f 
d2(0,1,0);
   458     if(fabs(d1.dot(point_b_normal)) < 0.2 && fabs(d2.dot(point_b_normal)) < 0.2){
   466     ROS_INFO(
"stairs position callback enterd");
   467     pcl::PointCloud<pcl::PointXYZ>::Ptr input_cloud(
new pcl::PointCloud<pcl::PointXYZ>);
   468     pcl::PCLPointCloud2 pcl_pc2;
   470     pcl::fromPCLPointCloud2(pcl_pc2,*input_cloud);
   478                                   time, transform_cloud_to_map);
   481         ROS_ERROR(
"Lookup Transform failed: %s",ex.what());
   489     pcl::transformPointCloud(*input_cloud, *cloud_tmp, 
to_map_);
   490     input_cloud = cloud_tmp;
   491     input_cloud->header.frame_id= transform_cloud_to_map.
frame_id_;
   496     pcl::PointCloud<pcl::PointNormal>::Ptr input_surface_cloud(
new pcl::PointCloud<pcl::PointNormal>);
   497     pcl::PointCloud<pcl::PointXYZI>::Ptr possible_stairsCloud(
new pcl::PointCloud<pcl::PointXYZI>);
   498     pcl::PointCloud<pcl::PointXYZI>::Ptr cluster_cloud_debug(
new pcl::PointCloud<pcl::PointXYZI>);
   502     possible_stairsCloud->header.frame_id=input_surface_cloud->header.frame_id;
   505     pcl::IndicesClustersPtr clusters (
new pcl::IndicesClusters);
   506     pcl::ConditionalEuclideanClustering<pcl::PointNormal> cec (
false);
   507     cec.setInputCloud (input_surface_cloud);
   512     cec.segment (*clusters);
   515     std::vector<Eigen::Vector3f> avg_point_per_cluster;
   520     float max_x=-FLT_MAX;
   522     float max_y=-FLT_MAX;
   524     float max_z=-FLT_MAX;
   528     int clusterCounter=0;
   530     ROS_INFO(
"number cluster: %i", clusters->size ());
   531     std::vector<int> cluster_idx_corresponding_to_avg_point;
   532     for (
int i = 0; i < clusters->size (); ++i){
   533         clusterSize= (*clusters)[i].indices.size ();
   543         pcl::PointNormal point;
   544         for (
int j = 0; j < (*clusters)[i].indices.size (); ++j){
   545             point=input_surface_cloud->points[(*clusters)[i].indices[j]];
   546             sum_x=sum_x + point.x;
   547             sum_y=sum_y + point.y;
   548             sum_z=sum_z + point.z;
   570             clusterCounter=clusterCounter+1;
   574         Eigen::Vector3f avg_point;
   575         avg_point(0)=sum_x/clusterSize;
   576         avg_point(1)=sum_y/clusterSize;
   577         avg_point(2)=sum_z/clusterSize;
   579         if(fabs(max_z-min_z)/2<clusterHeightTresh){
   580             avg_point_per_cluster.push_back(avg_point);
   581             cluster_idx_corresponding_to_avg_point.push_back(clusterCounter);
   583             pcl::PointXYZI tempP;
   584             tempP.x=avg_point(0);
   585             tempP.y=avg_point(1);
   586             tempP.z=avg_point(2);
   587             tempP.intensity=clusterColor;
   588             possible_stairsCloud->points.push_back(tempP);
   589             cluster_cloud_debug->clear();
   591             for (
int j = 0; j < (*clusters)[i].indices.size (); ++j){
   592                 pcl::PointXYZI tempP;
   593                 tempP.x=input_surface_cloud->points[(*clusters)[i].indices[j]].x;
   594                 tempP.y=input_surface_cloud->points[(*clusters)[i].indices[j]].y;
   595                 tempP.z=input_surface_cloud->points[(*clusters)[i].indices[j]].z;
   596                 tempP.intensity=clusterColor;
   597                 possible_stairsCloud->points.push_back(tempP);
   598                 cluster_cloud_debug->points.push_back(tempP);
   600             clusterColor=clusterColor+1;
   602         clusterCounter=clusterCounter+1;
   608     ROS_INFO(
"number final cluster: %i", avg_point_per_cluster.size());
   610     if(avg_point_per_cluster.size()>=2){
   614         int pointsAtLineCounter=0;
   616         Eigen::Vector3f direction;
   617         Eigen::Vector3f base;
   618         Eigen::Vector3f point;
   619         std::vector<int> point_in_line_counter;
   620         point_in_line_counter.resize(avg_point_per_cluster.size());
   621         for(
int i=0; i< point_in_line_counter.size(); i++){
   622             point_in_line_counter.at(i)=0;
   626         int maxPointOnLineCounter=0;
   629         pcl::PointCloud<pcl::PointXYZI>::Ptr debug_line_cloud(
new pcl::PointCloud<pcl::PointXYZI>());
   630         if(avg_point_per_cluster.size() != 0){
   631             for(
int i=0; i<avg_point_per_cluster.size()-1; i++){
   632                 for(
int j=i+1; j<avg_point_per_cluster.size(); j++){
   633                     debug_line_cloud->clear();
   634                     debug_line_cloud->header.frame_id=input_surface_cloud->header.frame_id;
   636                     base(0)= avg_point_per_cluster.at(i)(0);
   637                     base(1)= avg_point_per_cluster.at(i)(1);
   638                     base(2)= avg_point_per_cluster.at(i)(2);
   640                     direction(0)= avg_point_per_cluster.at(j)(0) - base(0);
   641                     direction(1)= avg_point_per_cluster.at(j)(1) - base(1);
   642                     direction(2)= avg_point_per_cluster.at(j)(2) - base(2);
   644                     pcl::PointXYZI pushbackPoint;
   645                     pushbackPoint.x=base(0);
   646                     pushbackPoint.y=base(1);
   647                     pushbackPoint.z=base(2);
   648                     pushbackPoint.intensity=10;
   649                     debug_line_cloud->push_back(pushbackPoint);
   650                     pushbackPoint.x=direction(0)+base(0);
   651                     pushbackPoint.y=direction(1)+base(1);
   652                     pushbackPoint.z=direction(2)+base(2);
   653                     pushbackPoint.intensity=10;
   654                     debug_line_cloud->push_back(pushbackPoint);
   656                     pointsAtLineCounter=0;
   657                     for(
int p=0; p<avg_point_per_cluster.size(); p++){
   658                         point(0)=avg_point_per_cluster.at(p)(0);
   659                         point(1)=avg_point_per_cluster.at(p)(1);
   660                         point(2)=avg_point_per_cluster.at(p)(2);
   662                         float tempA= std::sqrt(direction.cross(point-base).dot(direction.cross(point-base)));
   663                         float lengthDirection= std::sqrt(direction.dot(direction));
   664                         float distance= tempA/lengthDirection;
   666                         if(distance <= distanceToLineThreshold){
   667                             pointsAtLineCounter=pointsAtLineCounter+1;
   668                             pushbackPoint.x=point(0);
   669                             pushbackPoint.y=point(1);
   670                             pushbackPoint.z=point(2);
   671                             pushbackPoint.intensity=distance;
   672                             debug_line_cloud->push_back(pushbackPoint);
   674                             point_in_line_counter.at(p)=point_in_line_counter.at(p)+1;
   678                     if(pointsAtLineCounter >= maxPointOnLineCounter){
   679                         maxPointOnLineCounter=pointsAtLineCounter;
   690         int iterationCounter=0;
   693             maxPointOnLineCounter=0;
   696             for(
int p=0; p<point_in_line_counter.size(); p++){
   697                 if(point_in_line_counter.at(p) > maxPointOnLineCounter){
   698                     maxPointOnLineCounter=point_in_line_counter.at(p);
   699                     best_pair_idx2=best_pair_idx1;
   704             if(best_pair_idx1==-1 || best_pair_idx2==-1){
   708             point_in_line_counter.at(best_pair_idx1)=0;
   712             base=avg_point_per_cluster.at(best_pair_idx1);
   714             direction(0)= avg_point_per_cluster.at(best_pair_idx2)(0) - base(0);
   715             direction(1)= avg_point_per_cluster.at(best_pair_idx2)(1) - base(1);
   716             direction(2)= avg_point_per_cluster.at(best_pair_idx2)(2) - base(2);
   718             pcl::PointXYZI pushbackPoint;
   719             debug_line_cloud->clear();
   720             debug_line_cloud->header.frame_id=input_cloud->header.frame_id;
   721             pushbackPoint.x=base(0);
   722             pushbackPoint.y=base(1);
   723             pushbackPoint.z=base(2);
   725             debug_line_cloud->push_back(pushbackPoint);
   726             pushbackPoint.x=avg_point_per_cluster.at(best_pair_idx2)(0);
   727             pushbackPoint.y=avg_point_per_cluster.at(best_pair_idx2)(1);
   728             pushbackPoint.z=avg_point_per_cluster.at(best_pair_idx2)(2);
   730             debug_line_cloud->push_back(pushbackPoint);
   732             pointsAtLineCounter=2;
   733             std::vector<int> final_cluster_idx;
   734             for(
int p=0; p<avg_point_per_cluster.size(); p++){
   735                 if(p==best_pair_idx1 || p== best_pair_idx2) {
   736                     final_cluster_idx.push_back(cluster_idx_corresponding_to_avg_point.at(p));
   739                 pushbackPoint.x=point(0)=avg_point_per_cluster.at(p)(0);
   740                 pushbackPoint.y=point(1)=avg_point_per_cluster.at(p)(1);
   741                 pushbackPoint.z=point(2)=avg_point_per_cluster.at(p)(2);
   744                 float tempA= std::sqrt(direction.cross(point-base).dot(direction.cross(point-base)));
   745                 float lengthDirection= std::sqrt(direction.dot(direction));
   746                 float distance= tempA/lengthDirection;
   748                 if(distance <= distanceToLineThreshold){
   749                     pointsAtLineCounter=pointsAtLineCounter+1;
   750                     final_cluster_idx.push_back(cluster_idx_corresponding_to_avg_point.at(p));
   751                     debug_line_cloud->push_back(pushbackPoint);
   756             if(pointsAtLineCounter >= minCountPointsAtLine){
   762                     ROS_INFO(
"Staris; number points on line: %i", pointsAtLineCounter);
   765                     if(avg_point_per_cluster.at(best_pair_idx2)(2) >=base(2)){
   766                         dir=avg_point_per_cluster.at(best_pair_idx2)-base;
   768                         dir=base-avg_point_per_cluster.at(best_pair_idx2);
   770                     pcl::PointCloud<pcl::PointXYZ>::Ptr planeCloud(
new pcl::PointCloud<pcl::PointXYZ>());
   773                     publishResults(input_surface_cloud, planeCloud, clusters, final_cluster_idx, base, direction+base);
   775                     ROS_INFO(
"No stairs, distance between points to large, or heightDistance between point too small");
   782             iterationCounter=iterationCounter+1;
   785     ROS_INFO(
"No more possible stairs");
   789 void HectorStairDetection::stairsSreachPlaneDetection(pcl::PointCloud<pcl::PointNormal>::Ptr &input_surface_cloud, pcl::PointCloud<pcl::PointXYZI>::Ptr points_on_line, Eigen::Vector3f base, Eigen::Vector3f dir, pcl::PointCloud<pcl::PointXYZ>::Ptr &planeCloud){
   792     Eigen::Vector3f temp=dir.cross(Eigen::Vector3f(0,0,1));
   793     Eigen::Vector3f searchAxes=dir.cross(temp);
   794     searchAxes=searchAxes/searchAxes.squaredNorm();
   796     visualization_msgs::Marker line_list;
   799     line_list.type = visualization_msgs::Marker::LINE_LIST;
   800     line_list.scale.x = 0.1;
   801     line_list.color.r = 1.0;
   802     line_list.color.a = 1.0;
   804     geometry_msgs::Point p;
   809     line_list.points.push_back(p);
   810     p.x = base(0) + searchAxes(0);
   811     p.y = base(1) + searchAxes(1);
   812     p.z = base(2) + searchAxes(2);
   813     line_list.points.push_back(p);
   817     pcl::PointCloud<pcl::PointXYZ>::Ptr searchCloud(
new pcl::PointCloud<pcl::PointXYZ>());
   818     searchCloud->resize(input_surface_cloud->size());
   820     for (
size_t i = 0; i < input_surface_cloud->points.size(); ++i)
   822         const pcl::PointNormal &mls_pt = input_surface_cloud->points[i];
   823         pcl::PointXYZ pt(mls_pt.x, mls_pt.y, mls_pt.z);
   824         searchCloud->push_back(pt);
   828     Eigen::Vector2f xAxes;
   831     Eigen::Vector2f dir2f;
   834     float angleXToStairs=
acos((dir2f.dot(xAxes))/(dir2f.norm()*xAxes.norm()));
   836     pcl::PointCloud<pcl::PointXYZ>::Ptr processCloud_v1(
new pcl::PointCloud<pcl::PointXYZ>());
   837     pcl::PointCloud<pcl::PointXYZ>::Ptr processCloud_v2(
new pcl::PointCloud<pcl::PointXYZ>());
   838     pcl::PassThrough<pcl::PointXYZ> pass;
   839     pass.setInputCloud(searchCloud);
   840     pass.setFilterFieldName(
"z");
   842     pass.filter(*processCloud_v1);
   844     pass.setInputCloud(processCloud_v1);
   845     pass.setFilterFieldName(
"y");
   847     pass.filter(*processCloud_v2);
   849     pass.setInputCloud(processCloud_v2);
   850     pass.setFilterFieldName(
"x");
   852     pass.filter(*searchCloud);
   857     pcl::ModelCoefficients::Ptr coefficients (
new pcl::ModelCoefficients);
   858     pcl::PointIndices::Ptr inliers (
new pcl::PointIndices);
   860     pcl::SACSegmentation<pcl::PointXYZ> seg;
   861     seg.setModelType (pcl::SACMODEL_PERPENDICULAR_PLANE);
   862     seg.setMethodType (pcl::SAC_RANSAC);
   864     seg.setAxis(searchAxes);
   867     seg.setInputCloud (searchCloud);
   868     seg.segment (*inliers, *coefficients);
   870     if (inliers->indices.size () == 0)
   872         PCL_ERROR (
"Could not estimate more planar models for the given dataset.");
   875     ROS_DEBUG(
"extract plane and rest potins");
   876     pcl::ExtractIndices<pcl::PointXYZ> extract;
   877     extract.setInputCloud (searchCloud);
   878     extract.setIndices (inliers);
   879     extract.setNegative(
false);
   880     extract.filter (*planeCloud);
   884     Eigen::Vector3f normal;
   885     normal(0)=coefficients->values[0];
   886     normal(1)=coefficients->values[1];
   887     normal(2)=coefficients->values[2];
   889     Eigen::Vector3f point;
   892     point(2)=-(coefficients->values[3]/coefficients->values[2]);
   894     Eigen::Vector3f normal_0;
   895     normal_0= normal/normal.squaredNorm();
   897     float d_hesse= point.dot(normal_0);
   899     bool isPossiblePlane=
true;
   900     Eigen::Vector3f stairs_point;
   901     for(
int i=0; i<points_on_line->size(); i++){
   902         stairs_point(0)=points_on_line->at(i).x;
   903         stairs_point(1)=points_on_line->at(i).y;
   904         stairs_point(2)=points_on_line->at(i).z;
   906         if(fabs(stairs_point.dot(normal_0)-d_hesse) > 
hesseTresh_){
   907             isPossiblePlane=
false;
   916         planeCloud->resize(0);
   923     for(
int i=0; i<input_cloud->size(); i++){
   924         for(
int j=i; j<input_cloud->size(); j++){
   925             temp_dist= std::sqrt(std::pow(input_cloud->at(i).x-input_cloud->at(j).x, 2)+std::pow(input_cloud->at(i).y-input_cloud->at(j).y, 2)+std::pow(input_cloud->at(i).z-input_cloud->at(j).z, 2));
   926             if(temp_dist>max_dist){
   935     float min_dist=FLT_MAX;
   937     for(
int i=0; i<input_cloud->size(); i++){
   938         for(
int j=i+1; j<input_cloud->size(); j++){
   939             temp_dist= fabs(input_cloud->at(i).z-input_cloud->at(j).z);
   940             if(temp_dist<min_dist){
 void getStairsPositionAndOrientation(Eigen::Vector3f &base, Eigen::Vector3f point, std::string frameID, Eigen::Vector3f &direction, geometry_msgs::PoseStamped &position_and_orientaion)
ros::Publisher line_marker_pub_
ros::Publisher final_stairs_cloud_pub_
virtual ~HectorStairDetection()
ros::Publisher border_of_stairs_pub_
void publish(const boost::shared_ptr< M > &message) const 
void transformTFToEigen(const tf::Transform &t, Eigen::Affine3d &e)
ros::Publisher temp_orginal_pub_
void projectStairsToFloor(Eigen::Vector3f direction, visualization_msgs::MarkerArray &stairs_boarder_marker)
Subscriber subscribe(const std::string &topic, uint32_t queue_size, void(T::*fp)(M), T *obj, const TransportHints &transport_hints=TransportHints())
ros::Publisher cloud_after_plane_detection_debug_pub_
void stairsSreachPlaneDetection(pcl::PointCloud< pcl::PointNormal >::Ptr &input_surface_cloud, pcl::PointCloud< pcl::PointXYZI >::Ptr points_on_line, Eigen::Vector3f base, Eigen::Vector3f dir, pcl::PointCloud< pcl::PointXYZ >::Ptr &planeCloud)
tf::TransformListener listener_
TFSIMD_FORCE_INLINE tfScalar distance(const Vector3 &v) const 
double maxClusterXYDimension_
TFSIMD_FORCE_INLINE const tfScalar & getW() const 
bool refineSurfaceRequired_
int minRequiredPointsOnLine_
void getPreprocessedCloud(pcl::PointCloud< pcl::PointXYZ >::Ptr &input_cloud, pcl::PointCloud< pcl::PointNormal >::Ptr &output_cloud)
ros::Publisher stairs_position_and_orientaion_with_direction_pub_
ros::Publisher possible_stairs_cloud_pub_
double planeSegDistTresh_
ros::Publisher surfaceCloud_pub_debug_
bool param(const std::string ¶m_name, T ¶m_val, const T &default_val) const 
float maxDistBetweenPoints(pcl::PointCloud< pcl::PointXYZI >::Ptr input_cloud)
double maxDistBetweenStairsPoints_
ros::Publisher points_on_line_cloud_debug_
void setEulerZYX(const tfScalar &yaw, const tfScalar &pitch, const tfScalar &roll) __attribute__((deprecated))
Publisher advertise(const std::string &topic, uint32_t queue_size, bool latch=false)
double clusterHeightTresh_
int getZComponent(Eigen::Vector2f directionStairs, Eigen::Vector2f minXminY, Eigen::Vector2f maxXminY, Eigen::Vector2f minXmaxY)
void PclCallback(const sensor_msgs::PointCloud2::ConstPtr &pc_msg)
uint32_t getNumSubscribers() const 
INLINE Rall1d< T, V, S > acos(const Rall1d< T, V, S > &x)
INLINE Rall1d< T, V, S > atan2(const Rall1d< T, V, S > &y, const Rall1d< T, V, S > &x)
float minHightDistBetweenPoints(pcl::PointCloud< pcl::PointXYZI >::Ptr input_cloud)
ros::Publisher temp_after_pass_trough_pub_
INLINE Rall1d< T, V, S > cos(const Rall1d< T, V, S > &arg)
bool customRegionGrowing(const pcl::PointNormal &point_a, const pcl::PointNormal &point_b, float squared_distance)
void getFinalStairsCloud_and_position(std::string frameID, Eigen::Vector3f directionS, pcl::PointCloud< pcl::PointNormal >::Ptr &input_surface_cloud, pcl::PointCloud< pcl::PointXYZ >::Ptr &planeCloud, pcl::IndicesClustersPtr cluster_indices, std::vector< int > final_cluster_idx, pcl::PointCloud< pcl::PointXYZ >::Ptr &final_stairsCloud, visualization_msgs::MarkerArray &stairs_boarder_marker, Eigen::Vector3f base)
INLINE Rall1d< T, V, S > sin(const Rall1d< T, V, S > &arg)
ros::Publisher stairs_position_and_orientaion_pub_
ros::Publisher border_and_orientation_stairs_combined_pub_
ros::Publisher temp_after_voxel_grid_pub_
void toPCL(const ros::Time &stamp, pcl::uint64_t &pcl_stamp)
ros::Publisher temp_after_mls_pub_
void publishResults(pcl::PointCloud< pcl::PointNormal >::Ptr &input_surface_cloud, pcl::PointCloud< pcl::PointXYZ >::Ptr &planeCloud, pcl::IndicesClustersPtr cluster_indices, std::vector< int > final_cluster_idx, Eigen::Vector3f base, Eigen::Vector3f point)
double minHightDistBetweenAllStairsPoints_
double distanceToLineTresh_