diff --git a/cfg/GroundSegmentation.cfg b/cfg/GroundSegmentation.cfg index 3046ecd74bad018534327d76525fdc4cddf092ab..bacd6f6f8d625bf8ee8c8b8416c8b4ae3156d68d 100644 --- a/cfg/GroundSegmentation.cfg +++ b/cfg/GroundSegmentation.cfg @@ -52,20 +52,15 @@ gen.add("elevation_grid_resolution", double_t, 0, "define the coarseness of the gen.add("angle_reduction_factor", double_t, 0, "To make the search area dependent to the data sparseness", 2.0, -100.0, 100.0); gen.add("search_limit_in_shadow_area", double_t, 0, "minimum ROI area = 4*search_limit_in_shadow_area squared", 3.0, 0.0, 1000.0); -gen.add("distance_to_virtual_references_in_shadow_area", double_t, 0, "distance from origin to the virtual ground reference points created under the shadow area", 2.75, 0.0, 1000.0); gen.add("propagation_z_additive_noise_per_meter", double_t, 0, "Noise added to new ground references scaled by the range", 0.1, 0.0, 1000.0); gen.add("propagation_additive_noise_deg_per_meter", double_t, 0, "Noise added to new ground references scaled by the range", 0.1, 0.0, 1000.0); gen.add("z_observation_std_dev", double_t, 0, "Measurement std_dev", 0.1, 0.0, 1000.0); -gen.add("robot_width", double_t, 0, "used to discard edges", 1.05, 0.0, 3.0); gen.add("robot_height", double_t, 0, "used to discard edges", 1.20, 0.0, 3.0); -gen.add("safety_margin", double_t, 0, "used to discard edges", 0.15, 0.0, 1.0); gen.add("max_traversable_obstacle_height", double_t, 0, "used to discard edges", 0.15, 0.01, 0.99); gen.add("max_slope_abs", double_t, 0, "used to discard edges", 0.3, 0.01, 0.99); -gen.add("flag_generate_discontinuity_obstacles_for_real_obstacles", bool_t, 0, "used to display obstacles perceived", True); -gen.add("flag_connect_vertices_even_if_there_are_obstacles", bool_t, 0, "used to avoid discarding edges", False); gen.add("measure_performance", bool_t, 0, "to measure times of inner functions", False); gen.add("show_dense_reconstruction", bool_t, 0, "creates dense pointcloud with ground predictions", False); diff --git a/include/ground_segmentation_alg.h b/include/ground_segmentation_alg.h index da73383be2be29b15bb7a78a1f301183257e79f5..332add5fefd4ce87f91a212c4c9dca66d0c5a70d 100644 --- a/include/ground_segmentation_alg.h +++ b/include/ground_segmentation_alg.h @@ -139,7 +139,7 @@ public: * * \param level level in which the update is taken place */ - void config_update(Config& config, uint32_t level = 0); + void config_update(Config &config, uint32_t level = 0); // here define all two_segmented_inputs_vehicle_detector_alg interface methods to retrieve and set // the driver parameters @@ -154,10 +154,9 @@ public: void showPerformanceStatistics(void); - void segmentGround(pcl::PointCloud<pcl::PointXYZRGBNormal>& velodyne_pcl_cloud, - pcl::PointCloud<pcl::PointXYZRGBNormal>& ground_references_pcl_cloud, - visualization_msgs::MarkerArray& local_goals, iri_ground_segmentation::edges_array& edges_array, - std_msgs::Header common_header); + void segmentGround(const std_msgs::Header common_header, pcl::PointCloud<pcl::PointXYZRGBNormal> &lidar_pcl_cloud, + pcl::PointCloud<pcl::PointXYZRGBNormal> &roadmap_vertices_pcl_cloud, iri_ground_segmentation::edges_array &edges_array, + pcl::PointCloud<pcl::PointXYZRGBNormal> &ground_dense_reconstruction_pcl_cloud, visualization_msgs::MarkerArray &roadmap_markers); }; #endif diff --git a/include/ground_segmentation_alg_node.h b/include/ground_segmentation_alg_node.h index 365966ebd2fb028afa9ec2855a1a4bf0da3931b9..66ce27be4db47475aa0348c4e5107aaaf3fc2983 100644 --- a/include/ground_segmentation_alg_node.h +++ b/include/ground_segmentation_alg_node.h @@ -50,9 +50,11 @@ private: ros::Publisher roadmap_markers_publisher_; visualization_msgs::MarkerArray roadmap_MarkerArray_msg_; - ros::Publisher roadmap_nodes_publisher_; - sensor_msgs::PointCloud2 roadmap_nodes_ros_cloud_; - pcl::PointCloud<pcl::PointXYZRGBNormal> roadmap_nodes_pcl_cloud_; + ros::Publisher ground_dense_reconstruction_publisher_; + sensor_msgs::PointCloud2 ground_dense_reconstruction_ros_cloud_; + pcl::PointCloud<pcl::PointXYZRGBNormal> ground_dense_reconstruction_pcl_cloud_; + + pcl::PointCloud<pcl::PointXYZRGBNormal> roadmap_vertices_pcl_cloud_; ros::Publisher roadmap_edges_publisher_; iri_ground_segmentation::edges_array roadmap_edges_array_; @@ -60,7 +62,6 @@ private: ros::Publisher roadmap_vertices_publisher_; iri_ground_segmentation::vertices_array roadmap_vertices_array_; - // Publishers for integration with navigation stack ros::Publisher obstacle_points_publisher_; sensor_msgs::PointCloud2 obstacle_points_ros_cloud_; pcl::PointCloud<pcl::PointXYZ> obstacle_points_pcl_cloud_; @@ -69,21 +70,11 @@ private: sensor_msgs::PointCloud2 ground_points_ros_cloud_; pcl::PointCloud<pcl::PointXYZ> ground_points_pcl_cloud_; - ros::Publisher dicontinuity_obstacles_publisher_; - sensor_msgs::PointCloud2 dicontinuity_obstacles_ros_cloud_; - pcl::PointCloud<pcl::PointXYZ> dicontinuity_obstacles_pcl_cloud_; - - ros::Publisher exploration_frontier_points_publisher_; - sensor_msgs::PointCloud2 exploration_frontier_points_ros_cloud_; - pcl::PointCloud<pcl::PointXYZ> exploration_frontier_points_pcl_cloud_; - // [subscriber attributes] // Variables for copying the callbacks inputs sensor_msgs::PointCloud2 lidar_ros_cloud_; pcl::PointCloud<pcl::PointXYZRGBNormal> lidar_pcl_cloud_; - - ros::Subscriber lidar_subscriber_; void cb_lidar(const sensor_msgs::PointCloud2::ConstPtr &msg); diff --git a/src/ground_segmentation_alg.cpp b/src/ground_segmentation_alg.cpp index e8edffc24ac36e95786ef03d121d00b3cd58befc..7db306481f4678567b125e8bd86d6a92c3df07ef 100644 --- a/src/ground_segmentation_alg.cpp +++ b/src/ground_segmentation_alg.cpp @@ -29,11 +29,12 @@ void GroundSegmentationAlgorithm::showPerformanceStatistics(void) performance_supervisor_ptr_->printStatistics(); } -void GroundSegmentationAlgorithm::segmentGround(pcl::PointCloud<pcl::PointXYZRGBNormal> &velodyne_pcl_cloud, - pcl::PointCloud<pcl::PointXYZRGBNormal> &ground_references_pcl_cloud, - visualization_msgs::MarkerArray &local_goals, - iri_ground_segmentation::edges_array &edges_array, - std_msgs::Header common_header) +void GroundSegmentationAlgorithm::segmentGround( + const std_msgs::Header common_header, pcl::PointCloud<pcl::PointXYZRGBNormal> &lidar_pcl_cloud, + pcl::PointCloud<pcl::PointXYZRGBNormal> &roadmap_vertices_pcl_cloud, + iri_ground_segmentation::edges_array &edges_array, + pcl::PointCloud<pcl::PointXYZRGBNormal> &ground_dense_reconstruction_pcl_cloud, + visualization_msgs::MarkerArray &roadmap_markers) { CFunctionMonitor performance_monitor("segmentGround", performance_supervisor_ptr_); std::vector<std::vector<int>> edges(100000); @@ -41,19 +42,23 @@ void GroundSegmentationAlgorithm::segmentGround(pcl::PointCloud<pcl::PointXYZRGB //std::cout << "Calling to processor_.groundSegmentation!" << std::endl; - processor_.groundSegmentation(lidar_configuration_, filtering_configuration_, velodyne_pcl_cloud, - ground_references_pcl_cloud, edges, discarded_edges); + processor_.groundSegmentation(lidar_configuration_, filtering_configuration_, lidar_pcl_cloud, + roadmap_vertices_pcl_cloud, edges, discarded_edges, + ground_dense_reconstruction_pcl_cloud); - //std::cout << "Number of vertices = " << ground_references_pcl_cloud.points.size(); + //std::cout << "Number of vertices = " << roadmap_vertices_pcl_cloud.points.size(); //std::cout << "Number of edge vectors = " << edges.size(); + // Now we create the markers for visualization and change the format of edges to implement the interface + // between the library and the node + int vertex_id = 0; int discarded_vertex_id = 0; int edge_id = 0; int discarded_edge_id = 0; - for (pcl::PointCloud<pcl::PointXYZRGBNormal>::iterator i = ground_references_pcl_cloud.begin(); - i != ground_references_pcl_cloud.end(); ++i) + for (pcl::PointCloud<pcl::PointXYZRGBNormal>::iterator i = roadmap_vertices_pcl_cloud.begin(); + i != roadmap_vertices_pcl_cloud.end(); ++i) { pcl::PointXYZRGBNormal ground_ref = *i; @@ -87,7 +92,7 @@ void GroundSegmentationAlgorithm::segmentGround(pcl::PointCloud<pcl::PointXYZRGB vertex.pose.position.x = ground_ref.x; vertex.pose.position.y = ground_ref.y; - vertex.pose.position.z = ground_ref.z; + vertex.pose.position.z = ground_ref.z + 0.15 / 2.0; vertex.pose.orientation.x = 0.0; vertex.pose.orientation.y = 0.0; @@ -96,14 +101,14 @@ void GroundSegmentationAlgorithm::segmentGround(pcl::PointCloud<pcl::PointXYZRGB vertex.scale.x = 0.15; vertex.scale.y = 0.15; - vertex.scale.z = 0.30; + vertex.scale.z = 0.15; vertex.color.a = 1.0; // Don't forget to set the alpha! - if (ground_ref.data_n[GRND_REF_DATA_N_2_VERTEX_CLASS] < VERTEX_NOT_CONNECTED_TO_ROOT) + if (ground_ref.data_n[GRND_REF_DATA_N_2_VERTEX_CLASS] == VERTEX_CONNECTED_TO_ROOT) { - vertex.color.r = 1.0; - vertex.color.g = 0.66; - vertex.color.b = 0.0; + vertex.color.r = 1.0; + vertex.color.g = 0.66; + vertex.color.b = 0.0; } else { @@ -112,9 +117,8 @@ void GroundSegmentationAlgorithm::segmentGround(pcl::PointCloud<pcl::PointXYZRGB vertex.color.b = 0.0; } vertex.lifetime = ros::Duration(0.1); - //vertex.frame_locked = true; - local_goals.markers.push_back(vertex); + roadmap_markers.markers.push_back(vertex); iri_ground_segmentation::edges edges_temp; for (std::vector<int>::iterator e = edges[ground_ref.data_n[GRND_REF_DATA_N_3_ORIGINAL_INDEX]].begin(); @@ -126,7 +130,7 @@ void GroundSegmentationAlgorithm::segmentGround(pcl::PointCloud<pcl::PointXYZRGB edge.action = visualization_msgs::Marker::ADD; edge.header = common_header; - if (ground_ref.data_n[GRND_REF_DATA_N_2_VERTEX_CLASS] < VERTEX_NOT_CONNECTED_TO_ROOT) + if (ground_ref.data_n[GRND_REF_DATA_N_2_VERTEX_CLASS] == VERTEX_CONNECTED_TO_ROOT) { edge.ns = "edges"; edge.id = edge_id++; @@ -145,8 +149,7 @@ void GroundSegmentationAlgorithm::segmentGround(pcl::PointCloud<pcl::PointXYZRGB p.z = ground_ref.z; edge.points.push_back(p); - //pcl::PointXYZRGBNormal parent_ground_ref = ground_references_pcl_cloud.points[ground_ref.data_n[3]]; //GRND_REF_DATA_N_3_PARENT_INDEX - pcl::PointXYZRGBNormal child_ground_ref = ground_references_pcl_cloud.points[*e]; + pcl::PointXYZRGBNormal child_ground_ref = roadmap_vertices_pcl_cloud.points[*e]; p.x = child_ground_ref.x; p.y = child_ground_ref.y; p.z = child_ground_ref.z; @@ -160,7 +163,7 @@ void GroundSegmentationAlgorithm::segmentGround(pcl::PointCloud<pcl::PointXYZRGB edge.pose.orientation.w = 1.0; edge.color.a = 0.7; // Don't forget to set the alpha! - if (ground_ref.data_n[GRND_REF_DATA_N_2_VERTEX_CLASS] < VERTEX_NOT_CONNECTED_TO_ROOT) + if (ground_ref.data_n[GRND_REF_DATA_N_2_VERTEX_CLASS] == VERTEX_CONNECTED_TO_ROOT) { edge.color.r = 0.8; edge.color.g = 0.53; @@ -168,15 +171,15 @@ void GroundSegmentationAlgorithm::segmentGround(pcl::PointCloud<pcl::PointXYZRGB } else { - edge.color.r = R_CLASS_VIRTUAL_OBSTACLE_NOT_CONNECTED_TO_ROOT / 255.0; - edge.color.g = G_CLASS_VIRTUAL_OBSTACLE_NOT_CONNECTED_TO_ROOT / 255.0; - edge.color.b = B_CLASS_VIRTUAL_OBSTACLE_NOT_CONNECTED_TO_ROOT / 255.0; + edge.color.r = R_VERTEX_NOT_CONNECTED_TO_ROOT / 255.0; + edge.color.g = G_VERTEX_NOT_CONNECTED_TO_ROOT / 255.0; + edge.color.b = B_VERTEX_NOT_CONNECTED_TO_ROOT / 255.0; } edge.lifetime = ros::Duration(0.1); - //edge.frame_locked = true; - local_goals.markers.push_back(edge); + roadmap_markers.markers.push_back(edge); } + edges_array.edges_array.push_back(edges_temp); // We create markers for the discarded edges @@ -199,7 +202,7 @@ void GroundSegmentationAlgorithm::segmentGround(pcl::PointCloud<pcl::PointXYZRGB discarded_edge.points.push_back(p); pcl::PointXYZRGBNormal child_ground_ref = - ground_references_pcl_cloud.points[discarded_edge_index_and_class.vertex_index]; + roadmap_vertices_pcl_cloud.points[discarded_edge_index_and_class.vertex_index]; p.x = child_ground_ref.x; p.y = child_ground_ref.y; p.z = child_ground_ref.z; @@ -215,26 +218,26 @@ void GroundSegmentationAlgorithm::segmentGround(pcl::PointCloud<pcl::PointXYZRGB discarded_edge.color.a = 0.7; switch (discarded_edge_index_and_class.edge_class) { - case CLASS_VIRTUAL_OBSTACLE_TOO_MUCH_UNCERTAINTY: + case CLASS_EDGE_DISCARDED_TOO_MUCH_UNCERTAINTY: //std::cout << "Coloring edge too much uncertainty! class = " << discarded_edge_index_and_class.edge_class // << std::endl; - discarded_edge.color.r = (float)R_CLASS_VIRTUAL_OBSTACLE_TOO_MUCH_UNCERTAINTY / 255.0; - discarded_edge.color.g = (float)G_CLASS_VIRTUAL_OBSTACLE_TOO_MUCH_UNCERTAINTY / 255.0; - discarded_edge.color.b = (float)B_CLASS_VIRTUAL_OBSTACLE_TOO_MUCH_UNCERTAINTY / 255.0; + discarded_edge.color.r = (float)R_EDGE_DISCARDED_TOO_MUCH_UNCERTAINTY / 255.0; + discarded_edge.color.g = (float)G_EDGE_DISCARDED_TOO_MUCH_UNCERTAINTY / 255.0; + discarded_edge.color.b = (float)B_EDGE_DISCARDED_TOO_MUCH_UNCERTAINTY / 255.0; break; - case CLASS_VIRTUAL_OBSTACLE_TOO_MUCH_MAHALANOBIS_DISTANCE: + case CLASS_EDGE_DISCARDED_TOO_MUCH_MAHALANOBIS_DISTANCE: //std::cout << "Coloring edge too much Mahalanobis distance! class = " // << discarded_edge_index_and_class.edge_class << std::endl; - discarded_edge.color.r = (float)R_CLASS_VIRTUAL_OBSTACLE_TOO_MUCH_MAHALANOBIS_DISTANCE / 255.0; - discarded_edge.color.g = (float)G_CLASS_VIRTUAL_OBSTACLE_TOO_MUCH_MAHALANOBIS_DISTANCE / 255.0; - discarded_edge.color.b = (float)B_CLASS_VIRTUAL_OBSTACLE_TOO_MUCH_MAHALANOBIS_DISTANCE / 255.0; + discarded_edge.color.r = (float)R_EDGE_DISCARDED_TOO_MUCH_MAHALANOBIS_DISTANCE / 255.0; + discarded_edge.color.g = (float)G_EDGE_DISCARDED_TOO_MUCH_MAHALANOBIS_DISTANCE / 255.0; + discarded_edge.color.b = (float)B_EDGE_DISCARDED_TOO_MUCH_MAHALANOBIS_DISTANCE / 255.0; break; - case CLASS_VIRTUAL_OBSTACLE_TOO_MUCH_SLOPE: + case CLASS_EDGE_DISCARDED_TOO_MUCH_SLOPE: //std::cout << "Coloring edge too much slope! class = " << discarded_edge_index_and_class.edge_class // << std::endl; - discarded_edge.color.r = (float)R_CLASS_VIRTUAL_OBSTACLE_TOO_MUCH_SLOPE / 255.0; - discarded_edge.color.g = (float)G_CLASS_VIRTUAL_OBSTACLE_TOO_MUCH_SLOPE / 255.0; - discarded_edge.color.b = (float)B_CLASS_VIRTUAL_OBSTACLE_TOO_MUCH_SLOPE / 255.0; + discarded_edge.color.r = (float)R_EDGE_DISCARDED_TOO_MUCH_SLOPE / 255.0; + discarded_edge.color.g = (float)G_EDGE_DISCARDED_TOO_MUCH_SLOPE / 255.0; + discarded_edge.color.b = (float)B_EDGE_DISCARDED_TOO_MUCH_SLOPE / 255.0; break; default: //std::cout << "WARNING! Discarded edge class not known!! class = " << discarded_edge_index_and_class.edge_class @@ -245,7 +248,7 @@ void GroundSegmentationAlgorithm::segmentGround(pcl::PointCloud<pcl::PointXYZRGB break; } discarded_edge.lifetime = ros::Duration(0.1); - local_goals.markers.push_back(discarded_edge); + roadmap_markers.markers.push_back(discarded_edge); } } diff --git a/src/ground_segmentation_alg_node.cpp b/src/ground_segmentation_alg_node.cpp index 05bd58e32bfab5d2f7a5662e25969e8f89a00f70..c649e31743ab214ce6f9ca1962106771268902aa 100644 --- a/src/ground_segmentation_alg_node.cpp +++ b/src/ground_segmentation_alg_node.cpp @@ -42,13 +42,15 @@ GroundSegmentationAlgNode::GroundSegmentationAlgNode(void) : this->alg_.filtering_configuration_.pitch_initial_std_dev = tan(config_.initial_angular_std_dev_deg * M_PI / 180.0); } - if (!this->private_node_handle_.getParam("ground_reference_search_resolution_deg", this->config_.ground_reference_search_resolution_deg)) + if (!this->private_node_handle_.getParam("ground_reference_search_resolution_deg", + this->config_.ground_reference_search_resolution_deg)) { - ROS_WARN("GroundSegmentationAlgNode::GroundSegmentationAlgNode: param 'ground_reference_search_resolution_deg' not found"); + ROS_WARN( + "GroundSegmentationAlgNode::GroundSegmentationAlgNode: param 'ground_reference_search_resolution_deg' not found"); } else - this->alg_.filtering_configuration_.ground_reference_search_resolution = config_.ground_reference_search_resolution_deg - * M_PI / 180.0; + this->alg_.filtering_configuration_.ground_reference_search_resolution = + config_.ground_reference_search_resolution_deg * M_PI / 180.0; if (!this->private_node_handle_.getParam("elevation_grid_resolution", this->config_.elevation_grid_resolution)) { @@ -71,24 +73,20 @@ GroundSegmentationAlgNode::GroundSegmentationAlgNode(void) : else this->alg_.filtering_configuration_.search_limit_in_shadow_area = config_.search_limit_in_shadow_area; - if (!this->private_node_handle_.getParam("distance_to_virtual_references_in_shadow_area", this->config_.distance_to_virtual_references_in_shadow_area)) - { - ROS_WARN("GroundSegmentationAlgNode::GroundSegmentationAlgNode: param 'distance_to_virtual_references_in_shadow_area' not found"); - } - else - this->alg_.filtering_configuration_.distance_to_virtual_references_in_shadow_area = - config_.distance_to_virtual_references_in_shadow_area; - - if (!this->private_node_handle_.getParam("propagation_z_additive_noise_per_meter", this->config_.propagation_z_additive_noise_per_meter)) + if (!this->private_node_handle_.getParam("propagation_z_additive_noise_per_meter", + this->config_.propagation_z_additive_noise_per_meter)) { - ROS_WARN("GroundSegmentationAlgNode::GroundSegmentationAlgNode: param 'propagation_z_additive_noise_per_meter' not found"); + ROS_WARN( + "GroundSegmentationAlgNode::GroundSegmentationAlgNode: param 'propagation_z_additive_noise_per_meter' not found"); } else this->alg_.filtering_configuration_.propagation_z_additive_noise = config_.propagation_z_additive_noise_per_meter; - if (!this->private_node_handle_.getParam("propagation_additive_noise_deg_per_meter", this->config_.propagation_additive_noise_deg_per_meter)) + if (!this->private_node_handle_.getParam("propagation_additive_noise_deg_per_meter", + this->config_.propagation_additive_noise_deg_per_meter)) { - ROS_WARN("GroundSegmentationAlgNode::GroundSegmentationAlgNode: param 'propagation_additive_noise_deg_per_meter' not found"); + ROS_WARN( + "GroundSegmentationAlgNode::GroundSegmentationAlgNode: param 'propagation_additive_noise_deg_per_meter' not found"); } else this->alg_.filtering_configuration_.propagation_additive_noise = config_.propagation_additive_noise_deg_per_meter @@ -101,12 +99,6 @@ GroundSegmentationAlgNode::GroundSegmentationAlgNode(void) : else this->alg_.filtering_configuration_.z_observation_std_dev = config_.z_observation_std_dev; - if (!this->private_node_handle_.getParam("robot_width", this->config_.robot_width)) - { - ROS_WARN("GroundSegmentationAlgNode::GroundSegmentationAlgNode: param 'robot_width' not found"); - } - else - this->alg_.filtering_configuration_.robot_width = config_.robot_width; if (!this->private_node_handle_.getParam("robot_height", this->config_.robot_height)) { @@ -115,13 +107,6 @@ GroundSegmentationAlgNode::GroundSegmentationAlgNode(void) : else this->alg_.filtering_configuration_.robot_height = config_.robot_height; - if (!this->private_node_handle_.getParam("safety_margin", this->config_.safety_margin)) - { - ROS_WARN("GroundSegmentationAlgNode::GroundSegmentationAlgNode: param 'safety_margin' not found"); - } - else - this->alg_.filtering_configuration_.safety_margin = config_.safety_margin; - if (!this->private_node_handle_.getParam("max_slope_abs", this->config_.max_slope_abs)) { ROS_WARN("GroundSegmentationAlgNode::GroundSegmentationAlgNode: param 'max_slope_abs' not found"); @@ -129,27 +114,14 @@ GroundSegmentationAlgNode::GroundSegmentationAlgNode(void) : else this->alg_.filtering_configuration_.max_slope_abs = config_.max_slope_abs; - if (!this->private_node_handle_.getParam("max_traversable_obstacle_height", this->config_.max_traversable_obstacle_height)) + if (!this->private_node_handle_.getParam("max_traversable_obstacle_height", + this->config_.max_traversable_obstacle_height)) { ROS_WARN("GroundSegmentationAlgNode::GroundSegmentationAlgNode: param 'max_traversable_obstacle_height' not found"); } else this->alg_.filtering_configuration_.max_traversable_obstacle_height = config_.max_traversable_obstacle_height; - if (!this->private_node_handle_.getParam("flag_generate_discontinuity_obstacles_for_real_obstacles", this->config_.flag_generate_discontinuity_obstacles_for_real_obstacles)) - { - ROS_WARN("GroundSegmentationAlgNode::GroundSegmentationAlgNode: param 'flag_generate_discontinuity_obstacles_for_real_obstacles' not found"); - } - else - this->alg_.filtering_configuration_.flag_generate_discontinuity_obstacles_for_real_obstacles = config_.flag_generate_discontinuity_obstacles_for_real_obstacles; - - if (!this->private_node_handle_.getParam("flag_connect_vertices_even_if_there_are_obstacles", this->config_.flag_connect_vertices_even_if_there_are_obstacles)) - { - ROS_WARN("GroundSegmentationAlgNode::GroundSegmentationAlgNode: param 'flag_connect_vertices_even_if_there_are_obstacles' not found"); - } - else - this->alg_.filtering_configuration_.flag_connect_vertices_even_if_there_are_obstacles = config_.flag_connect_vertices_even_if_there_are_obstacles; - if (!this->private_node_handle_.getParam("measure_performance", this->config_.measure_performance)) { ROS_WARN("GroundSegmentationAlgNode::GroundSegmentationAlgNode: param 'measure_performance' not found"); @@ -164,41 +136,38 @@ GroundSegmentationAlgNode::GroundSegmentationAlgNode(void) : else this->alg_.filtering_configuration_.show_dense_reconstruction = config_.show_dense_reconstruction; - flag_new_lidar_data_ = false; + // [init subscribers] + this->lidar_subscriber_ = this->public_node_handle_.subscribe("/lidar_points_extended_structure", 1, + &GroundSegmentationAlgNode::cb_lidar, this); // [init publishers] + + //////// Segmentation outputs ///////////////////// + // This pointcloud has several point classes represented with different colors this->lidar_points_ground_segmented_publisher_ = this->private_node_handle_.advertise < sensor_msgs::PointCloud2 > ("lidar_points_ground_segmented", 1); - this->roadmap_markers_publisher_ = this->private_node_handle_.advertise < visualization_msgs::MarkerArray - > ("roadmap_markers", 1); + this->obstacle_points_publisher_ = this->private_node_handle_.advertise < sensor_msgs::PointCloud2 + > ("obstacle_points", 1); - this->roadmap_nodes_publisher_ = this->private_node_handle_.advertise < sensor_msgs::PointCloud2 - > ("roadmap_nodes", 1); + this->ground_points_publisher_ = this->private_node_handle_.advertise < sensor_msgs::PointCloud2 + > ("ground_points", 1); + //////// Roadmap outputs ////////////////////////// this->roadmap_edges_publisher_ = this->private_node_handle_.advertise < iri_ground_segmentation::edges_array > ("roadmap_edges", 1); this->roadmap_vertices_publisher_ = this->private_node_handle_.advertise < iri_ground_segmentation::vertices_array > ("roadmap_vertices", 1); - // Outputs for integration with navigation stack - this->obstacle_points_publisher_ = this->private_node_handle_.advertise < sensor_msgs::PointCloud2 - > ("obstacle_points", 1); - - this->ground_points_publisher_ = this->private_node_handle_.advertise < sensor_msgs::PointCloud2 - > ("ground_points", 1); - - this->dicontinuity_obstacles_publisher_ = this->private_node_handle_.advertise < sensor_msgs::PointCloud2 - > ("discontinuity_obstacle_points", 1); - - this->exploration_frontier_points_publisher_ = this->private_node_handle_.advertise < sensor_msgs::PointCloud2 - > ("exploration_frontier_points", 1); + //////// Visualization outputs /////////////////// + this->roadmap_markers_publisher_ = this->private_node_handle_.advertise < visualization_msgs::MarkerArray + > ("roadmap_markers", 1); - // [init subscribers] - this->lidar_subscriber_ = this->public_node_handle_.subscribe("/lidar_points_extended_structure", 1, - &GroundSegmentationAlgNode::cb_lidar, this); + this->ground_dense_reconstruction_publisher_ = this->private_node_handle_.advertise < sensor_msgs::PointCloud2 + > ("ground_dense_reconstruction", 1); + flag_new_lidar_data_ = false; pthread_mutex_init(&this->mutex_, NULL); // [init services] } @@ -294,7 +263,6 @@ void GroundSegmentationAlgNode::storeHeaderForSync(void) void GroundSegmentationAlgNode::convertInputsToSuitableFormats(void) { //std::cout << "GroundSegmentationAlgNode::convertInputsToSuitableFormats..." << std::endl; - //std::cout << " 1) rosPointCloudtoPCLPointCloud with lidar_ros_cloud_..." << std::endl; this->rosPointCloudtoPCLPointCloud(lidar_ros_cloud_, lidar_pcl_cloud_); flag_new_lidar_data_ = false; } @@ -318,14 +286,7 @@ void GroundSegmentationAlgNode::splitSegmentedCloudInOnePerClass(void) case CLASS_OBSTACLE: obstacle_points_pcl_cloud_.push_back(regular_point); break; - case CLASS_DISCONTINUITY: - dicontinuity_obstacles_pcl_cloud_.push_back(regular_point); - break; - case CLASS_FRONTIER: - exploration_frontier_points_pcl_cloud_.push_back(regular_point); - break; default: - //if ((int)std::floor(classified_point.data_c[DATA_C_1_ID_CLASS]) != CLASS_UNKNOWN) //TODO: See if it is needed to add more outputs // std::cout << "GroundSegmentationAlgNode::splitSegmentedCloudInOnePerClass -> unexpected class value of: " // << classified_point.data_c[DATA_C_1_ID_CLASS] << std::endl; break; @@ -340,51 +301,52 @@ void GroundSegmentationAlgNode::convertOutputsToSuitableFormats(void) this->PCLPointCloudToRosPointCloud(lidar_pcl_cloud_, lidar_points_ground_segmented_ros_cloud_); - this->PCLPointCloudToRosPointCloud(roadmap_nodes_pcl_cloud_, roadmap_nodes_ros_cloud_); + this->PCLPointCloudToRosPointCloud(ground_dense_reconstruction_pcl_cloud_, ground_dense_reconstruction_ros_cloud_); - this->nodesPCLPointCloudToVerticesArray(roadmap_nodes_pcl_cloud_, roadmap_vertices_array_); + this->nodesPCLPointCloudToVerticesArray(roadmap_vertices_pcl_cloud_, roadmap_vertices_array_); - // Outputs for integration with navigation stack this->splitSegmentedCloudInOnePerClass(); this->PCLPointCloudToRosPointCloud(obstacle_points_pcl_cloud_, obstacle_points_ros_cloud_); this->PCLPointCloudToRosPointCloud(ground_points_pcl_cloud_, ground_points_ros_cloud_); - - this->PCLPointCloudToRosPointCloud(dicontinuity_obstacles_pcl_cloud_, dicontinuity_obstacles_ros_cloud_); - - this->PCLPointCloudToRosPointCloud(exploration_frontier_points_pcl_cloud_, exploration_frontier_points_ros_cloud_); } void GroundSegmentationAlgNode::publishAll(void) { //std::cout << "Starting GroundSegmentationAlgNode::publishAll.." << std::endl; + + // Segmentation topics this->lidar_points_ground_segmented_publisher_.publish(this->lidar_points_ground_segmented_ros_cloud_); - this->roadmap_nodes_publisher_.publish(this->roadmap_nodes_ros_cloud_); - this->roadmap_markers_publisher_.publish(this->roadmap_MarkerArray_msg_); + this->obstacle_points_publisher_.publish(this->obstacle_points_ros_cloud_); + this->ground_points_publisher_.publish(this->ground_points_ros_cloud_); + + // Roadmap topics this->roadmap_edges_publisher_.publish(this->roadmap_edges_array_); this->roadmap_vertices_publisher_.publish(this->roadmap_vertices_array_); - // Publishers for integration with navigation stack - this->obstacle_points_publisher_.publish(this->obstacle_points_ros_cloud_); - this->ground_points_publisher_.publish(this->ground_points_ros_cloud_); - this->dicontinuity_obstacles_publisher_.publish(this->dicontinuity_obstacles_ros_cloud_); - this->exploration_frontier_points_publisher_.publish(this->exploration_frontier_points_ros_cloud_); + // Visualization topics + this->ground_dense_reconstruction_publisher_.publish(this->ground_dense_reconstruction_ros_cloud_); + this->roadmap_markers_publisher_.publish(this->roadmap_MarkerArray_msg_); } void GroundSegmentationAlgNode::prepareForNextIteration(void) { + // Segmentation lidar_pcl_cloud_.clear(); - roadmap_nodes_pcl_cloud_.clear(); - roadmap_MarkerArray_msg_.markers.clear(); + obstacle_points_pcl_cloud_.clear(); + ground_points_pcl_cloud_.clear(); + + // Roadmap roadmap_edges_array_.edges_array.clear(); roadmap_vertices_array_.vertices_array.clear(); - // Pointclouds for integration with navigation stack - obstacle_points_pcl_cloud_.clear(); - ground_points_pcl_cloud_.clear(); - dicontinuity_obstacles_pcl_cloud_.clear(); - exploration_frontier_points_pcl_cloud_.clear(); + // Visualization + ground_dense_reconstruction_pcl_cloud_.clear(); + roadmap_MarkerArray_msg_.markers.clear(); + + // Aux pointcloud to store vertices information (internally vertices are organized in a pointcloud) + roadmap_vertices_pcl_cloud_.clear(); } void GroundSegmentationAlgNode::showPerformanceStatistics(void) @@ -409,8 +371,8 @@ void GroundSegmentationAlgNode::mainNodeThread(void) this->mutex_exit(); // Then we can free the callback - this->alg_.segmentGround(lidar_pcl_cloud_, roadmap_nodes_pcl_cloud_, roadmap_MarkerArray_msg_, roadmap_edges_array_, - common_header_); + this->alg_.segmentGround(common_header_, lidar_pcl_cloud_, roadmap_vertices_pcl_cloud_, roadmap_edges_array_, + ground_dense_reconstruction_pcl_cloud_, roadmap_MarkerArray_msg_); this->convertOutputsToSuitableFormats(); this->publishAll(); @@ -427,8 +389,8 @@ void GroundSegmentationAlgNode::cb_lidar(const sensor_msgs::PointCloud2::ConstPt assert(msg != NULL && "Null pointer!!! in function cb_lidar!"); this->mutex_enter(); - flag_new_lidar_data_ = true; // This flag is shared with the main node thread, as the lidar_ros_cloud, but the latter is protected - // by the flag, so it is not required to use the mutex + flag_new_lidar_data_ = true; // This flag is shared with the main node thread, as the lidar_ros_cloud, but the latter is protected + // by the flag, so it is not required to use the mutex this->mutex_exit(); } @@ -470,22 +432,16 @@ void GroundSegmentationAlgNode::node_config_update(Config &config, uint32_t leve this->alg_.filtering_configuration_.angle_reduction_factor = config.angle_reduction_factor; this->alg_.filtering_configuration_.search_limit_in_shadow_area = config.search_limit_in_shadow_area; - this->alg_.filtering_configuration_.distance_to_virtual_references_in_shadow_area = - config.distance_to_virtual_references_in_shadow_area; this->alg_.filtering_configuration_.propagation_z_additive_noise = config.propagation_z_additive_noise_per_meter; this->alg_.filtering_configuration_.propagation_additive_noise = config.propagation_additive_noise_deg_per_meter * M_PI / 180.0; this->alg_.filtering_configuration_.z_observation_std_dev = config.z_observation_std_dev; - this->alg_.filtering_configuration_.robot_width = config.robot_width; this->alg_.filtering_configuration_.robot_height = config.robot_height; - this->alg_.filtering_configuration_.safety_margin = config.safety_margin; this->alg_.filtering_configuration_.max_traversable_obstacle_height = config_.max_traversable_obstacle_height; this->alg_.filtering_configuration_.max_slope_abs = config.max_slope_abs; - this->alg_.filtering_configuration_.flag_generate_discontinuity_obstacles_for_real_obstacles = config.flag_generate_discontinuity_obstacles_for_real_obstacles; - this->alg_.filtering_configuration_.flag_connect_vertices_even_if_there_are_obstacles = config.flag_connect_vertices_even_if_there_are_obstacles; this->alg_.filtering_configuration_.measure_performance = config.measure_performance; this->alg_.filtering_configuration_.show_dense_reconstruction = config.show_dense_reconstruction; @@ -517,9 +473,6 @@ void GroundSegmentationAlgNode::node_config_update(Config &config, uint32_t leve std::cout << "search_limit_in_shadow_area = " << this->alg_.filtering_configuration_.search_limit_in_shadow_area << std::endl; - std::cout << "distance_to_virtual_references_in_shadow_area = " - << this->alg_.filtering_configuration_.distance_to_virtual_references_in_shadow_area << std::endl; - std::cout << "propagation_z_additive_noise in m/m = " << this->alg_.filtering_configuration_.propagation_z_additive_noise << std::endl; std::cout << "propagation_additive_noise in deg/m = " @@ -527,18 +480,11 @@ void GroundSegmentationAlgNode::node_config_update(Config &config, uint32_t leve std::cout << "z_observation_std_dev = " << this->alg_.filtering_configuration_.z_observation_std_dev << std::endl; - std::cout << "robot_width = " << this->alg_.filtering_configuration_.robot_width << std::endl; std::cout << "robot_height = " << this->alg_.filtering_configuration_.robot_height << std::endl; - std::cout << "safety_margin = " << this->alg_.filtering_configuration_.safety_margin << std::endl; std::cout << "max_traversable_obstacle_height = " << this->alg_.filtering_configuration_.max_traversable_obstacle_height << std::endl; - std::cout << "max_slope_abs (adimensional) = " - << this->alg_.filtering_configuration_.max_slope_abs << std::endl; - std::cout << "flag_generate_discontinuity_obstacles_for_real_obstacles = " - << this->alg_.filtering_configuration_.flag_generate_discontinuity_obstacles_for_real_obstacles << std::endl; - std::cout << "flag_connect_vertices_even_if_there_are_obstacles = " - << this->alg_.filtering_configuration_.flag_connect_vertices_even_if_there_are_obstacles << std::endl; + std::cout << "max_slope_abs (adimensional) = " << this->alg_.filtering_configuration_.max_slope_abs << std::endl; std::cout << "measure_performance = " << this->alg_.filtering_configuration_.measure_performance << std::endl; std::cout << "show_dense_reconstruction = " << this->alg_.filtering_configuration_.show_dense_reconstruction