5 #include <ed_msgs/SimpleQuery.h>
7 #include <nav_core/base_local_planner.h>
17 using namespace cb_base_navigation_msgs;
21 LocalPlannerInterface::~LocalPlannerInterface()
24 local_planner_.reset();
27 controller_thread_->join();
31 controller_thread_(nullptr),
32 action_server_(nullptr),
33 lp_loader_(
"nav_core",
"nav_core::BaseLocalPlanner"),
38 ros::NodeHandle nh(
"~");
42 nh.param(
"local_planner", local_planner,
std::string(
"dwa_local_planner/DWAPlannerROS"));
48 vel_pub_ = gh.advertise<geometry_msgs::Twist>(
"cmd_vel", 1);
52 if(!
lp_loader_.isClassAvailable(local_planner)){
54 for(
unsigned int i = 0; i < classes.
size(); ++i){
55 if(local_planner ==
lp_loader_.getName(classes[i])){
56 local_planner = classes[i];
break;
62 }
catch (
const pluginlib::PluginlibException& ex)
64 ROS_FATAL(
"Failed to create the %s planner, are you sure it is properly registered and that the containing library is built? Exception: %s", local_planner.
c_str(), ex.what());
74 ROS_INFO_STREAM(
"Local planner of type: '" << local_planner <<
"' initialized.");
79 ed_client_ = gh.serviceClient<ed_msgs::SimpleQuery>(
"ed/simple_query");
84 boost::unique_lock<boost::mutex> lock(
goal_mtx_);
86 ROS_DEBUG(
"Incoming topic plan.");
94 ROS_ERROR(
"Received a plan of length 0, is something wrong?");
100 boost::unique_lock<boost::mutex> lock(
goal_mtx_);
102 ROS_DEBUG(
"Incoming actionlib plan.");
110 ROS_ERROR(
"Received a plan of length 0, is something wrong?");
116 boost::unique_lock<boost::mutex> lock(
goal_mtx_);
134 ROS_ERROR(
"LPI: Local costmap map update frequency should be 0, it is now: %2f Hz. This is not allowed by the Local Planner Interface!",
costmap_->
getMapUpdateFrequency());
135 ROS_ERROR(
"LPI: [[ Shutting down ... ]] ");
160 static ros::Time t_last_rate_met = ros::Time::now();
162 if (r.cycleTime() < r.expectedCycleTime())
163 t_last_rate_met = ros::Time::now();
165 if ((ros::Time::now() - t_last_rate_met).toSec() > 1.0)
167 ROS_WARN_STREAM(
"LPI: Local planner rate of " << 1.0 / r.expectedCycleTime().toSec() <<
" hz not met. " <<
profiler);
168 t_last_rate_met = ros::Time::now();
183 while(it != plan.
end()){
184 const geometry_msgs::PoseStamped& w = *it;
186 double x_diff = global_pose.pose.position.x - w.pose.position.x;
187 double y_diff = global_pose.pose.position.y - w.pose.position.y;
188 double distance_sq = x_diff * x_diff + y_diff * y_diff;
189 if(distance_sq < .5){
191 ROS_DEBUG(
"Nearest waypoint to <%f, %f> is <%f, %f>\n", global_pose.pose.position.x, global_pose.pose.position.y, w.pose.position.x, w.pose.position.y);
203 for (
unsigned int i = 1; i < plan.
size(); ++i)
204 distance+=hypot(plan[i].pose.position.x-plan[i-1].pose.position.x, plan[i].pose.position.y-plan[i-1].pose.position.y);
214 if (costmap->
worldToMap(it->pose.position.x, it->pose.position.y, mx, my))
218 p = it->pose.position;
228 boost::unique_lock<boost::mutex> lock(
goal_mtx_);
230 geometry_msgs::PoseStamped global_pose;
240 geometry_msgs::Twist tw;
242 ROS_INFO(
"LPI: Local planner arrived at the goal position/orientation; clearing plan...");
249 geometry_msgs::Twist tw;
270 tf2::Transform constraint_to_world_tf;
272 if (
goal_.orientation_constraint.frame ==
"/map" ||
goal_.orientation_constraint.frame ==
"map")
274 constraint_to_world_tf = tf2::Transform::getIdentity();
278 ed_msgs::SimpleQuery ed_query;
279 ed_query.request.id =
goal_.orientation_constraint.frame;
284 ROS_ERROR(
"LPI: Failed to get robot orientation constraint frame: ED could not be queried.");
288 if (ed_query.response.entities.empty())
290 ROS_ERROR_STREAM(
"LPI: Failed to get robot orientation constraint frame: ED returns 'no such entity'. ("
291 <<
goal_.orientation_constraint.frame <<
").");
295 const ed_msgs::EntityInfo& e_info = ed_query.response.entities.front();
297 tf2::Transform world_to_constraint_tf;
298 tf2::fromMsg(e_info.pose, world_to_constraint_tf);
299 constraint_to_world_tf = world_to_constraint_tf;
314 tf2::Vector3 look_at, end_point;
315 tf2::fromMsg(
goal_.orientation_constraint.look_at, look_at);
316 tf2::fromMsg(
goal_.plan.back().pose.position, end_point);
319 tf2::Vector3 diff = constraint_to_world_tf*look_at - end_point;
322 geometry_msgs::Quaternion& q =
goal_.plan.back().pose.orientation;
323 tf2::Quaternion new_quat;
324 new_quat.setRPY(0, 0, atan2(diff.y(),diff.x()) +
goal_.orientation_constraint.angle_offset);
327 bool changed = (q.x == 0 && q.y == 0 && q.z == 0 && q.w == 0);
331 tf2::Quaternion current_quat;
332 tf2::fromMsg(
goal_.plan.back().pose.orientation, current_quat);
333 changed = abs(current_quat.dot(new_quat)) < 1-1e-6;
340 q = tf2::toMsg(new_quat);