2 * SPDX-FileCopyrightText: 2021 Jiri Vlasak <jiri.vlasak.2@cvut.cz>
4 * SPDX-License-Identifier: GPL-3.0-only
7 /*! \brief RRT* extensions.
9 * The extensions are used to implement or change the default behavior of the
13 * \defgroup ext-col Collision detection extensions
14 * \defgroup ext-store Node storage and searching tree extensions
15 * \defgroup ext-cost Cost extensions
16 * \defgroup ext-opt Path optimization extensions
17 * \defgroup ext-sampl Random sampling extensions
18 * \defgroup ext-steer Steering procedure extensions
19 * \defgroup ext-aux Auxilliary extensions
30 #define GRID 1 // in meters
31 #define GRID_WIDTH 40 // in meters
32 #define GRID_HEIGHT 40 // in meters
33 #define GRID_MAX_XI ((unsigned int) floor(GRID_WIDTH / GRID)) // min is 0
34 #define GRID_MAX_YI ((unsigned int) floor(GRID_HEIGHT / GRID)) // min is 0
37 #define GRID_MAX_HI 60
41 /*! \brief Collision check based on enlarged occupancy grid.
45 class RRTExt21 : public virtual RRTS {
47 unsigned int _grid_width = 0;
48 unsigned int _grid_height = 0;
49 float _grid_res = 0.0;
50 int8_t const *_grid_data = nullptr;
51 double _origin_x = 0.0;
52 double _origin_y = 0.0;
53 bool collide(RRTNode const &n);
54 bool collide_steered();
56 void set_grid_to_check(unsigned int w, unsigned int h, float r,
57 int8_t const *d, double x, double y);
60 /*! \brief Collision check based on occupancy grid.
62 * This approach expects obstacles to be represented by points and the collision
63 * occures whenever the point is inside the frame given by the car pose and the
68 class RRTExt20 : public virtual RRTS {
70 std::vector<bcar::Point> const *_points_to_check = nullptr;
71 bool collide_steered();
73 void set_points_to_check(std::vector<bcar::Point> const *p);
76 /*! \brief Use Dubins paths-based steering procedure.
79 * \see https://github.com/AndrewWalker/Dubins-Curves
81 class RRTExt19 : public virtual RRTS {
83 void steer(RRTNode const &f, RRTNode const &t);
86 /*! \brief Finish when more than 1000 iterations.
90 class RRTExt18 : public virtual RRTS {
92 bool should_finish() const;
95 /*! \brief Finish when goal found or more than 1000 iterations.
99 class RRTExt17 : public virtual RRTS {
101 bool should_finish() const;
104 /*! \brief Use Reeds & Shepp steering procedure.
108 class RRTExt16 : public virtual RRTS {
110 void steer(RRTNode const& f, RRTNode const& t);
113 /*! \brief Log goal's cumulative cost each iteration.
117 class RRTExt15 : public virtual RRTS {
119 std::vector<double> log_path_cost_;
121 Json::Value json() const;
122 void json(Json::Value jvi);
126 /*! \brief Random sampling in the circuit between root and goal.
129 * \see https://stackoverflow.com/questions/5837572/generate-a-random-point-within-a-circle-uniformly/50746409#50746409
131 class RRTExt14 : public virtual RRTS {
134 double circle_r_ = 0.0;
135 std::uniform_real_distribution<double> udr_;
136 std::uniform_real_distribution<double> udt_;
137 std::uniform_real_distribution<double> udh_;
144 /*! \brief Use Dijkstra algorithm to find path between interesting nodes.
146 * The search for interesting nodes starts at root, the last drivable nodes is
147 * added to interesting nodes until goal is reached.
151 class RRTExt13 : public virtual RRTS {
155 RRTNode* node = nullptr;
160 DijkstraNode(RRTNode* n);
162 class DijkstraNodeComparator {
164 int operator() (DijkstraNode const& n1, DijkstraNode const& n2);
166 class DijkstraNodeBackwardComparator {
168 int operator() (DijkstraNode const& n1, DijkstraNode const& n2);
170 std::vector<RRTNode*> opath_;
171 double ogoal_cc_ = 0.0;
173 std::vector<DijkstraNode> dn_;
174 void interesting_forward();
175 void interesting_backward();
176 void dijkstra_forward();
177 void dijkstra_backward();
181 Json::Value json() const;
182 void json(Json::Value jvi);
186 /* \brief Different `steer` procedures.
188 Use sampling in control input for `steer1`. Use R&S steering for `steer2`.
190 class RRTExt12 : public virtual RRTS {
192 void steer1(RRTNode &f, RRTNode &t);
201 class RRTExt11 : public virtual RRTS {
203 bool goal_found(RRTNode &f);
206 /*! \brief Reeds & Shepp (build) and Euclidean + abs angle (search).
208 * Use Reeds & Shepp path length for building tree data structure and Euclidean
209 * distance + (abs) heading difference + 0.1 * backward-forward direction
210 * changes for searching it.
213 * \see https://doi.org/10.1109/TITS.2015.2477355
215 class RRTExt10 : public virtual RRTS {
217 double cost_build(RRTNode const& f, RRTNode const& t) const;
218 double cost_search(RRTNode const& f, RRTNode const& t) const;
221 /* \brief Use grid data structure to store RRT nodes.
223 This approach speeds up the search process for the nearest neighbor and
224 the near vertices procedures.
226 class RRTExt9 : public virtual RRTS {
230 bool changed_ = false;
231 std::vector<RRTNode *> nodes_;
233 void nn(RRTNode *t, RRTNode **nn, RRTS *p);
234 void store_node(RRTNode *n);
239 return this->changed_;
241 std::vector<RRTNode *> &nodes()
248 Cell grid_[GRID_MAX_XI][GRID_MAX_YI][GRID_MAX_HI];
254 double h_max_ = 2 * M_PI;
256 unsigned int xi(RRTNode n);
257 unsigned int yi(RRTNode n);
258 unsigned int hi(RRTNode n);
262 void store_node(RRTNode n);
263 RRTNode *nn(RRTNode &t);
264 std::vector<RRTNode *> nv(RRTNode &t);
267 /*! \brief Use 3D k-d tree data structure to store RRT nodes.
269 * This approach speeds up the search process for the nearest neighbor and the
270 * near vertices procedures. This extension implements 3D K-d tree.
273 * \see https://en.wikipedia.org/wiki/K-d_tree
275 class RRTExt8 : public virtual RRTS {
279 RRTNode* node = nullptr;
280 KdNode* left = nullptr;
281 KdNode* right = nullptr;
284 KdNode* kdroot_ = nullptr;
285 std::vector<KdNode> kdnodes_;
286 void store(RRTNode* n, KdNode*& ref, unsigned int lvl);
287 void find_nn(RRTNode const& t, KdNode const* const r, unsigned int lvl);
288 void find_nv(RRTNode const& t, KdNode const* const r, unsigned int lvl);
292 void store(RRTNode n);
293 void find_nn(RRTNode const& t);
294 void find_nv(RRTNode const& t);
297 /* \brief Use k-d tree data structure to store RRT nodes.
299 This approach speeds up the search process for the nearest neighbor and
300 the near vertices procedures. This extension implements 2D K-d tree.
302 \see https://en.wikipedia.org/wiki/K-d_tree
304 class RRTExt7 : public virtual RRTS {
308 RRTNode *node_ = nullptr;
309 KdNode *left_ = nullptr;
310 KdNode *right_ = nullptr;
313 RRTNode *node() const { return this->node_; }
314 KdNode *&left() { return this->left_; }
315 KdNode *&right() { return this->right_; }
318 KdNode *kdroot_ = nullptr;
319 void delete_kd_nodes(KdNode *n);
320 void store_node(RRTNode *n, KdNode *&r, int l);
321 void nn(RRTNode *&n, RRTNode &t, KdNode *r, int l, double &d);
325 void store_node(RRTNode n);
326 RRTNode *nn(RRTNode &t);
327 std::vector<RRTNode *> nv(RRTNode &t);
330 /*! \brief Reeds & Shepp (build, search).
332 * Use Reeds & Shepp path length for building tree data structure as well as for
337 class RRTExt6 : public virtual RRTS {
339 double cost_build(RRTNode const& f, RRTNode const& t) const;
340 double cost_search(RRTNode const& f, RRTNode const& t) const;
343 /* \brief Different costs extension.
345 Use different cost for bulding tree data structure and searching in the
346 structure. This one is complementary to `rrtext1.cc`.
348 class RRTExt5 : public virtual RRTS {
350 /* \brief Reeds and Shepp path length.
352 double cost_build(RRTNode &f, RRTNode &t);
353 /* \brief Euclidean distance.
355 double cost_search(RRTNode &f, RRTNode &t);
358 /* \brief Use grid data structure to store RRT nodes.
360 This approach speeds up the search process for the nearest neighbor and
361 the near vertices procedures.
363 class RRTExt4 : public virtual RRTS {
367 bool changed_ = false;
368 std::vector<RRTNode *> nodes_;
370 void nn(RRTNode *t, RRTNode **nn, RRTS *p);
371 void store_node(RRTNode *n);
376 return this->changed_;
378 std::vector<RRTNode *> &nodes()
385 Cell grid_[GRID_MAX_XI][GRID_MAX_YI]; // [0, 0] is bottom left
391 unsigned int xi(RRTNode n);
392 unsigned int yi(RRTNode n);
396 void store_node(RRTNode n);
397 RRTNode *nn(RRTNode &t);
398 std::vector<RRTNode *> nv(RRTNode &t);
401 /* \brief Use Dijkstra algorithm to find the shorter path.
403 class RRTExt3 : public virtual RRTS {
407 std::vector<RRTNode *> orig_path_;
408 double orig_path_cost_ = 9999;
409 std::vector<RRTNode *> first_optimized_path_;
410 double first_optimized_path_cost_ = 9999;
411 void first_path_optimization();
412 void second_path_optimization();
415 void json(Json::Value jvi);
418 std::vector<RRTNode *> &orig_path()
420 return this->orig_path_;
422 double &orig_path_cost() { return this->orig_path_cost_; }
423 void orig_path_cost(double c) { this->orig_path_cost_ = c; }
424 std::vector<RRTNode *> &first_optimized_path()
426 return this->first_optimized_path_;
428 double &first_optimized_path_cost() {
429 return this->first_optimized_path_cost_;
431 void first_optimized_path_cost(double c) {
432 this->first_optimized_path_cost_ = c;
436 /*! \brief Use cute_c2 library for collision detection.
439 * \see https://github.com/RandyGaul/cute_headers/blob/master/cute_c2.h
441 class RRTExt2 : public virtual RRTS {
445 std::vector<c2Poly> c2_obstacles_;
446 bool collide(RRTNode const& n);
447 bool collide_steered();
450 Json::Value json() const;
451 void json(Json::Value jvi);
455 /* \brief Different costs extension.
457 Use different cost for bulding tree data structure and searching in the
460 class RRTExt1 : public virtual RRTS {
462 /* \brief Reeds and Shepp path length.
464 double cost_build(RRTNode &f, RRTNode &t);
465 /* \brief Matej's heuristics.
467 double cost_search(RRTNode &f, RRTNode &t);
471 #endif /* RRTS_RRTEXT_H */