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