action_check_path.cpp
Go to the documentation of this file.
00001 /*********************************************************************
00002  * Software License Agreement (BSD License)
00003  * 
00004  *  Copyright (c) 2008, Willow Garage, Inc.
00005  *  All rights reserved.
00006  * 
00007  *  Redistribution and use in source and binary forms, with or without
00008  *  modification, are permitted provided that the following conditions
00009  *  are met:
00010  * 
00011  *   * Redistributions of source code must retain the above copyright
00012  *     notice, this list of conditions and the following disclaimer.
00013  *   * Redistributions in binary form must reproduce the above
00014  *     copyright notice, this list of conditions and the following
00015  *     disclaimer in the documentation and/or other materials provided
00016  *     with the distribution.
00017  *   * Neither the name of Willow Garage nor the names of its
00018  *     contributors may be used to endorse or promote products derived
00019  *     from this software without specific prior written permission.
00020  * 
00021  *  THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
00022  *  "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
00023  *  LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
00024  *  FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
00025  *  COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
00026  *  INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
00027  *  BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
00028  *  LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
00029  *  CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
00030  *  LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
00031  *  ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
00032  *  POSSIBILITY OF SUCH DAMAGE.
00033  *********************************************************************/
00034 
00035 /* Author: Wim Meeussen */
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   // transform goal message to map frame
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   // check how far goal point is from current robot pose
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     // check for timeout
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     // find path
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       // calculate length of path
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 


pr2_doors_actions
Author(s): Wim Meeussen
autogenerated on Wed Dec 11 2013 14:17:44