find_base_pose.cpp
Go to the documentation of this file.
00001 /*
00002  * Copyright (c) 2011, Thomas Ruehr <ruehr@cs.tum.edu>
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 Willow Garage, Inc. 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 <ros/ros.h>
00032 #include <eigen_conversions/eigen_msg.h>
00033 #include <tf/tf.h>
00034 #include <actionlib/server/simple_action_server.h>
00035 #include <find_base_pose/FindBasePoseAction.h>
00036 #include <tf/transform_listener.h>
00037 #include <kinematics_msgs/GetPositionIK.h>
00038 #include <kinematics_msgs/GetPositionFK.h>
00039 #include <pr2_arm_kinematics/pr2_arm_kinematics.h>
00040 #include <pr2_arm_kinematics/pr2_arm_ik.h>
00041 #include <pr2_arm_kinematics/pr2_arm_kinematics_utils.h>
00042 #include <pr2_arm_kinematics/pr2_arm_ik_solver.h>
00043 #include <pr2_arm_kinematics/pr2_arm_kinematics_plugin.h>
00044 #include <kinematics_base/kinematics_base.h>
00045 
00046 #include <urdf/model.h>
00047 
00048 #include <algorithm>
00049 
00050 #include <laser_geometry/laser_geometry.h>
00051 #include <visualization_msgs/Marker.h>
00052 
00053 pr2_arm_kinematics::PR2ArmKinematics *kinemar,*kinemal;
00054 pr2_arm_kinematics::PR2ArmIK *ik_r;
00055 pr2_arm_kinematics::PR2ArmIKSolver *solver;
00056 
00057 
00059 #include <nav_msgs/OccupancyGrid.h>
00060 
00061 bool we_have_a_map = false;
00062 bool map_processed = false;
00063 
00064 nav_msgs::OccupancyGrid map, map_inscribed, map_circumscribed;
00065 nav_msgs::OccupancyGrid coarsemap;
00066 
00067 float resolution_ = 0;
00068 int size_x_ = 0;
00069 int size_y_ = 0;
00070 
00071 float origin_x_ = 0;
00072 float origin_y_ = 0;
00073 
00074 void mapToWorld(unsigned int mx, unsigned int my, double& wx, double& wy)
00075 {
00076     wx = origin_x_ + (mx + 0.5) * resolution_;
00077     wy = origin_y_ + (my + 0.5) * resolution_;
00078 }
00079 
00080 bool worldToMap(double wx, double wy, unsigned int& mx, unsigned int& my)
00081 {
00082     if (wx < origin_x_ || wy < origin_y_)
00083         return false;
00084 
00085     mx = (int) ((wx - origin_x_) / resolution_);
00086     my = (int) ((wy - origin_y_) / resolution_);
00087 
00088     if (mx < size_x_ && my < size_y_)
00089         return true;
00090 
00091     return false;
00092 }
00093 
00094 void worldToMapNoBounds(double wx, double wy, int& mx, int& my)
00095 {
00096     mx = (int) ((wx - origin_x_) / resolution_);
00097     my = (int) ((wy - origin_y_) / resolution_);
00098 }
00099 
00100 ros::Publisher occ_pub;
00101 
00102 void mapCallback(const nav_msgs::OccupancyGrid& msg)
00103 {
00104     if (we_have_a_map)
00105         return;
00106 
00107     we_have_a_map = true;
00108 
00109     map = msg;
00110     map_inscribed = msg;
00111 
00112     resolution_ = map.info.resolution;
00113     size_x_ = map.info.width;
00114     size_y_ = map.info.height;
00115 
00116     origin_x_ = map.info.origin.position.x;
00117     origin_y_ = map.info.origin.position.y;
00118 
00119     ROS_INFO("got map, processing ");
00120 
00121     double inscribing_radius = .35;
00122     int inscr_rad = inscribing_radius / map.info.resolution;
00123 
00124     for (int my = 0; my < size_y_; my++)
00125     {
00126         if ((my + 1) % (int)(size_x_ / 20) == 0)
00127         {
00128             ROS_INFO("processing %i/%i", my, size_y_);
00129         }
00130         for (int mx = 0; mx < size_x_; mx++)
00131         {
00132             bool found = false;
00133             if (map_inscribed.data[mx + my * size_x_] ==0)
00134                 for (int ax = -inscr_rad; !found && (ax < inscr_rad); ax++)
00135                     for (int ay = -inscr_rad; !found && (ay < inscr_rad); ay++)
00136                     {
00137                         if ((ax * ax + ay * ay < inscr_rad * inscr_rad)  &&
00138                                 (mx + ax > 0) && (mx + ax < size_x_) &&
00139                                 (my + ay > 0) && (my + ay < size_y_) &&
00140                                 (map.data[mx + ax + (my + ay) * size_x_] != 0))
00141                         {
00142                             found = true;
00143                             map_inscribed.data[mx + my * size_x_] = 100;
00144                         }
00145                     }
00146         }
00147     }
00148 
00149     inscribing_radius = tf::Vector3(.35,.35,0).length();
00150     ROS_INFO("circumscribed circle radius %f", inscribing_radius);
00151     inscr_rad = inscribing_radius / map.info.resolution;
00152 
00153     map_circumscribed = map_inscribed;
00154 
00155     for (int my = 0; my < size_y_; my++)
00156     {
00157         if ((my + 1) % (int)(size_x_ / 20) == 0)
00158         {
00159             ROS_INFO("processing %i/%i", my, size_y_);
00160         }
00161         for (int mx = 0; mx < size_x_; mx++)
00162         {
00163             bool found = false;
00164             if (map_circumscribed.data[mx + my * size_x_] ==0)
00165                 for (int ax = -inscr_rad; !found && (ax < inscr_rad); ax++)
00166                     for (int ay = -inscr_rad; !found && (ay < inscr_rad); ay++)
00167                     {
00168                         if ((ax * ax + ay * ay < inscr_rad * inscr_rad)  &&
00169                                 (mx + ax > 0) && (mx + ax < size_x_) &&
00170                                 (my + ay > 0) && (my + ay < size_y_) &&
00171                                 (map.data[mx + ax + (my + ay) * size_x_] != 0))
00172                         {
00173                             found = true;
00174                             map_circumscribed.data[mx + my * size_x_] = 100;
00175                         }
00176                     }
00177         }
00178     }
00179 
00180     map_processed = true;
00181 
00182     ROS_INFO("Processing done");
00183 
00184     ros::NodeHandle node_handle;
00185     occ_pub = node_handle.advertise<nav_msgs::OccupancyGrid>( "occ_map", 1000, true );
00186     occ_pub.publish(map_inscribed);
00187 
00188     ROS_INFO("Publishing done");
00189 }
00190 
00191 //will take a pose in map coordinates and say if its free given the pr2s footprint
00192 bool mapFreeCoarse(tf::Stamped<tf::Pose> absPose)
00193 {
00194     ros::Rate rt(2);
00195     while (!map_processed)
00196     {
00197         rt.sleep();
00198         ROS_INFO("Waiting for map to be published on /map");
00199     }
00200     //bool worldToMap(double wx, double wy, unsigned int& mx, unsigned int& my)
00201     unsigned int mx, my;
00202     worldToMap(absPose.getOrigin().x(), absPose.getOrigin().y(), mx,my);
00203     if (map_inscribed.data[mx + my * map.info.width] == 0)
00204         return true;
00205     return false;
00206 }
00207 
00208 bool mapFreeCoarseCircumscribed(tf::Stamped<tf::Pose> absPose)
00209 {
00210     ros::Rate rt(2);
00211     while (!map_processed)
00212     {
00213         rt.sleep();
00214         ROS_INFO("Waiting for map to be published on /map");
00215     }
00216     //bool worldToMap(double wx, double wy, unsigned int& mx, unsigned int& my)
00217     unsigned int mx, my;
00218     worldToMap(absPose.getOrigin().x(), absPose.getOrigin().y(), mx,my);
00219     if (map_circumscribed.data[mx + my * map.info.width] == 0)
00220         return true;
00221     return false;
00222 }
00223 
00224 bool mapFreeFine(tf::Stamped<tf::Pose> absPose)
00225 {
00226     ros::Rate rt(2);
00227     while (!map_processed)
00228     {
00229         rt.sleep();
00230         ROS_INFO("Waiting for map to be published on /map");
00231     }
00232     //bool worldToMap(double wx, double wy, unsigned int& mx, unsigned int& my)
00233 
00234     unsigned int mx, my;
00235     worldToMap(absPose.getOrigin().x(), absPose.getOrigin().y(), mx,my);
00236     if (map.data[mx + my * map.info.width] == 0)
00237         return true;
00238     return false;
00239 }
00240 
00241 
00243 
00244 
00245 class FindBasePoseAction
00246 {
00247 protected:
00248 
00249     ros::NodeHandle nh_;
00250     actionlib::SimpleActionServer<find_base_pose::FindBasePoseAction> as_;
00251     std::string action_name_;
00252     // create messages that are used to published feedback/result
00253     find_base_pose::FindBasePoseFeedback feedback_;
00254     find_base_pose::FindBasePoseResult result_;
00255     tf::TransformListener *listener_;
00256     ros::ServiceClient ik_client[2];
00257 
00259     ros::Subscriber subScan_;
00260     laser_geometry::LaserProjection *projector_;
00261     boost::mutex scan_mutex;
00262     bool weHaveScan;
00263     //float scanPoints[5000][2];
00264     btVector3 scanPoints[5000];
00265 
00266     size_t numScanPoints;
00267 
00268     // bounding box of reachable area
00269     btVector3 bbox[2][2];
00270 
00271     ros::Publisher vis_pub;
00272 
00273     int markerCnt;
00274 
00275 public:
00276 
00277     FindBasePoseAction(std::string name) :
00278             as_(nh_, name, boost::bind(&FindBasePoseAction::executeCB, this, _1), false),
00279             action_name_(name)
00280     {
00281         listener_ = new tf::TransformListener();
00282         for (int side = 0; side <= 1; ++side)
00283             ik_client[side] = nh_.serviceClient<kinematics_msgs::GetPositionIK>((side == 0) ? "/pr2_right_arm_kinematics/get_ik" : "/pr2_left_arm_kinematics/get_ik" , true);
00284         as_.start();
00285 
00286 
00287         subScan_ = nh_.subscribe("base_scan", 10, &FindBasePoseAction::scanCallback, this);
00288 
00289         vis_pub = nh_.advertise<visualization_msgs::Marker>( "find_base_pose_markers", 10000, true );
00290 
00291         projector_ = 0;
00292         markerCnt = 0;
00293 
00294         float padding = 0.02;
00295 
00296         bbox[0][0].setX(-0.564000 - padding);
00297         bbox[0][0].setY(-0.990000 - padding);
00298         bbox[0][0].setZ(0.336000 - padding);
00299 
00300         bbox[0][1].setX(0.759333 + padding);
00301         bbox[0][1].setY(0.396000 + padding);
00302         bbox[0][1].setZ(1.494000 + padding);
00303 
00304         bbox[1][0].setX(-0.564000 - padding);
00305         bbox[1][0].setY(-0.396000 - padding);
00306         bbox[1][0].setZ(0.336000 - padding);
00307 
00308         bbox[1][1].setX(0.759333 + padding);
00309         bbox[1][1].setY(0.990000 + padding);
00310         bbox[1][1].setZ(1.494000 + padding);
00311     }
00312 
00313     ~FindBasePoseAction(void)
00314     {
00315     }
00316 
00317     void pubBaseMarkerBlob(float dx, float dy, float dz, float colr = 0, float colg = 1, float colb = 0)
00318     {
00319         visualization_msgs::Marker marker;
00320         marker.header.frame_id = "base_link";
00321         marker.header.stamp = ros::Time::now();
00322         marker.ns = "target base footprints";
00323         marker.id = ++markerCnt;
00324         marker.type = visualization_msgs::Marker::CUBE;
00325         marker.action = visualization_msgs::Marker::ADD;
00326         marker.pose.position.x = dx;
00327         marker.pose.position.y = dy;
00328         marker.pose.position.z = dz;
00329         marker.pose.orientation.x = 0.0;
00330         marker.pose.orientation.y = 0.0;
00331         marker.pose.orientation.z = 0.0;
00332         marker.pose.orientation.w = 1.0;
00333         marker.scale.x = 0.05;
00334         marker.scale.y = 0.05;
00335         marker.scale.z = 0.05;
00336         marker.color.a = 0.5;
00337         marker.color.r = colr;
00338         marker.color.g = colg;
00339         marker.color.b = colb;
00340         vis_pub.publish( marker );
00341         ros::spinOnce();
00342     }
00343 
00344     void pubBaseMarkerBlob(tf::Pose pose, float colr = 0, float colg = 1, float colb = 0)
00345     {
00346         visualization_msgs::Marker marker;
00347         marker.header.frame_id = "base_link";
00348         marker.header.stamp = ros::Time::now();
00349         marker.ns = "target base footprints";
00350         marker.id = ++markerCnt;
00351         marker.type = visualization_msgs::Marker::CUBE;
00352         marker.action = visualization_msgs::Marker::ADD;
00353         marker.pose.position.x = pose.getOrigin().x();
00354         marker.pose.position.y = pose.getOrigin().y();
00355         marker.pose.position.z = pose.getOrigin().z();
00356         marker.pose.orientation.x = pose.getRotation().x();
00357         marker.pose.orientation.y = pose.getRotation().y();
00358         marker.pose.orientation.z = pose.getRotation().z();
00359         marker.pose.orientation.w = pose.getRotation().w();
00360         marker.scale.x = 0.05;
00361         marker.scale.y = 0.05;
00362         marker.scale.z = 0.05;
00363         marker.color.a = 0.5;
00364         marker.color.r = colr;
00365         marker.color.g = colg;
00366         marker.color.b = colb;
00367         vis_pub.publish( marker );
00368         ros::spinOnce();
00369     }
00370 
00371     void pubBaseMarkerArrow(tf::Pose pose, float colr = 0, float colg = 1, float colb = 0)
00372     {
00373         visualization_msgs::Marker marker;
00374         marker.header.frame_id = "base_link";
00375         marker.header.stamp = ros::Time::now();
00376         marker.ns = "target base footprints";
00377         marker.id = ++markerCnt;
00378         marker.type = visualization_msgs::Marker::ARROW;
00379         marker.action = visualization_msgs::Marker::ADD;
00380         marker.pose.position.x = pose.getOrigin().x();
00381         marker.pose.position.y = pose.getOrigin().y();
00382         marker.pose.position.z = pose.getOrigin().z();
00383         marker.pose.orientation.x = pose.getRotation().x();
00384         marker.pose.orientation.y = pose.getRotation().y();
00385         marker.pose.orientation.z = pose.getRotation().z();
00386         marker.pose.orientation.w = pose.getRotation().w();
00387         marker.scale.x = 0.05;
00388         marker.scale.y = 0.05;
00389         marker.scale.z = 0.05;
00390         marker.color.a = 1;
00391         marker.color.r = colr;
00392         marker.color.g = colg;
00393         marker.color.b = colb;
00394         vis_pub.publish( marker );
00395         ros::spinOnce();
00396     }
00397 
00398     void pubBaseMarkerArrow(geometry_msgs::PoseStamped pose, float colr = 0, float colg = 1, float colb = 0)
00399     {
00400         visualization_msgs::Marker marker;
00401         marker.header.frame_id = pose.header.frame_id;
00402         marker.header.stamp = ros::Time::now();
00403         marker.ns = "target base footprints";
00404         marker.id = ++markerCnt;
00405         marker.type = visualization_msgs::Marker::ARROW;
00406         marker.action = visualization_msgs::Marker::ADD;
00407         marker.pose = pose.pose;
00408         marker.scale.x = 0.02;
00409         marker.scale.y = 0.07;
00410         marker.scale.z = 0.07;
00411         marker.color.a = 1;
00412         marker.color.r = colr;
00413         marker.color.g = colg;
00414         marker.color.b = colb;
00415         vis_pub.publish( marker );
00416         ros::spinOnce();
00417 
00418         //marker.header.stamp = ros::Time(0);
00419         //marker.id = ++markerCnt;
00420         //vis_pub.publish( marker );
00421         ros::spinOnce();
00422 
00423     }
00424 
00425     void pubBaseMarker(float dx, float dy, float dz = 0, float colr = 0, float colg = 1, float colb = 0, float si_ = 0.325)
00426     {
00427         visualization_msgs::Marker marker;
00428         marker.header.frame_id = "base_link";
00429         marker.header.stamp = ros::Time::now();
00430         marker.ns = "target base footprints";
00431         marker.id = ++markerCnt;
00432         marker.type = visualization_msgs::Marker::LINE_STRIP;
00433         marker.action = visualization_msgs::Marker::ADD;
00434         marker.pose.position.x = 0;
00435         marker.pose.position.y = 0;
00436         marker.pose.position.z = 0;
00437         marker.pose.orientation.x = 0.0;
00438         marker.pose.orientation.y = 0.0;
00439         marker.pose.orientation.z = 0.0;
00440         marker.pose.orientation.w = 1.0;
00441         marker.scale.x = 0.01;
00442         marker.scale.y = 0.01;
00443         marker.scale.z = 0.01;
00444         marker.color.a = 0.5;
00445         marker.color.r = colr;
00446         marker.color.g = colg;
00447         marker.color.b = colb;
00448         float si = .325;
00449         //if (!isGood)
00450         si = .3;
00451 
00452         si = si_;
00453 
00454         //si = 0.01;
00455         //if (!isGood)
00456         //  marker.color.b = markerCnt / 1000.0f;
00457         {
00458             geometry_msgs::Point p;
00459             p.x =  -si +  dx;
00460             p.y =  -si +  dy;
00461             p.z = dz;
00462             marker.points.push_back(p);
00463         }
00464         {
00465             geometry_msgs::Point p;
00466             p.x =  si + dx;
00467             p.y =  -si +  dy;
00468             p.z = dz;
00469             marker.points.push_back(p);
00470         }
00471         {
00472             geometry_msgs::Point p;
00473             p.x =  si +  dx;
00474             p.y =  si +  dy;
00475             p.z = dz;
00476             marker.points.push_back(p);
00477         }
00478         {
00479             geometry_msgs::Point p;
00480             p.x =  -si +  dx;
00481             p.y =  si +  dy;
00482             p.z = dz;
00483             marker.points.push_back(p);
00484         }
00485         {
00486             geometry_msgs::Point p;
00487             p.x =  -si +  dx;
00488             p.y =  -si +  dy;
00489             p.z = dz;
00490             marker.points.push_back(p);
00491         }
00492 
00493         vis_pub.publish( marker );
00494     }
00495 
00496     void pubBaseMarker(tf::Pose pose, float colr = 0, float colg = 1, float colb = 0, float si_ = 0.325)
00497     {
00498         visualization_msgs::Marker marker;
00499         marker.header.frame_id = "base_link";
00500         marker.header.stamp = ros::Time::now();
00501         marker.ns = "target base footprints";
00502         marker.id = ++markerCnt;
00503         marker.type = visualization_msgs::Marker::LINE_STRIP;
00504         marker.action = visualization_msgs::Marker::ADD;
00505         marker.pose.position.x = pose.getOrigin().x();
00506         marker.pose.position.y = pose.getOrigin().y();
00507         marker.pose.position.z = pose.getOrigin().z();
00508         marker.pose.orientation.x = pose.getRotation().x();
00509         marker.pose.orientation.y = pose.getRotation().y();
00510         marker.pose.orientation.z = pose.getRotation().z();
00511         marker.pose.orientation.w = pose.getRotation().w();
00512         /*marker.pose.position.x = 1;
00513         marker.pose.position.y = 0.5;
00514         marker.pose.position.z = 0;
00515         marker.pose.orientation.x = 0;
00516         marker.pose.orientation.y = 0;
00517         marker.pose.orientation.z = 1;
00518         marker.pose.orientation.w = 0.1;*/
00519         marker.scale.x = 0.01;
00520         marker.scale.y = 0.01;
00521         marker.scale.z = 0.01;
00522         marker.color.a = 0.5;
00523         marker.color.r = colr;
00524         marker.color.g = colg;
00525         marker.color.b = colb;
00526         float si = .325;
00527         //if (!isGood)
00528         si = .3;
00529 
00530         si = si_;
00531 
00532         //si = 0.01;
00533         //if (!isGood)
00534         //  marker.color.b = markerCnt / 1000.0f;
00535         {
00536             geometry_msgs::Point p;
00537             p.x =  -si;
00538             p.y =  -si;
00539             p.z = 0;
00540             marker.points.push_back(p);
00541         }
00542         {
00543             geometry_msgs::Point p;
00544             p.x =  si;
00545             p.y =  -si;
00546             p.z = 0;
00547             marker.points.push_back(p);
00548         }
00549         {
00550             geometry_msgs::Point p;
00551             p.x =  si;
00552             p.y =  si;
00553             p.z = 0;
00554             marker.points.push_back(p);
00555         }
00556         {
00557             geometry_msgs::Point p;
00558             p.x =  -si;
00559             p.y =  si;
00560             p.z = 0;
00561             marker.points.push_back(p);
00562         }
00563         {
00564             geometry_msgs::Point p;
00565             p.x =  -si;
00566             p.y =  -si;
00567             p.z = 0;
00568             marker.points.push_back(p);
00569         }
00570 
00571         vis_pub.publish( marker );
00572     }
00573 
00574     void pubBaseMarker(std::vector<btVector3> pts, float colr = 0, float colg = 1, float colb = 0, float si_ = 0.325)
00575     {
00576         visualization_msgs::Marker marker;
00577         marker.header.frame_id = "base_link";
00578         marker.header.stamp = ros::Time::now();
00579         marker.ns = "target base footprints";
00580         marker.id = ++markerCnt;
00581         marker.type = visualization_msgs::Marker::LINE_STRIP;
00582         marker.action = visualization_msgs::Marker::ADD;
00583         marker.pose.position.x = 0;
00584         marker.pose.position.y = 0;
00585         marker.pose.position.z = 0;
00586         marker.pose.orientation.x = 0.0;
00587         marker.pose.orientation.y = 0.0;
00588         marker.pose.orientation.z = 0.0;
00589         marker.pose.orientation.w = 1.0;
00590         marker.scale.x = 0.01;
00591         marker.scale.y = 0.01;
00592         marker.scale.z = 0.01;
00593         marker.color.a = 0.5;
00594         marker.color.r = colr;
00595         marker.color.g = colg;
00596         marker.color.b = colb;
00597 
00598         std::vector<btVector3>::iterator it;
00599         for (it = pts.begin(); it != pts.end(); ++it)
00600         {
00601             geometry_msgs::Point p;
00602             p.x =  it->x();
00603             p.y =  it->y();
00604             p.z =  it->z();
00605             marker.points.push_back(p);
00606         }
00607         it = pts.begin();
00608         {
00609             geometry_msgs::Point p;
00610             p.x =  it->x();
00611             p.y =  it->y();
00612             p.z =  it->z();
00613             marker.points.push_back(p);
00614         }
00615 
00616         vis_pub.publish( marker );
00617     }
00618 
00619     void scanCallback(const sensor_msgs::LaserScan::ConstPtr& scan_in)
00620     {
00621         if (!projector_)
00622             projector_ = new laser_geometry::LaserProjection();
00623 
00624         scan_mutex.lock();
00625         sensor_msgs::PointCloud scan_cloud;
00626         projector_->projectLaser(*scan_in,scan_cloud);
00627         int step = 1;
00628         for (size_t k = 0; k < scan_cloud.points.size(); k += step)
00629         {
00630             //scanPoints[k/step][0] = scan_cloud.points[k].x;
00631             //scanPoints[k/step][1] = scan_cloud.points[k].y;
00632             scanPoints[k] = btVector3(scan_cloud.points[k].x + 0.275, scan_cloud.points[k].y, 0);
00633             numScanPoints = k / step;
00634             //ROS_INFO("SCAN POINTS : %i %f %f",numScanPoints, scanPoints[k/step][0], scanPoints[k/step][1]);
00635         }
00636         scan_mutex.unlock();
00637         weHaveScan = true;
00638     }
00639 
00640 
00641     //bool collisionFree(tf::Stamped<tf::Pose> relativePose)
00642 
00643     //check against map collision
00644     bool collisionFreeCoarse(btTransform relativePose)
00645     {
00646 
00647         tf::Stamped<tf::Pose> relPose;
00648         relPose.setOrigin(relativePose.getOrigin());
00649         relPose.setRotation(relativePose.getRotation());
00650         relPose.frame_id_ = "/base_link";
00651         tf::Stamped<tf::Pose> absPose = getPoseIn("/map", relPose);
00652 
00653         if (!mapFreeCoarse(absPose))
00654             return false;
00655 
00656         return true;
00657     }
00658 
00659     //check against map collision
00660     bool collisionFreeFine(btTransform relativePose)
00661     {
00662 
00663         tf::Stamped<tf::Pose> relPose;
00664         relPose.setOrigin(relativePose.getOrigin());
00665         relPose.setRotation(relativePose.getRotation());
00666         relPose.frame_id_ = "/base_link";
00667 
00668         tf::Stamped<tf::Pose> absPose = getPoseIn("/map", relPose);
00669         if (mapFreeCoarseCircumscribed(absPose))
00670           return true;
00671 
00672         for (double ax = -.35; ax <= .35; ax += .1)
00673             for (double ay = -.35; ay <= .35; ay += .1) {
00674                 tf::Stamped<tf::Pose> act = relPose;
00675                 act.getOrigin() += tf::Vector3(ax,ay,0);
00676 
00677                 tf::Stamped<tf::Pose> absPose = getPoseIn("/map", act);
00678                 if (!mapFreeCoarse(absPose))
00679                     return false;
00680         }
00681 
00682         return true;
00683     }
00684 
00685     //todo: speed this up ! 10x should be no problem, with a real algorithm ;)
00686     // other idea: first check circumscribed circle against points, then incircle,
00687     // only check polygon for points inside circumscribed and outside of inscribed circle
00688 
00689     bool collisionFree(btTransform relativePose)
00690     {
00691         ros::Rate rate(10);
00692         while (!weHaveScan)
00693         {
00694             rate.sleep();
00695             ros::spinOnce();
00696         }
00697         scan_mutex.lock();
00698 
00699         tf::Stamped<tf::Pose> relPose;
00700         relPose.setOrigin(relativePose.getOrigin());
00701         relPose.setRotation(relativePose.getRotation());
00702         relPose.frame_id_ = "/base_link";
00703         tf::Stamped<tf::Pose> absPose = getPoseIn("/map", relPose);
00704 
00705         if (!mapFreeCoarse(absPose))
00706             return false;
00707 
00708         //ROS_INFO("SCAN POINTS : %i",numScanPoints);
00709         bool good = true;
00710         bool happy = true;
00711         bool indifferent = true;
00712         float padding = 0.05;
00713         float inscribed = .325;
00714         float circumscribed = sqrt(inscribed * inscribed + inscribed * inscribed);
00715         for (size_t k = 0; good && (k < numScanPoints); k += 1)
00716         {
00717             btVector3 in = scanPoints[k];
00718             float dist = (in  - relativePose.getOrigin()).length();
00719             if (dist < inscribed)
00720                 happy = false;
00721             if (dist < circumscribed)
00722                 indifferent = false;
00723             btVector3 transformed = relativePose.invXform(in);
00724             //btVector3 transformed = in * relativePose;
00725             if ((transformed.x() < .325 + padding) && (transformed.x() > -.325 - padding) && (transformed.y() < .325 + padding) && (transformed.y() > -.325 - padding))
00726             {
00727                 //ROS_INFO("POINT %f %f",  scanPoints[k][0] , scanPoints[k][1]);
00728                 good = false;
00729             }
00730             if (good && !happy)
00731                 ROS_ERROR("Good but not happy? Point lies in in incircle but not in box, how can that be ?");
00732             if (!good && indifferent)
00733                 ROS_ERROR("Not good but indifferent? Point lies in footprint box but not inside circumscribed circle, how can that be?");
00734         }
00735         scan_mutex.unlock();
00736         return good;
00737     }
00738 
00739     tf::Stamped<tf::Pose> tool2wrist(tf::Stamped<tf::Pose> toolPose)
00740     {
00741         tf::Stamped<tf::Pose> wrist2tool;
00742         wrist2tool.stamp_ = ros::Time();
00743         wrist2tool.setOrigin(btVector3(-.18,0,0));
00744         wrist2tool.setRotation(btQuaternion(0,0,0,1));
00745         tf::Stamped<tf::Pose> ret;
00746         ret = toolPose;
00747         ret *= wrist2tool;
00748         return ret;
00749     }
00750 
00751     tf::Stamped<tf::Pose> getPoseIn(const char target_frame[], tf::Stamped<tf::Pose>src)
00752     {
00753 
00754         if (!listener_)
00755             listener_ = new tf::TransformListener();
00756 
00757         // tf::Stamped<tf::Pose>
00758         tf::Stamped<tf::Pose> transform;
00759         //this shouldnt be here TODO
00760         src.stamp_ = ros::Time(0);
00761 
00762         listener_->waitForTransform(src.frame_id_, target_frame,
00763                                     ros::Time(0), ros::Duration(30.0));
00764         bool transformOk = false;
00765         while (!transformOk)
00766         {
00767             try
00768             {
00769                 transformOk = true;
00770                 listener_->transformPose(target_frame, src, transform);
00771             }
00772             catch (tf::TransformException ex)
00773             {
00774                 ROS_ERROR("getPoseIn %s",ex.what());
00775                 // dirty:
00776                 src.stamp_ = ros::Time(0);
00777                 transformOk = false;
00778             }
00779             ros::spinOnce();
00780         }
00781         return transform;
00782     }
00783 
00784     bool insideBB(int side, geometry_msgs::PoseStamped pose)
00785     {
00786         btVector3 *min = &bbox[side][0];
00787         btVector3 *max = &bbox[side][1];
00788         if ((pose.pose.position.x >= min->x()) &&
00789                 (pose.pose.position.x <= max->x()) &&
00790                 (pose.pose.position.y >= min->y()) &&
00791                 (pose.pose.position.y <= max->y()))
00792             return true;
00793         else
00794             return false;
00795     }
00796 
00797 
00798     tf::Pose rotateAroundPose(tf::Pose toolPose, tf::Pose pivot, btQuaternion qa)
00799     {
00800         btTransform curr = toolPose;
00801         btTransform pivo = pivot;
00802 
00803         curr = pivo.inverseTimes(curr);
00804 
00805         btTransform rot;
00806         rot.setOrigin(btVector3(0,0,0));
00807         rot.setRotation(qa);
00808         curr = rot * curr;
00809         curr = pivo * curr;
00810 
00811         tf::Pose act;
00812         //act.frame_id_ = toolPose.frame_id_;
00813         act.setOrigin(curr.getOrigin());
00814         act.setRotation(curr.getRotation());
00815 
00816         return act;
00817     }
00818 
00819 
00820 
00821     bool run_ik(int side_,geometry_msgs::PoseStamped pose, double start_angles[7],
00822                 double solution[7]) //, std::string link_name)
00823     {
00824 
00825         kinematics_msgs::GetPositionIK::Request  ik_request;
00826         kinematics_msgs::GetPositionIK::Response ik_response;
00827 
00828         ik_request.timeout = ros::Duration(5.0);
00829         if (side_ == 0)
00830         {
00831             ik_request.ik_request.ik_seed_state.joint_state.name.push_back("r_shoulder_pan_joint");
00832             ik_request.ik_request.ik_seed_state.joint_state.name.push_back("r_shoulder_lift_joint");
00833             ik_request.ik_request.ik_seed_state.joint_state.name.push_back("r_upper_arm_roll_joint");
00834             ik_request.ik_request.ik_seed_state.joint_state.name.push_back("r_elbow_flex_joint");
00835             ik_request.ik_request.ik_seed_state.joint_state.name.push_back("r_forearm_roll_joint");
00836             ik_request.ik_request.ik_seed_state.joint_state.name.push_back("r_wrist_flex_joint");
00837             ik_request.ik_request.ik_seed_state.joint_state.name.push_back("r_wrist_roll_joint");
00838 
00839             ik_request.ik_request.robot_state.joint_state.name.push_back("r_shoulder_pan_joint");
00840             ik_request.ik_request.robot_state.joint_state.name.push_back("r_shoulder_lift_joint");
00841             ik_request.ik_request.robot_state.joint_state.name.push_back("r_upper_arm_roll_joint");
00842             ik_request.ik_request.robot_state.joint_state.name.push_back("r_elbow_flex_joint");
00843             ik_request.ik_request.robot_state.joint_state.name.push_back("r_forearm_roll_joint");
00844             ik_request.ik_request.robot_state.joint_state.name.push_back("r_wrist_flex_joint");
00845             ik_request.ik_request.robot_state.joint_state.name.push_back("r_wrist_roll_joint");
00846         }
00847         else
00848         {
00849             ik_request.ik_request.ik_seed_state.joint_state.name.push_back("l_shoulder_pan_joint");
00850             ik_request.ik_request.ik_seed_state.joint_state.name.push_back("l_shoulder_lift_joint");
00851             ik_request.ik_request.ik_seed_state.joint_state.name.push_back("l_upper_arm_roll_joint");
00852             ik_request.ik_request.ik_seed_state.joint_state.name.push_back("l_elbow_flex_joint");
00853             ik_request.ik_request.ik_seed_state.joint_state.name.push_back("l_forearm_roll_joint");
00854             ik_request.ik_request.ik_seed_state.joint_state.name.push_back("l_wrist_flex_joint");
00855             ik_request.ik_request.ik_seed_state.joint_state.name.push_back("l_wrist_roll_joint");
00856 
00857             ik_request.ik_request.robot_state.joint_state.name.push_back("l_shoulder_pan_joint");
00858             ik_request.ik_request.robot_state.joint_state.name.push_back("l_shoulder_lift_joint");
00859             ik_request.ik_request.robot_state.joint_state.name.push_back("l_upper_arm_roll_joint");
00860             ik_request.ik_request.robot_state.joint_state.name.push_back("l_elbow_flex_joint");
00861             ik_request.ik_request.robot_state.joint_state.name.push_back("l_forearm_roll_joint");
00862             ik_request.ik_request.robot_state.joint_state.name.push_back("l_wrist_flex_joint");
00863             ik_request.ik_request.robot_state.joint_state.name.push_back("l_wrist_roll_joint");
00864         }
00865 
00866         ik_request.ik_request.ik_link_name = side_ ? "l_wrist_roll_link" : "r_wrist_roll_link";
00867 
00868         ik_request.ik_request.pose_stamped = pose;
00869         ik_request.ik_request.ik_seed_state.joint_state.position.resize(7);
00870         ik_request.ik_request.robot_state.joint_state.position.resize(7);
00871 
00872         for (int i=0; i<7; i++)
00873         {
00874             ik_request.ik_request.ik_seed_state.joint_state.position[i] = start_angles[i];
00875             ik_request.ik_request.robot_state.joint_state.position[i] = start_angles[i];
00876         }
00877 
00878         //ROS_INFO("request pose: %s %0.3f %0.3f %0.3f %0.3f %0.3f %0.3f %0.3f",ik_request.ik_request.ik_link_name.c_str() , pose.pose.position.x, pose.pose.position.y, pose.pose.position.z, pose.pose.orientation.x, pose.pose.orientation.y, pose.pose.orientation.z, pose.pose.orientation.w);
00879 
00880         //ROS_INFO("error code a %i",ik_response.error_code.val);
00881 
00882         bool ik_service_call ;
00883 
00884         if (0)
00885         {
00886             ik_service_call = ik_client[side_].call(ik_request,ik_response);
00887         }
00888         //for (int i = 0; i < 1; ++i)
00889         //if (0)
00890         {
00891             if (side_==0)
00892                 ik_service_call  = kinemar->getPositionIK(ik_request,ik_response);
00893             else
00894                 ik_service_call  = kinemal->getPositionIK(ik_request,ik_response);
00895         }
00896 
00898 
00899         //bool ik_service_call = true;
00900         //Eigen::eigen2_Transform3d pose_eigen;
00901         //KDL::Frame pose_kdl;
00902         //tf::PoseMsgToKDL(pose.pose, pose_kdl);
00903         //tf::poseMsgToEigen(pose.pose, pose_eigen);
00904         //Eigen::Matrix4f pose_eigen = pr2_arm_kinematics::KDLToEigenMatrix(pose_kdl);
00905 
00906         //std::vector<std::vector<double> > direct_solution;
00907         //int numtry = 0;
00908         //while ((numtry++ < 50) && (direct_solution.size() == 0)) {
00909         //double free_angle = ((rand() % 10000) / 10000.0) * 2 * M_PI  - M_PI;
00910         //ROS_INFO("free_angle = %f", free_angle);
00911         //ik_r->computeIKShoulderRoll(pose_eigen, free_angle,direct_solution);
00912         //}
00913 
00914         //ROS_INFO("len %i", direct_solution.size());
00915         //if (direct_solution.size()>0)
00916         //ROS_INFO("len first %i", direct_solution[0].size());
00917         //(const KDL::JntArray& q_init,
00918         //      const KDL::Frame& p_in,
00919         //    std::vector<KDL::JntArray> &q_out);
00920         //KDL::JntArray q_init;
00921         //bool found = solver->CartToJntSearch(
00922 
00923         if (!ik_service_call)
00924         {
00925             ROS_ERROR("IK service call failed! is ik service running? /pr2_right_arm_kinematics/get_ik");
00926             return false;
00927         }
00928 
00929         //        if (ik_response.error_code.val ==  pr2_arm_kinematics::TIMED_OUT)
00930 
00931         //ROS_INFO("error code %i",ik_response.error_code.val);
00932         if (ik_response.error_code.val == pr2_arm_kinematics::NO_IK_SOLUTION)
00933         {
00934             //  ROS_INFO("no solution found");
00935             return false;
00936         }
00937 
00938 
00939         if (ik_response.error_code.val == ik_response.error_code.SUCCESS)
00940         {
00941             for (int i=0; i<7; i++)
00942             {
00943                 solution[i] = ik_response.solution.joint_state.position[i];
00944             }
00945             //ROS_INFO("solution angles: %0.3f %0.3f %0.3f %0.3f %0.3f %0.3f %0.3f",solution[0],solution[1], solution[2],solution[3],solution[4],solution[5],solution[6]);
00946             //ROS_INFO("IK service call succeeded, solution found");
00947             return true;
00948         }
00949         //ROS_INFO("IK service call error code: %d", ik_response.error_code.val);
00950         return false;
00951     }
00952 
00953     // todo: we should penalize angle/ robot rotation also!
00954     static bool pose_compare(tf::Pose a,tf::Pose b)
00955     {
00956         //float angle_factor = 0.1 / (15 / 180 * M_PI); // 30 deg turn is equal to 10cm drive
00957         float angle_factor = 0.5;
00958         return (a.getOrigin().length() + angle_factor * a.getRotation().getAngle() < b.getOrigin().length() + angle_factor * b.getRotation().getAngle());
00959     }
00960 
00961     void generateCandidatePoses(std::vector<tf::Pose> &search_poses,std::vector<tf::Stamped<tf::Pose> > target_poses , tf::Pose preTrans, const std::vector<std_msgs::Int32> &arm)
00962     {
00963 
00964         std::vector<tf::Pose>  target_poses_transformed;
00965         std::vector<tf::Stamped<tf::Pose> >::iterator it;
00966         for (it = target_poses.begin(); it != target_poses.end(); ++it)
00967         {
00968             tf::Pose act;
00969             act.setOrigin(it->getOrigin());
00970             act.setRotation(it->getRotation());
00971             //act = act * preTrans;
00972             act = preTrans.inverseTimes(act);
00973             target_poses_transformed.push_back(act);
00974         }
00975 
00976         double minx = target_poses_transformed[0].getOrigin().x()-bbox[arm[0].data][1].x(); //goalInBaseMsg[0].pose.position.x - reach;
00977         double maxx = target_poses_transformed[0].getOrigin().x()-bbox[arm[0].data][0].x(); //goalInBaseMsg[0].pose.position.x + reach;
00978         double miny = target_poses_transformed[0].getOrigin().y()-bbox[arm[0].data][1].y();//goalInBaseMsg[0].pose.position.y - reach;
00979         double maxy = target_poses_transformed[0].getOrigin().y()-bbox[arm[0].data][0].y();//goalInBaseMsg[0].pose.position.y + reach;
00980         //}(-1.008435,-1.813615)-(1.591565,0.786385)
00981 
00982         // max of mins and vice versa gives the overlap of approx inverse capability maps
00983         //ROS_INFO("GOAL TARGETS SIZE: %zu", target_poses_transformed.size());
00984         for (size_t i=0; i < target_poses_transformed.size(); ++i)
00985         {
00986             // take 1.5m for approx upper bound of arms reach
00987             minx = std::max(target_poses_transformed[i].getOrigin().x()-bbox[arm[i].data][1].x(),minx);
00988             maxx = std::min(target_poses_transformed[i].getOrigin().x()-bbox[arm[i].data][0].x(),maxx);
00989             miny = std::max(target_poses_transformed[i].getOrigin().y()-bbox[arm[i].data][1].y(),miny);
00990             maxy = std::min(target_poses_transformed[i].getOrigin().y()-bbox[arm[i].data][0].y(),maxy);
00991             //ROS_INFO("%zu BOUNDING BOX : (%f,%f)-(%f,%f) size : %f %f ",i, minx,miny, maxx, maxy, maxx - minx, maxy - miny);
00992             //pubBaseMarker(goalInBaseMsg[i].pose.position.x,goalInBaseMsg[i].pose.position.y,goalInBaseMsg[i].pose.position.z,1,0,0);
00993         }
00994 
00995         //ROS_INFO("BOUNDING BOX : (%f,%f)-(%f,%f) size : %f %f ", minx,miny, maxx, maxy, maxx - minx, maxy - miny);
00996 
00997         //discretize on a grid around 0,0
00998         double discretisation = 0.075;
00999         //discretisation = 0.2;
01000         //discretize and padd by one grid cell
01001         minx = floor(minx * (1 / discretisation) - 1) * discretisation;
01002         maxx =  ceil(maxx * (1 / discretisation) + 1) * discretisation;
01003 
01004         miny = floor(miny * (1 / discretisation) - 1) * discretisation;
01005         maxy =  ceil(maxy * (1 / discretisation) + 1) * discretisation;
01006 
01007         std::vector<btVector3> bbpts;
01008         bbpts.push_back(preTrans * btVector3(minx,miny,0));
01009         bbpts.push_back(preTrans * btVector3(minx,maxy,0));
01010         bbpts.push_back(preTrans * btVector3(maxx,maxy,0));
01011         bbpts.push_back(preTrans * btVector3(maxx,miny,0));
01012 
01013 
01014         //std::vector<tf::Pose> search_poses;
01015         for (double xgen = minx; xgen <= maxx; xgen += discretisation)
01016         {
01017             for (double ygen = miny; ygen <= maxy; ygen += discretisation)
01018             {
01019                 tf::Pose act;
01020                 act.setOrigin(btVector3(xgen,ygen,0));
01021                 //act.setRotation(btQuaternion(btVector3(0, 0, 1), -0.1));
01022                 act.setRotation(btQuaternion(0,0,0,1));
01023 
01024                 act = preTrans * act;
01025 
01026                 //act = rotateAroundPose(act, , btQuaternion qa)
01027 
01028                 //float po[2] = {xgen,ygen};
01029 
01030                 //if (collisionFree(po))
01031                 //if (collisionFree(act))
01032                 //{
01033                 search_poses.push_back(act);
01034                 //pubBaseMarker(xgen,ygen);
01035                 //pubBaseMarker(act);
01036                 //pubBaseMarkerBlob(act,0,1,0.5);
01037                 //}
01038                 //else
01039                 //{
01040                 //ROS_INFO("tick");
01041                 //pubBaseMarkerBlob(xgen,ygen,1,0,0,0.5);
01042                 //}
01043                 //pubBaseMarker(act);
01044                 //pubBaseMarkerBlob(act,1,.7,0.3);
01046                 //if (0)
01047                 //    for (int u = 0; u < 15; u++)
01048                 //    {
01049                 //        ros::Duration(0.001).sleep();
01050                 //        ros::spinOnce();
01051                 //    }
01052             }
01053         }
01054 
01055     }
01056 
01057 
01058 
01059     void executeCB(const find_base_pose::FindBasePoseGoalConstPtr &goal)
01060     {
01061         // helper variables
01062         ros::Rate r(5000);
01063         bool success = true;
01064 
01065         result_.base_poses.clear();
01066 
01067         // publish info to the console for the user
01068         //  ROS_INFO("%s: Executing, creating fibonacci sequence of order %i with seeds %i, %i", action_name_.c_str(), goal->order, feedback_.sequence[0], feedback_.sequence[1]);
01069 
01070         // start executing the action
01071         //for(int i=1; i<=goal->order; i++)
01072 
01073         if (goal->target_poses.size() == 0)
01074         {
01075             as_.setAborted();
01076             ROS_ERROR("find_base_pose called without target trajectories");
01077             return; // todo: set result accordingly
01078         }
01079 
01080         ROS_INFO("New goal");
01081 
01082         std::vector<tf::Stamped<tf::Pose > > goalInBase;
01083         goalInBase.resize(goal->target_poses.size());
01084 
01085         std::vector<geometry_msgs::PoseStamped> goalInBaseMsg;
01086         goalInBaseMsg.resize(goal->target_poses.size());
01087 
01088         //double reach = 1.3;
01089 
01090         for (size_t i=0; i < goal->target_poses.size(); ++i)
01091         {
01092             tf::Stamped<tf::Pose> act;
01093             poseStampedMsgToTF(goal->target_poses[i], act);
01094             //get in baselink and convert to wrist pose
01095             //goalInBase[i] = tool2wrist(getPoseIn("base_link", act));
01096             goalInBase[i] = tool2wrist(getPoseIn("base_link", act));
01097             poseStampedTFToMsg(goalInBase[i], goalInBaseMsg[i]);
01098 
01099             tf::Stamped<tf::Pose> inBase = getPoseIn("base_link", act);
01100             ROS_INFO("TOOL in base: %f %f %f  %f %f %f %f", inBase.getOrigin().x(), inBase.getOrigin().y(), inBase.getOrigin().z(),
01101                      inBase.getRotation().x(), inBase.getRotation().y(), inBase.getRotation().z(), inBase.getRotation().w());
01102 
01103             for (int k = 0 ; k < 5 ; k++)
01104             {
01105                 //pubBaseMarkerArrow(goal->target_poses[i],goal->arm[i].data,1-goal->arm[i].data,0);
01106                 pubBaseMarkerArrow(goalInBaseMsg[i],goal->arm[i].data,1-goal->arm[i].data,0);
01107                 ros::spinOnce();
01108                 ros::spinOnce();
01109                 ros::spinOnce();
01110                 ros::Duration(0.0001).sleep();
01111             }
01112 
01113             ROS_INFO("FRAME: %s", goalInBaseMsg[i].header.frame_id.c_str());
01114             ROS_INFO("WRIST POSE: %f %f %f", goalInBaseMsg[i].pose.position.x, goalInBaseMsg[i].pose.position.y, goalInBaseMsg[i].pose.position.z);
01115             ROS_INFO("WRIST ROT: %f %f %f %f", goalInBaseMsg[i].pose.orientation.x, goalInBaseMsg[i].pose.orientation.y, goalInBaseMsg[i].pose.orientation.z, goalInBaseMsg[i].pose.orientation.w);
01116         }
01117 
01118         std::vector<tf::Pose> search_poses;
01119 
01120         tf::Pose preTrans;
01121         ros::Rate rat(1000);
01122         std::vector<float> angles;
01123         angles.push_back(0);
01124         angles.push_back(-30 * M_PI / 180.0f );
01125         angles.push_back(+30 * M_PI / 180.0f );
01126         if (0)
01127             for (std::vector<float>::iterator it = angles.begin(); it != angles.end(); ++it)
01128             {
01129                 preTrans.setRotation(btQuaternion(btVector3(0, 0, 1), *it));
01130                 generateCandidatePoses(search_poses,goalInBase, preTrans, goal->arm);
01131                 rat.sleep();
01132             }
01133         for (float angle = -180 * M_PI / 180.0f ; angle <= 180 * M_PI / 180.0f; angle+= 30 * M_PI / 180.0f)
01134         {
01135             preTrans.setRotation(btQuaternion(btVector3(0, 0, 1), angle));
01136             generateCandidatePoses(search_poses,goalInBase, preTrans, goal->arm);
01137             //rat.sleep();
01138         }
01139 
01140 
01141 
01142         //ROS_INFO("SIZE Of searchspace : %i .. sorting", (int)search_poses.size());
01143 
01144         std::sort(search_poses.begin(), search_poses.end(), pose_compare);
01145 
01146         std::vector<tf::Pose>::iterator it;
01147         //for (it = search_poses.begin(); it!=search_poses.end(); ++it)
01148         //{
01149         //ROS_INFO("POS: %f %f (dist %f)", it->getOrigin().x(), it->getOrigin().y(), it->getOrigin().length());
01150         //}
01151 
01152         ROS_INFO("SIZE Of searchspace : %i .. sorted", (int)search_poses.size());
01153 
01154         double start_angles[2][7];
01155         double sol_angles[7];
01156         for (int i=0; i < 7; ++i)
01157         {
01158             start_angles[0][i] = 0;
01159             start_angles[1][i] = 0;
01160         }
01161 
01162         //double distResolution = 0.2;
01163         //double currdist = 0;
01164 
01165         /*float max_dist = 0;
01166 
01167         float bbx[2] = {1000,-1000};
01168         float bby[2] = {1000,-1000};
01169         float bbz[2] = {1000,-1000};
01170 
01171         int cnt = 0;
01172 
01173         //for generating bounding boxes
01174 
01175         if (0)
01176         while (ros::ok()) {
01177 
01178             cnt++;
01179 
01180             if (cnt % 1000 == 0)
01181               ROS_INFO("CNT %i", cnt);
01182 
01183             double x, y, z;
01184             x = (rand() % 3000 - 1500) / 1500.0f;
01185             y = (rand() % 3000 - 1500) / 1500.0f;
01186             z = (rand() % 2000 ) / 1000.0f;
01187             geometry_msgs::PoseStamped currgoal = goalInBaseMsg[0];
01188             currgoal.header.frame_id = "base_link";
01189             currgoal.pose.position.x = x;
01190             currgoal.pose.position.y = y;
01191             currgoal.pose.position.z = z;
01192             currgoal.pose.orientation.x = (rand() % 200 - 100) / 100.0f;
01193             currgoal.pose.orientation.y = (rand() % 200 - 100) / 100.0f;
01194             currgoal.pose.orientation.z = (rand() % 200 - 100) / 100.0f;
01195             currgoal.pose.orientation.w = (rand() % 200 - 100) / 100.0f;
01196             //bool good = (insideBB(0,currgoal) && run_ik(0,currgoal,start_angles[0],sol_angles));
01197             bool good = run_ik(0,currgoal,start_angles[0],sol_angles);
01198             if (good) {
01199               //pubBaseMarkerBlob(x,y,z,0,1,0);
01200               btVector3 dive(x,y,0);
01201               if (dive.length() > max_dist)
01202                 max_dist = dive.length();
01203               ROS_INFO("xyz %f %f %f, max len %f", x,y,z, max_dist);
01204 
01205               if (x < bbx[0])
01206                 bbx[0] = x;
01207               if (x > bbx[1])
01208                 bbx[1] = x;
01209               if (y < bby[0])
01210                 bby[0] = y;
01211               if (y > bby[1])
01212                 bby[1] = y;
01213               if (z < bbz[0])
01214                 bbz[0] = z;
01215               if (z > bbz[1])
01216                 bbz[1] = z;
01217 
01218               ROS_INFO("BBOX : %f %f  %f %f  %f %f", bbx[0], bbx[1], bby[0], bby[1], bbz[0], bbz[1]);
01219               ROS_INFO("BBOX size : %f %f  %f ", bbx[1] - bbx[0], bby[1] - bby[0], bbz[1] - bbz[0]);
01220 
01221             }
01222             //else
01223             //              pubBaseMarkerBlob(x,y,z,1,0,0);
01224 
01225             ros::spinOnce();ros::spinOnce();ros::spinOnce();
01226         }
01227         */
01228 
01229         bool found = false;
01230         //while (!found)
01231 
01232         float mindist = 10000;
01233 
01234         int cnt = 1;
01235 
01236         for (it = search_poses.begin(); (it!=search_poses.end()) && (!found); ++it)
01237             //for (it = search_poses.begin(); it!=search_poses.end(); ++it)
01238         {
01239             if (cnt % 50 == 0)
01240                 ROS_INFO("Cnt %i", cnt);
01241 
01242 
01243             if (!collisionFreeCoarse(*it))
01244                 continue;
01245 
01246             //double x_add = it->getOrigin().x();
01247             //double y_add = it->getOrigin().y();
01248 
01249             //btVector3 a(x_add, y_add,0);
01250 
01251             bool good = true;
01252             geometry_msgs::PoseStamped currgoal;
01253             //for (int z=0; z < 1000; z++) // for benchmarking
01254 
01255             for (size_t i=0; (i < goal->target_poses.size()) & good; ++i)
01256             {
01257                 currgoal = goalInBaseMsg[i];
01258                 tf::Pose actP;
01259                 tf::poseMsgToTF(currgoal.pose,actP);
01260                 //ROS_INFO("TRANSFORM %f %f %f", it->getOrigin().x(), it->getOrigin().y(),it->getOrigin().z());
01261                 //ROS_INFO("TRANSFORM AXIS %f %f %f ROT %f ", it->getRotation().getAxis().x(), it->getRotation().getAxis().y(), it->getRotation().getAxis().z(), it->getRotation().getAngle());
01262                 //ROS_INFO("BEFORE %f %f %f", currgoal.pose.position.x, currgoal.pose.position.y, currgoal.pose.position.z);
01263                 //btTransform tr =
01264                 actP = it->inverseTimes(actP);
01265                 //actP.setOrigin(tr.getOrigin());
01266                 //actP.setRotation(tr.getRotation());
01267 
01268                 //currgoal.pose.position.x = goalInBaseMsg[i].pose.position.x - x_add;
01269                 //currgoal.pose.position.y = goalInBaseMsg[i].pose.position.y - y_add;
01270                 tf::poseTFToMsg(actP,currgoal.pose);
01271                 //ROS_INFO("AFTER %f %f %f", currgoal.pose.position.x, currgoal.pose.position.y, currgoal.pose.position.z);
01272                 good &= run_ik(goal->arm[i].data,currgoal ,start_angles[0],sol_angles);
01273             }
01274 
01275             //ROS_INFO("x %f y %f d %f good %i", x_add, y_add, a.length(), good);
01276 
01277             if (good) // collision checking seems to take longer than checking ik, this may differ for long trajectories! todo: check this first, then decide order
01278                 // apart from that: todo: speed up collision checking,
01279                 if (collisionFree(*it) && collisionFreeFine(*it))
01280                 //if (collisionFree(*it) && collisionFreeFine(*it))
01281                 {
01282                     if (!found)
01283                     {
01284                         //ROS_INFO("x %f y %f d %f d+angle %f good %i", x_add, y_add, a.length(), a.length() + 0.5 * it->getRotation().getAngle(), good);
01285                         ROS_INFO("XXXXXXXXXXX FOUND A COMBINED SOLUTION: %f %f %f", it->getOrigin().x(), it->getOrigin().y(), it->getRotation().getAngle());
01286                     }
01287                     found = true;
01288 
01289                     geometry_msgs::PoseStamped psm;
01290                     tf::poseTFToMsg(*it, psm.pose);
01291                     psm.header.frame_id = "/base_link";
01292                     psm.header.stamp = ros::Time::now();
01293                     result_.base_poses.push_back(psm);
01294                     //ROS_INFO("x %f y %f d %f d+angle %f good %i", x_add, y_add, a.length(), a.length() + 0.5 * it->getRotation().getAngle(), good);
01295                     //ROS_INFO("XXXXXXXXXXX FOUND A COMBINED SOLUTION: %f %f %f", x_add, y_add, it->getRotation().getAngle());
01296                     //ROS_INFO("SOL ANGLES : %f %f %f %f %f %f %f", sol_angles[0], sol_angles[1], sol_angles[2], sol_angles[3], sol_angles[4], sol_angles[5], sol_angles[6]);
01297                     //pubBaseMarker(x_add,y_add);
01298                     //pubBaseMarkerBlob(x_add,y_add,0.05,0.7,0.5,0.2);
01299                     tf::Pose ps;
01300                     ps.setOrigin(it->getOrigin() + btVector3(0,0,0.01));
01301                     ps.setRotation(it->getRotation());
01302                     pubBaseMarker(ps,0.7,0.5,0.2);
01303                     float col_factor = ps.getOrigin().length() + 0.5 * it->getRotation().getAngle();
01304                     if (col_factor < mindist)
01305                         mindist = col_factor;
01306                     col_factor -= mindist;
01307                     col_factor *= 0.05;
01308                     ps.setOrigin(it->getOrigin() + btVector3(0,0,col_factor));
01309                     pubBaseMarkerArrow(ps,1-col_factor*20.0,0,col_factor * 5.0);
01310                     //ROS_INFO("pose in base %f %f rot %f", currgoal.pose.position.x, currgoal.pose.position.y,0);
01311                     for (int r = 0; r < 10; r++)
01312                     {
01313                         ros::spinOnce();
01314                         ros::Duration(0.0001).sleep();
01315                         ros::spinOnce();
01316                     }
01317                 }
01318 
01319             // check that preempt has not been requested by the client
01320             if (as_.isPreemptRequested() || !ros::ok())
01321             {
01322                 ROS_INFO("%s: Preempted", action_name_.c_str());
01323                 // set the action state to preempted
01324                 as_.setPreempted();
01325                 success = false;
01326                 break;
01327             }
01328             //if (counter++ % 100 == 1)
01329             //r.sleep();
01330         }
01331 
01332 
01333         if (success)
01334         {
01335             //    result_.sequence = feedback_.sequence;
01336             ROS_INFO("%s: Succeeded", action_name_.c_str());
01337             // set the action state to succeeded
01338             as_.setSucceeded(result_);
01339         }
01340     }
01341 };
01342 
01343 
01344 int main(int argc, char** argv)
01345 {
01346     ros::init(argc, argv, "find_base_pose");
01347 
01348     tf::TransformListener tflistener;
01349 
01350     //pr2_arm_kinematics::PR2ArmKinematics pr2_arm_kinematics;
01351 
01352 
01353 
01354     // ik_r = new pr2_arm_kinematics::PR2ArmIK();
01355     //urdf::Model robot_model;
01356     //std::string root_name, tip_name, xml_string;
01357     //pr2_arm_kinematics::loadRobotModel(ros::NodeHandle(),robot_model,root_name,tip_name,xml_string);
01358     //ik_r->init(robot_model,root_name,tip_name);
01359 
01360 
01361     // solver = new pr2_arm_kinematics::PR2ArmIKSolver(robot_model, root_name, tip_name, 0.1, 2);
01362     // plugin_ = new pr2_arm_kinematics::PR2ArmKinematicsPlugin();
01363 
01364     ros::param::set("/find_base_pose/root_name", "torso_lift_link");
01365     ros::param::set("/find_base_pose/tip_name", "r_wrist_roll_link");
01366 
01367     ros::NodeHandle nh_;
01368     ros::Subscriber subMap = nh_.subscribe("map", 10, mapCallback);
01369 
01370     ros::Rate rt(10);
01371 
01372     while (!(ros::param::has("/find_base_pose/root_name") && ros::param::has("/find_base_pose/tip_name") ))
01373     {
01374         rt.sleep();
01375         ros::spinOnce();
01376         ROS_INFO("Waiting for params to show");
01377     }
01378 
01379 
01380     pr2_arm_kinematics::PR2ArmKinematics kinem;
01381     kinemar = &kinem;
01382 
01383     ros::param::set("/find_base_pose/root_name", "torso_lift_link");
01384     ros::param::set("/find_base_pose/tip_name", "l_wrist_roll_link");
01385 
01386     std::string tip;
01387     ros::param::get("/find_base_pose/tip_name",tip);
01388     ROS_INFO("TIP NAME %s", tip.c_str());
01389 
01390     pr2_arm_kinematics::PR2ArmKinematics kineml;
01391     kinemal = &kineml;
01392 
01393     ROS_ERROR("ABOVE ERRORS (Tried to advertise) can be neglected!");
01394 
01395     tflistener.waitForTransform("base_link", "torso_lift_link", ros::Time::now(), ros::Duration(5.0));
01396     tflistener.waitForTransform("base_link", "map", ros::Time::now(), ros::Duration(5.0));
01397 
01398     //FindBasePoseAction findbasepose(ros::this_node::getName());
01399     FindBasePoseAction findbasepose("find_base_pose_action");
01400 
01401     ROS_INFO("NAME: %s", ros::this_node::getName().c_str());
01402 
01403     ROS_INFO("DONE with test");
01404 
01405     ros::spin();
01406 
01407     return 0;
01408 }
01409 
01410 
01411 // failed goal (in base): 0.125900 0.564599 1.007231 -0.057600 0.007678 0.132418 0.989489 (time 1.000000)


find_base_pose
Author(s): Thomas Ruehr
autogenerated on Mon Oct 6 2014 08:57:31