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_;
}
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;
i += 1;
}
delete c; // not in q and collide
- // BFS
while (!q.empty()) {
c = q.front();
q.pop();
delete c; // not in q and collide
}
}
+ std::swap(q, empty);
+ return;
createcuspandfinish:
std::vector<RRTNode *> cusp;
while (c) {
}
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);
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();
+ 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 {
- cc = BicycleCar(B->x(), B->y(), B->h()).ccl();
+ 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();
}
- float di = -1;
- if (this->slotSide() == LEFT)
- di = 1;
BicycleCar *p;
int i = 1;
- p = B->move(cc, i * di * this->DH());
- while (!this->slot().collide(p->frame())) {
+ 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 * di * this->DH());
- while (!this->slot().collide(p->frame())) {
+ 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;
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());
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());
}
}
}
+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;
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;
}