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/>.
25 #include "rrtplanner.h"
28 #define CATI(a, b) a ## b
29 #define CAT(a, b) CATI(a, b)
30 #define KUWATA2008_CCOST CAT(c, CO)
31 #define KUWATA2008_DCOST CO
33 LaValle1998::LaValle1998(RRTNode *init, RRTNode *goal):
40 srand(static_cast<unsigned>(time(0)));
43 bool LaValle1998::next()
47 if (this->samples().size() == 0)
54 this->samples().push_back(rs);
56 RRTNode *nn = this->nn(this->iy_, rs, this->cost, '0');
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, '0');
123 RRTNode *nn = this->nn(this->iy_, rs, this->cost);
125 RRTNode *nn = this->nn(this->nodes(), rs, this->cost);
128 std::vector<RRTNode *> newly_added;
130 for (auto ns: this->steer(nn, rs)) {
134 this->nodes().push_back(ns);
136 pn->add_child(ns, KUWATA2008_DCOST(pn, ns));
137 if (this->collide(pn, ns)) {
138 pn->children().pop_back();
140 this->iy_[IYI(ns->y())].pop_back();
145 newly_added.push_back(pn);
146 if (this->goal_found(pn, &KUWATA2008_DCOST)) {
147 this->tlog(this->findt());
153 if (this->samples().size() <= 1)
154 return this->goal_found();
155 for (auto na: newly_added) {
158 for (auto ns: this->steer(na, this->goal())) {
162 this->nodes().push_back(ns);
164 pn->add_child(ns, KUWATA2008_DCOST(pn, ns));
165 if (this->collide(pn, ns)) {
166 pn->children().pop_back();
168 this->iy_[IYI(ns->y())].pop_back();
173 if (this->goal_found(pn,
174 &KUWATA2008_DCOST)) {
175 this->tlog(this->findt());
182 return this->goal_found();
185 Karaman2011::Karaman2011(RRTNode *init, RRTNode *goal):
193 srand(static_cast<unsigned>(time(0)));
196 bool Karaman2011::next()
200 if (this->samples().size() == 0)
207 this->samples().push_back(rs);
209 RRTNode *nn = this->nn(this->iy_, rs, this->cost, '0');
211 RRTNode *nn = this->nn(this->iy_, rs, this->cost);
213 RRTNode *nn = this->nn(this->nodes(), rs, this->cost);
216 std::vector<RRTNode *> nvs;
218 for (auto ns: this->steer(nn, rs)) {
229 this->nodes().size()),
239 this->nodes().size()),
248 this->nodes().size()),
251 this->nodes().push_back(ns);
254 if (!this->connect(pn, ns, nvs)) {
255 this->iy_[IYI(ns->y())].pop_back();
259 this->rewire(nvs, ns);
261 if (this->goal_found(pn, this->cost)) {
262 this->tlog(this->findt());
268 return this->goal_found();
271 bool Karaman2011::connect(
274 std::vector<RRTNode *> nvs)
276 RRTNode *op; // old parent
277 float od; // old direct cost
278 float oc; // old cumulative cost
279 bool connected = false;
280 pn->add_child(ns, this->cost(pn, ns));
281 if (this->collide(pn, ns)) {
282 pn->children().pop_back();
289 if (!connected || (nv->ccost() + this->cost(nv, ns) <
294 nv->add_child(ns, this->cost(nv, ns));
295 if (this->collide(nv, ns)) {
296 nv->children().pop_back();
303 } else if (connected) {
304 op->children().pop_back();
314 bool Karaman2011::rewire(std::vector<RRTNode *> nvs, RRTNode *ns)
316 RRTNode *op; // old parent
317 float od; // old direct cost
318 float oc; // old cumulative cost
320 if (ns->ccost() + this->cost(ns, nv) < nv->ccost()) {
324 ns->add_child(nv, this->cost(ns, nv));
325 if (this->collide(ns, nv)) {
326 ns->children().pop_back();
338 T1::T1(RRTNode *init, RRTNode *goal):
346 srand(static_cast<unsigned>(time(0)));
352 if (this->samples().size() == 0)
356 this->samples().push_back(rs);
358 RRTNode *nn = this->nn(this->iy_, rs, this->cost, '0');
360 RRTNode *nn = this->nn(this->iy_, rs, this->cost);
362 RRTNode *nn = this->nn(this->nodes(), rs, this->cost);
365 std::vector<RRTNode *> nvs;
367 RRTNode *op; // old parent
368 float od; // old direct cost
369 float oc; // old cumulative cost
370 std::vector<RRTNode *> steered = this->steer(nn, rs);
371 // RRT* for first node
372 RRTNode *ns = steered[0];
381 this->nodes().size()),
385 nvs = this->nv(this->iy_, ns, this->cost, MIN(
386 GAMMA_RRTSTAR(this->nodes().size()),
389 nvs = this->nv(this->root(), ns, this->cost, MIN(
390 GAMMA_RRTSTAR(this->nodes().size()),
393 this->nodes().push_back(ns);
396 pn->add_child(ns, this->cost(pn, ns));
397 if (this->collide(pn, ns)) {
398 pn->children().pop_back();
404 if (!connected || (nv->ccost() + this->cost(nv, ns) <
409 nv->add_child(ns, this->cost(nv, ns));
410 if (this->collide(nv, ns)) {
411 nv->children().pop_back();
415 } else if (connected) {
416 op->children().pop_back();
426 if (ns->ccost() + this->cost(ns, nv) < nv->ccost()) {
430 ns->add_child(nv, this->cost(ns, nv));
431 if (this->collide(ns, nv)) {
432 ns->children().pop_back();
442 if (this->goal_found(pn, this->cost)) {
443 this->tlog(this->findt());
447 for (i = 1; i < steered.size(); i++) {
449 this->nodes().push_back(ns);
451 pn->add_child(ns, this->cost(pn, ns));
452 if (this->collide(pn, ns)) {
453 pn->children().pop_back();
457 if (this->goal_found(pn, this->cost)) {
458 this->tlog(this->findt());
462 return this->goal_found();
469 if (this->samples().size() == 0)
476 this->samples().push_back(rs);
478 RRTNode *nn = this->nn(this->iy_, rs, this->cost, '0');
480 RRTNode *nn = this->nn(this->iy_, rs, this->cost);
482 RRTNode *nn = this->nn(this->nodes(), rs, this->cost);
487 std::vector<RRTNode *> nvs;
488 std::vector<RRTNode *> newly_added;
491 for (auto ns: this->steer(nn, rs)) {
494 } else if (IS_NEAR(pn, ns)) {
497 if (sgn(ns->s()) == 0 || sgn(pn->s()) != sgn(ns->s()))
508 this->nodes().size()),
518 this->nodes().size()),
527 this->nodes().size()),
530 this->nodes().push_back(ns);
533 if (!this->connect(pn, ns, nvs)) {
534 this->iy_[IYI(ns->y())].pop_back();
538 this->rewire(nvs, ns);
540 newly_added.push_back(pn);
541 if (this->goal_found(pn, this->cost)) {
543 this->tlog(this->findt());
549 if (this->samples().size() <= 1)
550 return this->goal_found();
551 for (auto na: newly_added) {
555 for (auto ns: this->steer(na, this->goal())) {
558 } else if (IS_NEAR(pn, ns)) {
561 if (sgn(pn->s()) != sgn(ns->s()))
565 this->nodes().push_back(ns);
567 pn->add_child(ns, this->cost(pn, ns));
568 if (this->collide(pn, ns)) {
569 pn->children().pop_back();
571 this->iy_[IYI(ns->y())].pop_back();
576 if (this->goal_found(pn, this->cost)) {
578 this->tlog(this->findt());
585 return this->goal_found();
588 float T2::goal_cost()
590 std::vector<RRTNode *> nvs;
598 this->nodes().size()),
615 if (std::abs(this->goal()->h() - nv->h()) >=
616 this->GOAL_FOUND_ANGLE)
618 if (nv->ccost() + (*cost)(nv, this->goal()) >=
619 this->goal()->ccost())
621 RRTNode *op; // old parent
622 float oc; // old cumulative cost
623 float od; // old direct cost
624 op = this->goal()->parent();
625 oc = this->goal()->ccost();
626 od = this->goal()->dcost();
627 nv->add_child(this->goal(),
628 (*cost)(nv, this->goal()));
629 if (this->collide(nv, this->goal())) {
630 nv->children().pop_back();
631 this->goal()->parent(op);
632 this->goal()->ccost(oc);
633 this->goal()->dcost(od);
635 op->rem_child(this->goal());
638 return this->goal()->ccost();
641 T3::T3(RRTNode *init, RRTNode *goal):
646 srand(static_cast<unsigned>(time(0)));
651 RRTNode *ron = nullptr;
652 RRTNode *gon = nullptr;
654 ret = this->p_root_.next();
655 ret &= this->p_goal_.next();
656 if (this->overlaptrees(&ron, &gon)) {
657 if (this->connecttrees(ron, gon))
658 this->goal_found(true);
659 this->tlog(this->findt());
665 bool T3::link_obstacles(
666 std::vector<CircleObstacle> *cobstacles,
667 std::vector<SegmentObstacle> *sobstacles)
670 ret = RRTBase::link_obstacles(cobstacles, sobstacles);
671 ret &= this->p_root_.link_obstacles(cobstacles, sobstacles);
672 ret &= this->p_goal_.link_obstacles(cobstacles, sobstacles);
676 bool T3::connecttrees(RRTNode *rn, RRTNode *gn)
678 while (gn != this->goal()) {
679 this->p_root_.nodes().push_back(new RRTNode(
684 this->p_root_.nodes().back(),
687 this->p_root_.nodes().back()));
688 rn = this->p_root_.nodes().back();
691 rn->add_child(this->goal(), this->p_root_.cost(rn, this->goal()));
695 bool T3::overlaptrees(RRTNode **ron, RRTNode **gon)
697 for (auto rn: this->p_root_.nodes()) {
698 if (rn->parent() == nullptr)
700 for (auto gn: this->p_goal_.nodes()) {
701 if (gn->parent() == nullptr)
703 if (IS_NEAR(rn, gn)) {
713 Klemm2015::Klemm2015(RRTNode *init, RRTNode *goal):
714 Karaman2011(init, goal),
718 srand(static_cast<unsigned>(time(0)));
721 bool Klemm2015::next()
723 RRTNode *xn = nullptr;
726 if (this->samples().size() == 0)
733 this->samples().push_back(rs);
734 //std::cerr << "next" << std::endl;
735 if (this->extendstar1(rs, &xn) != 2) {
737 // std::cerr << "- xn: " << xn->x() << ", " << xn->y();
738 // std::cerr << std::endl;
740 // std::cerr << "- xn: nullptr" << std::endl;
743 this->connectstar(xn);
747 return this->goal_found();
750 int Klemm2015::extendstar()
755 int Klemm2015::connectstar()
760 void Klemm2015::swap()
764 this->root(this->goal());