helper.cpp
Go to the documentation of this file.
00001 /*
00002  * Copyright (c) 2012, Daniel Claes, Maastricht University
00003  * All rights reserved.
00004  *
00005  * Redistribution and use in source and binary forms, with or without
00006  * modification, are permitted provided that the following conditions are met:
00007  *
00008  *     * Redistributions of source code must retain the above copyright
00009  *       notice, this list of conditions and the following disclaimer.
00010  *     * Redistributions in binary form must reproduce the above copyright
00011  *       notice, this list of conditions and the following disclaimer in the
00012  *       documentation and/or other materials provided with the distribution.
00013  *     * Neither the name of the Maastricht University nor the names of its
00014  *       contributors may be used to endorse or promote products derived from
00015  *       this software without specific prior written permission.
00016  *
00017  * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
00018  * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
00019  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
00020  * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
00021  * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
00022  * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
00023  * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
00024  * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
00025  * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
00026  * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
00027  * POSSIBILITY OF SUCH DAMAGE.
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     // ROS_ERROR("points in list = %d", (int)points.size());
00083     // double testSum = 0;
00084     // for (int i = 0; i<(int)points.size(); i++) {
00085     //   testSum += points[i].weight;
00086     //   //ROS_ERROR("%f, weight = %f", abs(points[i].point), points[i].weight);
00087     // }
00088     // ROS_ERROR("%f testSUm ", testSum);
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     // ROS_ERROR("CALU points %d", j);
00097     // for (int i = 0; i<j; i++) {
00098     //   ROS_ERROR("%f", abs(points[i].point));
00099     // }
00100     cur_loc_unc_radius_ = collvoid::abs(points[j-1].point);
00101     //ROS_ERROR("Loc Uncertainty = %f", cur_loc_unc_radius_);
00102     //radius_ = footprint_radius_ + cur_loc_unc_radius_;
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       //ROS_WARN("SUM = %f (%f), num Particles = %d, eps = %f", sum, total_sum, (int) points.size(), eps_);
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     //    ROS_ERROR("COLLVOID points %d", (int) minkowski_footprint_.size());
00164 
00165     // for (int i = 0; i<(int)minkowski_footprint_.size(); i++) {
00166     //   ROS_ERROR("%f", abs(minkowski_footprint_[i]));
00167     // }
00168 
00169     // BOOST_FOREACH(geometry_msgs::Point32 p, footprint_msg_.polygon.points) {
00170     //   own_footprint.push_back(Vector2(p.x, p.y));
00171     //   //      ROS_WARN("footprint point p = (%f, %f) ", footprint_[i].x, footprint_[i].y);
00172     // }
00173     // minkowski_footprint_ = minkowskiSum(localization_footprint, own_footprint);
00174 
00175     // //publish footprint
00176     // geometry_msgs::PolygonStamped msg_pub = createFootprintMsgFromVector2(minkowski_footprint_);
00177     // polygon_pub_.publish(msg_pub);
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     //    if (!convex_ || orca_) {
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       //ROS_ERROR("eps = %f", eps_);
00211       //ROS_ERROR("radius = %f, area = %f", cur_loc_unc_radius_, M_PI*sqr(cur_loc_unc_radius_));
00212       circle.push_back(M_PI * sqr(cur_loc_unc_radius_));
00213       convex.push_back(area);
00214       //std::sort(minkowski_footprint_.begin(),minkowski_footprint_.end(), comparePoint);
00215       
00216       //ROS_ERROR("area conv_ = %f", area);
00217       //ROS_ERROR("furthest point= %f", collvoid::abs(minkowski_footprint_[int(minkowski_footprint_.size())-1]));
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     //we assume that the odometry is published in the frame of the base
00232     tf::Stamped<tf::Pose> global_pose;
00233     //let's get the pose of the robot in the frame of the plan
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     //let's get the pose of the robot in the frame of the plan
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     //std::cout << "[" <<pose_msg.pose.position.x << ", " << pose_msg.pose.position.y <<"]" << std::endl;
00271     //std::cout <<"[" <<odom_pose_msg.pose.position.x << ", " << odom_pose_msg.pose.position.y <<"]" << std::endl;
00272   }
00273 
00274 
00275   double CalcArea(std::vector<Vector2> list)
00276   {
00277     double area = 0; // Total area
00278     double diff = 0; // Difference Of Y{i + 1} - Y{i - 1}
00279     unsigned int last = list.size() - 1; // Size Of Vector - 1
00280     /* Given vertices from 1 to n, we first loop through
00281            the vertices 2 to n - 1. We will take into account
00282            vertex 1 and vertex n sepereately */
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     /* Now We Consider The Vertex 1 And The Vertex N */
00290     diff = list[1].y() - list[last].y();
00291     area += list[0].x() * diff; // Vertex 1
00292     diff = list[0].y() - list[last - 1].y();
00293     area += list[last].x() * diff; // Vertex N
00294     /* Calculate The Final Answer */
00295     area = 0.5 * std::abs(area);
00296     return area; // Return The 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     //ros::Subscriber odom_sub = nh.subscribe("odom", 1, collvoid::odomCallback);
00319 
00320     collvoid::eps_ = 0.1;
00321     ros::spin();
00322     
00323     delete tf_filter;
00324   }
00325 
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Properties Friends Defines


collvoid_local_planner
Author(s): Daniel Claes
autogenerated on Sun Aug 25 2013 10:10:23