]> rtime.felk.cvut.cz Git - hubacji1/iamcar.git/blob - base/rrtbase.cc
Add random engine to RRTBase
[hubacji1/iamcar.git] / base / rrtbase.cc
1 /*
2 This file is part of I am car.
3
4 I am car is free software: you can redistribute it and/or modify
5 it under the terms of the GNU General Public License as published by
6 the Free Software Foundation, either version 3 of the License, or
7 (at your option) any later version.
8
9 I am car is distributed in the hope that it will be useful,
10 but WITHOUT ANY WARRANTY; without even the implied warranty of
11 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
12 GNU General Public License for more details.
13
14 You should have received a copy of the GNU General Public License
15 along with I am car. If not, see <http://www.gnu.org/licenses/>.
16 */
17
18 #include <algorithm>
19 #include <cmath>
20 #include <omp.h>
21 #include <queue>
22 #include "bcar.h"
23 #include "rrtbase.h"
24 // OpenGL
25 #include <GL/gl.h>
26 #include <GL/glu.h>
27 #include <SDL2/SDL.h>
28 // RRT
29 #include "sample.h"
30 #include "cost.h"
31 #include "steer.h"
32 #include "nn.h"
33 #include "nv.h"
34
35 extern SDL_Window* gw;
36 extern SDL_GLContext gc;
37
38 Cell::Cell()
39 {}
40
41 bool Cell::changed()
42 {
43         pthread_mutex_lock(&this->m_);
44         bool ret = this->changed_;
45         pthread_mutex_unlock(&this->m_);
46         return ret;
47 }
48
49 std::vector<RRTNode *> Cell::nodes()
50 {
51         pthread_mutex_lock(&this->m_);
52         std::vector<RRTNode *> ret(this->nodes_);
53         pthread_mutex_unlock(&this->m_);
54         return ret;
55 }
56
57 void Cell::add_node(RRTNode *n)
58 {
59         pthread_mutex_lock(&this->m_);
60         this->nodes_.push_back(n);
61         this->changed_ = true;
62         pthread_mutex_unlock(&this->m_);
63 }
64
65 RRTBase::~RRTBase()
66 {
67 // Fix heap-use-after-free error when T3 planner is used. If only T2 is used,
68 // please uncommend the following code:
69 //
70         for (auto n: this->nodes_)
71                 if (n != this->root_)
72                         delete n;
73         for (auto n: this->dnodes_)
74                 if (n != this->root_ && n != this->goal_)
75                         delete n;
76         for (auto s: this->samples_)
77                 if (s != this->goal_)
78                         delete s;
79         for (auto edges: this->rlog_)
80                 for (auto e: edges)
81                         delete e;
82         delete this->root_;
83         delete this->goal_;
84 }
85
86 RRTBase::RRTBase():
87         root_(new RRTNode()),
88         goal_(new RRTNode()),
89         gen_(std::random_device{}())
90 {
91         this->nodes_.reserve(NOFNODES);
92         this->nodes_.push_back(this->root_);
93         this->add_iy(this->root_);
94         this->add_ixy(this->root_);
95 }
96
97 RRTBase::RRTBase(RRTNode *init, RRTNode *goal):
98         root_(init),
99         goal_(goal),
100         gen_(std::random_device{}())
101 {
102         this->nodes_.reserve(NOFNODES);
103         this->nodes_.push_back(init);
104         this->add_iy(init);
105         this->add_ixy(init);
106 }
107
108 // getter
109 RRTNode *RRTBase::root()
110 {
111         return this->root_;
112 }
113
114 RRTNode *RRTBase::goal()
115 {
116         return this->goal_;
117 }
118
119 std::vector<RRTNode *> &RRTBase::nodes()
120 {
121         return this->nodes_;
122 }
123
124 std::vector<RRTNode *> &RRTBase::dnodes()
125 {
126         return this->dnodes_;
127 }
128
129 PolygonObstacle &RRTBase::frame()
130 {
131         return this->frame_;
132 }
133
134 std::vector<RRTNode *> &RRTBase::samples()
135 {
136         return this->samples_;
137 }
138
139 std::vector<CircleObstacle> *RRTBase::co()
140 {
141         return this->cobstacles_;
142 }
143
144 std::vector<SegmentObstacle> *RRTBase::so()
145 {
146         return this->sobstacles_;
147 }
148
149 std::vector<float> &RRTBase::clog()
150 {
151         return this->clog_;
152 }
153
154 std::vector<float> &RRTBase::nlog()
155 {
156         return this->nlog_;
157 }
158
159 std::vector<std::vector<RRTEdge *>> &RRTBase::rlog()
160 {
161         return this->rlog_;
162 }
163
164 std::vector<float> &RRTBase::slog()
165 {
166         return this->slog_;
167 }
168
169 std::vector<std::vector<RRTNode *>> &RRTBase::tlog()
170 {
171         return this->tlog_;
172 }
173
174 std::vector<RRTNode *> &RRTBase::slot_cusp()
175 {
176         return this->slot_cusp_;
177 }
178
179 bool RRTBase::goal_found()
180 {
181         return this->goal_found_;
182 }
183
184 float RRTBase::elapsed()
185 {
186         std::chrono::duration<float> dt;
187         dt = std::chrono::duration_cast<std::chrono::duration<float>>(
188                         this->tend_ - this->tstart_);
189         return dt.count();
190 }
191
192 // setter
193 void RRTBase::root(RRTNode *node)
194 {
195         this->root_ = node;
196 }
197
198 void RRTBase::goal(RRTNode *node)
199 {
200         this->goal_ = node;
201 }
202
203 bool RRTBase::logr(RRTNode *root)
204 {
205         std::vector<RRTEdge *> e; // Edges to log
206         std::vector<RRTNode *> s; // DFS stack
207         std::vector<RRTNode *> r; // reset visited_
208         RRTNode *tmp;
209         s.push_back(root);
210         while (s.size() > 0) {
211                 tmp = s.back();
212                 s.pop_back();
213                 if (!tmp->visit()) {
214                         r.push_back(tmp);
215                         for (auto ch: tmp->children()) {
216                                 s.push_back(ch);
217                                 e.push_back(new RRTEdge(tmp, ch));
218                         }
219                 }
220         }
221         for (auto n: r)
222                 n->visit(false);
223         this->rlog_.push_back(e);
224         return true;
225 }
226
227 float RRTBase::ocost(RRTNode *n)
228 {
229         float dist = 9999;
230         for (auto o: *this->cobstacles_)
231                 if (o.dist_to(n) < dist)
232                         dist = o.dist_to(n);
233         for (auto o: *this->sobstacles_)
234                 if (o.dist_to(n) < dist)
235                         dist = o.dist_to(n);
236         return n->ocost(dist);
237 }
238
239 bool RRTBase::tlog(std::vector<RRTNode *> t)
240 {
241         if (t.size() > 0) {
242                 this->slog_.push_back(this->elapsed());
243                 this->clog_.push_back(t.front()->ccost() - t.back()->ccost());
244                 this->nlog_.push_back(this->nodes_.size());
245                 this->tlog_.push_back(t);
246                 return true;
247         } else {
248                 return false;
249         }
250 }
251
252 void RRTBase::tstart()
253 {
254         this->tstart_ = std::chrono::high_resolution_clock::now();
255 }
256
257 void RRTBase::tend()
258 {
259         this->tend_ = std::chrono::high_resolution_clock::now();
260 }
261
262 bool RRTBase::link_obstacles(
263                 std::vector<CircleObstacle> *cobstacles,
264                 std::vector<SegmentObstacle> *sobstacles)
265 {
266         this->cobstacles_ = cobstacles;
267         this->sobstacles_ = sobstacles;
268         if (!this->cobstacles_ || !this->sobstacles_) {
269                 return false;
270         }
271         return true;
272 }
273
274 bool RRTBase::add_iy(RRTNode *n)
275 {
276         int i = IYI(n->y());
277         if (i < 0)
278                 i = 0;
279         if (i >= IYSIZE)
280                 i = IYSIZE - 1;
281         this->iy_[i].push_back(n);
282         return true;
283 }
284
285 bool RRTBase::add_ixy(RRTNode *n)
286 {
287         int ix = IXI(n->x());
288         if (ix < 0)
289                 ix = 0;
290         if (ix >= IXSIZE)
291                 ix = IXSIZE - 1;
292         int iy = IYI(n->y());
293         if (iy < 0)
294                 iy = 0;
295         if (iy >= IYSIZE)
296                 iy = IYSIZE - 1;
297         this->ixy_[ix][iy].add_node(n);
298         return true;
299 }
300
301 bool RRTBase::goal_found(bool f)
302 {
303         this->goal_found_ = f;
304         return f;
305 }
306
307 void RRTBase::slot_cusp(std::vector<RRTNode *> sc)
308 {
309         for (unsigned int i = 0; i < sc.size() - 1; i++)
310                 sc[i]->add_child(sc[i + 1], this->cost(sc[i], sc[i + 1]));
311         sc[0]->parent(this->goal());
312         this->slot_cusp_ = sc;
313 }
314
315 // other
316 bool RRTBase::glplot()
317 {
318         glClear(GL_COLOR_BUFFER_BIT);
319         glLineWidth(1);
320         glPointSize(1);
321         // Plot obstacles
322         glBegin(GL_LINES);
323         for (auto o: *this->sobstacles_) {
324                 glColor3f(0, 0, 0);
325                 glVertex2f(GLVERTEX(o.init()));
326                 glVertex2f(GLVERTEX(o.goal()));
327         }
328         glEnd();
329         // Plot root, goal
330         glPointSize(8);
331         glBegin(GL_POINTS);
332         glColor3f(1, 0, 0);
333         glVertex2f(GLVERTEX(this->root_));
334         glVertex2f(GLVERTEX(this->goal_));
335         glEnd();
336         // Plot last sample
337         if (this->samples_.size() > 0) {
338                 glPointSize(8);
339                 glBegin(GL_POINTS);
340                 glColor3f(0, 1, 0);
341                 glVertex2f(GLVERTEX(this->samples_.back()));
342                 glEnd();
343         }
344         // Plot nodes
345         std::vector<RRTNode *> s; // DFS stack
346         std::vector<RRTNode *> r; // reset visited_
347         RRTNode *tmp;
348         glBegin(GL_LINES);
349         s.push_back(this->root_);
350         while (s.size() > 0) {
351                 tmp = s.back();
352                 s.pop_back();
353                 if (!tmp->visit()) {
354                         r.push_back(tmp);
355                         for (auto ch: tmp->children()) {
356                                 s.push_back(ch);
357                                 glColor3f(0.5, 0.5, 0.5);
358                                 glVertex2f(GLVERTEX(tmp));
359                                 glVertex2f(GLVERTEX(ch));
360                         }
361                 }
362         }
363         glEnd();
364         // Plot nodes (from goal)
365         glBegin(GL_LINES);
366         s.push_back(this->goal_);
367         while (s.size() > 0) {
368                 tmp = s.back();
369                 s.pop_back();
370                 if (!tmp->visit()) {
371                         r.push_back(tmp);
372                         for (auto ch: tmp->children()) {
373                                 s.push_back(ch);
374                                 glColor3f(0.5, 0.5, 0.5);
375                                 glVertex2f(GLVERTEX(tmp));
376                                 glVertex2f(GLVERTEX(ch));
377                         }
378                 }
379         }
380         glEnd();
381         std::vector<RRTNode *> cusps;
382         // Plot last trajectory
383         if (this->tlog().size() > 0) {
384                 glLineWidth(2);
385                 glBegin(GL_LINES);
386                 for (auto n: this->tlog().back()) {
387                         if (n->parent()) {
388                                 glColor3f(0, 0, 1);
389                                 glVertex2f(GLVERTEX(n));
390                                 glVertex2f(GLVERTEX(n->parent()));
391                                 if (sgn(n->s()) != sgn(n->parent()->s()))
392                                         cusps.push_back(n);
393                         }
394                 }
395                 glEnd();
396         }
397         // Plot cusps
398         glPointSize(8);
399         glBegin(GL_POINTS);
400         for (auto n: cusps) {
401                 glColor3f(0, 0, 1);
402                 glVertex2f(GLVERTEX(n));
403         }
404         glEnd();
405         SDL_GL_SwapWindow(gw);
406         for (auto n: r)
407                 n->visit(false);
408         return true;
409 }
410
411 bool RRTBase::goal_found(
412                 RRTNode *node,
413                 float (*cost)(RRTNode *, RRTNode* ))
414 {
415         if (IS_NEAR(node, this->goal_)) {
416                 if (this->goal_found_) {
417                         if (node->ccost() + this->cost(node, this->goal_) <
418                                         this->goal_->ccost()) {
419                                 RRTNode *op; // old parent
420                                 float oc; // old cumulative cost
421                                 float od; // old direct cost
422                                 op = this->goal_->parent();
423                                 oc = this->goal_->ccost();
424                                 od = this->goal_->dcost();
425                                 node->add_child(this->goal_,
426                                                 this->cost(node, this->goal_));
427                                 if (this->collide(node, this->goal_)) {
428                                         node->children().pop_back();
429                                         this->goal_->parent(op);
430                                         this->goal_->ccost(oc);
431                                         this->goal_->dcost(od);
432                                 } else {
433                                         op->rem_child(this->goal_);
434                                         return true;
435                                 }
436                         } else {
437                                 return false;
438                         }
439                 } else {
440                         node->add_child(
441                                         this->goal_,
442                                         this->cost(node, this->goal_));
443                         if (this->collide(node, this->goal_)) {
444                                 node->children().pop_back();
445                                 this->goal_->remove_parent();
446                                 return false;
447                         }
448                         this->goal_found_ = true;
449                         return true;
450                 }
451         }
452         return false;
453 }
454
455 bool RRTBase::collide(RRTNode *init, RRTNode *goal)
456 {
457         std::vector<RRTEdge *> edges;
458         RRTNode *tmp = goal;
459         volatile bool col = false;
460         unsigned int i;
461         while (tmp != init) {
462                 BicycleCar bc(tmp->x(), tmp->y(), tmp->h());
463                 std::vector<RRTEdge *> bcframe = bc.frame();
464                 #pragma omp parallel for reduction(|: col)
465                 for (i = 0; i < (*this->cobstacles_).size(); i++) {
466                         if ((*this->cobstacles_)[i].collide(tmp)) {
467                                 col = true;
468                         }
469                         for (auto &e: bcframe) {
470                                 if ((*this->cobstacles_)[i].collide(e)) {
471                                         col = true;
472                                 }
473                         }
474                 }
475                 if (col) {
476                         for (auto e: bcframe) {
477                                 delete e->init();
478                                 delete e->goal();
479                                 delete e;
480                         }
481                         for (auto e: edges) {
482                                 delete e;
483                         }
484                         return true;
485                 }
486                 #pragma omp parallel for reduction(|: col)
487                 for (i = 0; i < (*this->sobstacles_).size(); i++) {
488                         for (auto &e: bcframe) {
489                                 if ((*this->sobstacles_)[i].collide(e)) {
490                                         col = true;
491                                 }
492                         }
493                 }
494                 if (col) {
495                         for (auto e: bcframe) {
496                                 delete e->init();
497                                 delete e->goal();
498                                 delete e;
499                         }
500                         for (auto e: edges) {
501                                 delete e;
502                         }
503                         return true;
504                 }
505                 if (!tmp->parent()) {
506                         break;
507                 }
508                 edges.push_back(new RRTEdge(tmp, tmp->parent()));
509                 tmp = tmp->parent();
510                 for (auto e: bcframe) {
511                         delete e->init();
512                         delete e->goal();
513                         delete e;
514                 }
515         }
516         for (auto &e: edges) {
517                 #pragma omp parallel for reduction(|: col)
518                 for (i = 0; i < (*this->cobstacles_).size(); i++) {
519                         if ((*this->cobstacles_)[i].collide(e)) {
520                                 col = true;
521                         }
522                 }
523                 if (col) {
524                         for (auto e: edges) {
525                                 delete e;
526                         }
527                         return true;
528                 }
529                 #pragma omp parallel for reduction(|: col)
530                 for (i = 0; i < (*this->sobstacles_).size(); i++) {
531                         if ((*this->sobstacles_)[i].collide(e)) {
532                                 col = true;
533                         }
534                 }
535                 if (col) {
536                         for (auto e: edges) {
537                                 delete e;
538                         }
539                         return true;
540                 }
541         }
542         for (auto e: edges) {
543                 delete e;
544         }
545         return false;
546 }
547
548 class RRTNodeDijkstra {
549         public:
550                 RRTNodeDijkstra(int i):
551                         ni(i),
552                         pi(0),
553                         c(9999),
554                         v(false)
555                 {};
556                 RRTNodeDijkstra(int i, float c):
557                         ni(i),
558                         pi(0),
559                         c(c),
560                         v(false)
561                 {};
562                 RRTNodeDijkstra(int i, int p, float c):
563                         ni(i),
564                         pi(p),
565                         c(c),
566                         v(false)
567                 {};
568                 unsigned int ni;
569                 unsigned int pi;
570                 float c;
571                 bool v;
572                 bool vi()
573                 {
574                         if (this->v)
575                                 return true;
576                         this->v = true;
577                         return false;
578                 };
579 };
580
581 class RRTNodeDijkstraComparator {
582         public:
583                 int operator() (
584                                 const RRTNodeDijkstra& n1,
585                                 const RRTNodeDijkstra& n2)
586                 {
587                         return n1.c > n2.c;
588                 }
589 };
590
591 bool RRTBase::optp_dijkstra(
592                 std::vector<RRTNode *> &cusps,
593                 std::vector<int> &npi)
594 {
595         std::vector<RRTNodeDijkstra> dnodes;
596         for (unsigned int i = 0; i < cusps.size(); i++)
597                 if (i > 0)
598                         dnodes.push_back(RRTNodeDijkstra(
599                                                 i,
600                                                 i - 1,
601                                                 cusps[i]->ccost()));
602                 else
603                         dnodes.push_back(RRTNodeDijkstra(
604                                                 i,
605                                                 cusps[i]->ccost()));
606         dnodes[0].vi();
607         std::priority_queue<
608                 RRTNodeDijkstra,
609                 std::vector<RRTNodeDijkstra>,
610                 RRTNodeDijkstraComparator> pq;
611         RRTNodeDijkstra tmp = dnodes[0];
612         pq.push(tmp);
613         float ch_cost = 9999;
614         std::vector<RRTNode *> steered;
615         while (!pq.empty()) {
616                 tmp = pq.top();
617                 pq.pop();
618                 for (unsigned int i = tmp.ni + 1; i < cusps.size(); i++) {
619                         ch_cost = dnodes[tmp.ni].c +
620                                 this->cost(cusps[tmp.ni], cusps[i]);
621                         steered = this->steer(cusps[tmp.ni], cusps[i]);
622                         for (unsigned int j = 0; j < steered.size() - 1; j++)
623                                 steered[j]->add_child(steered[j + 1], 1);
624                         if (this->collide(
625                                         steered[0],
626                                         steered[steered.size() - 1])) {
627                                 for (auto n: steered)
628                                         delete n;
629                                 continue;
630                         }
631                         if (ch_cost < dnodes[i].c) {
632                                 dnodes[i].c = ch_cost;
633                                 dnodes[i].pi = tmp.ni;
634                                 if (!dnodes[i].vi())
635                                         pq.push(dnodes[i]);
636                         }
637                         for (auto n: steered)
638                                 delete n;
639                 }
640         }
641         unsigned int tmpi = 0;
642         for (auto n: dnodes) {
643                 if (n.v && n.ni > tmpi)
644                         tmpi = n.ni;
645         }
646         while (tmpi > 0) {
647                 npi.push_back(tmpi);
648                 tmpi = dnodes[tmpi].pi;
649         }
650         npi.push_back(tmpi);
651         std::reverse(npi.begin(), npi.end());
652         return true;
653 }
654
655 bool RRTBase::optp_rrp(
656                 std::vector<RRTNode *> &cusps,
657                 std::vector<int> &npi)
658 {
659         std::vector<RRTNode *> steered;
660         std::vector<int> candidates;
661         RRTNode *x_j = nullptr;
662         RRTNode *x_i = nullptr;
663         int j = cusps.size() - 1;
664         int i_min = 0;
665         float c_min = 0;
666         float cost = 0;
667         float dx = 0;
668         float dy = 0;
669         float ed = 0;
670         float th_i = 0;
671         float th_j = 0;
672         while (j > 0) {
673                 npi.push_back(j);
674                 steered.clear();
675                 candidates.clear();
676                 x_j = cusps[j];
677                 for (int i = 0; i < j; i++) {
678                         steered = this->steer(cusps[i], x_j);
679                         for (unsigned int k = 0; k < steered.size() - 1; k++)
680                                 steered[k]->add_child(steered[k + 1], 1);
681                         if (!this->collide(
682                                         steered[0],
683                                         steered[steered.size() - 1]))
684                                 candidates.push_back(i);
685                 }
686                 if (candidates.size() <= 0)
687                         return false;
688                 i_min = candidates[0];
689                 x_i = cusps[i_min];
690                 c_min = 9999;
691                 for (auto c: candidates) {
692                         x_i = cusps[c];
693                         dx = x_j->x() - x_i->x();
694                         dy = x_j->y() - x_i->y();
695                         ed = EDIST(x_i, x_j);
696                         th_i = (cos(x_i->h()) * dx + sin(x_i->h()) * dy) / ed;
697                         th_j = (cos(x_j->h()) * dx + sin(x_j->h()) * dy) / ed;
698                         cost = th_i + th_j;
699                         if (cost < c_min) {
700                                 i_min = c;
701                                 c_min = cost;
702                         }
703                 }
704                 j = i_min;
705
706         }
707         npi.push_back(j);
708         std::reverse(npi.begin(), npi.end());
709         return true;
710 }
711
712 bool RRTBase::optp_smart(
713                 std::vector<RRTNode *> &cusps,
714                 std::vector<int> &npi)
715 {
716         std::vector<RRTNode *> steered;
717         int li = cusps.size() - 1;
718         int ai = li - 1;
719         npi.push_back(li);
720         while (ai > 1) {
721                 steered = this->steer(cusps[ai - 1], cusps[li]);
722                 for (unsigned int j = 0; j < steered.size() - 1; j++)
723                         steered[j]->add_child(steered[j + 1], 1);
724                 if (this->collide(steered[0], steered[steered.size() - 1])) {
725                         npi.push_back(ai);
726                         li = ai;
727                 }
728                 ai--;
729                 for (auto n: steered)
730                         delete n;
731         }
732         npi.push_back(0);
733         std::reverse(npi.begin(), npi.end());
734         return true;
735 }
736
737 bool RRTBase::opt_path()
738 {
739         if (this->tlog().size() == 0)
740                 return false;
741         float oc = this->tlog().back().front()->ccost();
742         std::vector<RRTNode *> tmp_cusps;
743         for (auto n: this->tlog().back()) {
744                 if (sgn(n->s()) == 0) {
745                         tmp_cusps.push_back(n);
746                 } else if (n->parent() &&
747                                 sgn(n->s()) != sgn(n->parent()->s())) {
748                         tmp_cusps.push_back(n);
749                         tmp_cusps.push_back(n->parent());
750                 }
751                 //tmp_cusps.push_back(n);
752         }
753         if (tmp_cusps.size() < 2)
754                 return false;
755         std::vector<RRTNode *> cusps;
756         for (unsigned int i = 0; i < tmp_cusps.size(); i++) {
757                 if (tmp_cusps[i] != tmp_cusps[(i + 1) % tmp_cusps.size()])
758                         cusps.push_back(tmp_cusps[i]);
759         }
760         std::reverse(cusps.begin(), cusps.end());
761         std::vector<int> npi; // new path indexes
762         if (!this->optp_dijkstra(cusps, npi))
763                 return false;
764         RRTNode *pn = cusps[npi[0]];
765         RRTNode *tmp = nullptr;
766         bool en_add = true;
767         for (unsigned int i = 0; i < npi.size() - 1; i++) {
768                 pn = cusps[npi[i]];
769                 for (auto ns: this->steer(cusps[npi[i]], cusps[npi[i + 1]])) {
770                         if (!en_add) {
771                                 delete ns;
772                         } else if (IS_NEAR(cusps[npi[i]], ns)) {
773                                 tmp = ns;
774                                 while (tmp && tmp != cusps[npi[i]]) {
775                                         pn = tmp->parent();
776                                         delete tmp;
777                                         tmp = pn;
778                                 }
779                                 pn = cusps[npi[i]];
780                         } else if (IS_NEAR(ns, cusps[npi[i + 1]])) {
781                                 delete ns;
782                                 cusps[npi[i + 1]]->parent()->rem_child(
783                                                 cusps[npi[i + 1]]);
784                                 pn->add_child(
785                                         cusps[npi[i + 1]],
786                                         this->cost(pn, cusps[npi[i + 1]]));
787                                 en_add = false;
788                         } else if (IS_NEAR(pn, ns)) {
789                                 delete ns;
790                         } else {
791                                 this->nodes().push_back(ns);
792                                 this->add_iy(ns);
793                                 this->add_ixy(ns);
794                                 pn->add_child(ns, this->cost(pn, ns));
795                                 pn = ns;
796                         }
797                 }
798         }
799         this->root()->update_ccost();
800         if (this->tlog().back().front()->ccost() < oc)
801                 return true;
802         return false;
803 }
804
805 bool RRTBase::rebase(RRTNode *nr)
806 {
807         if (!nr || this->goal_ == nr || this->root_ == nr)
808                 return false;
809         std::vector<RRTNode *> s; // DFS stack
810         RRTNode *tmp;
811         unsigned int i = 0;
812         unsigned int to_del = 0;
813         int iy = 0;
814         s.push_back(this->root_);
815         while (s.size() > 0) {
816                 tmp = s.back();
817                 s.pop_back();
818                 for (auto ch: tmp->children()) {
819                         if (ch != nr)
820                                 s.push_back(ch);
821                 }
822                 to_del = this->nodes_.size();
823                 #pragma omp parallel for reduction(min: to_del)
824                 for (i = 0; i < this->nodes_.size(); i++) {
825                         if (this->nodes_[i] == tmp)
826                                 to_del = i;
827                 }
828                 if (to_del < this->nodes_.size())
829                         this->nodes_.erase(this->nodes_.begin() + to_del);
830                 iy = IYI(tmp->y());
831                 to_del = this->iy_[iy].size();
832                 #pragma omp parallel  for reduction(min: to_del)
833                 for (i = 0; i < this->iy_[iy].size(); i++) {
834                         if (this->iy_[iy][i] == tmp)
835                                 to_del = i;
836                 }
837                 if (to_del < this->iy_[iy].size())
838                         this->iy_[iy].erase(this->iy_[iy].begin() + to_del);
839                 this->dnodes().push_back(tmp);
840         }
841         this->root_ = nr;
842         this->root_->remove_parent();
843         return true;
844 }
845
846 std::vector<RRTNode *> RRTBase::findt()
847 {
848         return this->findt(this->goal_);
849 }
850
851 std::vector<RRTNode *> RRTBase::findt(RRTNode *n)
852 {
853         std::vector<RRTNode *> nodes;
854         if (!n || !n->parent())
855                 return nodes;
856         while (n) {
857                 nodes.push_back(n);
858                 n = n->parent();
859         }
860         return nodes;
861 }
862
863 // RRT Framework
864 RRTNode *RRTBase::sample()
865 {
866         return sa1();
867 }
868
869 float RRTBase::cost(RRTNode *init, RRTNode *goal)
870 {
871         return co2(init, goal);
872 }
873
874 RRTNode *RRTBase::nn(RRTNode *rs)
875 {
876         return nn4(this->iy_, rs, nullptr);
877         //return nn3(this->iy_, rs, nullptr);
878 }
879
880 std::vector<RRTNode *> RRTBase::nv(RRTNode *node, float dist)
881 {
882         std::vector<RRTNode *> nvs;
883         unsigned int iy = IYI(node->y());
884         unsigned int iy_dist = floor(dist / IYSTEP) + 1;
885         unsigned int i = 0; // vector index
886         unsigned int j = 0; // array index
887         unsigned int jmin = 0; // minimal j index
888         unsigned int jmax = 0; // maximal j index
889         jmin = iy - iy_dist;
890         jmin = (jmin > 0) ? jmin : 0;
891         jmax = iy + iy_dist + 1;
892         jmax = (jmax < IYSIZE) ? jmax : IYSIZE;
893         #pragma omp parallel for reduction(merge: nvs)
894         for (j = jmin; j < jmax; j++) {
895                 #pragma omp parallel for reduction(merge: nvs)
896                 for (i = 0; i < this->iy_[j].size(); i++) {
897                         if (this->cost(this->iy_[j][i], node) < dist) {
898                                 nvs.push_back(this->iy_[j][i]);
899                         }
900                 }
901         }
902         return nvs;
903 }
904
905 std::vector<RRTNode *> RRTBase::steer(RRTNode *init, RRTNode *goal)
906 {
907         return st3(init, goal);
908 }
909
910 std::vector<RRTNode *> RRTBase::steer(RRTNode *init, RRTNode *goal, float step)
911 {
912         return st3(init, goal, step);
913 }