$search
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)