00001 
00002 
00003 
00004 
00005 
00006 
00007 
00008 
00009 
00010 
00011 
00012 
00013 
00014 
00015 
00016 
00017 
00018 
00019 
00020 
00021 
00022 
00023 
00024 
00025 
00026 
00027 
00028 
00029 
00030 
00031 #include <angles/angles.h>
00032 #include <boost/foreach.hpp>
00033 #include <boost/tuple/tuple.hpp>
00034 
00035 
00036 #include "collvoid_local_planner/ROSAgent.h"
00037 
00038 #include "collvoid_local_planner/orca.h"
00039 #include "collvoid_local_planner/collvoid_publishers.h"
00040 
00041 
00042 namespace collvoid{
00043 
00044   tf::TransformListener* tf_;
00045   std::string base_frame_, global_frame_, odom_frame_;
00046   std::vector<std::pair<double, geometry_msgs::PoseStamped> > pose_array_weighted_;
00047   double footprint_radius_, radius_, cur_loc_unc_radius_;
00048   std::vector<Vector2> minkowski_footprint_;
00049   geometry_msgs::PolygonStamped footprint_msg_;
00050   double eps_;
00051   
00052   void computeNewLocUncertainty();
00053   void computeNewMinkowskiFootprint();
00054   void amclPoseArrayWeightedCallback(const amcl::PoseArrayWeighted::ConstPtr& msg);
00055   double CalcArea(std::vector<Vector2> list);
00056 
00057   
00058 
00059   bool compareConvexHullPointsPosition(const ConvexHullPoint& p1, const ConvexHullPoint& p2) {
00060     return collvoid::absSqr(p1.point) <= collvoid::absSqr(p2.point);
00061   }
00062 
00063   bool comparePoint(const Vector2& p1, const Vector2& p2) {
00064     return collvoid::absSqr(p1) <= collvoid::absSqr(p2);
00065   }
00066 
00067   
00068   void computeNewLocUncertainty(){
00069     std::vector<ConvexHullPoint> points;
00070     
00071     for (int i = 0; i < (int) pose_array_weighted_.size(); i++) {
00072       ConvexHullPoint p;
00073       p.point = Vector2(pose_array_weighted_[i].second.pose.position.x, pose_array_weighted_[i].second.pose.position.y);
00074       p.weight = pose_array_weighted_[i].first;
00075       p.index = i;
00076       p.orig_index = i;
00077       points.push_back(p);
00078     }
00079 
00080     std::sort(points.begin(),points.end(), compareConvexHullPointsPosition);
00081 
00082     
00083     
00084     
00085     
00086     
00087     
00088     
00089     
00090     double sum = 0.0;
00091     int j = 0;
00092     while (sum <= 1.0 -eps_  && j < (int) points.size()) {
00093       sum += points[j].weight;
00094       j++;
00095     }
00096     
00097     
00098     
00099     
00100     cur_loc_unc_radius_ = collvoid::abs(points[j-1].point);
00101     
00102     
00103   }
00104 
00105   void computeNewMinkowskiFootprint(){
00106     bool done = false;
00107     std::vector<ConvexHullPoint> convex_hull;
00108     std::vector<ConvexHullPoint> points;
00109     points.clear();
00110 
00111     
00112     for (int i = 0; i < (int) pose_array_weighted_.size(); i++) {
00113       ConvexHullPoint p;
00114       p.point = Vector2(pose_array_weighted_[i].second.pose.position.x, pose_array_weighted_[i].second.pose.position.y);
00115       p.weight = pose_array_weighted_[i].first;
00116       p.index = i;
00117       p.orig_index = i;
00118       points.push_back(p);
00119     }
00120     std::sort(points.begin(), points.end(), compareVectorsLexigraphically);
00121     for (int i = 0; i < (int) points.size(); i++) {
00122       points[i].index = i;
00123     }
00124 
00125     double total_sum = 0;
00126     std::vector<int> skip_list;
00127     
00128     while (!done && points.size() >= 3) {
00129       double sum = 0;
00130       convex_hull.clear();
00131       convex_hull = convexHull(points, true);
00132 
00133       skip_list.clear();
00134       for (int j = 0; j< (int) convex_hull.size()-1; j++){
00135         skip_list.push_back(convex_hull[j].index);
00136         sum += convex_hull[j].weight;
00137       }
00138       total_sum +=sum;
00139 
00140       
00141 
00142       if (total_sum >= eps_){
00143         done = true;
00144         break;
00145       }
00146             
00147       std::sort(skip_list.begin(), skip_list.end());
00148       for (int i = (int)skip_list.size() -1; i >= 0; i--) {
00149         points.erase(points.begin() + skip_list[i]);
00150       }
00151 
00152       for (int i = 0; i < (int) points.size(); i++) {
00153         points[i].index = i;
00154       }
00155     }
00156 
00157     std::vector<Vector2> localization_footprint, own_footprint;
00158     for (int i = 0; i < (int)convex_hull.size(); i++) {
00159       localization_footprint.push_back(convex_hull[i].point);
00160     }
00161 
00162     minkowski_footprint_ = localization_footprint;
00163     
00164 
00165     
00166     
00167     
00168 
00169     
00170     
00171     
00172     
00173     
00174 
00175     
00176     
00177     
00178   
00179   }
00180 
00181 
00182 
00183   void amclPoseArrayWeightedCallback(const amcl::PoseArrayWeighted::ConstPtr& msg){
00184     pose_array_weighted_.clear();
00185     geometry_msgs::PoseStamped in;
00186     in.header = msg->header;
00187     for (int i = 0; i< (int)msg->poses.size(); i++){
00188       in.pose = msg->poses[i];
00189       geometry_msgs::PoseStamped result;
00190       try {
00191         tf_->waitForTransform(global_frame_, base_frame_, msg->header.stamp, ros::Duration(0.3));
00192         tf_->transformPose(base_frame_, in, result);    
00193         pose_array_weighted_.push_back(std::make_pair(msg->weights[i], result));
00194       }
00195       catch (tf::TransformException ex){
00196         ROS_ERROR("%s",ex.what());
00197         ROS_ERROR("point transform failed");
00198       };
00199     }
00200     
00201 
00202     
00203 
00204     std::vector<double> circle, convex;
00205     
00206     for (eps_ = 0; eps_<=1; eps_+=0.05) {
00207       computeNewLocUncertainty();
00208       computeNewMinkowskiFootprint();
00209       double area = CalcArea(minkowski_footprint_);
00210       
00211       
00212       circle.push_back(M_PI * sqr(cur_loc_unc_radius_));
00213       convex.push_back(area);
00214       
00215       
00216       
00217       
00218     }
00219     for (int i = 0; i<(int)circle.size(); i++){
00220       std::cout << circle[i] << ", ";
00221     }
00222     for (int i = 0; i<(int)circle.size(); i++){
00223       std::cout << convex[i] << ", ";
00224     }
00225     std::cout <<";" << std::endl;
00226   
00227   }
00228 
00229 
00230   void odomCallback(const nav_msgs::Odometry::ConstPtr& msg){
00231     
00232     tf::Stamped<tf::Pose> global_pose;
00233     
00234     global_pose.setIdentity();
00235     global_pose.frame_id_ = base_frame_;
00236     global_pose.stamp_ = msg->header.stamp;
00237 
00238     try {
00239       tf_->waitForTransform(global_frame_, base_frame_, global_pose.stamp_, ros::Duration(0.2));
00240       tf_->transformPose(global_frame_, global_pose, global_pose);
00241     }
00242     catch (tf::TransformException ex){
00243       ROS_ERROR("%s",ex.what());
00244       ROS_ERROR("point odom transform failed");
00245       return;
00246     };
00247 
00248     geometry_msgs::PoseStamped pose_msg;
00249     tf::poseStampedTFToMsg(global_pose, pose_msg);
00250 
00251     tf::Stamped<tf::Pose> odom_pose;
00252     
00253     odom_pose.setIdentity();
00254     odom_pose.frame_id_ = base_frame_;
00255     odom_pose.stamp_ = msg->header.stamp;
00256 
00257     try {
00258       tf_->waitForTransform(odom_frame_, base_frame_, odom_pose.stamp_, ros::Duration(0.2));
00259       tf_->transformPose(odom_frame_, odom_pose, odom_pose);
00260     }
00261     catch (tf::TransformException ex){
00262       ROS_ERROR("%s",ex.what());
00263       ROS_ERROR("point odom transform failed");
00264       return;
00265     };
00266     
00267     geometry_msgs::PoseStamped odom_pose_msg;
00268     tf::poseStampedTFToMsg(odom_pose, odom_pose_msg);
00269 
00270     
00271     
00272   }
00273 
00274 
00275   double CalcArea(std::vector<Vector2> list)
00276   {
00277     double area = 0; 
00278     double diff = 0; 
00279     unsigned int last = list.size() - 1; 
00280     
00281 
00282 
00283     for(unsigned int i = 1; i < last; i++)
00284       {
00285         diff =list[i + 1].y() - list[i - 1].y();
00286         area += list[i].x() * diff;
00287       }
00288 
00289     
00290     diff = list[1].y() - list[last].y();
00291     area += list[0].x() * diff; 
00292     diff = list[0].y() - list[last - 1].y();
00293     area += list[last].x() * diff; 
00294     
00295     area = 0.5 * std::abs(area);
00296     return area; 
00297   }
00298   
00299   
00300 }
00301 
00302 int main(int argc, char **argv) {
00303     ros::init(argc, argv, "Helper");
00304     ros::NodeHandle nh;
00305     tf::TransformListener tf;
00306     collvoid::pose_array_weighted_.clear();
00307     collvoid::odom_frame_ = "odom";
00308     collvoid::global_frame_ = "/map";
00309     collvoid::base_frame_ = "base_link";
00310 
00311     collvoid::tf_ = &tf;
00312     message_filters::Subscriber<amcl::PoseArrayWeighted> amcl_posearray_sub;
00313     amcl_posearray_sub.subscribe(nh, "particlecloud_weighted", 10);
00314     tf::MessageFilter<amcl::PoseArrayWeighted> * tf_filter;
00315 
00316     tf_filter = new tf::MessageFilter<amcl::PoseArrayWeighted>(amcl_posearray_sub, *collvoid::tf_, collvoid::global_frame_,10);
00317     tf_filter->registerCallback(boost::bind(&collvoid::amclPoseArrayWeightedCallback,_1));
00318     
00319 
00320     collvoid::eps_ = 0.1;
00321     ros::spin();
00322     
00323     delete tf_filter;
00324   }
00325