]> rtime.felk.cvut.cz Git - hubacji1/iamcar.git/blobdiff - decision_control/slotplanner.cc
Add find init pose in forward direction method
[hubacji1/iamcar.git] / decision_control / slotplanner.cc
index 93ea4c7dfde109722e3ce93798d3cace9bdcecb8..e4a61ebdbd88215c56b950be72d809c01b0ed54b 100644 (file)
@@ -25,6 +25,19 @@ ParallelSlot::ParallelSlot()
 {}
 
 // getter
+std::vector<RRTNode *> &ParallelSlot::goals()
+{
+        return this->goals_;
+}
+
+RRTNode *ParallelSlot::getMidd()
+{
+        if (this->cusp().size() > 0)
+                return this->cusp().front().front();
+        else
+                return nullptr;
+}
+
 std::vector<std::vector<RRTNode *>> &ParallelSlot::cusp()
 {
         return this->cusp_;
@@ -42,13 +55,7 @@ PolygonObstacle &ParallelSlot::slot()
 
 float ParallelSlot::slotHeading()
 {
-        float y0 = this->slot().bnodes()[0]->y();
-        float x0 = this->slot().bnodes()[0]->x();
-        float y3 = this->slot().bnodes()[3]->y();
-        float x3 = this->slot().bnodes()[3]->x();
-        float dy = y0 - y3;
-        float dx = x0 - x3;
-        return atan2(dy, dx);
+        return this->slotHeading_;
 }
 
 SlotSide ParallelSlot::slotSide()
@@ -69,14 +76,18 @@ void ParallelSlot::DH(float dh)
 
 void ParallelSlot::setAll()
 {
-        // slot side
+        // slot heading
         float y0 = this->slot().bnodes()[0]->y();
         float x0 = this->slot().bnodes()[0]->x();
-        float y1 = this->slot().bnodes()[1]->y();
-        float x1 = this->slot().bnodes()[1]->x();
         float y3 = this->slot().bnodes()[3]->y();
         float x3 = this->slot().bnodes()[3]->x();
-        if (sgn((x1 - x3) * (y0 - y3) - (y1 - y3) * (x0 - x3)) < 0)
+        float dy = y3 - y0;
+        float dx = x3 - x0;
+        this->slotHeading_ = atan2(dy, dx);
+        // slot side
+        float y1 = this->slot().bnodes()[1]->y();
+        float x1 = this->slot().bnodes()[1]->x();
+        if (sgn((x1 - x0) * (y3 - y0) - (y1 - y0) * (x3 - x0)) < 0)
                 this->slotSide_ = LEFT;
         else
                 this->slotSide_ = RIGHT;
@@ -96,8 +107,59 @@ void ParallelSlot::setAll()
 }
 
 // other
-void ParallelSlot::fip()
+void ParallelSlot::fip(
+        std::vector<CircleObstacle>& co,
+        std::vector<SegmentObstacle>& so
+)
 {
+        this->setAll();
+        if (this->slotType() == PERPENDICULAR) {
+                std::vector<RRTNode *> tmpc;
+                BicycleCar *tmpf = this->getFP();
+                BicycleCar *tmpb = this->getISPP(tmpf);
+                RRTNode *cc;
+                if (this->slotSide() == LEFT)
+                        cc = tmpb->ccl();
+                else
+                        cc = tmpb->ccr();
+                if (this->slotSide() == LEFT)
+                        this->DH(1 * 0.5 / tmpb->out_radi());
+                else
+                        this->DH(-1 * 0.5 / tmpb->out_radi());
+                BicycleCar *p;
+                int i = 1;
+                p = tmpb->move(cc, i * this->DH());
+                while (
+                        !this->slot().collide(p->frame())
+                        && ((
+                                this->slotSide() == LEFT
+                                && p->h() < this->slotHeading()
+                        ) || (
+                                this->slotSide() == RIGHT
+                                && p->h() > this->slotHeading()
+                        ))
+                ) {
+                        bool end = false;
+                        std::vector<RRTEdge *> eds = p->frame();
+                        for (auto o: co)
+                                if (o.collide(eds))
+                                        end = true;
+                        for (auto o: so)
+                                if (o.collide(eds))
+                                        end = true;
+                        for (auto e: eds)
+                                delete e;
+                        if (end)
+                                break;
+                        this->goals_.push_back(p);
+                        tmpc.push_back(p);
+                        i += 1;
+                        p = tmpb->move(cc, i * this->DH());
+                }
+                if (tmpc.size() > 0)
+                        this->cusp().push_back(tmpc);
+                return;
+        }
         // see https://courses.cs.washington.edu/courses/cse326/03su/homework/hw3/bfs.html
         // RRTNode.s() works as iteration level
         std::queue<BicycleCar *, std::list<BicycleCar *>> q;
@@ -112,7 +174,18 @@ void ParallelSlot::fip()
         int i = 0;
         c = B->move(CC, -i * di * 0.01 / CC->diag_radi());
         while (!this->slot().collide(c->frame())) {
-                q.push(c);
+                bool end = false;
+                std::vector<RRTEdge *> eds = c->frame();
+                for (auto o: co)
+                        if (o.collide(eds))
+                                end = true;
+                for (auto o: so)
+                        if (o.collide(eds))
+                                end = true;
+                for (auto e: eds)
+                        delete e;
+                if (!end)
+                        q.push(c);
                 c = B->move(CC, -i * di * 0.01 / CC->diag_radi());
                 i += 1;
         }
@@ -123,7 +196,7 @@ void ParallelSlot::fip()
                 if (this->isInside(c)) {
                         goto createcuspandfinish;
                 } else if (c->s() < 9) {
-                        BicycleCar *cc = this->flnc(c);
+                        BicycleCar *cc = this->flnc(c, co, so);
                         cc->s(c->s() + 1);
                         cc->bcparent(c);
                         q.push(cc);
@@ -144,6 +217,130 @@ createcuspandfinish:
         std::swap(q, empty);
 }
 
+void ParallelSlot::fipf(
+        std::vector<CircleObstacle>& co,
+        std::vector<SegmentObstacle>& so
+)
+{
+        this->setAll();
+        std::vector<RRTNode *> tmpc;
+        BicycleCar *tmpf = this->getFPf();
+        BicycleCar *tmpb = this->getISPPf(tmpf);
+        RRTNode *cc;
+        if (this->slotSide() == LEFT)
+                cc = tmpb->ccl();
+        else
+                cc = tmpb->ccr();
+        if (this->slotSide() == LEFT)
+                this->DH(-1 * 0.5 / tmpb->out_radi());
+        else
+                this->DH(1 * 0.5 / tmpb->out_radi());
+        BicycleCar *p;
+        int i = 1;
+        p = tmpb->move(cc, i * this->DH());
+        while (
+                !this->slot().collide(p->frame())
+                && ((
+                        this->slotSide() == LEFT
+                        && p->h() > this->slotHeading()
+                ) || (
+                        this->slotSide() == RIGHT
+                        && p->h() < this->slotHeading()
+                ))
+        ) {
+                bool end = false;
+                std::vector<RRTEdge *> eds = p->frame();
+                for (auto o: co)
+                        if (o.collide(eds))
+                                end = true;
+                for (auto o: so)
+                        if (o.collide(eds))
+                                end = true;
+                for (auto e: eds)
+                        delete e;
+                if (end)
+                        break;
+                this->goals_.push_back(p);
+                tmpc.push_back(p);
+                i += 1;
+                p = tmpb->move(cc, i * this->DH());
+        }
+        if (tmpc.size() > 0)
+                this->cusp().push_back(tmpc);
+        return;
+}
+
+BicycleCar *ParallelSlot::flnc(
+        BicycleCar *B,
+        std::vector<CircleObstacle>& co,
+        std::vector<SegmentObstacle>& so
+)
+{
+        RRTNode *cc;
+        if (this->slotSide() == LEFT) {
+                if (int(B->s()) % 2 == 0)
+                        cc = BicycleCar(B->x(), B->y(), B->h()).ccr();
+                else
+                        cc = BicycleCar(B->x(), B->y(), B->h()).ccl();
+        } else {
+                if (int(B->s()) % 2 == 0)
+                        cc = BicycleCar(B->x(), B->y(), B->h()).ccl();
+                else
+                        cc = BicycleCar(B->x(), B->y(), B->h()).ccr();
+        }
+        BicycleCar *p;
+        int i = 1;
+        p = B->move(cc, i * this->DH());
+        while (
+                !this->slot().collide(p->frame())
+                && std::abs(this->slotHeading() - p->h()) < M_PI / 2
+        ) {
+                delete p;
+                i += 10;
+                p = B->move(cc, i * this->DH());
+                bool end = false;
+                std::vector<RRTEdge *> eds = p->frame();
+                for (auto o: co)
+                        if (o.collide(eds))
+                                end = true;
+                for (auto o: so)
+                        if (o.collide(eds))
+                                end = true;
+                for (auto e: eds)
+                        delete e;
+                if (end)
+                        break;
+        }
+        i -= 10;
+        p = B->move(cc, i * this->DH());
+        while (
+                !this->slot().collide(p->frame())
+                && std::abs(this->slotHeading() - p->h()) < M_PI / 2
+        ) {
+                if (this->isInside(p)) {
+                        i += 1;
+                        break;
+                }
+                delete p;
+                i += 1;
+                p = B->move(cc, i * this->DH());
+                bool end = false;
+                std::vector<RRTEdge *> eds = p->frame();
+                for (auto o: co)
+                        if (o.collide(eds))
+                                end = true;
+                for (auto o: so)
+                        if (o.collide(eds))
+                                end = true;
+                for (auto e: eds)
+                        delete e;
+                if (end)
+                        break;
+        }
+        delete p;
+        return B->move(cc, (i - 1) * this->DH());
+}
+
 void ParallelSlot::fipr(RRTNode *n)
 {
         return this->fipr(new BicycleCar(n->x(), n->y(), n->h()));
@@ -213,49 +410,6 @@ void ParallelSlot::fipr(BicycleCar *B)
         this->cusp().push_back(cusp);
 }
 
-BicycleCar *ParallelSlot::flnc(BicycleCar *B)
-{
-        RRTNode *cc;
-        if (this->slotSide() == LEFT) {
-                if (int(B->s()) % 2 == 0)
-                        cc = BicycleCar(B->x(), B->y(), B->h()).ccr();
-                else
-                        cc = BicycleCar(B->x(), B->y(), B->h()).ccl();
-        } else {
-                if (int(B->s()) % 2 == 0)
-                        cc = BicycleCar(B->x(), B->y(), B->h()).ccl();
-                else
-                        cc = BicycleCar(B->x(), B->y(), B->h()).ccr();
-        }
-        BicycleCar *p;
-        int i = 1;
-        p = B->move(cc, i * this->DH());
-        while (
-                !this->slot().collide(p->frame())
-                && std::abs(this->slotHeading() - p->h()) < M_PI / 2
-        ) {
-                delete p;
-                i += 10;
-                p = B->move(cc, i * this->DH());
-        }
-        i -= 10;
-        p = B->move(cc, i * this->DH());
-        while (
-                !this->slot().collide(p->frame())
-                && std::abs(this->slotHeading() - p->h()) < M_PI / 2
-        ) {
-                if (this->isInside(p)) {
-                        i += 1;
-                        break;
-                }
-                delete p;
-                i += 1;
-                p = B->move(cc, i * this->DH());
-        }
-        delete p;
-        return B->move(cc, (i - 1) * this->DH());
-}
-
 BicycleCar *ParallelSlot::flncr(BicycleCar *B)
 {
         RRTNode *cc;
@@ -329,7 +483,7 @@ BicycleCar *ParallelSlot::flncr(BicycleCar *B)
 
 RRTNode *ParallelSlot::fposecenter()
 {
-        return this->slot().bnodes().front();
+        return this->slot().bnodes().back();
 }
 
 bool ParallelSlot::flast(
@@ -478,8 +632,9 @@ BicycleCar *ParallelSlot::getEPC()
 
 BicycleCar *ParallelSlot::getFP()
 {
-        float x = this->slot().bnodes()[3]->x();
-        float y = this->slot().bnodes()[3]->y();
+        this->setAll();
+        float x = this->slot().bnodes()[0]->x();
+        float y = this->slot().bnodes()[0]->y();
         float h = this->slotHeading();
         float nx;
         float ny;
@@ -515,6 +670,99 @@ BicycleCar *ParallelSlot::getFP()
         return new BicycleCar(x, y, h);
 }
 
+BicycleCar *ParallelSlot::getISPP(BicycleCar *B)
+{
+        float x = this->slot().bnodes().back()->x();
+        float y = this->slot().bnodes().back()->y();
+        float y0;
+        if (this->slotSide() == LEFT) // TODO only for backward parking now
+                y0 = B->ccl()->y();
+        else
+                y0 = B->ccr()->y();
+        float IR = BCAR_IN_RADI;
+        float a = 1;
+        float b = -2 * x;
+        float c = pow(x, 2) + pow(y - y0, 2) - pow(IR, 2);
+        float D = pow(b, 2) - 4 * a * c;
+        float x0;
+        if (this->slotSide() == LEFT)
+                x0 = -b - sqrt(D);
+        else
+                x0 = -b + sqrt(D);
+        x0 /= 2 * a;
+        return new BicycleCar(x0, B->y(), B->h());
+}
+
+BicycleCar *ParallelSlot::getFPf()
+{
+        this->setAll();
+        float x = this->slot().bnodes().front()->x();
+        float y = this->slot().bnodes().front()->y();
+        float h = this->slotHeading();
+        float nx;
+        float ny;
+        if (this->slotSide() == LEFT) {
+                h += M_PI / 2;
+                nx = x + (BCAR_LENGTH - BCAR_WHEEL_BASE) / 2
+                        * cos(h);
+                ny = y + (BCAR_LENGTH - BCAR_WHEEL_BASE) / 2
+                        * sin(h);
+                x = nx + (BCAR_DIAG_RRADI) * cos(h - M_PI / 2);
+                y = ny + (BCAR_DIAG_RRADI) * sin(h - M_PI / 2);
+        } else {
+                h -= M_PI / 2;
+                nx = x + (BCAR_LENGTH - BCAR_WHEEL_BASE) / 2
+                        * cos(h);
+                ny = y + (BCAR_LENGTH - BCAR_WHEEL_BASE) / 2
+                        * sin(h);
+                x = nx + (BCAR_DIAG_RRADI) * cos(h + M_PI / 2);
+                y = ny + (BCAR_DIAG_RRADI) * sin(h + M_PI / 2);
+        }
+        return new BicycleCar(x, y, h);
+}
+
+BicycleCar *ParallelSlot::getISPPf(BicycleCar *B)
+{
+        float x = this->slot().bnodes().front()->x();
+        float y = this->slot().bnodes().front()->y();
+        float y0;
+        if (this->slotSide() == LEFT)
+                y0 = B->ccl()->y();
+        else
+                y0 = B->ccr()->y();
+        float IR = BCAR_IN_RADI;
+        float a = 1;
+        float b = -2 * x;
+        float c = pow(x, 2) + pow(y - y0, 2) - pow(IR, 2);
+        float D = pow(b, 2) - 4 * a * c;
+        float x0;
+        if (this->slotSide() == LEFT)
+                x0 = -b - sqrt(D);
+        else
+                x0 = -b + sqrt(D);
+        x0 /= 2 * a;
+        float x0_1 = x0;
+        // left front
+        x = this->slot().bnodes().back()->x();
+        y = this->slot().bnodes().back()->y();
+        IR = BCAR_OUT_RADI;
+        a = 1;
+        b = -2 * x;
+        c = pow(x, 2) + pow(y - y0, 2) - pow(IR, 2);
+        D = pow(b, 2) - 4 * a * c;
+        if (this->slotSide() == LEFT)
+                x0 = -b + sqrt(D);
+        else
+                x0 = -b - sqrt(D);
+        x0 /= 2 * a;
+        float x0_2 = x0;
+        if (this->slotSide() == LEFT)
+                x0 = std::max(x0_1, x0_2);
+        else
+                x0 = std::min(x0_1, x0_2);
+        return new BicycleCar(x0, B->y(), B->h());
+}
+
 bool ParallelSlot::isInside(BicycleCar *c)
 {
         bool inside = true;
@@ -541,48 +789,22 @@ bool ParallelSlot::isInside(BicycleCar *c)
 struct SamplingInfo ParallelSlot::getSamplingInfo()
 {
         struct SamplingInfo si;
-#ifdef USE_SLOTPLANNER
-        BicycleCar *CC = this->getEPC();
-        si.x = this->slot().bnodes()[0]->x();
-        si.y = this->slot().bnodes()[0]->y();
-        if (this->slotSide() == RIGHT) {
-                si.dx = 1;
-                si.dy = 1;
-                si.dh = 1;
-        } else {
-                si.dx = -1;
-                si.dy = -1;
-                si.dh = -1;
-        }
-        si.sh = this->slotHeading();
+        RRTNode *n = this->getMidd();
         if (this->slotType() == PARALLEL) {
-                si.h = this->slotHeading() - acos(EDIST(
-                        this->slot().bnodes()[0],
-                        this->slot().bnodes()[1]
-                ) / BCAR_LENGTH);
-        } else {
-                si.h = M_PI /2;
-        }
-#else
-        si.x = this->slot().bnodes()[3]->x() - this->slot().bnodes()[0]->x();
-        si.x /= 2;
-        si.x += this->slot().bnodes()[0]->x();
-        si.y = this->slot().bnodes()[3]->y() - this->slot().bnodes()[0]->y();
-        si.y /= 2;
-        si.y += this->slot().bnodes()[0]->y();
-        if (this->slotSide() == RIGHT) {
-                si.dx = 1;
-                si.dy = 1;
-                si.dh = 1;
+                if (n != nullptr) {
+                        si.x0 = n->x() + 1.5 * BCAR_LENGTH * cos(n->h());
+                        si.y0 = n->y() + 1.5 * BCAR_LENGTH * sin(n->h());
+                        si.h0 = n->h();
+                } else {
+                        si.x0 = this->slot().bnodes().front()->x();
+                        si.y0 = this->slot().bnodes().front()->y();
+                        si.h0 = this->slotHeading();
+                }
+                si.x = BCAR_WIDTH;
+                si.y = BCAR_WIDTH;
+                si.h = M_PI / 8;
         } else {
-                si.dx = -1;
-                si.dy = -1;
-                si.dh = -1;
+                // TODO
         }
-        si.r = EDIST(this->slot().bnodes()[0], this->slot().bnodes()[3]) / 2;
-        si.r *= 2;
-        si.sh = this->slotHeading();
-        si.h = M_PI / 2;
-#endif
         return si;
 }