]> rtime.felk.cvut.cz Git - hubacji1/iamcar.git/blobdiff - base/rrtbase.cc
Reformat IS_NEAR, add IS_NEAR for goal
[hubacji1/iamcar.git] / base / rrtbase.cc
index 1513b2bccf19a67e5bb3113f8d932cb2843882c2..8a44e6e572cbfff7a61fc79b92b579226c1e1cff 100644 (file)
@@ -91,10 +91,13 @@ RRTBase::~RRTBase()
         delete this->goal_;
 }
 
-RRTBase::RRTBase():
-        root_(new RRTNode()),
-        goal_(new RRTNode()),
-        gen_(std::random_device{}())
+RRTBase::RRTBase()
+        : root_(new RRTNode())
+        , goal_(new RRTNode())
+        , gen_(std::random_device{}())
+        , ndx_(HMAX - HMIN, (HMAX - HMIN) / 4)
+        , ndy_(VMAX - VMIN, (VMAX - VMIN) / 4)
+        , ndh_(0, M_PI * 2 / 4)
 {
         this->nodes_.reserve(NOFNODES);
         this->nodes_.push_back(this->root_);
@@ -102,10 +105,13 @@ RRTBase::RRTBase():
         this->add_ixy(this->root_);
 }
 
-RRTBase::RRTBase(RRTNode *init, RRTNode *goal):
-        root_(init),
-        goal_(goal),
-        gen_(std::random_device{}())
+RRTBase::RRTBase(RRTNode *init, RRTNode *goal)
+        : root_(init)
+        , goal_(goal)
+        , gen_(std::random_device{}())
+        , ndx_(HMIN + (HMAX - HMIN) / 2, (HMAX - HMIN) / 4)
+        , ndy_(VMIN + (VMAX - VMIN) / 2, (VMAX - VMIN) / 4)
+        , ndh_(0, M_PI * 2 / 4)
 {
         this->nodes_.reserve(NOFNODES);
         this->nodes_.push_back(init);
@@ -124,6 +130,11 @@ RRTNode *RRTBase::goal()
         return this->goal_;
 }
 
+std::vector<RRTNode *> &RRTBase::goals()
+{
+        return this->goals_;
+}
+
 std::vector<RRTNode *> &RRTBase::nodes()
 {
         return this->nodes_;
@@ -134,6 +145,11 @@ std::vector<RRTNode *> &RRTBase::dnodes()
         return this->dnodes_;
 }
 
+std::queue<RRTNode *> &RRTBase::firsts()
+{
+        return this->firsts_;
+}
+
 PolygonObstacle &RRTBase::frame()
 {
         return this->frame_;
@@ -197,6 +213,26 @@ float RRTBase::elapsed()
         return dt.count();
 }
 
+std::vector<RRTNode *> RRTBase::traj_cusp()
+{
+        std::vector<RRTNode *> tmp_cusps;
+        for (auto n: this->tlog().back()) {
+                if (sgn(n->s()) == 0) {
+                        tmp_cusps.push_back(n);
+                } else if (n->parent() &&
+                                sgn(n->s()) != sgn(n->parent()->s())) {
+                        tmp_cusps.push_back(n);
+                        tmp_cusps.push_back(n->parent());
+                }
+        }
+        std::vector<RRTNode *> cusps;
+        for (unsigned int i = 0; i < tmp_cusps.size(); i++) {
+                if (tmp_cusps[i] != tmp_cusps[(i + 1) % tmp_cusps.size()])
+                        cusps.push_back(tmp_cusps[i]);
+        }
+        return cusps;
+}
+
 // setter
 void RRTBase::root(RRTNode *node)
 {
@@ -208,6 +244,19 @@ void RRTBase::goal(RRTNode *node)
         this->goal_ = node;
 }
 
+void RRTBase::goals(std::vector<RRTNode *> g)
+{
+        this->goals_ = g;
+        std::reverse(this->goals_.begin(), this->goals_.end());
+        RRTNode *pn = this->goals_.front();
+        for (auto n: this->goals_) {
+                if (n != pn) {
+                        pn->add_child(n, this->cost(pn ,n));
+                        pn = n;
+                }
+        }
+}
+
 bool RRTBase::logr(RRTNode *root)
 {
         std::vector<RRTEdge *> e; // Edges to log
@@ -422,7 +471,7 @@ bool RRTBase::goal_found(
                 RRTNode *node,
                 float (*cost)(RRTNode *, RRTNode* ))
 {
-        if (IS_NEAR(node, this->goal_)) {
+        if (GOAL_IS_NEAR(node, this->goal_)) {
                 if (this->goal_found_) {
                         if (node->ccost() + this->cost(node, this->goal_) <
                                         this->goal_->ccost()) {
@@ -456,6 +505,76 @@ bool RRTBase::goal_found(
                                 return false;
                         }
                         this->goal_found_ = true;
+                        // Update ccost of goal's parents
+                        if (this->goals().size() > 0) {
+                                RRTNode *ch = this->goals().back();
+                                RRTNode *pn = this->goals().back()->parent();
+                                while (pn) {
+                                        pn->ccost(
+                                                ch->ccost()
+                                                - this->cost(pn, ch)
+                                        );
+                                        ch = pn;
+                                        pn = pn->parent();
+                                }
+                        }
+                        return true;
+                }
+        }
+        return false;
+}
+
+bool RRTBase::goal_found(
+        RRTNode *node,
+        RRTNode *goal
+)
+{
+        if (GOAL_IS_NEAR(node, goal)) {
+                if (this->goal_found_) {
+                        if (
+                                goal->ccost() != -1
+                                && node->ccost() + this->cost(node, goal)
+                                < goal->ccost()
+                        ) {
+                                RRTNode *op; // old parent
+                                float oc; // old cumulative cost
+                                float od; // old direct cost
+                                op = goal->parent();
+                                oc = goal->ccost();
+                                od = goal->dcost();
+                                node->add_child(goal,
+                                                this->cost(node, goal));
+                                if (this->collide(node, goal)) {
+                                        node->children().pop_back();
+                                        goal->parent(op);
+                                        goal->ccost(oc);
+                                        goal->dcost(od);
+                                } else {
+                                        op->rem_child(goal);
+                                        return true;
+                                }
+                        } else {
+                                return false;
+                        }
+                } else {
+                        node->add_child(
+                                goal,
+                                this->cost(node, goal)
+                        );
+                        if (this->collide(node, goal)) {
+                                node->children().pop_back();
+                                goal->remove_parent();
+                                return false;
+                        }
+                        this->goal_found_ = true;
+                        // Update ccost of goal's children
+                        goal->update_ccost();
+                        // Update ccost of goals
+                        for (auto g: this->goals()) {
+                                if (g == goal)
+                                        break;
+                                g->ccost(-1);
+                        }
                         return true;
                 }
         }
@@ -871,40 +990,19 @@ std::vector<RRTNode *> RRTBase::findt(RRTNode *n)
 }
 
 // RRT Framework
+void RRTBase::setSamplingInfo(SamplingInfo si)
+{
+        this->ndx_ = std::normal_distribution<float>(si.x0, si.x);
+        this->ndy_ = std::normal_distribution<float>(si.y0, si.y);
+        this->ndh_ = std::normal_distribution<float>(si.h0, si.h);
+}
+
 RRTNode *RRTBase::sample()
 {
-#ifdef USE_SLOTPLANNER
-        float x = this->samplingInfo_.x;
-        float y = this->samplingInfo_.y;
-        std::normal_distribution<float> xdist(
-                0,
-                BCAR_WIDTH / 3
-        );
-        x += this->samplingInfo_.dx
-                * (BCAR_WIDTH / 2 + std::abs(xdist(this->gen_)))
-                * cos(this->samplingInfo_.sh + M_PI / 2);
-        y += this->samplingInfo_.dx
-                * (BCAR_WIDTH / 2 + std::abs(xdist(this->gen_)))
-                * sin(this->samplingInfo_.sh + M_PI / 2);
-        std::normal_distribution<float> ydist(
-                0,
-                BCAR_LENGTH / 3
-        );
-        x += ydist(this->gen_) * cos(this->samplingInfo_.sh);
-        y += ydist(this->gen_) * sin(this->samplingInfo_.sh);
-        std::normal_distribution<float> hdist(
-                0,
-                this->samplingInfo_.h / 3
-        );
-        float h = std::abs(hdist(this->gen_));
-        return new RRTNode(
-                x,
-                y,
-                this->samplingInfo_.sh + this->samplingInfo_.dh * h
-        );
-#else
-        return sa1();
-#endif
+        float x = this->ndx_(this->gen_);
+        float y = this->ndy_(this->gen_);
+        float h = this->ndh_(this->gen_);
+        return new RRTNode(x, y, h);
 }
 
 float RRTBase::cost(RRTNode *init, RRTNode *goal)