cb_base_navigation
a_star_planner.cpp
Go to the documentation of this file.
1 #include "a_star_planner.h"
2 
4 
5 namespace cb_global_planner {
6 
8 
10 
11 AStarPlanner::AStarPlanner(int width, int height) : visited_map_(0) {
12  resize(width, height);
13  ++N_OBJECTS;
14 }
15 
17  deleteMap();
18  --N_OBJECTS;
19 }
20 
21 /*
22 void AStarPlanner::setCost(int x, int y, double cost) {
23  cost_map_[x][y] = cost;
24 }
25 */
26 
27 void AStarPlanner::setCostmap(const unsigned char* char_cost_map) {
28  char_cost_map_ = char_cost_map;
29 }
30 
31 double AStarPlanner::getCost(int x, int y) {
32  int k = width_ * y + x;
33 
34  unsigned char cost = char_cost_map_[k];
35 
36  if (cost == costmap_2d::NO_INFORMATION)
37  // cost = 0;
38  return DBL_MAX; // Do not plan through unknown space
39 
40  double cell_pass_through_time = DBL_MAX;
41 
43  {
44  double max_vel = (1 - (double) cost / 256) * 1.0; //max_velocity_;
45  cell_pass_through_time = 1 / max_vel; // cell_size
46  }
47 
48  //printf("k = %d, cost = %f\n", k, cell_pass_through_time);
49 
50  return cell_pass_through_time;
51 }
52 
53 void AStarPlanner::resize(int width, int height) {
54  if (visited_map_) {
55  deleteMap();
56  }
57 
58  width_ = width;
59  height_ = height;
60 
61  visited_map_ = new double*[width_];
62  for(unsigned int i = 0; i < width_; ++i) {
63  visited_map_[i] = new double[height_];
64  }
65 
66  // to make sure the algorithm won't expand off the map, mark all border cells as visited
67  // todo: this limits the search space: border cells can now not be used in the solution. FIX
68  for(unsigned int x = 0; x < width_; ++x) {
69  visited_map_[x][0] = 0;
70  visited_map_[x][height_ - 1] = 0;
71  }
72 
73  for(unsigned int y = 0; y < height_; ++y) {
74  visited_map_[0][y] = 0;
75  visited_map_[width_ - 1][y] = 0;
76  }
77 }
78 
79 bool AStarPlanner::plan(std::vector<unsigned int> mx_start, std::vector<unsigned int> my_start, int mx_goal, int my_goal, std::vector<int>& plan_xs, std::vector<int>& plan_ys, bool best_heuristic) {
80  // - initialize all cells in visited_map to false
81  // - determine minimum cell cost in cost map
82  double min_cell_cost = 1; //DBL_MAX;
83  for(unsigned int x = 1; x < width_ - 1; ++x) {
84  for(unsigned int y = 1; y < height_ - 1; ++y) {
85  visited_map_[x][y] = DBL_MAX;
86  //min_cell_cost = min(getCost(x, y), min_cell_cost);
87  }
88  }
89 
91 
92  std::list<CellInfo*> visited_cells; // remember visited cells to be able to clear memory
93 
94  // add start points to priority queue and visited map
95  for (unsigned int i = 0; i < mx_start.size(); ++i)
96  {
97  if (mx_start[i] > 0 && mx_start[i] < width_-1 && my_start[i] > 0 && my_start[i] < height_-1)
98  {
99  CellInfo* start = new CellInfo(mx_start[i], my_start[i], 0, calculateHeuristicCost(mx_start[i], my_start[i], mx_goal, my_goal, min_cell_cost));
100  visited_map_[mx_start[i]][my_start[i]] = 0;
101  Q.push(start);
102  }
103  }
104 
105  CellInfo* goal_cell = 0;
106  CellInfo* best_cell = 0;
107 
108  double best_score = 1e9;
109 
110  while(!Q.empty() && !goal_cell) {
111  CellInfo* c = Q.top();
112  visited_cells.push_back(c);
113  Q.pop();
114 
115  // check if goal is reached
116  if (c->x_ == mx_goal && c->y_ == my_goal) {
117  // goal reached!
118  goal_cell = c;
119  } else {
120 
121  if (c->h_ < best_score) {
122  best_cell = c;
123  best_score = c->h_;
124  }
125 
126  // direct adjacent expansion
127  expandCell(c, -1, 0, 1.0, visited_map_, mx_goal, my_goal, min_cell_cost, Q);
128  expandCell(c, +1, 0, 1.0, visited_map_, mx_goal, my_goal, min_cell_cost, Q);
129  expandCell(c, 0, -1, 1.0, visited_map_, mx_goal, my_goal, min_cell_cost, Q);
130  expandCell(c, 0, +1, 1.0, visited_map_, mx_goal, my_goal, min_cell_cost, Q);
131 
132  // diagonal expansion
133  expandCell(c, -1, -1, SQRT2, visited_map_, mx_goal, my_goal, min_cell_cost, Q);
134  expandCell(c, +1, -1, SQRT2, visited_map_, mx_goal, my_goal, min_cell_cost, Q);
135  expandCell(c, -1, +1, SQRT2, visited_map_, mx_goal, my_goal, min_cell_cost, Q);
136  expandCell(c, +1, +1, SQRT2, visited_map_, mx_goal, my_goal, min_cell_cost, Q);
137  }
138  }
139 
140  // Path to goal found
141  if (goal_cell) {
142  while(goal_cell) {
143  plan_xs.push_back(goal_cell->x_);
144  plan_ys.push_back(goal_cell->y_);
145  goal_cell = goal_cell->visited_from_;
146  }
147 
148  // delete remaining CellInfos in Q
149  while(!Q.empty()) {
150  delete Q.top();
151  Q.pop();
152  }
153  } else if (best_heuristic) {
154  if (best_cell) {
155  while(best_cell) {
156  plan_xs.push_back(best_cell->x_);
157  plan_ys.push_back(best_cell->y_);
158  best_cell = best_cell->visited_from_;
159  }
160 
161  // delete remaining CellInfos in Q
162  while(!Q.empty()) {
163  delete Q.top();
164  Q.pop();
165  }
166  }
167  }
168 
169  // delete visited CellInfos
170  for (std::list<CellInfo*>::iterator it = visited_cells.begin(); it != visited_cells.end(); ++it)
171  delete *it;
172 
173  return (goal_cell);
174 }
175 
176 void AStarPlanner::expandCell(CellInfo* c, int dx, int dy, double cost_factor, double** visited_map,
177  int x_goal, int y_goal, double min_cell_cost,
179 {
180 
181  int x = c->x_ + dx;
182  int y = c->y_ + dy;
183 
184  double g_child = c->g_ + getCost(x, y) * cost_factor;
185  if (g_child < visited_map[x][y]) {
186  CellInfo* c_child = new CellInfo(x, y, g_child, calculateHeuristicCost(x, y, x_goal, y_goal, min_cell_cost));
187  c_child->visited_from_ = c;
188  Q.push(c_child);
189  visited_map_[x][y] = g_child;
190  }
191 }
192 
193 double AStarPlanner::calculateHeuristicCost(int x, int y, int x_goal, int y_goal, double min_cell_cost) {
194  double dx = (double)(x_goal - x);
195  double dy = (double)(y_goal - y);
196  return sqrt(dx * dx + dy * dy) * min_cell_cost;
197 }
198 
200  for(unsigned int i = 0; i < width_; ++i) {
201  delete[] visited_map_[i];
202  }
203 
204  delete[] visited_map_;
205  visited_map_ = nullptr;
206 }
207 
208 }
cb_global_planner::AStarPlanner::SQRT2
static constexpr double SQRT2
Definition: a_star_planner.h:50
cb_global_planner::AStarPlanner::CellInfo::y_
int y_
Definition: a_star_planner.h:71
std::list
cb_global_planner::AStarPlanner::calculateHeuristicCost
double calculateHeuristicCost(int x, int y, int x_goal, int y_goal, double min_cell_cost)
Definition: a_star_planner.cpp:193
std::vector
std::vector::size
T size(T... args)
costmap_2d::INSCRIBED_INFLATED_OBSTACLE
static const unsigned char INSCRIBED_INFLATED_OBSTACLE
a_star_planner.h
costmap_2d::NO_INFORMATION
static const unsigned char NO_INFORMATION
cb_global_planner::AStarPlanner::width_
unsigned int width_
Definition: a_star_planner.h:59
cb_global_planner::AStarPlanner::~AStarPlanner
virtual ~AStarPlanner()
Definition: a_star_planner.cpp:16
cost_values.h
cb_global_planner::AStarPlanner::compareCellInfos
Definition: a_star_planner.h:87
std::list::push_back
T push_back(T... args)
cb_global_planner::AStarPlanner::resize
void resize(int nx, int ny)
Definition: a_star_planner.cpp:53
cb_global_planner::AStarPlanner::CellInfo
Definition: a_star_planner.h:66
std::priority_queue::pop
T pop(T... args)
std::priority_queue::top
T top(T... args)
cb_global_planner::AStarPlanner::CellInfo::visited_from_
CellInfo * visited_from_
Definition: a_star_planner.h:75
costmap_2d::LETHAL_OBSTACLE
static const unsigned char LETHAL_OBSTACLE
cb_global_planner::AStarPlanner::setCostmap
void setCostmap(const unsigned char *char_cost_map)
Definition: a_star_planner.cpp:27
std::priority_queue
cb_global_planner::AStarPlanner::AStarPlanner
AStarPlanner(int width, int height)
Definition: a_star_planner.cpp:11
DBL_MAX
#define DBL_MAX
cb_global_planner::AStarPlanner::plan
bool plan(std::vector< unsigned int > mx_start, std::vector< unsigned int > my_start, int mx_goal, int my_goal, std::vector< int > &plan_xs, std::vector< int > &plan_ys, bool best_heuristic=false)
Definition: a_star_planner.cpp:79
std::list::begin
T begin(T... args)
cb_global_planner::AStarPlanner::CellInfo::x_
int x_
Definition: a_star_planner.h:70
cb_global_planner::AStarPlanner::height_
unsigned int height_
Definition: a_star_planner.h:60
std::priority_queue::empty
T empty(T... args)
std::priority_queue::push
T push(T... args)
cb_global_planner
Definition: a_star_planner.cpp:5
std::list::end
T end(T... args)
cb_global_planner::AStarPlanner::visited_map_
double ** visited_map_
Definition: a_star_planner.h:58
cb_global_planner::AStarPlanner::getCost
double getCost(int x, int y)
Definition: a_star_planner.cpp:31
cb_global_planner::AStarPlanner::N_OBJECTS
static long N_OBJECTS
Definition: a_star_planner.h:52
c
void c()
cb_global_planner::AStarPlanner::expandCell
void expandCell(CellInfo *c, int dx, int dy, double cost_factor, double **visited_map, int x_goal, int y_goal, double min_cell_cost, std::priority_queue< CellInfo *, std::vector< CellInfo * >, compareCellInfos > &Q)
Definition: a_star_planner.cpp:176
cb_global_planner::AStarPlanner::CellInfo::N_OBJECTS
static long N_OBJECTS
Definition: a_star_planner.h:68
cb_global_planner::AStarPlanner::char_cost_map_
const unsigned char * char_cost_map_
Definition: a_star_planner.h:56
cb_global_planner::AStarPlanner::deleteMap
void deleteMap()
Definition: a_star_planner.cpp:199