]> rtime.felk.cvut.cz Git - hubacji1/iamcar.git/blobdiff - decision_control/slotplanner.cc
Add perpendicular reverse parking proporsal
[hubacji1/iamcar.git] / decision_control / slotplanner.cc
index 6b378cb883dedcde3d03b546330587529a69aa50..ed1446de490c20a83eab26a9392b45d6ebe59f76 100644 (file)
@@ -53,39 +53,11 @@ float ParallelSlot::slotHeading()
 
 SlotSide ParallelSlot::slotSide()
 {
-        if (!this->slotSide_) {
-                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();
-                float h1 = atan2(y0 - y3, x0 - x3);
-                float h2 = atan2(y1 - y3, x1 - x3);
-                if (h2 - h1 > 0)
-                        this->slotSide_ = LEFT;
-                else
-                        this->slotSide_ = RIGHT;
-        }
         return this->slotSide_;
 }
 
 SlotType ParallelSlot::slotType()
 {
-        if (!this->slotType_) {
-                float d1 = EDIST(
-                        this->slot().bnodes()[0],
-                        this->slot().bnodes()[1]
-                );
-                float d2 = EDIST(
-                        this->slot().bnodes()[1],
-                        this->slot().bnodes()[2]
-                );
-                if (d1 > d2)
-                        this->slotType_ = PERPENDICULAR;
-                else
-                        this->slotType_ = PARALLEL;
-        }
         return this->slotType_;
 }
 
@@ -95,49 +67,46 @@ void ParallelSlot::DH(float dh)
         this->DH_ = dh;
 }
 
+void ParallelSlot::setAll()
+{
+        // slot side
+        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)
+                this->slotSide_ = LEFT;
+        else
+                this->slotSide_ = RIGHT;
+        // slot type
+        float d1 = EDIST(
+                this->slot().bnodes()[0],
+                this->slot().bnodes()[1]
+        );
+        float d2 = EDIST(
+                this->slot().bnodes()[1],
+                this->slot().bnodes()[2]
+        );
+        if (d1 > d2)
+                this->slotType_ = PERPENDICULAR;
+        else
+                this->slotType_ = PARALLEL;
+}
+
 // other
 void ParallelSlot::fip()
 {
         // 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;
-
-        // TODO add init nodes
-        // for now just copy fpose()
-        bool left = false; // right parking slot
-        float di = -1;
-        // new pose for parallel parking to right slot
-        float tnx;
-        float tny;
-        float nx;
-        float ny;
-        // temporary tnx is angle
-        tnx = this->slotHeading() + M_PI;
-        if (this->slotSide() == RIGHT)
-                tnx -= M_PI / 4;
-        else
-                tnx += M_PI / 4;
-        nx = this->fposecenter()->x() + 0.01 * cos(tnx);
-        ny = this->fposecenter()->y() + 0.01 * sin(tnx);
-        BicycleCar *CC = new BicycleCar(nx, ny, this->slotHeading());
-        // move left by car width / 2
-        tnx = CC->x() + CC->width() / 2 * cos(CC->h() + M_PI / 2);
-        tny = CC->y() + CC->width() / 2 * sin(CC->h() + M_PI / 2);
-        // move down
-        nx = tnx - (CC->length() + CC->wheelbase()) / 2 * cos(CC->h());
-        ny = tny - (CC->length() + CC->wheelbase()) / 2 * sin(CC->h());
-        if (this->slotSide() == LEFT) {
-                std::cerr << "left PS" << std::endl;
-                left = true;
+        std::queue<BicycleCar *, std::list<BicycleCar *>> empty;
+        int di = -1;
+        if (this->slotSide() == LEFT)
                 di = 1;
-                // move right by car width / 2
-                tnx = CC->x() + CC->width() / 2 * cos(CC->h() - M_PI / 2);
-                tny = CC->y() + CC->width() / 2 * sin(CC->h() - M_PI / 2);
-                // move down
-                nx = tnx - (CC->length() + CC->wheelbase()) / 2 * cos(CC->h());
-                ny = tny - (CC->length() + CC->wheelbase()) / 2 * sin(CC->h());
-        }
-        BicycleCar *B = new BicycleCar(nx, ny, CC->h());
+        BicycleCar *CC = this->getEPC();
+        BicycleCar *B = this->getEP();
         this->DH(di * 0.01 / CC->out_radi());
         BicycleCar *c;
         int i = 0;
@@ -148,7 +117,6 @@ void ParallelSlot::fip()
                 i += 1;
         }
         delete c; // not in q and collide
-        // BFS
         while (!q.empty()) {
                 c = q.front();
                 q.pop();
@@ -163,6 +131,8 @@ void ParallelSlot::fip()
                         delete c; // not in q and collide
                 }
         }
+        std::swap(q, empty);
+        return;
 createcuspandfinish:
         std::vector<RRTNode *> cusp;
         while (c) {
@@ -171,22 +141,37 @@ createcuspandfinish:
         }
         std::reverse(cusp.begin(), cusp.end());
         this->cusp().push_back(cusp);
-        std::queue<BicycleCar *, std::list<BicycleCar *>> empty;
         std::swap(q, empty);
 }
 
 void ParallelSlot::fipr(BicycleCar *B)
 {
-        // TODO for right parallel parking also
-        // it's only for lpar scenario now
-
         std::vector<RRTNode *> cusp;
         cusp.push_back(new RRTNode(B->x(), B->y(), B->h()));
-        // just copied from fip()
-        this->DH(-0.01 / B->out_radi());
+        int di = 1;
+        if (this->slotSide() == LEFT)
+                di = -1;
+        if (this->slotType() == PERPENDICULAR) {
+                cusp.push_back(new RRTNode(
+                        B->x() - di * B->length(),
+                        B->y(),
+                        B->h()
+                ));
+                std::reverse(cusp.begin(), cusp.end());
+                this->cusp().push_back(cusp);
+                return;
+        }
+        this->DH(di * 0.01 / B->out_radi());
         BicycleCar *c;
         c = this->flncr(B);
-        while (c->lfx() < 0) {
+        c->s(B->s() + 1);
+        while ((
+                this->slotSide() == LEFT
+                && this->slot().collide(new RRTNode(c->lfx(), c->lfy(), 0))
+        ) || (
+                this->slotSide() == RIGHT
+                && this->slot().collide(new RRTNode(c->rfx(), c->rfy(), 0))
+        )) {
                 cusp.push_back(new RRTNode(c->x(), c->y(), c->h()));
                 BicycleCar *cc = this->flncr(c);
                 cc->s(c->s() + 1);
@@ -200,37 +185,36 @@ void ParallelSlot::fipr(BicycleCar *B)
 
 BicycleCar *ParallelSlot::flnc(BicycleCar *B)
 {
-        // TODO find last not colliding
-        // for now just copy flast()
         RRTNode *cc;
-        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();
+        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())
-                        && (
-                                (this->DH() > 0 && p->x() <= 0)
-                                || (this->DH() < 0 && p->x() >= 0)
-                        )) {
+        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())
-                        && (
-                                (this->DH() > 0 && p->x() <= 0)
-                                || (this->DH() < 0 && p->x() >= 0)
-                        )) {
-                if (this->DH() > 0 && p->rfx() <= 0 && p->rrx() <= 0) {
-                        i += 1;
-                        break;
-                }
-                if (this->DH() < 0 && p->lfx() >= 0 && p->lrx() >= 0) {
+        while (
+                !this->slot().collide(p->frame())
+                && std::abs(this->slotHeading() - p->h()) < M_PI / 2
+        ) {
+                if (this->isInside(p)) {
                         i += 1;
                         break;
                 }
@@ -244,21 +228,39 @@ BicycleCar *ParallelSlot::flnc(BicycleCar *B)
 
 BicycleCar *ParallelSlot::flncr(BicycleCar *B)
 {
-        // TODO find last not colliding
-        // for now just copy flast()
         RRTNode *cc;
-        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();
+        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())
-                        && (
-                                (this->DH() > 0 && p->x() >= 0)
-                                || (this->DH() < 0 && p->lfx() <= 0)
-                        )) {
+        while (
+                !this->slot().collide(p->frame())
+                && ((
+                        this->slotSide() == LEFT
+                        && this->slot().collide(new RRTNode(
+                                p->lfx(),
+                                p->lfy(),
+                                0
+                        ))
+                ) || (
+                        this->slotSide() == RIGHT
+                        && this->slot().collide(new RRTNode(
+                                p->rfx(),
+                                p->rfy(),
+                                0
+                        ))
+                ))
+        ) {
                 delete p;
                 i += 10;
                 p = B->move(cc, i * this->DH());
@@ -266,15 +268,28 @@ BicycleCar *ParallelSlot::flncr(BicycleCar *B)
         i -= 10;
         p = B->move(cc, i * this->DH());
         while (!this->slot().collide(p->frame())) {
-                if (this->DH() > 0 && p->x() <= 0) {
+                if(
+                        this->slotSide() == LEFT
+                        && !this->slot().collide(new RRTNode(
+                                p->lfx(),
+                                p->lfy(),
+                                0
+                        ))
+                ) {
                         i += 1;
                         break;
                 }
-                if (this->DH() < 0 && p->lfx() >= 0) {
+                if(
+                        this->slotSide() == RIGHT
+                        && !this->slot().collide(new RRTNode(
+                                p->rfx(),
+                                p->rfy(),
+                                0
+                        ))
+                ) {
                         i += 1;
                         break;
                 }
-                delete p;
                 i += 1;
                 p = B->move(cc, i * this->DH());
         }
@@ -387,6 +402,89 @@ void ParallelSlot::fpose()
         }
 }
 
+BicycleCar *ParallelSlot::getEP()
+{
+        // new pose for parallel parking to right slot
+        float tnx;
+        float tny;
+        float nx;
+        float ny;
+        BicycleCar *CC = this->getEPC();
+        // move left by car width / 2
+        tnx = CC->x() + CC->width() / 2 * cos(CC->h() + M_PI / 2);
+        tny = CC->y() + CC->width() / 2 * sin(CC->h() + M_PI / 2);
+        if (this->slotSide() == LEFT) {
+                // move right by car width / 2
+                tnx = CC->x() + CC->width() / 2 * cos(CC->h() - M_PI / 2);
+                tny = CC->y() + CC->width() / 2 * sin(CC->h() - M_PI / 2);
+        }
+        if (this->slotType() == PARALLEL) {
+                // move down
+                nx = tnx - (CC->length() + CC->wheelbase()) / 2 * cos(CC->h());
+                ny = tny - (CC->length() + CC->wheelbase()) / 2 * sin(CC->h());
+        } else {
+                // move down
+                nx = tnx + (CC->length() - CC->wheelbase()) / 2 * cos(CC->h());
+                ny = tny + (CC->length() - CC->wheelbase()) / 2 * sin(CC->h());
+        }
+        return new BicycleCar(nx, ny, CC->h());
+}
+
+BicycleCar *ParallelSlot::getEPC()
+{
+        // new pose for parallel parking to right slot
+        float ta;
+        float nx;
+        float ny;
+        ta = this->slotHeading() + M_PI;
+        if (this->slotSide() == RIGHT)
+                ta -= M_PI / 4;
+        else
+                ta += M_PI / 4;
+        nx = this->fposecenter()->x() + 0.01 * cos(ta);
+        ny = this->fposecenter()->y() + 0.01 * sin(ta);
+        return new BicycleCar(nx, ny, this->slotHeading());
+}
+
+BicycleCar *ParallelSlot::getFP()
+{
+        float x = this->slot().bnodes()[3]->x();
+        float y = this->slot().bnodes()[3]->y();
+        float h = this->slotHeading();
+        float nx;
+        float ny;
+        if (this->slotType() == PARALLEL) {
+                if (this->slotSide() == LEFT) {
+                        nx = x + BCAR_WIDTH / 2 * cos(h + M_PI / 2);
+                        ny = y + BCAR_WIDTH / 2 * sin(h + M_PI / 2);
+                } else {
+                        nx = x + BCAR_WIDTH / 2 * cos(h - M_PI / 2);
+                        ny = y + BCAR_WIDTH / 2 * sin(h - M_PI / 2);
+                }
+                x = nx + ((BCAR_LENGTH - BCAR_WHEEL_BASE) / 2 + 0.01) * cos(h);
+                y = ny + ((BCAR_LENGTH - BCAR_WHEEL_BASE) / 2 + 0.01) * sin(h);
+        } else {
+                if (this->slotSide() == LEFT) {
+                        h -= M_PI / 2;
+                        nx = x + (BCAR_LENGTH + BCAR_WHEEL_BASE) / 2
+                                * cos(h + M_PI);
+                        ny = y + (BCAR_LENGTH + BCAR_WHEEL_BASE) / 2
+                                * sin(h + M_PI);
+                        x = nx + (BCAR_WIDTH + 0.01) * cos(h + M_PI / 2);
+                        y = ny + (BCAR_WIDTH + 0.01) * sin(h + M_PI / 2);
+                } else {
+                        h += M_PI / 2;
+                        nx = x + (BCAR_LENGTH + BCAR_WHEEL_BASE) / 2
+                                * cos(h - M_PI);
+                        ny = y + (BCAR_LENGTH + BCAR_WHEEL_BASE) / 2
+                                * sin(h - M_PI);
+                        x = nx + (BCAR_WIDTH / 2 + 0.01) * cos(h - M_PI / 2);
+                        y = ny + (BCAR_WIDTH / 2 + 0.01) * sin(h - M_PI / 2);
+                }
+        }
+        return new BicycleCar(x, y, h);
+}
+
 bool ParallelSlot::isInside(BicycleCar *c)
 {
         bool inside = true;
@@ -413,17 +511,27 @@ bool ParallelSlot::isInside(BicycleCar *c)
 struct SamplingInfo ParallelSlot::getSamplingInfo()
 {
         struct SamplingInfo si;
-        BicycleCar *CC = new BicycleCar(
-                this->fposecenter()->x(),
-                this->fposecenter()->y() - 0.01,
-                this->slotHeading()
-        );
+        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.r = CC->diag_radi();
-        si.h = this->slotHeading() - acos(EDIST( // TODO generalize
-                this->slot().bnodes()[0],
-                this->slot().bnodes()[1]
-        ) / BCAR_LENGTH);
+        si.sh = this->slotHeading();
+        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;
+        }
         return si;
 }