}
void
-RRTNode::p(RRTNode& p)
+RRTNode::p(RRTNode& p, bool connecting_goal)
{
- if (this != &p) {
- this->_p = &p;
+ assert(this != &p);
+ if (!connecting_goal) {
+ assert(!(std::abs(p.x() - this->x()) < 1e-3
+ && std::abs(p.y() - this->y()) < 1e-3
+ && std::abs(p.h() - this->h()) < 1e-3));
}
+ this->_p = &p;
+ this->p_is_cusp(this->would_be_cusp_if_parent(p));
+ this->cusp_cnt(p);
+}
+
+void
+RRTNode::p(RRTNode& p)
+{
+ return this->p(p, false);
}
unsigned int
RRTNode::cusp_cnt(RRTNode const& p)
{
this->_cusp_cnt = p.cusp_cnt();
- if (this->sp() != p.sp() || this->sp() == 0.0) {
+ if (this->_p_is_cusp) {
this->_cusp_cnt++;
}
}
this->_segment_type = st;
}
+bool
+RRTNode::p_is_cusp(void) const
+{
+ return this->_p_is_cusp;
+}
+
+void
+RRTNode::p_is_cusp(bool isit)
+{
+ this->_p_is_cusp = isit;
+}
+
+bool
+RRTNode::would_be_cusp_if_parent(RRTNode const& p) const
+{
+ if (std::abs(p.sp()) < 1e-3) {
+ // It should not be possible to have two zero speed nodes next
+ // to each other. In practice, this sometimes happens.
+ //assert(std::abs(this->sp()) > 1e-3);
+ if (p.p()) {
+ if (sgn(p.p()->sp()) != sgn(this->sp())) {
+ return true;
+ } else {
+ return false;
+ }
+ } else {
+ return true; // only root has no parent and it is cusp
+ }
+ } else {
+ if (std::abs(this->sp()) < 1e-3) {
+ return false; // this is cusp, not the parent
+ } else if (sgn(p.sp()) != sgn(this->sp())) {
+ return true;
+ } else {
+ return false;
+ }
+ }
+}
+
bool
RRTNode::operator==(RRTNode const& n)
{
RRTNode* t = &this->_nodes.back();
t->p(*f);
t->c(this->cost_build(*f, *t));
- t->cusp_cnt(*f);
this->_steered.erase(this->_steered.begin());
f = t;
}
RRTNode* f = this->_nn;
RRTNode* t = &this->_steered.front();
// Require the steer method to return first node equal to nn:
- assert(std::abs(t->x() - f->x()) < 1e-3);
- assert(std::abs(t->y() - f->x()) < 1e-3);
- assert(std::abs(t->h() - f->x()) < 1e-3);
- // When f and t has different directions, the node (f == t) is cusp:
- // TODO
+ assert(std::abs(t->x() - f->x()) < 1e-3
+ && std::abs(t->y() - f->y()) < 1e-3
+ && std::abs(t->h() - f->h()) < 1e-3);
this->_steered.erase(this->_steered.begin());
t = &this->_steered.front();
+ assert(!(std::abs(t->x() - f->x()) < 1e-3
+ && std::abs(t->y() - f->y()) < 1e-3
+ && std::abs(t->h() - f->h()) < 1e-3));
#if USE_RRTS
double cost = f->cc() + this->cost_build(*f, *t);
for (auto n: this->nv_) {
t = &this->_nodes.back();
t->p(*f);
t->c(this->cost_build(*f, *t));
- t->cusp_cnt(*f);
this->_steered.erase(this->_steered.begin());
return true;
}
jvo["paths"][j][i][2] = n.h();
jvo["paths"][j][i][3] = n.sp();
jvo["paths"][j][i][4] = n.st();
+ jvo["paths"][j][i][5] = false;
+ if (n.p_is_cusp()) {
+ assert(i > 0);
+ jvo["paths"][j][i - 1][5] = true;
+ }
i++;
}
jvo["costs"][j] = path.back().cc();
jvo["paths"][j][i][2] = n->h();
jvo["paths"][j][i][3] = n->sp();
jvo["paths"][j][i][4] = n->st();
+ jvo["paths"][j][i][5] = n->p_is_cusp();
jvo["path"][i][0] = n->x();
jvo["path"][i][1] = n->y();
jvo["path"][i][2] = n->h();
jvo["path"][i][3] = n->sp();
jvo["path"][i][4] = n->st();
+ jvo["path"][i][5] = false;
+ if (n->p_is_cusp()) {
+ assert(i > 0);
+ jvo["path"][i - 1][5] = true;
+ }
i++;
}
jvo["costs"][j] = this->_path.back()->cc();
this->join_steered(&this->_nodes.back());
RRTNode* just_added = &this->_nodes.back();
bool gf = false;
- while (ss > 0 && just_added->p() != nullptr) {
+ while (ss > 0 && just_added != nullptr) {
this->steer(*just_added, this->_goal);
if (this->collide_steered()) {
ss--;
just_added = just_added->p();
continue;
}
+ // The first of steered is the same as just_added.
+ this->_steered.erase(this->_steered.begin());
this->join_steered(just_added);
bool gn = this->_goal.edist(this->_nodes.back()) < this->eta();
bool gd = this->goal_drivable_from(this->_nodes.back());
double ncc = this->_nodes.back().cc() + nc;
if (this->_goal.p() == nullptr
|| ncc < this->_goal.cc()) {
- this->_goal.p(this->_nodes.back());
+ this->_goal.p(this->_nodes.back(), true);
this->_goal.c(nc);
gf = true;
}