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 <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
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
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
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
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
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
00264 btVector3 scanPoints[5000];
00265
00266 size_t numScanPoints;
00267
00268
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
00419
00420
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
00450 si = .3;
00451
00452 si = si_;
00453
00454
00455
00456
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
00513
00514
00515
00516
00517
00518
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
00528 si = .3;
00529
00530 si = si_;
00531
00532
00533
00534
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
00631
00632 scanPoints[k] = btVector3(scan_cloud.points[k].x + 0.275, scan_cloud.points[k].y, 0);
00633 numScanPoints = k / step;
00634
00635 }
00636 scan_mutex.unlock();
00637 weHaveScan = true;
00638 }
00639
00640
00641
00642
00643
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
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
00686
00687
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
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
00725 if ((transformed.x() < .325 + padding) && (transformed.x() > -.325 - padding) && (transformed.y() < .325 + padding) && (transformed.y() > -.325 - padding))
00726 {
00727
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
00758 tf::Stamped<tf::Pose> transform;
00759
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
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
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])
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
00879
00880
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
00889
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
00900
00901
00902
00903
00904
00905
00906
00907
00908
00909
00910
00911
00912
00913
00914
00915
00916
00917
00918
00919
00920
00921
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
00930
00931
00932 if (ik_response.error_code.val == pr2_arm_kinematics::NO_IK_SOLUTION)
00933 {
00934
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
00946
00947 return true;
00948 }
00949
00950 return false;
00951 }
00952
00953
00954 static bool pose_compare(tf::Pose a,tf::Pose b)
00955 {
00956
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
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();
00977 double maxx = target_poses_transformed[0].getOrigin().x()-bbox[arm[0].data][0].x();
00978 double miny = target_poses_transformed[0].getOrigin().y()-bbox[arm[0].data][1].y();
00979 double maxy = target_poses_transformed[0].getOrigin().y()-bbox[arm[0].data][0].y();
00980
00981
00982
00983
00984 for (size_t i=0; i < target_poses_transformed.size(); ++i)
00985 {
00986
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
00992
00993 }
00994
00995
00996
00997
00998 double discretisation = 0.075;
00999
01000
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
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
01022 act.setRotation(btQuaternion(0,0,0,1));
01023
01024 act = preTrans * act;
01025
01026
01027
01028
01029
01030
01031
01032
01033 search_poses.push_back(act);
01034
01035
01036
01037
01038
01039
01040
01041
01042
01043
01044
01046
01047
01048
01049
01050
01051
01052 }
01053 }
01054
01055 }
01056
01057
01058
01059 void executeCB(const find_base_pose::FindBasePoseGoalConstPtr &goal)
01060 {
01061
01062 ros::Rate r(5000);
01063 bool success = true;
01064
01065 result_.base_poses.clear();
01066
01067
01068
01069
01070
01071
01072
01073 if (goal->target_poses.size() == 0)
01074 {
01075 as_.setAborted();
01076 ROS_ERROR("find_base_pose called without target trajectories");
01077 return;
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
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
01095
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
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
01138 }
01139
01140
01141
01142
01143
01144 std::sort(search_poses.begin(), search_poses.end(), pose_compare);
01145
01146 std::vector<tf::Pose>::iterator it;
01147
01148
01149
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
01163
01164
01165
01166
01167
01168
01169
01170
01171
01172
01173
01174
01175
01176
01177
01178
01179
01180
01181
01182
01183
01184
01185
01186
01187
01188
01189
01190
01191
01192
01193
01194
01195
01196
01197
01198
01199
01200
01201
01202
01203
01204
01205
01206
01207
01208
01209
01210
01211
01212
01213
01214
01215
01216
01217
01218
01219
01220
01221
01222
01223
01224
01225
01226
01227
01228
01229 bool found = false;
01230
01231
01232 float mindist = 10000;
01233
01234 int cnt = 1;
01235
01236 for (it = search_poses.begin(); (it!=search_poses.end()) && (!found); ++it)
01237
01238 {
01239 if (cnt % 50 == 0)
01240 ROS_INFO("Cnt %i", cnt);
01241
01242
01243 if (!collisionFreeCoarse(*it))
01244 continue;
01245
01246
01247
01248
01249
01250
01251 bool good = true;
01252 geometry_msgs::PoseStamped currgoal;
01253
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
01261
01262
01263
01264 actP = it->inverseTimes(actP);
01265
01266
01267
01268
01269
01270 tf::poseTFToMsg(actP,currgoal.pose);
01271
01272 good &= run_ik(goal->arm[i].data,currgoal ,start_angles[0],sol_angles);
01273 }
01274
01275
01276
01277 if (good)
01278
01279 if (collisionFree(*it) && collisionFreeFine(*it))
01280
01281 {
01282 if (!found)
01283 {
01284
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
01295
01296
01297
01298
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
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
01320 if (as_.isPreemptRequested() || !ros::ok())
01321 {
01322 ROS_INFO("%s: Preempted", action_name_.c_str());
01323
01324 as_.setPreempted();
01325 success = false;
01326 break;
01327 }
01328
01329
01330 }
01331
01332
01333 if (success)
01334 {
01335
01336 ROS_INFO("%s: Succeeded", action_name_.c_str());
01337
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
01351
01352
01353
01354
01355
01356
01357
01358
01359
01360
01361
01362
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
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