2 This file is part of I am car.
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.
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.
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/>.
27 #include "rrtplanner.h"
30 #define CATI(a, b) a ## b
31 #define CAT(a, b) CATI(a, b)
32 #define KUWATA2008_CCOST CAT(c, CO)
33 #define KUWATA2008_DCOST CO
35 LaValle1998::LaValle1998(RRTNode *init, RRTNode *goal):
42 srand(static_cast<unsigned>(time(0)));
45 bool LaValle1998::next()
49 if (this->samples().size() == 0)
56 this->samples().push_back(rs);
58 RRTNode *nn = this->nn(this->iy_, rs, this->cost);
60 RRTNode *nn = this->nn(this->nodes(), rs, this->cost);
64 for (auto ns: this->steer(nn, rs)) {
68 this->nodes().push_back(ns);
70 pn->add_child(ns, this->cost(pn, ns));
71 if (this->collide(pn, ns)) {
72 pn->children().pop_back();
74 this->iy_[IYI(ns->y())].pop_back();
79 if (this->goal_found(pn, this->cost)) {
80 this->tlog(this->findt());
86 return this->goal_found();
89 Kuwata2008::Kuwata2008(RRTNode *init, RRTNode *goal):
94 cost(KUWATA2008_DCOST)
96 srand(static_cast<unsigned>(time(0)));
99 bool Kuwata2008::next()
102 if (this->samples().size() == 0) {
107 this->samples().push_back(rs);
108 float heur = static_cast<float>(rand()) / static_cast<float>(RAND_MAX);
109 if (this->goal_found()) {
111 this->cost = &KUWATA2008_CCOST;
113 this->cost = &KUWATA2008_DCOST;
116 this->cost = &KUWATA2008_CCOST;
118 this->cost = &KUWATA2008_DCOST;
121 RRTNode *nn = this->nn(this->iy_, rs, this->cost);
123 RRTNode *nn = this->nn(this->nodes(), rs, this->cost);
126 std::vector<RRTNode *> newly_added;
128 for (auto ns: this->steer(nn, rs)) {
132 this->nodes().push_back(ns);
134 pn->add_child(ns, KUWATA2008_DCOST(pn, ns));
135 if (this->collide(pn, ns)) {
136 pn->children().pop_back();
138 this->iy_[IYI(ns->y())].pop_back();
143 newly_added.push_back(pn);
144 if (this->goal_found(pn, &KUWATA2008_DCOST)) {
145 this->tlog(this->findt());
151 if (this->samples().size() <= 1)
152 return this->goal_found();
153 for (auto na: newly_added) {
156 for (auto ns: this->steer(na, this->goal())) {
160 this->nodes().push_back(ns);
162 pn->add_child(ns, KUWATA2008_DCOST(pn, ns));
163 if (this->collide(pn, ns)) {
164 pn->children().pop_back();
166 this->iy_[IYI(ns->y())].pop_back();
171 if (this->goal_found(pn,
172 &KUWATA2008_DCOST)) {
173 this->tlog(this->findt());
180 return this->goal_found();
183 Karaman2011::Karaman2011(RRTNode *init, RRTNode *goal):
191 srand(static_cast<unsigned>(time(0)));
194 bool Karaman2011::next()
198 if (this->samples().size() == 0)
205 this->samples().push_back(rs);
207 RRTNode *nn = this->nn(this->iy_, rs, this->cost);
209 RRTNode *nn = this->nn(this->nodes(), rs, this->cost);
212 std::vector<RRTNode *> nvs;
214 for (auto ns: this->steer(nn, rs)) {
225 this->nodes().size()),
234 this->nodes().size()),
237 this->nodes().push_back(ns);
240 if (!this->connect(pn, ns, nvs)) {
241 this->iy_[IYI(ns->y())].pop_back();
245 this->rewire(nvs, ns);
247 if (this->goal_found(pn, this->cost)) {
248 this->tlog(this->findt());
254 return this->goal_found();
257 bool Karaman2011::connect(
260 std::vector<RRTNode *> nvs)
262 RRTNode *op; // old parent
263 float od; // old direct cost
264 float oc; // old cumulative cost
265 bool connected = false;
266 pn->add_child(ns, this->cost(pn, ns));
267 if (this->collide(pn, ns)) {
268 pn->children().pop_back();
275 if (!connected || (nv->ccost() + this->cost(nv, ns) <
280 nv->add_child(ns, this->cost(nv, ns));
281 if (this->collide(nv, ns)) {
282 nv->children().pop_back();
289 } else if (connected) {
290 op->children().pop_back();
300 bool Karaman2011::rewire(std::vector<RRTNode *> nvs, RRTNode *ns)
302 RRTNode *op; // old parent
303 float od; // old direct cost
304 float oc; // old cumulative cost
306 if (ns->ccost() + this->cost(ns, nv) < nv->ccost()) {
310 ns->add_child(nv, this->cost(ns, nv));
311 if (this->collide(ns, nv)) {
312 ns->children().pop_back();
324 T1::T1(RRTNode *init, RRTNode *goal):
332 srand(static_cast<unsigned>(time(0)));
338 if (this->samples().size() == 0)
342 this->samples().push_back(rs);
344 RRTNode *nn = this->nn(this->iy_, rs, this->cost);
346 RRTNode *nn = this->nn(this->nodes(), rs, this->cost);
349 std::vector<RRTNode *> nvs;
351 RRTNode *op; // old parent
352 float od; // old direct cost
353 float oc; // old cumulative cost
354 std::vector<RRTNode *> steered = this->steer(nn, rs);
355 // RRT* for first node
356 RRTNode *ns = steered[0];
359 nvs = this->nv(this->iy_, ns, this->cost, MIN(
360 GAMMA_RRTSTAR(this->nodes().size()),
363 nvs = this->nv(this->root(), ns, this->cost, MIN(
364 GAMMA_RRTSTAR(this->nodes().size()),
367 this->nodes().push_back(ns);
370 pn->add_child(ns, this->cost(pn, ns));
371 if (this->collide(pn, ns)) {
372 pn->children().pop_back();
378 if (!connected || (nv->ccost() + this->cost(nv, ns) <
383 nv->add_child(ns, this->cost(nv, ns));
384 if (this->collide(nv, ns)) {
385 nv->children().pop_back();
389 } else if (connected) {
390 op->children().pop_back();
400 if (ns->ccost() + this->cost(ns, nv) < nv->ccost()) {
404 ns->add_child(nv, this->cost(ns, nv));
405 if (this->collide(ns, nv)) {
406 ns->children().pop_back();
416 if (this->goal_found(pn, this->cost)) {
417 this->tlog(this->findt());
421 for (i = 1; i < steered.size(); i++) {
423 this->nodes().push_back(ns);
425 pn->add_child(ns, this->cost(pn, ns));
426 if (this->collide(pn, ns)) {
427 pn->children().pop_back();
431 if (this->goal_found(pn, this->cost)) {
432 this->tlog(this->findt());
436 return this->goal_found();
443 if (this->samples().size() == 0)
450 this->samples().push_back(rs);
452 RRTNode *nn = this->nn(this->iy_, rs, this->cost);
454 RRTNode *nn = this->nn(this->nodes(), rs, this->cost);
459 std::vector<RRTNode *> nvs;
460 std::vector<RRTNode *> newly_added;
463 for (auto ns: this->steer(nn, rs)) {
466 } else if (IS_NEAR(pn, ns)) {
469 if (sgn(pn->s()) != sgn(ns->s()))
480 this->nodes().size()),
489 this->nodes().size()),
492 this->nodes().push_back(ns);
495 if (!this->connect(pn, ns, nvs)) {
496 this->iy_[IYI(ns->y())].pop_back();
500 this->rewire(nvs, ns);
502 newly_added.push_back(pn);
503 if (this->goal_found(pn, this->cost)) {
505 this->tlog(this->findt());
511 if (this->samples().size() <= 1)
512 return this->goal_found();
513 for (auto na: newly_added) {
517 for (auto ns: this->steer(na, this->goal())) {
520 } else if (IS_NEAR(pn, ns)) {
523 if (sgn(pn->s()) != sgn(ns->s()))
527 this->nodes().push_back(ns);
529 pn->add_child(ns, this->cost(pn, ns));
530 if (this->collide(pn, ns)) {
531 pn->children().pop_back();
533 this->iy_[IYI(ns->y())].pop_back();
538 if (this->goal_found(pn, this->cost)) {
540 this->tlog(this->findt());
547 return this->goal_found();
550 float T2::goal_cost()
552 std::vector<RRTNode *> nvs;
567 if (std::abs(this->goal()->h() - nv->h()) >=
568 this->GOAL_FOUND_ANGLE)
570 if (nv->ccost() + (*cost)(nv, this->goal()) >=
571 this->goal()->ccost())
573 RRTNode *op; // old parent
574 float oc; // old cumulative cost
575 float od; // old direct cost
576 op = this->goal()->parent();
577 oc = this->goal()->ccost();
578 od = this->goal()->dcost();
579 nv->add_child(this->goal(),
580 (*cost)(nv, this->goal()));
581 if (this->collide(nv, this->goal())) {
582 nv->children().pop_back();
583 this->goal()->parent(op);
584 this->goal()->ccost(oc);
585 this->goal()->dcost(od);
587 op->rem_child(this->goal());
590 return this->goal()->ccost();
593 class RRTNodeDijkstra {
595 RRTNodeDijkstra(int i):
601 RRTNodeDijkstra(int i, float c):
620 class RRTNodeDijkstraComparator {
623 const RRTNodeDijkstra& n1,
624 const RRTNodeDijkstra& n2)
632 if (this->tlog().size() == 0)
634 float oc = this->tlog().back().front()->ccost();
635 std::vector<RRTNode *> tmp_cusps;
636 for (auto n: this->tlog().back()) {
637 if (n->parent() && sgn(n->s()) != sgn(n->parent()->s())) {
638 tmp_cusps.push_back(n);
639 tmp_cusps.push_back(n->parent());
642 std::vector<RRTNode *> cusps;
643 for (unsigned int i = 0; i < tmp_cusps.size() - 1; i++) {
644 if (tmp_cusps[i] != tmp_cusps[i + 1])
645 cusps.push_back(tmp_cusps[i]);
647 cusps.push_back(this->root());
648 std::reverse(cusps.begin(), cusps.end());
649 cusps.push_back(this->tlog().back().front());
651 std::vector<RRTNodeDijkstra> dnodes;
652 for (unsigned int i = 0; i < cusps.size(); i++)
653 dnodes.push_back(RRTNodeDijkstra(i));
658 std::vector<RRTNodeDijkstra>,
659 RRTNodeDijkstraComparator> pq;
660 RRTNodeDijkstra tmp = dnodes[0];
662 float ch_cost = 9999;
663 std::vector<RRTNode *> steered;
664 while (!pq.empty() && tmp.ni != cusps.size() - 1) {
667 for (unsigned int i = tmp.ni + 1; i < cusps.size(); i++) {
668 ch_cost = dnodes[tmp.ni].c +
669 this->cost(cusps[tmp.ni], cusps[i]);
670 steered = this->steer(cusps[tmp.ni], cusps[i]);
671 for (unsigned int j = 0; j < steered.size() - 1; j++)
672 steered[j]->add_child(
679 steered[steered.size() - 1]))
681 if (ch_cost < dnodes[i].c) {
682 dnodes[i].c = ch_cost;
683 dnodes[i].pi = tmp.ni;
689 std::vector<int> npi; // new path indexes
693 tmpi = dnodes[tmpi].pi;
696 std::vector<RRTNode *> npn; // new path nodes
697 std::reverse(npi.begin(), npi.end());
698 RRTNode *pn = cusps[0];
699 for (unsigned int i = 0; i < npi.size() - 1; i++) {
700 for (auto ns: this->steer(cusps[npi[i]], cusps[npi[i + 1]])) {
701 pn->add_child(ns, this->cost(pn, ns));
706 this->tlog().back().front(),
707 this->cost(pn, this->tlog().back().front()));
709 if (this->tlog().back().front()->ccost() < oc)
714 bool T2::opt_part(RRTNode *init, RRTNode *goal)
716 std::vector<RRTNode *> steered;
717 steered = this->steer(init, goal);
718 unsigned int ss = steered.size();
719 for (unsigned int i = 0; i < ss - 1; i++) {
720 steered[i]->add_child(
724 steered[ss - 1])); // FIXME
726 if (this->collide(steered[0], steered[ss - 1])) {
727 for (auto n: steered)
735 op->add_child(steered[0], this->cost(op, steered[0]));
736 steered[ss - 1]->add_child(goal, this->cost(steered[ss - 1], goal));