Go to the documentation of this file.00001
00002
00003
00004
00005
00006
00007 #include "ros/ros.h"
00008 #include <geometry_msgs/PointStamped.h>
00009 #include <geometry_msgs/PolygonStamped.h>
00010 #include <geometry_msgs/Point32.h>
00011
00012 #include <costmap_2d/costmap_2d_ros.h>
00013 #include <costmap_2d/costmap_2d.h>
00014
00015 #include <heatmap/geometry_tools.h>
00016
00017 #include <visualization_msgs/Marker.h>
00018
00019 #include <boost/foreach.hpp>
00020 #include <ros/wall_timer.h>
00021
00022 geometry_msgs::PolygonStamped input_;
00023 ros::Publisher point_viz_pub_;
00024 ros::Publisher polygon_planner_pub;
00025 ros::WallTimer point_viz_timer_;
00026
00027 void vizPubCb()
00028 {
00029 visualization_msgs::Marker points, line_strip;
00030 points.header = line_strip.header = input_.header;
00031 points.ns = line_strip.ns = "explore_points";
00032 points.id = 0;
00033 line_strip.id = 1;
00034 points.type = visualization_msgs::Marker::SPHERE_LIST;
00035 line_strip.type = visualization_msgs::Marker::LINE_STRIP;
00036 if (!input_.polygon.points.empty())
00037 {
00038 points.action = line_strip.action = visualization_msgs::Marker::ADD;
00039 points.pose.orientation.w = line_strip.pose.orientation.w = 1.0;
00040 points.scale.x = points.scale.y = 0.1;
00041 line_strip.scale.x = 0.05;
00042 BOOST_FOREACH(geometry_msgs::Point32 point, input_.polygon.points){
00043 line_strip.points.push_back(costmap_2d::toPoint(point));
00044 points.points.push_back(costmap_2d::toPoint(point));
00045 }
00046 if (false)
00047 {
00048 line_strip.points.push_back(costmap_2d::toPoint(input_.polygon.points.front()));
00049 points.color.a = points.color.r = line_strip.color.r = line_strip.color.a = 1.0;
00050 }
00051 else
00052 {
00053 points.color.a = points.color.b = line_strip.color.b = line_strip.color.a = 1.0;
00054 }
00055 }
00056 else
00057 {
00058 points.action = line_strip.action = visualization_msgs::Marker::DELETE;
00059 }
00060 point_viz_pub_.publish(points);
00061 point_viz_pub_.publish(line_strip);
00062 }
00063
00064 void pointCb(const geometry_msgs::PointStampedConstPtr& point)
00065 {
00066 double average_distance = heatmap::polygonPerimeter(input_.polygon) / input_.polygon.points.size();
00067
00068 if (input_.polygon.points.empty())
00069 {
00070 ROS_INFO("First point!");
00071 input_.header = point->header;
00072 input_.polygon.points.push_back(costmap_2d::toPoint32(point->point));
00073 }
00074 else if (input_.header.frame_id != point->header.frame_id)
00075 {
00076 ROS_ERROR("Frame mismatch, restarting polygon selection");
00077 input_.polygon.points.clear();
00078 }
00079 else if (input_.polygon.points.size() > 1
00080 && heatmap::pointsNearby(input_.polygon.points.front(), point->point, average_distance * 0.1))
00081 {
00082 ROS_INFO("Last point received!");
00083
00084 if (input_.polygon.points.size() < 3)
00085 {
00086 ROS_ERROR("Not a valid polygon, restarting");
00087 }
00088 else
00089 polygon_planner_pub.publish(input_);
00090
00091 input_.polygon.points.clear();
00092 }
00093 else
00094 {
00095 input_.polygon.points.push_back(costmap_2d::toPoint32(point->point));
00096 input_.header.stamp = ros::Time::now();
00097 }
00098 }
00099
00100 int main(int argc, char** argv)
00101 {
00102 ros::init(argc, argv, "points_to_polygon");
00103 ros::NodeHandle n;
00104
00105 ros::Subscriber sub = n.subscribe("clicked_point", 10, &pointCb);
00106 point_viz_pub_ = n.advertise<visualization_msgs::Marker>("exploration_polygon_marker", 10);
00107 polygon_planner_pub = n.advertise<geometry_msgs::PolygonStamped>("field/cut_area", 10);
00108
00109 point_viz_timer_ = n.createWallTimer(ros::WallDuration(0.1), boost::bind(&vizPubCb));
00110 ros::spin();
00111
00112 return 0;
00113 }