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/>.
26 #include "rrtplanner.h"
29 #define CATI(a, b) a ## b
30 #define CAT(a, b) CATI(a, b)
31 #define KUWATA2008_CCOST CAT(c, CO)
32 #define KUWATA2008_DCOST CO
34 LaValle1998::LaValle1998(RRTNode *init, RRTNode *goal):
41 srand(static_cast<unsigned>(time(0)));
44 bool LaValle1998::next()
48 if (this->samples().size() == 0)
55 this->samples().push_back(rs);
57 RRTNode *nn = this->nn(this->iy_, rs, this->cost);
59 RRTNode *nn = this->nn(this->nodes(), rs, this->cost);
63 for (auto ns: this->steer(nn, rs)) {
67 this->nodes().push_back(ns);
69 pn->add_child(ns, this->cost(pn, ns));
70 if (this->collide(pn, ns)) {
71 pn->children().pop_back();
73 this->iy_[IYI(ns->y())].pop_back();
78 if (this->goal_found(pn, this->cost)) {
79 this->tlog(this->findt());
85 return this->goal_found();
88 Kuwata2008::Kuwata2008(RRTNode *init, RRTNode *goal):
93 cost(KUWATA2008_DCOST)
95 srand(static_cast<unsigned>(time(0)));
98 bool Kuwata2008::next()
101 if (this->samples().size() == 0) {
106 this->samples().push_back(rs);
107 float heur = static_cast<float>(rand()) / static_cast<float>(RAND_MAX);
108 if (this->goal_found()) {
110 this->cost = &KUWATA2008_CCOST;
112 this->cost = &KUWATA2008_DCOST;
115 this->cost = &KUWATA2008_CCOST;
117 this->cost = &KUWATA2008_DCOST;
120 RRTNode *nn = this->nn(this->iy_, rs, this->cost);
122 RRTNode *nn = this->nn(this->nodes(), rs, this->cost);
125 std::vector<RRTNode *> newly_added;
127 for (auto ns: this->steer(nn, rs)) {
131 this->nodes().push_back(ns);
133 pn->add_child(ns, KUWATA2008_DCOST(pn, ns));
134 if (this->collide(pn, ns)) {
135 pn->children().pop_back();
137 this->iy_[IYI(ns->y())].pop_back();
142 newly_added.push_back(pn);
143 if (this->goal_found(pn, &KUWATA2008_DCOST)) {
144 this->tlog(this->findt());
150 if (this->samples().size() <= 1)
151 return this->goal_found();
152 for (auto na: newly_added) {
155 for (auto ns: this->steer(na, this->goal())) {
159 this->nodes().push_back(ns);
161 pn->add_child(ns, KUWATA2008_DCOST(pn, ns));
162 if (this->collide(pn, ns)) {
163 pn->children().pop_back();
165 this->iy_[IYI(ns->y())].pop_back();
170 if (this->goal_found(pn,
171 &KUWATA2008_DCOST)) {
172 this->tlog(this->findt());
179 return this->goal_found();
182 Karaman2011::Karaman2011(RRTNode *init, RRTNode *goal):
190 srand(static_cast<unsigned>(time(0)));
193 bool Karaman2011::next()
197 if (this->samples().size() == 0)
204 this->samples().push_back(rs);
206 RRTNode *nn = this->nn(this->iy_, rs, this->cost);
208 RRTNode *nn = this->nn(this->nodes(), rs, this->cost);
211 std::vector<RRTNode *> nvs;
213 for (auto ns: this->steer(nn, rs)) {
224 this->nodes().size()),
233 this->nodes().size()),
236 this->nodes().push_back(ns);
239 if (!this->connect(pn, ns, nvs)) {
240 this->iy_[IYI(ns->y())].pop_back();
244 this->rewire(nvs, ns);
246 if (this->goal_found(pn, this->cost)) {
247 this->tlog(this->findt());
253 return this->goal_found();
256 bool Karaman2011::connect(
259 std::vector<RRTNode *> nvs)
261 RRTNode *op; // old parent
262 float od; // old direct cost
263 float oc; // old cumulative cost
264 bool connected = false;
265 pn->add_child(ns, this->cost(pn, ns));
266 if (this->collide(pn, ns)) {
267 pn->children().pop_back();
274 if (!connected || (nv->ccost() + this->cost(nv, ns) <
279 nv->add_child(ns, this->cost(nv, ns));
280 if (this->collide(nv, ns)) {
281 nv->children().pop_back();
288 } else if (connected) {
289 op->children().pop_back();
299 bool Karaman2011::rewire(std::vector<RRTNode *> nvs, RRTNode *ns)
301 RRTNode *op; // old parent
302 float od; // old direct cost
303 float oc; // old cumulative cost
305 if (ns->ccost() + this->cost(ns, nv) < nv->ccost()) {
309 ns->add_child(nv, this->cost(ns, nv));
310 if (this->collide(ns, nv)) {
311 ns->children().pop_back();
323 T1::T1(RRTNode *init, RRTNode *goal):
331 srand(static_cast<unsigned>(time(0)));
337 if (this->samples().size() == 0)
341 this->samples().push_back(rs);
343 RRTNode *nn = this->nn(this->iy_, rs, this->cost);
345 RRTNode *nn = this->nn(this->nodes(), rs, this->cost);
348 std::vector<RRTNode *> nvs;
350 RRTNode *op; // old parent
351 float od; // old direct cost
352 float oc; // old cumulative cost
353 std::vector<RRTNode *> steered = this->steer(nn, rs);
354 // RRT* for first node
355 RRTNode *ns = steered[0];
358 nvs = this->nv(this->iy_, ns, this->cost, MIN(
359 GAMMA_RRTSTAR(this->nodes().size()),
362 nvs = this->nv(this->root(), ns, this->cost, MIN(
363 GAMMA_RRTSTAR(this->nodes().size()),
366 this->nodes().push_back(ns);
369 pn->add_child(ns, this->cost(pn, ns));
370 if (this->collide(pn, ns)) {
371 pn->children().pop_back();
377 if (!connected || (nv->ccost() + this->cost(nv, ns) <
382 nv->add_child(ns, this->cost(nv, ns));
383 if (this->collide(nv, ns)) {
384 nv->children().pop_back();
388 } else if (connected) {
389 op->children().pop_back();
399 if (ns->ccost() + this->cost(ns, nv) < nv->ccost()) {
403 ns->add_child(nv, this->cost(ns, nv));
404 if (this->collide(ns, nv)) {
405 ns->children().pop_back();
415 if (this->goal_found(pn, this->cost)) {
416 this->tlog(this->findt());
420 for (i = 1; i < steered.size(); i++) {
422 this->nodes().push_back(ns);
424 pn->add_child(ns, this->cost(pn, ns));
425 if (this->collide(pn, ns)) {
426 pn->children().pop_back();
430 if (this->goal_found(pn, this->cost)) {
431 this->tlog(this->findt());
435 return this->goal_found();
442 if (this->samples().size() == 0)
449 this->samples().push_back(rs);
451 RRTNode *nn = this->nn(this->iy_, rs, this->cost);
453 RRTNode *nn = this->nn(this->nodes(), rs, this->cost);
456 std::vector<RRTNode *> nvs;
457 std::vector<RRTNode *> newly_added;
460 for (auto ns: this->steer(nn, rs)) {
463 } else if (IS_NEAR(pn, ns)) {
466 if (sgn(pn->s()) != sgn(ns->s()))
477 this->nodes().size()),
486 this->nodes().size()),
489 this->nodes().push_back(ns);
492 if (!this->connect(pn, ns, nvs)) {
493 this->iy_[IYI(ns->y())].pop_back();
497 this->rewire(nvs, ns);
499 newly_added.push_back(pn);
500 if (this->goal_found(pn, this->cost)) {
502 this->tlog(this->findt());
504 this->tlog(this->findt());
510 if (this->samples().size() <= 1)
511 return this->goal_found();
512 for (auto na: newly_added) {
516 for (auto ns: this->steer(na, this->goal())) {
519 } else if (IS_NEAR(pn, ns)) {
522 if (sgn(pn->s()) != sgn(ns->s()))
526 this->nodes().push_back(ns);
528 pn->add_child(ns, this->cost(pn, ns));
529 if (this->collide(pn, ns)) {
530 pn->children().pop_back();
532 this->iy_[IYI(ns->y())].pop_back();
537 if (this->goal_found(pn, this->cost)) {
539 this->tlog(this->findt());
541 this->tlog(this->findt());
548 return this->goal_found();
551 float T2::goal_cost()
553 std::vector<RRTNode *> nvs;
568 if (std::abs(this->goal()->h() - nv->h()) >=
569 this->GOAL_FOUND_ANGLE)
571 if (nv->ccost() + (*cost)(nv, this->goal()) >=
572 this->goal()->ccost())
574 RRTNode *op; // old parent
575 float oc; // old cumulative cost
576 float od; // old direct cost
577 op = this->goal()->parent();
578 oc = this->goal()->ccost();
579 od = this->goal()->dcost();
580 nv->add_child(this->goal(),
581 (*cost)(nv, this->goal()));
582 if (this->collide(nv, this->goal())) {
583 nv->children().pop_back();
584 this->goal()->parent(op);
585 this->goal()->ccost(oc);
586 this->goal()->dcost(od);
588 op->rem_child(this->goal());
591 return this->goal()->ccost();
596 std::vector<RRTNode *> cusps;
597 if (this->tlog().size() == 0)
599 for (auto n: this->tlog().back()) {
600 if (n->parent() && sgn(n->s()) != sgn(n->parent()->s()))
603 cusps.push_back(this->root());
604 std::reverse(cusps.begin(), cusps.end());
605 cusps.push_back(this->goal());
606 int li = cusps.size() - 1;
609 if (this->opt_part(cusps[i], cusps[li]))
617 bool T2::opt_part(RRTNode *init, RRTNode *goal)
619 std::vector<RRTNode *> steered;
620 steered = this->steer(init, goal);
621 for (unsigned int i = 0; i < steered.size() - 1; i++) {
622 steered[i]->add_child(
626 steered[steered.size() - 1]));
628 if (this->collide(steered[0], steered[steered.size() - 1])) {
629 for (auto n: steered)
637 op->add_child(steered[0], this->cost(op, steered[0]));
639 steered[steered.size() - 1]->add_child(
642 steered[steered.size() - 1],