X-Git-Url: http://rtime.felk.cvut.cz/gitweb/hubacji1/iamcar2.git/blobdiff_plain/eaa68e474963c3d5e9502855db3c99ee9d029218..41afde61c4a85d0eb68521a232c43a012330b4aa:/rrts/src/rrts.cc diff --git a/rrts/src/rrts.cc b/rrts/src/rrts.cc index 4c016b2..1520d61 100644 --- a/rrts/src/rrts.cc +++ b/rrts/src/rrts.cc @@ -55,25 +55,37 @@ RRTNode::p() const } void -RRTNode::p(RRTNode& p) +RRTNode::p(RRTNode& p, bool can_be_too_close) { - if (this != &p) { - this->_p = &p; + assert(this != &p); + if (!can_be_too_close) { + 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() const +RRTNode::cusp_cnt() const { - return this->_cusp; + return this->_cusp_cnt; } void -RRTNode::cusp(RRTNode const& p) +RRTNode::cusp_cnt(RRTNode const& p) { - this->_cusp = p.cusp(); - if (this->sp() != p.sp() || this->sp() == 0.0) { - this->_cusp++; + this->_cusp_cnt = p.cusp_cnt(); + if (this->_p_is_cusp) { + this->_cusp_cnt++; } } @@ -89,6 +101,45 @@ RRTNode::st(int st) 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) { @@ -98,18 +149,16 @@ RRTNode::operator==(RRTNode const& n) void RRTS::recompute_cc_for_predecessors_and(RRTNode* g) { - assert(this->_path.size() == 0); + std::vector path; + path.reserve(this->_path.size()); while (g != nullptr) { - this->_path.push_back(g); + 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])); + std::reverse(path.begin(), path.end()); + for (unsigned int i = 1; i < path.size(); i++) { + path[i]->c(this->cost_build(*path[i - 1], *path[i])); } - this->_path.clear(); } void @@ -140,7 +189,6 @@ RRTS::join_steered(RRTNode* f) RRTNode* t = &this->_nodes.back(); t->p(*f); t->c(this->cost_build(*f, *t)); - t->cusp(*f); this->_steered.erase(this->_steered.begin()); f = t; } @@ -151,6 +199,15 @@ RRTS::connect() { 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 + && 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_) { @@ -172,7 +229,6 @@ RRTS::connect() t = &this->_nodes.back(); t->p(*f); t->c(this->cost_build(*f, *t)); - t->cusp(*f); this->_steered.erase(this->_steered.begin()); return true; } @@ -279,6 +335,12 @@ RRTS::set_bc_pose_to(Pose const& p) this->_bc.set_pose_to(p); } +void +RRTS::set_bc_to_become(std::string what) +{ + this->_bc.become(what); +} + RRTGoal const& RRTS::goal(void) const { @@ -328,11 +390,11 @@ RRTS::scnt() const } void -RRTS::start(double x, double y, double h) +RRTS::set_init_pose_to(Pose const& p) { - this->_nodes.front().x(x); - this->_nodes.front().y(y); - this->_nodes.front().h(h); + this->_nodes.front().x(p.x()); + this->_nodes.front().y(p.y()); + this->_nodes.front().h(p.h()); } std::vector @@ -374,7 +436,7 @@ RRTS::eta(double e) } Json::Value -RRTS::json() const +RRTS::json(void) const { Json::Value jvo; unsigned int i = 0, j = 0; @@ -386,8 +448,20 @@ RRTS::json() const 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++; } + // Initial point is part of the first segment. + jvo["paths"][j][0][3] = jvo["paths"][j][1][3]; + jvo["paths"][j][0][4] = jvo["paths"][j][1][4]; + // Goal point is part of the last segment. + jvo["paths"][j][i - 1][3] = jvo["paths"][j][i - 2][3]; + jvo["paths"][j][i - 1][4] = jvo["paths"][j][i - 2][4]; + // -- jvo["costs"][j] = path.back().cc(); j++; } @@ -398,15 +472,29 @@ RRTS::json() const 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(); - j++; + // Initial point is part of the first segment. + jvo["path"][0][3] = jvo["path"][1][3]; + jvo["path"][0][4] = jvo["path"][1][4]; + // Goal point is part of the last segment. + jvo["path"][i - 1][3] = jvo["path"][i - 2][3]; + jvo["path"][i - 1][4] = jvo["path"][i - 2][4]; + // -- + if (this->_path.size() > 0) { + jvo["costs"][j] = this->_path.back()->cc(); + } jvo["goal_cc"] = this->_goal.cc(); // TODO remove, use the following jvo["cost"] = this->path_cost(); jvo["time"] = this->scnt(); @@ -418,10 +506,10 @@ RRTS::json(Json::Value jvi) { assert(jvi["init"] != Json::nullValue); assert(jvi["goal"] != Json::nullValue); - this->start( + this->set_init_pose_to(Pose( jvi["init"][0].asDouble(), jvi["init"][1].asDouble(), - jvi["init"][2].asDouble()); + jvi["init"][2].asDouble())); if (jvi["goal"].size() == 4) { this->goal( jvi["goal"][0].asDouble(), @@ -472,13 +560,15 @@ RRTS::next() 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()); @@ -489,7 +579,7 @@ RRTS::next() 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; }