Go to the documentation of this file.00001 #include <lama_jockeys/navigating_jockey.h>
00002
00003 namespace lama_jockeys
00004 {
00005
00006 NavigatingJockey::NavigatingJockey(const std::string& name) :
00007 Jockey(name),
00008 server_(nh_, name, boost::bind(&NavigatingJockey::goalCallback, this, _1), false),
00009 goal_reached_(false)
00010 {
00011 server_.registerPreemptCallback(boost::bind(&NavigatingJockey::preemptCallback, this));
00012
00013 server_.start();
00014 ROS_DEBUG("Action server '%s' started for Navigation", jockey_name_.c_str());
00015
00016 if (!private_nh_.getParamCached("max_goal_distance", max_goal_distance_))
00017 max_goal_distance_ = 10.0;
00018 if (!private_nh_.getParamCached("max_goal_dtheta", max_goal_dtheta_))
00019 max_goal_dtheta_ = 0.785;
00020 if (!private_nh_.getParamCached("kp_v", kp_v_))
00021 kp_v_ = 0.05;
00022 if (!private_nh_.getParamCached("kp_w", kp_w_))
00023 kp_w_ = 0.2;
00024 if (!private_nh_.getParamCached("min_velocity", min_velocity_))
00025 min_velocity_ = 0.020;
00026 if (!private_nh_.getParamCached("reach_distance", reach_distance_))
00027 reach_distance_ = 0.050;
00028 }
00029
00030 void NavigatingJockey::goalCallback(const lama_jockeys::NavigateGoalConstPtr& goal)
00031 {
00032 goal_.action = goal->action;
00033
00034
00035 if (server_.isPreemptRequested() || !ros::ok())
00036 {
00037 ROS_INFO("%s: Preempted", jockey_name_.c_str());
00038
00039 server_.setPreempted();
00040 return;
00041 }
00042
00043 switch (goal_.action)
00044 {
00045 case lama_jockeys::NavigateGoal::STOP:
00046 ROS_DEBUG("Received action STOP");
00047 initAction();
00048
00049 goal_.edge = lama_msgs::LamaObject();
00050 goal_.descriptor_link = lama_msgs::DescriptorLink();
00051 goal_.relative_edge_start = geometry_msgs::Pose();
00052 onStop();
00053 break;
00054 case lama_jockeys::NavigateGoal::TRAVERSE:
00055 ROS_DEBUG("Received action TRAVERSE");
00056 initAction();
00057 goal_.edge = goal->edge;
00058 goal_.descriptor_link = goal->descriptor_link;
00059 goal_.relative_edge_start = goal->relative_edge_start;
00060 onTraverse();
00061 break;
00062 case lama_jockeys::NavigateGoal::INTERRUPT:
00063 ROS_DEBUG("Received action INTERRUPT");
00064 interrupt();
00065 onInterrupt();
00066 break;
00067 case lama_jockeys::NavigateGoal::CONTINUE:
00068 ROS_DEBUG("Received action CONTINUE");
00069 resume();
00070 onContinue();
00071 break;
00072 }
00073 }
00074
00075 void NavigatingJockey::preemptCallback()
00076 {
00077 ROS_INFO("%s: Preempted", jockey_name_.c_str());
00078
00079 server_.setPreempted();
00080 }
00081
00082 void NavigatingJockey::initAction()
00083 {
00084 Jockey::initAction();
00085 result_ = NavigateResult();
00086 }
00087
00088 void NavigatingJockey::onInterrupt()
00089 {
00090 ROS_DEBUG("%s: navigating goal %d interrupted", jockey_name_.c_str(), goal_.edge.id);
00091 }
00092
00093 void NavigatingJockey::onContinue()
00094 {
00095 ROS_DEBUG("%s: navigating goal %d resumed", jockey_name_.c_str(), goal_.edge.id);
00096 }
00097
00104 geometry_msgs::Twist NavigatingJockey::goToGoal(const geometry_msgs::Point& goal)
00105 {
00106 geometry_msgs::Twist twist;
00107
00108 if (isGoalReached())
00109 return twist;
00110
00111 double distance = std::sqrt(goal.x * goal.x + goal.y * goal.y);
00112 if (distance > max_goal_distance_)
00113 {
00114 ROS_DEBUG("%s: distance to goal (%f) is greater than max (%f)", jockey_name_.c_str(), distance, max_goal_distance_);
00115 return twist;
00116 }
00117
00118 if (distance < reach_distance_)
00119 {
00120 setGoalReached();
00121 return twist;
00122 }
00123
00124 double dtheta = std::atan2(goal.y, goal.x);
00125 ROS_DEBUG("%s: distance to goal: %f, dtheta to goal: %f", jockey_name_.c_str(), distance, dtheta);
00126 if (dtheta > max_goal_dtheta_) dtheta = max_goal_dtheta_;
00127 if (dtheta < -max_goal_dtheta_) dtheta = -max_goal_dtheta_;
00128
00129
00130
00131 double vx = kp_v_ * distance * (max_goal_dtheta_ - std::fabs(dtheta)) / max_goal_dtheta_;
00132 double wz = kp_w_ * dtheta;
00133 if (vx < min_velocity_)
00134 {
00135 vx = min_velocity_;
00136 }
00137
00138 twist.linear.x = vx;
00139 twist.angular.z = wz;
00140 return twist;
00141 }
00142
00143 }
00144