Go to the documentation of this file.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
00032
00033
00034
00035
00036
00037 #include <pr2_doors_common/door_functions.h>
00038 #include "pr2_doors_actions/action_check_path.h"
00039
00040 using namespace tf;
00041 using namespace KDL;
00042 using namespace ros;
00043 using namespace std;
00044 using namespace door_handle_detector;
00045 using namespace pr2_doors_common;
00046
00047 static const string fixed_frame = "map";
00048
00049
00050 CheckPathAction::CheckPathAction(tf::TransformListener& tf) :
00051 tf_(tf),
00052 action_server_(ros::NodeHandle(),
00053 "check_path",
00054 boost::bind(&CheckPathAction::execute, this, _1))
00055 {};
00056
00057
00058 CheckPathAction::~CheckPathAction()
00059 {};
00060
00061
00062
00063 void CheckPathAction::execute(const door_msgs::CheckPathGoalConstPtr& goal)
00064 {
00065 ROS_INFO("CheckPathAction: execute");
00066
00067
00068 geometry_msgs::PoseStamped goal_tr;
00069 ros::Duration timeout(3.0);
00070 if (!tf_.waitForTransform(goal->goal_pose.header.frame_id, fixed_frame, goal->goal_pose.header.stamp, timeout)){
00071 ROS_ERROR("cannot transform goal from %s to %s at time %f", goal->goal_pose.header.frame_id.c_str(), fixed_frame.c_str(), goal->goal_pose.header.stamp.toSec());
00072 action_server_.setPreempted();
00073 return;
00074 }
00075 tf_.transformPose(fixed_frame, goal->goal_pose, goal_tr);
00076
00077
00078 if (!tf_.waitForTransform(goal_tr.header.frame_id, "base_footprint", Time(), Duration(1.0))){
00079 ROS_ERROR("cannot get transform from %s to %s at time %f", goal_tr.header.frame_id.c_str(), string("base_footprint").c_str(), 0.0);
00080 action_server_.setPreempted();
00081 return;
00082 }
00083 tf::Stamped<tf::Point> goal_point;
00084 goal_point[0] = goal_tr.pose.position.x; goal_point[1] = goal_tr.pose.position.y; goal_point[2] = 0;
00085 goal_point.frame_id_ = goal_tr.header.frame_id;
00086 goal_point.stamp_ = Time();
00087 tf_.transformPoint("base_footprint", goal_point, goal_point);
00088 double length_straight = goal_point.length();
00089 ROS_INFO("Try to find path to (%f %f %f), which is %f [m] from the current robot pose.",
00090 goal_tr.pose.position.x, goal_tr.pose.position.y, goal_tr.pose.position.z, length_straight);
00091
00092
00093 ROS_INFO("call planner to find path");
00094 req_plan.goal = goal_tr;
00095 req_plan.tolerance = 0.0;
00096 Duration timeout_check_path(5.0);
00097 Time start_time = Time::now();
00098 while (ros::ok() && !action_server_.isPreemptRequested()){
00099
00100 if (Time::now() > start_time + timeout_check_path){
00101 ROS_ERROR("Timeout checking paths. Did not find a path.");
00102 action_result_.path_found = false;
00103 action_server_.setSucceeded(action_result_);
00104 return;
00105 }
00106
00107 if (!ros::service::call("move_base_node/make_plan", req_plan, res_plan))
00108 ROS_ERROR("Service for check path is not available");
00109 else if (res_plan.plan.poses.size() >= 2){
00110 ROS_INFO("Found possible path");
00111
00112 double length = 0;
00113 for (unsigned int i=0; i<res_plan.plan.poses.size()-1; i++){
00114 length += sqrt( ((res_plan.plan.poses[i].pose.position.x - res_plan.plan.poses[i+1].pose.position.x)*
00115 (res_plan.plan.poses[i].pose.position.x - res_plan.plan.poses[i+1].pose.position.x))+
00116 ((res_plan.plan.poses[i].pose.position.y - res_plan.plan.poses[i+1].pose.position.y)*
00117 (res_plan.plan.poses[i].pose.position.y - res_plan.plan.poses[i+1].pose.position.y)));
00118 }
00119 if (length < 2.0 * length_straight && length < 5.0){
00120 ROS_INFO("received path from planner of length %f", length);
00121 action_result_.path_found = true;
00122 action_server_.setSucceeded(action_result_);
00123 return;
00124 }
00125 }
00126 Duration(1.0).sleep();
00127 }
00128 ROS_ERROR("CheckPathAction: preempted");
00129 action_server_.setPreempted();
00130 };
00131