00001
00002
00003
00004
00005
00006
00007 #include "yocs_navigator/semantic_navigator.hpp"
00008
00009 namespace yocs_navigator {
00010 void SemanticNavigator::processNavigation(yocs_msgs::NavigateToGoal::ConstPtr goal)
00011 {
00012 std::string location = goal->location;
00013 int approach_type = goal->approach_type;
00014 unsigned int num_retry = goal->num_retry;
00015 double distance = goal->distance;
00016 double timeout = goal->timeout;
00017
00018 yocs_msgs::Waypoint waypoint;
00019 bool result;
00020
00021 result = getGoalLocation(location, waypoint);
00022 if(!result)
00023 {
00024 std::stringstream ss;
00025 ss << "failed to find the requested destination : " << location;
00026 terminateNavigation(false, ss.str());
00027 return;
00028 }
00029
00030 if(mtk::sameFrame(waypoint.header.frame_id, global_frame_) == false)
00031 {
00032 terminateNavigation(false, "Target is not in global frame");
00033 return;
00034 }
00035 clearCostmaps();
00036
00037 switch(approach_type) {
00038 case yocs_msgs::NavigateToGoal::APPROACH_NEAR:
00039 loginfo("Approach Type : NEAR");
00040 goNear(waypoint, distance, num_retry, timeout);
00041 break;
00042 case yocs_msgs::NavigateToGoal::APPROACH_ON:
00043 loginfo("Approach Type : ON");
00044 goOn(waypoint, distance, num_retry, timeout);
00045 break;
00046 default:
00047 terminateNavigation(false, "Invalid Approach Type");
00048 break;
00049 }
00050 }
00051
00052 void SemanticNavigator::goOn(const yocs_msgs::Waypoint waypoint, const double in_distance, const int num_retry, const double timeout)
00053 {
00054
00055 geometry_msgs::PoseStamped target;
00056 target.pose = waypoint.pose;
00057 target.header = waypoint.header;
00058
00059 int attempt = 0;
00060 int move_base_result;
00061 int navi_result;
00062 bool retry;
00063 bool final_result;
00064 std::string message;
00065 move_base_msgs::MoveBaseGoal mb_goal;
00066
00067 ros::Time started_time = ros::Time::now();
00068
00069 while(ros::ok())
00070 {
00071 move_base_result = NAVI_UNKNOWN;
00072 mb_goal.target_pose = target;
00073 ac_move_base_.sendGoal(mb_goal, actionlib::SimpleActionClient<move_base_msgs::MoveBaseAction>::SimpleDoneCallback(),
00074 actionlib::SimpleActionClient<move_base_msgs::MoveBaseAction>::SimpleActiveCallback(),
00075 boost::bind(&SemanticNavigator::processMoveBaseFeedback, this, _1, target));
00076
00077 waitForMoveBase(move_base_result, started_time, timeout);
00078 determineNavigationState(navi_result, move_base_result, ac_move_base_.getState());
00079 nextState(retry, final_result, message, navi_result, started_time);
00080
00081 if(retry == false) break;
00082 else if(attempt > num_retry)
00083 {
00084 final_result = false;
00085 message = "Tried enough... I failed to navigate..";
00086 break;
00087 }
00088
00089 attempt++;
00090 std::stringstream ss;
00091 ss << "Reattempt to naviate.. " << attempt;
00092
00093 ros::Time current_time = ros::Time::now();
00094 double diff = (current_time - started_time).toSec();
00095 double remain_time = timeout - diff;
00096
00097 feedbackNavigation(yocs_msgs::NavigateToFeedback::STATUS_RETRY, distance_to_goal_, remain_time, ss.str());
00098 clearCostmaps();
00099 }
00100
00101 terminateNavigation(final_result, message);
00102 }
00103
00104 void SemanticNavigator::goNear(const yocs_msgs::Waypoint waypoint, const double distance, const int num_retry, const double timeout)
00105 {
00106 geometry_msgs::PoseStamped target;
00107 target.pose = waypoint.pose;
00108 target.header = waypoint.header;
00109
00110 int attempt = 0;
00111 int move_base_result;
00112 int navi_result;
00113 bool retry;
00114 bool final_result;
00115 std::string message;
00116 move_base_msgs::MoveBaseGoal mb_goal;
00117
00118 ros::Time started_time = ros::Time::now();
00119
00120 while(attempt < num_retry && ros::ok())
00121 {
00122 move_base_result = NAVI_UNKNOWN;
00123 mb_goal.target_pose = target;
00124 ac_move_base_.sendGoal(mb_goal, actionlib::SimpleActionClient<move_base_msgs::MoveBaseAction>::SimpleDoneCallback(),
00125 actionlib::SimpleActionClient<move_base_msgs::MoveBaseAction>::SimpleActiveCallback(),
00126 boost::bind(&SemanticNavigator::processMoveBaseFeedback, this, _1, target));
00127 waitForMoveBase(move_base_result, started_time, timeout);
00128 determineNavigationState(navi_result, move_base_result, ac_move_base_.getState());
00129 nextState(retry, final_result, message, navi_result, started_time);
00130
00131 if(retry == false) break;
00132
00133 attempt++;
00134
00135 if(attempt > num_retry)
00136 {
00137 final_result = false;
00138 message = "Tried enough... I failed to navigate..";
00139 break;
00140 }
00141 }
00142
00143 terminateNavigation(final_result, message);
00144 }
00145
00146
00147 void SemanticNavigator::processMoveBaseFeedback(const move_base_msgs::MoveBaseFeedback::ConstPtr& feedback, const geometry_msgs::PoseStamped& target_pose)
00148 {
00149 geometry_msgs::PoseStamped robot_pose = feedback->base_position;
00150
00151
00152 double distance = mtk::distance2D(robot_pose.pose.position.x, robot_pose.pose.position.y, target_pose.pose.position.x, target_pose.pose.position.y);
00153 distance_to_goal_ = distance;
00154 }
00155 }