36 #include <unordered_map> 44 #include <costmap_cspace_msgs/CSpace3D.h> 45 #include <costmap_cspace_msgs/CSpace3DUpdate.h> 47 #include <geometry_msgs/PoseArray.h> 48 #include <nav_msgs/GetPlan.h> 49 #include <nav_msgs/OccupancyGrid.h> 50 #include <nav_msgs/Path.h> 51 #include <planner_cspace_msgs/PlannerStatus.h> 52 #include <sensor_msgs/PointCloud.h> 53 #include <std_srvs/Empty.h> 54 #include <trajectory_tracker_msgs/PathWithVelocity.h> 63 #include <move_base_msgs/MoveBaseAction.h> 64 #include <planner_cspace_msgs/MoveWithToleranceAction.h> 108 std::shared_ptr<Planner3DActionServer>
act_;
115 Astar::Gridmap<char, 0x40>
cm_;
218 std_srvs::EmptyResponse& res)
220 ROS_WARN(
"Forgetting remembered costmap.");
222 bbf_costmap_.
clear();
235 const int tolerance_range,
236 const int tolerance_angle,
239 if (!cm.validate(pose_discrete, range_))
243 if (cm[pose_discrete] == 100)
253 const int tolerance_range,
254 const int tolerance_angle,
255 bool use_cm_rough =
false)
const 259 pose_discrete[2] = 0;
269 nav_msgs::GetPlan::Response& res)
273 ROS_ERROR(
"make_plan service is called without map.");
277 if (req.start.header.frame_id != map_header_.frame_id ||
278 req.goal.header.frame_id != map_header_.frame_id)
280 ROS_ERROR(
"Start [%s] and Goal [%s] poses must be in the map frame [%s].",
281 req.start.header.frame_id.c_str(),
282 req.goal.header.frame_id.c_str(),
283 map_header_.frame_id.c_str());
289 map_info_, s[0], s[1], s[2],
290 req.start.pose.position.x, req.start.pose.position.y,
tf2::getYaw(req.start.pose.orientation));
292 map_info_, e[0], e[1], e[2],
293 req.goal.pose.position.x, req.goal.pose.position.y,
tf2::getYaw(req.goal.pose.orientation));
294 ROS_INFO(
"Path plan from (%d, %d) to (%d, %d)", s[0], s[1], e[0], e[1]);
296 const int tolerance_range = std::lround(req.tolerance / map_info_.linear_resolution);
299 switch (start_status)
302 ROS_ERROR(
"Given start is not on the map.");
308 ROS_INFO(
"Given start is moved (%d, %d)", s[0], s[1]);
316 ROS_ERROR(
"Given goal is not on the map.");
322 ROS_INFO(
"Given goal is moved (%d, %d)", e[0], e[1]);
328 const auto cb_progress = [](
const std::list<Astar::Vec>& ,
const SearchStats& )
333 const auto ts = boost::chrono::high_resolution_clock::now();
337 std::list<Astar::Vec> path_grid;
338 std::vector<GridAstarModel3D::VecWithCost> starts;
339 starts.emplace_back(s);
341 starts, e, path_grid,
344 0, 1.0f / freq_min_, find_best_))
346 ROS_WARN(
"Path plan failed (goal unreachable)");
349 const auto tnow = boost::chrono::high_resolution_clock::now();
351 boost::chrono::duration<float>(tnow - ts).count());
357 const std::list<Astar::Vecf> path_interpolated =
358 model_->path_interpolator_.interpolate(path_grid, 0.5, 0.0);
362 res.plan.poses.resize(path.poses.size());
363 for (
size_t i = 0; i < path.poses.size(); ++i)
365 res.plan.poses[i] = path.poses[i];
370 void cbGoal(
const geometry_msgs::PoseStamped::ConstPtr& msg)
372 if (act_->isActive() || act_tolerant_->isActive())
374 ROS_ERROR(
"Setting new goal is ignored since planner_3d is proceeding the action.");
381 ROS_WARN(
"Preempting the current goal.");
382 if (act_->isActive())
383 act_->setPreempted(move_base_msgs::MoveBaseResult(),
"Preempted.");
385 if (act_tolerant_->isActive())
386 act_tolerant_->setPreempted(planner_cspace_msgs::MoveWithToleranceResult(),
"Preempted.");
389 status_.status = planner_cspace_msgs::PlannerStatus::DONE;
392 bool setGoal(
const geometry_msgs::PoseStamped& msg)
394 if (msg.header.frame_id != map_header_.frame_id)
396 ROS_ERROR(
"Goal [%s] pose must be in the map frame [%s].",
397 msg.header.frame_id.c_str(), map_header_.frame_id.c_str());
401 goal_raw_ = goal_ = msg;
404 goal_.pose.orientation.x * goal_.pose.orientation.x +
405 goal_.pose.orientation.y * goal_.pose.orientation.y +
406 goal_.pose.orientation.z * goal_.pose.orientation.z +
407 goal_.pose.orientation.w * goal_.pose.orientation.w;
408 if (std::abs(len2 - 1.0) < 0.1)
418 status_.status = planner_cspace_msgs::PlannerStatus::DOING;
425 if (act_->isActive())
426 act_->setSucceeded(move_base_msgs::MoveBaseResult(),
"Goal cleared.");
427 if (act_tolerant_->isActive())
428 act_tolerant_->setSucceeded(planner_cspace_msgs::MoveWithToleranceResult(),
"Goal cleared.");
434 Astar::Gridmap<float>& g,
437 ROS_DEBUG(
"Cost estimation cache search queue initial size: %lu, capacity: %lu", open.size(), open.
capacity());
444 std::vector<Astar::Vec> pos;
447 std::vector<SearchDiffs> search_diffs;
451 const int range_rough = 4;
452 for (d[0] = -range_rough; d[0] <= range_rough; d[0]++)
454 for (d[1] = -range_rough; d[1] <= range_rough; d[1]++)
456 if (d[0] == 0 && d[1] == 0)
458 if (d.
sqlen() > range_rough * range_rough)
464 const int dist = d.
len();
465 const float dpx =
static_cast<float>(d[0]) / dist;
466 const float dpy =
static_cast<float>(d[1]) / dist;
468 for (
int i = 0; i < dist; i++)
471 if (diffs.pos.size() == 0 || diffs.pos.back() != ipos)
473 diffs.pos.push_back(std::move(ipos));
478 diffs.grid_to_len = grid_to_len;
480 search_diffs.push_back(std::move(diffs));
485 std::vector<Astar::PriorityVec> centers;
486 centers.reserve(num_cost_estim_task_);
490 std::vector<Astar::GridmapUpdate> updates;
491 updates.reserve(num_cost_estim_task_ * search_diffs.size() / omp_get_num_threads());
493 const float range_overshoot = ec_[0] * (range_ + local_range_ +
longcut_range_);
505 Astar::PriorityVec center(open.top());
507 if (center.p_raw_ > g[center.v_])
509 if (center.p_raw_ - range_overshoot > g[s_rough])
511 centers.emplace_back(std::move(center));
516 if (centers.size() == 0)
520 #pragma omp for schedule(static) 521 for (
auto it = centers.cbegin(); it < centers.cend(); ++it)
525 for (
const SearchDiffs& ds : search_diffs)
530 if (static_cast<size_t>(next[0]) >=
static_cast<size_t>(map_info_.width) ||
531 static_cast<size_t>(next[1]) >=
static_cast<size_t>(map_info_.height))
534 float cost = model_->euclidCostRough(d);
536 const float gnext = g[next];
538 if (gnext < g[p] + cost)
545 float sum = 0, sum_hist = 0;
546 bool collision =
false;
547 for (
const auto& d : ds.pos)
550 const char c = cm_rough_[pos];
557 sum_hist += bbf_costmap_.
getCost(pos);
562 (map_info_.linear_resolution * ds.grid_to_len / 100.0) *
572 const float cost_next = it->p_raw_ + cost;
573 if (gnext > cost_next)
575 updates.emplace_back(p, next, cost_next, cost_next);
582 for (
const Astar::GridmapUpdate& u : updates)
584 if (g[u.getPos()] > u.getCost())
586 g[u.getPos()] = u.getCost();
587 open.push(std::move(u.getPriorityVec()));
593 rough_cost_max_ = g[s_rough] + ec_[0] * (range_ +
local_range_);
598 const int cost_acceptable = 50,
const int min_xy_range = 0)
const 600 ROS_DEBUG(
"%d, %d (%d,%d,%d)", xy_range, angle_range, s[0], s[1], s[2]);
602 float range_min = std::numeric_limits<float>::max();
605 for (d[2] = -angle_range; d[2] <= angle_range; d[2]++)
607 for (d[0] = -xy_range; d[0] <= xy_range; d[0]++)
609 for (d[1] = -xy_range; d[1] <= xy_range; d[1]++)
611 if (d[0] == 0 && d[1] == 0 && d[2] == 0)
613 if (d.
sqlen() > xy_range * xy_range)
615 if (d.
sqlen() < min_xy_range * min_xy_range)
619 if ((
unsigned int)s2[0] >= (
unsigned int)map_info_.width ||
620 (
unsigned int)s2[1] >= (
unsigned int)map_info_.height)
623 if (!cm_.validate(s2, range_))
626 if (cm_[s2] >= cost_acceptable)
628 const auto cost = model_->euclidCost(d);
629 if (cost < range_min)
638 if (range_min == std::numeric_limits<float>::max())
640 if (cost_acceptable != 100)
648 ROS_DEBUG(
" (%d,%d,%d)", s[0], s[1], s[2]);
656 if (!has_map_ || !has_start_)
658 ROS_ERROR(
"Goal received, however map/goal/start are not ready. (%d/%d/%d)",
659 static_cast<int>(has_map_), static_cast<int>(has_goal_), static_cast<int>(has_start_));
665 map_info_, s[0], s[1], s[2],
666 start_.pose.position.x, start_.pose.position.y,
670 map_info_, e[0], e[1], e[2],
671 goal_.pose.position.x, goal_.pose.position.y,
677 "New goal received (%d, %d, %d)",
682 switch (start_pose_status)
685 ROS_ERROR(
"You are on the edge of the world.");
693 switch (goal_pose_status)
696 ROS_ERROR(
"Given goal is not on the map.");
703 ROS_INFO(
"Goal moved (%d, %d, %d)", e[0], e[1], e[2]);
707 goal_.pose.position.x = x;
708 goal_.pose.position.y = y;
713 const auto ts = boost::chrono::high_resolution_clock::now();
715 cost_estim_cache_.clear(std::numeric_limits<float>::max());
717 cost_estim_cache_[e] = -ec_[0] * 0.5;
718 pq_open_.push(Astar::PriorityVec(cost_estim_cache_[e], cost_estim_cache_[e], e));
720 const auto tnow = boost::chrono::high_resolution_clock::now();
721 ROS_DEBUG(
"Cost estimation cache generated (%0.4f sec.)",
722 boost::chrono::duration<float>(tnow - ts).count());
723 cost_estim_cache_[e] = 0;
728 has_hysteresis_map_ =
false;
733 goal_updated_ =
true;
739 for (
const Astar::Vec& p : hyst_updated_cells_)
743 hyst_updated_cells_.clear();
749 sensor_msgs::PointCloud distance_map;
752 distance_map.channels.resize(1);
753 distance_map.channels[0].name =
"distance";
754 distance_map.points.reserve(1024);
755 distance_map.channels[0].values.reserve(1024);
756 const float k_dist = map_info_.linear_resolution * cc_.
max_vel_;
757 for (
Astar::Vec p(0, 0, 0); p[1] < cost_estim_cache_.size()[1]; p[1]++)
759 for (p[0] = 0; p[0] < cost_estim_cache_.size()[0]; p[0]++)
764 geometry_msgs::Point32 point;
767 if (cost_estim_cache_[p] == std::numeric_limits<float>::max())
769 point.z = cost_estim_cache_[p] / 500;
770 distance_map.points.push_back(point);
771 distance_map.channels[0].values.push_back(cost_estim_cache_[p] * k_dist);
774 pub_distance_map_.
publish(distance_map);
779 nav_msgs::OccupancyGrid hysteresis_map;
780 hysteresis_map.header.frame_id = map_header_.frame_id;
781 hysteresis_map.info.resolution = map_info_.linear_resolution;
782 hysteresis_map.info.width = map_info_.width;
783 hysteresis_map.info.height = map_info_.height;
784 hysteresis_map.info.origin = map_info_.origin;
785 hysteresis_map.data.resize(map_info_.width * map_info_.height, 100);
787 for (
Astar::Vec p(0, 0, 0); p[1] < cost_estim_cache_.size()[1]; p[1]++)
789 for (p[0] = 0; p[0] < cost_estim_cache_.size()[0]; p[0]++)
791 if (cost_estim_cache_[p] == std::numeric_limits<float>::max())
795 for (
Astar::Vec p2 = p; p2[2] <
static_cast<int>(map_info_.angle); ++p2[2])
797 cost = std::min(cm_hyst_[p2], cost);
799 hysteresis_map.data[p[0] + p[1] * map_info_.width] = cost;
802 pub_hysteresis_map_.
publish(hysteresis_map);
809 nav_msgs::OccupancyGrid remembered_map;
810 remembered_map.header.frame_id = map_header_.frame_id;
811 remembered_map.info.resolution = map_info_.linear_resolution;
812 remembered_map.info.width = map_info_.width;
813 remembered_map.info.height = map_info_.height;
814 remembered_map.info.origin = map_info_.origin;
815 remembered_map.data.resize(map_info_.width * map_info_.height);
819 remembered_map.data[p[0] + p[1] * map_info_.width] =
822 bbf_costmap_.
forEach(generate_pointcloud);
823 pub_remembered_map_.
publish(remembered_map);
831 if (use_path_with_velocity_)
835 path, std::numeric_limits<double>::quiet_NaN()));
843 void cbMapUpdate(
const costmap_cspace_msgs::CSpace3DUpdate::ConstPtr& msg)
849 const auto ts_cm_init_start = boost::chrono::high_resolution_clock::now();
853 cm_.copy_partially(cm_base_,
Astar::Vec(prev_map_update_x_min_, prev_map_update_y_min_, 0),
854 Astar::Vec(prev_map_update_x_max_, prev_map_update_y_max_, static_cast<int>(map_info_.angle)));
855 cm_rough_.copy_partially(cm_rough_base_,
Astar::Vec(prev_map_update_x_min_, prev_map_update_y_min_, 0),
856 Astar::Vec(prev_map_update_x_max_, prev_map_update_y_max_, 1));
857 cm_updates_.clear_partially(-1,
Astar::Vec(prev_map_update_x_min_, prev_map_update_y_min_, 0),
858 Astar::Vec(prev_map_update_x_max_, prev_map_update_y_max_, 1));
860 const int map_update_x_min =
static_cast<int>(msg->x);
861 const int map_update_x_max =
static_cast<int>(msg->x + msg->width);
862 const int map_update_y_min =
static_cast<int>(msg->y);
863 const int map_update_y_max =
static_cast<int>(msg->y + msg->height);
864 const int search_range_x_min = std::max(0, std::min(prev_map_update_x_min_, map_update_x_min) - 1);
865 const int search_range_x_max = std::min(static_cast<int>(map_info_.width),
866 std::max(prev_map_update_x_max_, map_update_x_max) + 1);
867 const int search_range_y_min = std::max(0, std::min(prev_map_update_y_min_, map_update_y_min) - 1);
868 const int search_range_y_max = std::min(static_cast<int>(map_info_.height),
869 std::max(prev_map_update_y_max_, map_update_y_max) + 1);
870 prev_map_update_x_min_ = map_update_x_min;
871 prev_map_update_x_max_ = map_update_x_max;
872 prev_map_update_y_min_ = map_update_y_min;
873 prev_map_update_y_max_ = map_update_y_max;
875 bool clear_hysteresis(
false);
879 static_cast<int>(msg->x), static_cast<int>(msg->y), static_cast<int>(msg->yaw));
881 for (
Astar::Vec p(0, 0, 0); p[0] <
static_cast<int>(msg->width); p[0]++)
883 for (p[1] = 0; p[1] <
static_cast<int>(msg->height); p[1]++)
886 for (p[2] = 0; p[2] <
static_cast<int>(msg->angle); p[2]++)
888 const size_t addr = ((p[2] * msg->height) + p[1]) * msg->width + p[0];
889 const char c = msg->data[addr];
892 if (c == 100 && !clear_hysteresis && cm_hyst_[gp + p] == 0)
893 clear_hysteresis =
true;
896 cm_updates_[gp_rough + p] = cost_min;
897 if (cost_min > cm_rough_[gp_rough + p])
898 cm_rough_[gp_rough + p] = cost_min;
900 for (p[2] = 0; p[2] <
static_cast<int>(msg->angle); p[2]++)
902 const size_t addr = ((p[2] * msg->height) + p[1]) * msg->width + p[0];
903 const char c = msg->data[addr];
918 const auto ts_cm_init_end = boost::chrono::high_resolution_clock::now();
919 ROS_DEBUG(
"Costmaps updated (%.4f)", boost::chrono::duration<float>(ts_cm_init_end - ts_cm_init_start).count());
921 if (clear_hysteresis && has_hysteresis_map_)
923 ROS_INFO(
"The previous path collides to the obstacle. Clearing hysteresis map.");
925 has_hysteresis_map_ =
false;
933 map_info_, s[0], s[1], s[2],
934 start_.pose.position.x, start_.pose.position.y,
938 if (remember_updates_)
942 remember_hit_odds_, remember_miss_odds_,
943 hist_ignore_range_, hist_ignore_range_max_);
950 if (!fast_map_update_)
958 map_info_, e[0], e[1], e[2],
959 goal_.pose.position.x, goal_.pose.position.y,
971 const auto ts = boost::chrono::high_resolution_clock::now();
975 float cost_min = std::numeric_limits<float>::max();
976 for (p[1] = search_range_y_min; p[1] < search_range_y_max; p[1]++)
978 for (p[0] = search_range_x_min; p[0] < search_range_x_max; p[0]++)
980 if (cost_min > cost_estim_cache_[p])
983 cost_min = cost_estim_cache_[p];
991 if (cost_min != std::numeric_limits<float>::max())
992 pq_erase_.emplace(cost_min, cost_min, p_cost_min);
995 if (pq_erase_.size() < 1)
997 const Astar::PriorityVec center(pq_erase_.top());
1001 if (cost_estim_cache_[p] == std::numeric_limits<float>::max())
1003 cost_estim_cache_[p] = std::numeric_limits<float>::max();
1007 for (d[0] = -1; d[0] <= 1; d[0]++)
1009 for (d[1] = -1; d[1] <= 1; d[1]++)
1011 if (!((d[0] == 0) ^ (d[1] == 0)))
1015 if ((
unsigned int)next[0] >= (
unsigned int)map_info_.width ||
1016 (
unsigned int)next[1] >= (
unsigned int)map_info_.height)
1018 const float gn = cost_estim_cache_[next];
1019 if (gn == std::numeric_limits<float>::max())
1023 pq_open_.emplace(gn, gn, next);
1026 pq_erase_.emplace(gn, gn, next);
1030 if (pq_open_.size() == 0)
1032 pq_open_.emplace(-ec_[0] * 0.5, -ec_[0] * 0.5, e);
1034 ROS_DEBUG(
"Cost estimation cache partial update from: %0.3f", rough_cost_max_);
1038 for (p[0] = 0; p[0] <
static_cast<int>(map_info_.width); p[0]++)
1040 for (p[1] = 0; p[1] <
static_cast<int>(map_info_.height); p[1]++)
1042 const auto gp = cost_estim_cache_[p];
1043 if ((gp > rough_cost_max_) && (gp != std::numeric_limits<float>::max()))
1045 pq_open_.emplace(gp, gp, p);
1052 const auto tnow = boost::chrono::high_resolution_clock::now();
1053 ROS_DEBUG(
"Cost estimation cache updated (%0.4f sec.)",
1054 boost::chrono::duration<float>(tnow - ts).count());
1057 void cbMap(
const costmap_cspace_msgs::CSpace3D::ConstPtr& msg)
1060 ROS_INFO(
" linear_resolution %0.2f x (%dx%d) px", msg->info.linear_resolution,
1061 msg->info.width, msg->info.height);
1062 ROS_INFO(
" angular_resolution %0.2f x %d px", msg->info.angular_resolution,
1064 ROS_INFO(
" origin %0.3f m, %0.3f m, %0.3f rad",
1065 msg->info.origin.position.x,
1066 msg->info.origin.position.y,
1077 if (map_info_.linear_resolution != msg->info.linear_resolution ||
1078 map_info_.angular_resolution != msg->info.angular_resolution)
1080 map_info_ = msg->info;
1083 pq_open_.
reserve((map_info_.width + map_info_.height) * 2);
1084 pq_erase_.
reserve((map_info_.width + map_info_.height) * 2);
1086 range_ =
static_cast<int>(search_range_ / map_info_.linear_resolution);
1087 hist_ignore_range_ = std::lround(hist_ignore_range_f_ / map_info_.linear_resolution);
1088 hist_ignore_range_max_ = std::lround(hist_ignore_range_max_f_ / map_info_.linear_resolution);
1089 local_range_ = std::lround(local_range_f_ / map_info_.linear_resolution);
1090 longcut_range_ = std::lround(longcut_range_f_ / map_info_.linear_resolution);
1091 esc_range_ = std::lround(esc_range_f_ / map_info_.linear_resolution);
1092 esc_angle_ = map_info_.angle / 8;
1093 tolerance_range_ = std::lround(tolerance_range_f_ / map_info_.linear_resolution);
1094 tolerance_angle_ = std::lround(tolerance_angle_f_ / map_info_.angular_resolution);
1095 goal_tolerance_lin_ = std::lround(goal_tolerance_lin_f_ / map_info_.linear_resolution);
1096 goal_tolerance_ang_ = std::lround(goal_tolerance_ang_f_ / map_info_.angular_resolution);
1104 cost_estim_cache_, cm_, cm_hyst_, cm_rough_,
1111 map_info_ = msg->info;
1113 map_header_ = msg->header;
1118 static_cast<int>(map_info_.width),
1119 static_cast<int>(map_info_.height),
1120 static_cast<int>(map_info_.angle)
1123 cm_.reset(
Astar::Vec(size[0], size[1], size[2]));
1124 cm_hyst_.reset(
Astar::Vec(size[0], size[1], size[2]));
1126 cost_estim_cache_.reset(
Astar::Vec(size[0], size[1], 1));
1127 cm_rough_.reset(
Astar::Vec(size[0], size[1], 1));
1128 cm_updates_.reset(
Astar::Vec(size[0], size[1], 1));
1132 for (p[0] = 0; p[0] <
static_cast<int>(map_info_.width); p[0]++)
1134 for (p[1] = 0; p[1] <
static_cast<int>(map_info_.height); p[1]++)
1137 for (p[2] = 0; p[2] <
static_cast<int>(map_info_.angle); p[2]++)
1139 const size_t addr = ((p[2] * size[1]) + p[1]) * size[0] + p[0];
1140 char c = msg->data[addr];
1148 cm_rough_[p] = cost_min;
1153 cm_hyst_.clear(100);
1154 hyst_updated_cells_.clear();
1155 has_hysteresis_map_ =
false;
1161 bbf_costmap_.
clear();
1163 prev_map_update_x_min_ = std::numeric_limits<int>::max();
1164 prev_map_update_x_max_ = std::numeric_limits<int>::lowest();
1165 prev_map_update_y_min_ = std::numeric_limits<int>::max();
1166 prev_map_update_y_max_ = std::numeric_limits<int>::lowest();
1172 if (act_tolerant_->isActive())
1174 ROS_ERROR(
"Setting new goal is ignored since planner_3d is proceeding by tolerant_move action.");
1178 move_base_msgs::MoveBaseGoalConstPtr goal = act_->acceptNewGoal();
1179 if (!
setGoal(goal->target_pose))
1180 act_->setAborted(move_base_msgs::MoveBaseResult(),
"Given goal is invalid.");
1185 if (act_->isActive())
1187 ROS_ERROR(
"Setting new goal is ignored since planner_3d is proceeding by move_base action.");
1191 goal_tolerant_ = act_tolerant_->acceptNewGoal();
1192 if (!
setGoal(goal_tolerant_->target_pose))
1193 act_tolerant_->setAborted(planner_cspace_msgs::MoveWithToleranceResult(),
"Given goal is invalid.");
1198 geometry_msgs::PoseStamped start;
1201 start.pose.orientation.x = 0.0;
1202 start.pose.orientation.y = 0.0;
1203 start.pose.orientation.z = 0.0;
1204 start.pose.orientation.w = 1.0;
1205 start.pose.position.x = 0;
1206 start.pose.position.y = 0;
1207 start.pose.position.z = 0;
1210 geometry_msgs::TransformStamped trans =
1235 nh_,
"costmap_update",
1238 nh_,
"move_base_simple/goal",
1240 pub_start_ = pnh_.
advertise<geometry_msgs::PoseStamped>(
"path_start", 1,
true);
1241 pub_end_ = pnh_.
advertise<geometry_msgs::PoseStamped>(
"path_end", 1,
true);
1242 pub_status_ = pnh_.
advertise<planner_cspace_msgs::PlannerStatus>(
"status", 1,
true);
1244 nh_,
"forget_planning_cost",
1249 pub_distance_map_ = pnh_.
advertise<sensor_msgs::PointCloud>(
"distance_map", 1,
true);
1250 pub_hysteresis_map_ = pnh_.
advertise<nav_msgs::OccupancyGrid>(
"hysteresis_map", 1,
true);
1251 pub_remembered_map_ = pnh_.
advertise<nav_msgs::OccupancyGrid>(
"remembered_map", 1,
true);
1260 goal_tolerant_ =
nullptr;
1262 pnh_.
param(
"use_path_with_velocity", use_path_with_velocity_,
false);
1263 if (use_path_with_velocity_)
1265 pub_path_velocity_ = nh_.
advertise<trajectory_tracker_msgs::PathWithVelocity>(
1266 "path_velocity", 1,
true);
1270 pub_path_ = neonavigation_common::compat::advertise<nav_msgs::Path>(
1272 pnh_,
"path", 1,
true);
1274 pub_path_poses_ = pnh_.
advertise<geometry_msgs::PoseArray>(
1275 "path_poses", 1,
true);
1277 pnh_.
param(
"freq", freq_, 4.0
f);
1278 pnh_.
param(
"freq_min", freq_min_, 2.0
f);
1279 pnh_.
param(
"search_timeout_abort", search_timeout_abort_, 30.0
f);
1280 pnh_.
param(
"search_range", search_range_, 0.4
f);
1281 pnh_.
param(
"antialias_start", antialias_start_,
false);
1283 double costmap_watchdog;
1284 pnh_.
param(
"costmap_watchdog", costmap_watchdog, 0.0);
1302 pnh_.
param(
"goal_tolerance_lin", goal_tolerance_lin_f_, 0.05);
1303 pnh_.
param(
"goal_tolerance_ang", goal_tolerance_ang_f_, 0.1);
1304 pnh_.
param(
"goal_tolerance_ang_finish", goal_tolerance_ang_finish_, 0.05);
1306 pnh_.
param(
"unknown_cost", unknown_cost_, 100);
1307 pnh_.
param(
"overwrite_cost", overwrite_cost_,
false);
1309 pnh_.
param(
"hist_ignore_range", hist_ignore_range_f_, 0.6);
1310 pnh_.
param(
"hist_ignore_range_max", hist_ignore_range_max_f_, 1.25);
1311 pnh_.
param(
"remember_updates", remember_updates_,
false);
1312 double remember_hit_prob, remember_miss_prob;
1313 pnh_.
param(
"remember_hit_prob", remember_hit_prob, 0.6);
1314 pnh_.
param(
"remember_miss_prob", remember_miss_prob, 0.3);
1318 pnh_.
param(
"local_range", local_range_f_, 2.5);
1319 pnh_.
param(
"longcut_range", longcut_range_f_, 0.0);
1320 pnh_.
param(
"esc_range", esc_range_f_, 0.25);
1321 pnh_.
param(
"tolerance_range", tolerance_range_f_, 0.25);
1322 pnh_.
param(
"tolerance_angle", tolerance_angle_f_, 0.0);
1324 pnh_.
param(
"sw_wait", sw_wait_, 2.0
f);
1325 pnh_.
param(
"find_best", find_best_,
true);
1327 pnh_.
param(
"robot_frame", robot_frame_, std::string(
"base_link"));
1329 double pos_jump, yaw_jump;
1330 std::string jump_detect_frame;
1331 pnh_.
param(
"pos_jump", pos_jump, 1.0);
1332 pnh_.
param(
"yaw_jump", yaw_jump, 1.5);
1333 pnh_.
param(
"jump_detect_frame", jump_detect_frame, std::string(
"base_link"));
1337 pnh_.
param(
"force_goal_orientation", force_goal_orientation_,
true);
1339 pnh_.
param(
"temporary_escape", temporary_escape_,
true);
1341 pnh_.
param(
"fast_map_update", fast_map_update_,
false);
1342 if (fast_map_update_)
1344 ROS_WARN(
"planner_3d: Experimental fast_map_update is enabled. ");
1349 "planner_3d: ~/debug_mode parameter and ~/debug topic are deprecated. " 1350 "Use ~/distance_map, ~/hysteresis_map, and ~/remembered_map topics instead.");
1353 bool print_planning_duration;
1354 pnh_.
param(
"print_planning_duration", print_planning_duration,
false);
1355 if (print_planning_duration)
1363 pnh_.
param(
"max_retry_num", max_retry_num_, -1);
1365 int queue_size_limit;
1366 pnh_.
param(
"queue_size_limit", queue_size_limit, 0);
1370 pnh_.
param(
"num_threads", num_threads, 1);
1371 omp_set_num_threads(num_threads);
1374 pnh_.
param(
"num_search_task", num_task, num_threads * 16);
1376 pnh_.
param(
"num_cost_estim_task", num_cost_estim_task_, num_threads * 16);
1378 pnh_.
param(
"retain_last_error_status", retain_last_error_status_,
true);
1379 status_.status = planner_cspace_msgs::PlannerStatus::DONE;
1384 goal_updated_ =
false;
1388 is_path_switchback_ =
false;
1394 act_tolerant_->start();
1401 pose.pose.position.x, pose.pose.position.y,
tf2::getYaw(pose.pose.orientation));
1412 const bool costmap_udpated = last_costmap_ != prev_map_update_stamp;
1420 bbf_costmap_.
clear();
1425 if (costmap_udpated && previous_path.poses.size() > 1)
1427 for (
const auto& path_pose : previous_path.poses)
1437 if (is_path_switchback_)
1439 const float len = std::hypot(
1440 start_.pose.position.y - sw_pos_.pose.position.y,
1441 start_.pose.position.x - sw_pos_.pose.position.x);
1442 const float yaw =
tf2::getYaw(start_.pose.orientation);
1443 const float sw_yaw =
tf2::getYaw(sw_pos_.pose.orientation);
1444 float yaw_diff = yaw - sw_yaw;
1445 yaw_diff = std::atan2(std::sin(yaw_diff), std::cos(yaw_diff));
1446 if (len < goal_tolerance_lin_f_ && std::fabs(yaw_diff) < goal_tolerance_ang_f_)
1449 is_path_switchback_ =
false;
1466 nav_msgs::Path previous_path;
1470 waitUntil(next_replan_time, previous_path);
1474 if (has_map_ && !goal_updated_ && has_goal_)
1478 bool has_costmap(
false);
1481 if (last_costmap_ + costmap_watchdog_ < now)
1484 "Navigation is stopping since the costmap is too old (costmap: %0.3f)",
1485 last_costmap_.
toSec());
1486 status_.error = planner_cspace_msgs::PlannerStatus::DATA_MISSING;
1488 previous_path.poses.clear();
1500 bool is_path_switchback =
false;
1501 if (has_map_ && has_goal_ && has_start_ && has_costmap)
1503 if (act_->isActive())
1505 move_base_msgs::MoveBaseFeedback feedback;
1506 feedback.base_position =
start_;
1507 act_->publishFeedback(feedback);
1510 if (act_tolerant_->isActive())
1512 planner_cspace_msgs::MoveWithToleranceFeedback feedback;
1513 feedback.base_position =
start_;
1514 act_tolerant_->publishFeedback(feedback);
1517 if (status_.status == planner_cspace_msgs::PlannerStatus::FINISHING)
1519 const float yaw_s =
tf2::getYaw(start_.pose.orientation);
1520 float yaw_g =
tf2::getYaw(goal_.pose.orientation);
1521 if (force_goal_orientation_)
1524 float yaw_diff = yaw_s - yaw_g;
1525 if (yaw_diff > M_PI)
1526 yaw_diff -= M_PI * 2.0;
1527 else if (yaw_diff < -M_PI)
1528 yaw_diff += M_PI * 2.0;
1529 if (std::abs(yaw_diff) <
1532 status_.status = planner_cspace_msgs::PlannerStatus::DONE;
1538 if (act_->isActive())
1539 act_->setSucceeded(move_base_msgs::MoveBaseResult(),
"Goal reached.");
1540 if (act_tolerant_->isActive())
1541 act_tolerant_->setSucceeded(planner_cspace_msgs::MoveWithToleranceResult(),
"Goal reached.");
1548 status_.error = planner_cspace_msgs::PlannerStatus::PATH_NOT_FOUND;
1550 else if (max_retry_num_ != -1 && cnt_stuck_ > max_retry_num_)
1552 status_.error = planner_cspace_msgs::PlannerStatus::PATH_NOT_FOUND;
1553 status_.status = planner_cspace_msgs::PlannerStatus::DONE;
1557 previous_path.poses.clear();
1559 ROS_ERROR(
"Exceeded max_retry_num:%d", max_retry_num_);
1561 if (act_->isActive())
1563 move_base_msgs::MoveBaseResult(),
"Goal is in Rock");
1564 if (act_tolerant_->isActive())
1565 act_tolerant_->setAborted(
1566 planner_cspace_msgs::MoveWithToleranceResult(),
"Goal is in Rock");
1572 status_.error = planner_cspace_msgs::PlannerStatus::GOING_WELL;
1574 nav_msgs::Path path;
1576 path.header.stamp = now;
1577 makePlan(start_.pose, goal_.pose, path,
true);
1578 if (use_path_with_velocity_)
1588 previous_path = path;
1593 is_path_switchback = (sw_index >= 0);
1594 if (is_path_switchback)
1595 sw_pos_ = path.poses[sw_index];
1599 else if (!has_goal_)
1601 if (!retain_last_error_status_)
1602 status_.error = planner_cspace_msgs::PlannerStatus::GOING_WELL;
1604 previous_path.poses.clear();
1609 if (is_path_switchback)
1612 ROS_INFO(
"Planned path has switchback. Planner will stop until: %f at the latest.", next_replan_time.
toSec());
1618 is_path_switchback_ = is_path_switchback;
1623 bool makePlan(
const geometry_msgs::Pose& gs,
const geometry_msgs::Pose& ge,
1624 nav_msgs::Path& path,
bool hyst)
1628 map_info_, e[0], e[1], e[2],
1629 ge.position.x, ge.position.y,
tf2::getYaw(ge.orientation));
1634 map_info_, sf[0], sf[1], sf[2],
1635 gs.position.x, gs.position.y,
tf2::getYaw(gs.orientation));
1636 Astar::Vec s(static_cast<int>(std::floor(sf[0])), static_cast<int>(std::floor(sf[1])), std::lround(sf[2]));
1638 if (!cm_.validate(s, range_))
1640 ROS_ERROR(
"You are on the edge of the world.");
1644 std::vector<Astar::VecWithCost> starts;
1645 if (antialias_start_)
1647 const int x_cand[] =
1649 0, ((sf[0] - s[0]) < 0.5 ? -1 : 1)
1651 const int y_cand[] =
1653 0, ((sf[1] - s[1]) < 0.5 ? -1 : 1)
1655 for (
const int x : x_cand)
1657 for (
const int y : y_cand)
1660 if (!cm_.validate(p, range_))
1664 if (subpx.
sqlen() > 1.0)
1683 Astar::Vecf(s.v_[0] + 0.5f, s.v_[1] + 0.5f, 0.0f) - sf;
1684 s.c_ = std::hypot(diff[0] * ec_[0], diff[1] * ec_[0]);
1689 remain.
cycle(map_info_.angle);
1691 int g_tolerance_lin, g_tolerance_ang;
1692 if (act_tolerant_->isActive())
1694 g_tolerance_lin = std::lround(goal_tolerant_->goal_tolerance_lin / map_info_.linear_resolution);
1695 g_tolerance_ang = std::lround(goal_tolerant_->goal_tolerance_ang / map_info_.angular_resolution);
1703 if (remain.
sqlen() <= g_tolerance_lin * g_tolerance_lin &&
1704 std::abs(remain[2]) <= g_tolerance_ang)
1715 path.poses.resize(1);
1716 path.poses[0].header = path.header;
1717 if (force_goal_orientation_)
1718 path.poses[0].pose = goal_raw_.pose;
1720 path.poses[0].pose = ge;
1722 status_.status = planner_cspace_msgs::PlannerStatus::FINISHING;
1729 geometry_msgs::PoseStamped p;
1734 p.pose.position.x = x;
1735 p.pose.position.y = y;
1738 if (starts.size() == 0)
1742 ROS_WARN(
"Oops! You are in Rock!");
1743 status_.error = planner_cspace_msgs::PlannerStatus::IN_ROCK;
1753 if (cost_estim_cache_[s_rough] == std::numeric_limits<float>::max() || cm_[e] >= 100)
1755 status_.error = planner_cspace_msgs::PlannerStatus::PATH_NOT_FOUND;
1757 if (!escaping_ && temporary_escape_)
1763 ROS_INFO(
"Temporary goal (%d, %d, %d)",
1768 goal_.pose.position.x = x;
1769 goal_.pose.position.y = y;
1780 p.pose.position.x = x;
1781 p.pose.position.y = y;
1784 const float range_limit = cost_estim_cache_[s_rough] - (local_range_ +
range_) * ec_[0];
1786 const auto ts = boost::chrono::high_resolution_clock::now();
1790 const auto cb_progress = [
this, ts, s, e](
const std::list<Astar::Vec>& path_grid,
const SearchStats& stats) ->
bool 1792 const auto tnow = boost::chrono::high_resolution_clock::now();
1793 const auto tdiff = boost::chrono::duration<float>(tnow - ts).count();
1795 if (tdiff > search_timeout_abort_)
1798 "Search aborted due to timeout. " 1799 "search_timeout_abort may be too small or planner_3d may have a bug: " 1800 "s=(%d, %d, %d), g=(%d, %d, %d), tdiff=%0.4f, " 1802 "num_search_queue=%lu, " 1803 "num_prev_updates=%lu, " 1804 "num_total_updates=%lu, ",
1805 s[0], s[1], s[2], e[0], e[1], e[2], tdiff,
1806 stats.num_loop, stats.num_search_queue, stats.num_prev_updates, stats.num_total_updates);
1809 ROS_WARN(
"Search timed out (%0.4f sec.)", tdiff);
1813 model_->enableHysteresis(hyst && has_hysteresis_map_);
1814 std::list<Astar::Vec> path_grid;
1815 if (!as_.
search(starts, e, path_grid,
1822 ROS_WARN(
"Path plan failed (goal unreachable)");
1823 status_.error = planner_cspace_msgs::PlannerStatus::PATH_NOT_FOUND;
1827 const auto tnow = boost::chrono::high_resolution_clock::now();
1829 boost::chrono::duration<float>(tnow - ts).count());
1831 geometry_msgs::PoseArray poses;
1832 poses.header = path.header;
1833 for (
const auto& p : path_grid)
1835 geometry_msgs::Pose pose;
1838 pose.position.x = x;
1839 pose.position.y = y;
1842 poses.poses.push_back(pose);
1844 pub_path_poses_.
publish(poses);
1846 const std::list<Astar::Vecf> path_interpolated =
1847 model_->path_interpolator_.interpolate(path_grid, 0.5, local_range_);
1852 const auto ts = boost::chrono::high_resolution_clock::now();
1853 std::unordered_map<Astar::Vec, bool, Astar::Vec> path_points;
1856 const int path_range = range_ + max_dist + expand_dist + 5;
1860 for (d[0] = -path_range; d[0] <= path_range; d[0]++)
1862 for (d[1] = -path_range; d[1] <= path_range; d[1]++)
1866 if ((
unsigned int)point[0] >= (
unsigned int)map_info_.width ||
1867 (
unsigned int)point[1] >= (
unsigned int)map_info_.height)
1869 path_points[point] =
true;
1875 for (
auto& ps : path_points)
1878 float d_min = std::numeric_limits<float>::max();
1879 auto it_prev = path_interpolated.cbegin();
1880 for (
auto it = path_interpolated.cbegin(); it != path_interpolated.cend(); it++)
1884 int yaw = std::lround((*it)[2]) % map_info_.angle;
1885 int yaw_prev = std::lround((*it_prev)[2]) % map_info_.angle;
1887 yaw += map_info_.angle;
1889 yaw_prev += map_info_.angle;
1890 if (yaw == p[2] || yaw_prev == p[2])
1900 d_min = std::max(expand_dist, std::min(expand_dist + max_dist, d_min));
1901 cm_hyst_[p] = std::lround((d_min - expand_dist) * 100.0 / max_dist);
1902 hyst_updated_cells_.push_back(p);
1904 has_hysteresis_map_ =
true;
1905 const auto tnow = boost::chrono::high_resolution_clock::now();
1906 ROS_DEBUG(
"Hysteresis map generated (%0.4f sec.)",
1907 boost::chrono::duration<float>(tnow - ts).count());
1916 geometry_msgs::Pose p_prev;
1918 bool dir_set(
false);
1919 bool dir_prev(
false);
1920 for (
auto it = path.poses.begin(); it != path.poses.end(); ++it)
1922 const auto& p = *it;
1925 const float x_diff = p.pose.position.x - p_prev.position.x;
1926 const float y_diff = p.pose.position.y - p_prev.position.y;
1927 const float len_sq = std::pow(y_diff, 2) + std::pow(x_diff, 2);
1928 if (len_sq > std::pow(0.001
f, 2))
1930 const float yaw =
tf2::getYaw(p.pose.orientation);
1931 const bool dir = (std::cos(yaw) * x_diff + std::sin(yaw) * y_diff < 0);
1933 if (dir_set && (dir_prev ^ dir))
1935 return std::distance(path.poses.begin(), it);
1949 switch (status_.error)
1951 case planner_cspace_msgs::PlannerStatus::GOING_WELL:
1952 stat.
summary(diagnostic_msgs::DiagnosticStatus::OK,
"Going well.");
1954 case planner_cspace_msgs::PlannerStatus::IN_ROCK:
1955 stat.
summary(diagnostic_msgs::DiagnosticStatus::ERROR,
"The robot is in rock.");
1957 case planner_cspace_msgs::PlannerStatus::PATH_NOT_FOUND:
1958 stat.
summary(diagnostic_msgs::DiagnosticStatus::ERROR,
"Path not found.");
1960 case planner_cspace_msgs::PlannerStatus::DATA_MISSING:
1961 stat.
summary(diagnostic_msgs::DiagnosticStatus::ERROR,
"Required data is missing.");
1963 case planner_cspace_msgs::PlannerStatus::INTERNAL_ERROR:
1964 stat.
summary(diagnostic_msgs::DiagnosticStatus::ERROR,
"Planner internal error.");
1967 stat.
summary(diagnostic_msgs::DiagnosticStatus::ERROR,
"Unknown error.");
1970 stat.
addf(
"status",
"%u", status_.status);
1971 stat.
addf(
"error",
"%u", status_.error);
void remember(const BlockMemGridmapBase< char, 3, 2 > *const costmap, const Vec ¢er, const float remember_hit_odds, const float remember_miss_odds, const int range_min, const int range_max)
planner_cspace_msgs::MoveWithToleranceGoalConstPtr goal_tolerant_
geometry_msgs::PoseStamped goal_raw_
size_type capacity() const
ros::Publisher pub_path_velocity_
std::shared_ptr< GridAstarModel3D > Ptr
void cycle(const int res, const ArgList &...rest)
int hist_ignore_range_max_
float search_timeout_abort_
#define ROS_WARN_THROTTLE(rate,...)
ros::Publisher pub_hysteresis_map_
ROSCONSOLE_DECL void notifyLoggerLevelsChanged()
void publish(const boost::shared_ptr< M > &message) const
actionlib::SimpleActionServer< move_base_msgs::MoveBaseAction > Planner3DActionServer
std_msgs::Header map_header_
geometry_msgs::PoseStamped start_
ros::Publisher pub_path_poses_
void setSearchTaskNum(const size_t &search_task_num)
void summary(unsigned char lvl, const std::string s)
void diagnoseStatus(diagnostic_updater::DiagnosticStatusWrapper &stat)
double tolerance_angle_f_
costmap_cspace_msgs::MapMetaData3D map_info_
bool search(const std::vector< VecWithCost > &ss, const Vec &e, std::list< Vec > &path, const typename GridAstarModelBase< DIM, NONCYCLIC >::Ptr &model, ProgressCallback cb_progress, const float cost_leave, const float progress_interval, const bool return_best=false)
Astar::Gridmap< char, 0x80 > cm_rough_base_
const float MIN_PROBABILITY
int getSwitchIndex(const nav_msgs::Path &path) const
void setHardwareID(const std::string &hwid)
GridAstarModel3D::Ptr model_
float weight_costmap_turn_
double hist_ignore_range_f_
ros::ServiceServer srs_make_plan_
bool searchAvailablePos(const T &cm, Astar::Vec &s, const int xy_range, const int angle_range, const int cost_acceptable=50, const int min_xy_range=0) const
virtual geometry_msgs::TransformStamped lookupTransform(const std::string &target_frame, const std::string &source_frame, const ros::Time &time, const ros::Duration timeout) const
void cycleUnsigned(const int res, const ArgList &...rest)
ROSCPP_DECL void init(int &argc, char **argv, const std::string &name, uint32_t options=0)
IMETHOD Vector diff(const Vector &p_w_a, const Vector &p_w_b, double dt=1)
CyclicVecInt< DIM, NONCYCLIC > Vec
void reset(const Vec &size)
void add(const std::string &name, TaskFunction f)
void setQueueSizeLimit(const size_t size)
float remember_miss_odds_
double goal_tolerance_ang_f_
ros::Subscriber subscribe(ros::NodeHandle &nh_new, const std::string &topic_new, ros::NodeHandle &nh_old, const std::string &topic_old, uint32_t queue_size, void(*fp)(M), const ros::TransportHints &transport_hints=ros::TransportHints())
ServiceServer advertiseService(const std::string &service, bool(T::*srv_func)(MReq &, MRes &), T *obj)
void doTransform(const T &data_in, T &data_out, const geometry_msgs::TransformStamped &transform)
ros::Subscriber sub_map_update_
TFSIMD_FORCE_INLINE const tfScalar & y() const
ros::Publisher pub_start_
bool retain_last_error_status_
void metric2Grid(const costmap_cspace_msgs::MapMetaData3D &map_info, int &x, int &y, int &yaw, const float gx, const float gy, const float gyaw)
int main(int argc, char *argv[])
void addf(const std::string &key, const char *format,...)
char getCost(const Vec &p) const
void setBaseFrame(const std::string &frame_id)
void publishRememberedMap()
bool use_path_with_velocity_
Astar::Gridmap< char, 0x40 > cm_
std::shared_ptr< GridAstarModel2D > Ptr
Astar::Gridmap< char, 0x80 > cm_rough_
bool setGoal(const geometry_msgs::PoseStamped &msg)
GridAstarModel3D::Vec pathPose2Grid(const geometry_msgs::PoseStamped &pose) const
reservable_priority_queue< Astar::PriorityVec > pq_open_
void waitUntil(const ros::Time &next_replan_time, const nav_msgs::Path &previous_path)
bool cbForget(std_srvs::EmptyRequest &req, std_srvs::EmptyResponse &res)
ros::ServiceServer advertiseService(ros::NodeHandle &nh_new, const std::string &service_new, ros::NodeHandle &nh_old, const std::string &service_old, bool(T::*srv_func)(MReq &, MRes &), T *obj)
void cbGoal(const geometry_msgs::PoseStamped::ConstPtr &msg)
geometry_msgs::PoseStamped sw_pos_
std::shared_ptr< Planner3DTolerantActionServer > act_tolerant_
actionlib::SimpleActionServer< planner_cspace_msgs::MoveWithToleranceAction > Planner3DTolerantActionServer
reservable_priority_queue< Astar::PriorityVec > pq_erase_
tf2_ros::TransformListener tfl_
bool param(const std::string ¶m_name, T ¶m_val, const T &default_val) const
Astar::Gridmap< float > cost_estim_cache_
void reserve(const size_type capacity)
void reset(const Vec size)
std::vector< Astar::Vec > search_list_
ros::Subscriber sub_goal_
double hist_ignore_range_max_f_
TFSIMD_FORCE_INLINE const tfScalar & x() const
int prev_map_update_x_min_
float angle_resolution_aspect_
void cbMapUpdate(const costmap_cspace_msgs::CSpace3DUpdate::ConstPtr &msg)
void setMapFrame(const std::string &frame_id)
Publisher advertise(const std::string &topic, uint32_t queue_size, bool latch=false)
ros::ServiceServer srs_forget_
void setThresholds(const double pos_jump, const double yaw_jump)
std::shared_ptr< Planner3DActionServer > act_
const float MAX_PROBABILITY
double getYaw(const A &a)
typename GridAstarModelBase< DIM, NONCYCLIC >::VecWithCost VecWithCost
void grid2MetricPath(const costmap_cspace_msgs::MapMetaData3D &map_info, const STL_CONTAINER< CyclicVecFloat< 3, 2 >, std::allocator< CyclicVecFloat< 3, 2 >>> &path_grid, nav_msgs::Path &path)
Astar::Gridmap< char, 0x40 > cm_base_
bool force_goal_orientation_
std::array< float, 1024 > euclid_cost_lin_cache_
bool makePlan(const geometry_msgs::Pose &gs, const geometry_msgs::Pose &ge, nav_msgs::Path &path, bool hyst)
uint32_t getNumSubscribers() const
std::vector< Astar::Vec > search_list_rough_
constexpr float probabilityToOdds(const float &p)
void grid2Metric(const costmap_cspace_msgs::MapMetaData3D &map_info, const T x, const T y, const T yaw, float &gx, float &gy, float &gyaw)
ros::Publisher pub_distance_map_
double goal_tolerance_lin_f_
double tolerance_range_f_
float hysteresis_max_dist_
geometry_msgs::PoseStamped goal_
ros::Publisher pub_status_
planner_cspace_msgs::PlannerStatus status_
Astar::Gridmap< char, 0x80 > cm_hyst_
int prev_map_update_y_max_
float gridToLenFactor() const
int prev_map_update_y_min_
Astar::Gridmap< char, 0x80 > cm_updates_
double goal_tolerance_ang_finish_
void fillCostmap(reservable_priority_queue< Astar::PriorityVec > &open, Astar::Gridmap< float > &g, const Astar::Vec &s, const Astar::Vec &e)
ROSCONSOLE_DECL bool set_logger_level(const std::string &name, levels::Level level)
int prev_map_update_x_max_
bool hasParam(const std::string &key) const
DiscretePoseStatus relocateDiscretePoseIfNeededImpl(const T &cm, const int tolerance_range, const int tolerance_angle, Astar::Vec &pose_discrete) const
std::vector< Astar::Vec > hyst_updated_cells_
bool cbMakePlan(nav_msgs::GetPlan::Request &req, nav_msgs::GetPlan::Response &res)
ROSCPP_DECL void spinOnce()
#define ROSCONSOLE_DEFAULT_NAME
DiscretePoseStatus relocateDiscretePoseIfNeeded(Astar::Vec &pose_discrete, const int tolerance_range, const int tolerance_angle, bool use_cm_rough=false) const
ros::Duration costmap_watchdog_
diagnostic_updater::Updater diag_updater_
PathWithVelocity toPathWithVelocity(const nav_msgs::Path &src, const double vel)
CyclicVecFloat< DIM, NONCYCLIC > Vecf
void forEach(const std::function< void(const Vec &, bbf::BinaryBayesFilter &)> cb)
void cbMap(const costmap_cspace_msgs::CSpace3D::ConstPtr &msg)
ros::Publisher pub_remembered_map_
bool updateGoal(const bool goal_changed=true)