+#include <algorithm>
#include <queue>
#include "rrtext.hh"
return n1.node->cc() > n2.node->cc();
}
+int
+RRTExt13::DijkstraNodeBackwardComparator::operator() (DijkstraNode const& n1,
+ DijkstraNode const& n2)
+{
+ return n1.d > n2.d;
+}
+
void
-RRTExt13::pick_interesting()
+RRTExt13::interesting_forward()
{
this->dn_.clear();
this->dn_.reserve(this->path_.size());
return;
#endif
#if 1 // cusp and 1st non-drivable path poses are interesting
+ this->dn_.push_back(DijkstraNode(this->opath_.front()));
+ this->dn_.back().i = this->dn_.size() - 1;
for (unsigned int i = 0; i < this->opath_.size() - 1; i++) {
- //unsigned int i = 0; { // just for cusp, comment out drivable section
RRTNode& ni = *this->opath_[i];
this->bc_.set_pose(ni);
for (unsigned int j = i + 1; j < this->opath_.size(); j++) {
RRTNode& nj = *this->opath_[j];
RRTNode& njl = *this->opath_[j - 1];
- if (njl.sp() == 0.0 || sgn(njl.sp()) != sgn(nj.sp())
- || njl.edist(nj) < this->eta_) {
+ if (!this->bc_.drivable(nj)) {
+ this->dn_.push_back(DijkstraNode(&njl));
+ this->dn_.back().i = this->dn_.size() - 1;
+ i = j;
+ break;
+ }
+ if (njl.sp() == 0.0 || sgn(njl.sp()) != sgn(nj.sp())) {
this->dn_.push_back(DijkstraNode(&njl));
this->dn_.back().i = this->dn_.size() - 1;
}
+ }
+ }
+ this->dn_.push_back(DijkstraNode(this->opath_.back()));
+ this->dn_.back().i = this->dn_.size() - 1;
+#endif
+}
+
+void
+RRTExt13::interesting_backward()
+{
+ this->dn_.clear();
+ this->dn_.reserve(this->path_.size());
+#if 0 // all path poses are interesting
+ for (auto n: this->opath_) {
+ this->dn_.push_back(DijkstraNode(n));
+ this->dn_.back().i = this->dn_.size() - 1;
+ }
+ std::reverse(this->dn_.begin(), this->dn_.end());
+ return;
+#endif
+#if 1 // cusp and 1st non-drivable path poses are interesting
+ double goal_cc = this->goal_.cc();
+ this->dn_.push_back(DijkstraNode(this->opath_.back()));
+ this->dn_.back().i = this->dn_.size() - 1;
+ this->dn_.back().d = goal_cc - this->opath_.back()->cc();
+ for (unsigned int i = this->opath_.size() - 1; i > 1; i--) {
+ RRTNode& ni = *this->opath_[i];
+ this->bc_.set_pose(ni);
+ for (unsigned int j = i - 1; j > 0; j--) {
+ RRTNode& nj = *this->opath_[j];
+ RRTNode& njl = *this->opath_[j + 1];
if (!this->bc_.drivable(nj)) {
this->dn_.push_back(DijkstraNode(&njl));
this->dn_.back().i = this->dn_.size() - 1;
+ this->dn_.back().d = goal_cc - njl.cc();
i = j;
break;
}
+ if (njl.sp() == 0.0 || sgn(njl.sp()) != sgn(nj.sp())) {
+ this->dn_.push_back(DijkstraNode(&njl));
+ this->dn_.back().i = this->dn_.size() - 1;
+ this->dn_.back().d = goal_cc - njl.cc();
+ }
}
}
- this->dn_.push_back(DijkstraNode(this->opath_.back()));
+ this->dn_.push_back(DijkstraNode(this->opath_.front()));
this->dn_.back().i = this->dn_.size() - 1;
+ this->dn_.back().d = goal_cc - this->opath_.front()->cc();
#endif
}
DijkstraNode fd = pq.top();
RRTNode& f = *fd.node;
pq.pop();
+ this->bc_.set_pose(f);
for (unsigned int i = fd.i + 1; i < this->dn_.size(); i++) {
RRTNode& t = *this->dn_[i].node;
+ if (!this->bc_.drivable(t)) {
+ continue;
+ }
double cost = f.cc() + this->cost_build(f, t);
this->steer(f, t);
if (this->steered_.size() == 0) {
break;
}
- if (this->collide_steered()) {
+ unsigned int ss = this->steered_.size();
+ if (this->collide_steered()
+ || ss != this->steered_.size()) {
continue;
}
this->bc_.set_pose(this->steered_.back());
bool td = this->bc_.drivable(t);
- bool tn = this->bc_.edist(t) < this->eta_;
+ bool tn = this->bc_.edist(t) < 2.0 * this->eta_;
if (cost < t.cc() && td && tn) {
this->join_steered(&f);
t.p(this->nodes_.back());
{
std::priority_queue<DijkstraNode, std::vector<DijkstraNode>,
DijkstraNodeComparator> pq;
- this->dn_.back().vi();
- pq.push(this->dn_.back());
+ this->dn_.front().vi();
+ pq.push(this->dn_.front());
while (!pq.empty()) {
DijkstraNode td = pq.top();
RRTNode& t = *td.node;
pq.pop();
- for (unsigned int i = td.i - 1; i > 0; i--) {
+ this->bc_.set_pose(t);
+ for (unsigned int i = td.i; i > 0; i--) {
+ DijkstraNode& fd = this->dn_[i];
RRTNode& f = *this->dn_[i].node;
- double cost = f.cc() + this->cost_build(f, t);
+ if (!this->bc_.drivable(f)) {
+ continue;
+ }
+ double cost = td.d + this->cost_build(f, t);
this->steer(f, t);
if (this->steered_.size() == 0) {
break;
}
- if (this->collide_steered()) {
+ unsigned int ss = this->steered_.size();
+ if (this->collide_steered()
+ || ss != this->steered_.size()) {
continue;
}
this->bc_.set_pose(this->steered_.back());
bool td = this->bc_.drivable(t);
- bool tn = this->bc_.edist(t) < this->eta_;
- if (cost < t.cc() && td && tn) {
+ bool tn = this->bc_.edist(t) < 2.0 * this->eta_;
+ if (cost < fd.d && td && tn) {
+ fd.d = cost;
this->join_steered(&f);
t.p(this->nodes_.back());
t.c(this->cost_build(this->nodes_.back(), t));
+ this->recompute_path_cc();
if (!this->dn_[i].vi()) {
pq.push(this->dn_[i]);
}
if (measure_time) {
this->otime_ = -this->ter_.scnt();
}
- this->pick_interesting();
- this->dijkstra_forward();
-#if 0 // TODO Fix as the code does not always finish.
- RRTS::compute_path();
- this->pick_interesting();
- this->dijkstra_backward();
-#endif
- RRTS::compute_path();
+ double curr_cc = this->goal_.cc();
+ double last_cc = curr_cc + 1.0;
+ while (curr_cc < last_cc) {
+ last_cc = curr_cc;
+ RRTS::compute_path();
+ this->interesting_forward();
+ this->dijkstra_forward();
+ RRTS::compute_path();
+ this->interesting_backward();
+ this->dijkstra_backward();
+ RRTS::compute_path();
+ curr_cc = this->goal_.cc();
+ }
if (measure_time) {
this->otime_ += this->ter_.scnt();
}
return this == &n;
}
+void
+RRTS::recompute_path_cc()
+{
+ this->path_.clear();
+ RRTNode* g = &this->goal_;
+ while (g != nullptr) {
+ this->path_.push_back(g);
+ g = g->p();
+ }
+ std::reverse(this->path_.begin(), this->path_.end());
+ for (unsigned int i = 1; i < this->path_.size(); i++) {
+ this->path_[i]->c(this->cost_build(*this->path_[i - 1],
+ *this->path_[i]));
+ }
+}
+
double
RRTS::min_gamma_eta() const
{
double d1 = this->cost_search(this->nodes_.front(), rs);
double d2 = this->cost_search(rs, this->goal_);
if (this->last_goal_cc_ != 0.0 && d1 + d2 > this->last_goal_cc_) {
- this->icnt_ -= 1;
- return this->should_continue();
+ rs = this->last_path_[rand() % this->last_path_.size()];
}
}
#endif
ss--;
just_added = just_added->p();
}
-#if 1 // test if root -> just_added can be steered directly
- this->steer(this->nodes_.front(), *just_added);
- ss = this->steered_.size();
- if (!this->collide_steered() && this->steered_.size() == ss) {
- this->join_steered(&this->nodes_.front());
- just_added->p(this->nodes_.back());
- just_added->c(this->cost_build(this->nodes_.back(),
- *just_added));
- }
-#endif
if (gf) {
this->compute_path();
}
{
if (this->goal_.cc() != 0.0 && this->goal_.cc() < this->last_goal_cc_) {
this->last_goal_cc_ = this->goal_.cc();
+ this->last_path_.clear();
+ for (auto n: this->path_) {
+ this->last_path_.push_back(*n);
+ }
}
this->goal_ = RRTGoal(this->goal_.x(), this->goal_.y(), this->goal_.b(),
this->goal_.e());