return this->slotType_;
}
+float ParallelSlot::poseHeading()
+{
+ return this->poseHeading_;
+}
+
// setter
void ParallelSlot::DH(float dh)
{
float dy = y3 - y0;
float dx = x3 - x0;
this->slotHeading_ = atan2(dy, dx);
- // slot side
+ // pose heading
float y1 = this->slot().bnodes()[1]->y();
float x1 = this->slot().bnodes()[1]->x();
+ dy = y0 - y1;
+ dx = x0 - x1;
+ this->poseHeading_ = atan2(dy, dx);
+ // slot side
if (sgn((x1 - x0) * (y3 - y0) - (y1 - y0) * (x3 - x0)) < 0)
this->slotSide_ = LEFT;
else
&& p->h() < this->slotHeading()
) || (
this->slotSide() == RIGHT
- && p->h() > this->slotHeading()
+ && (
+ p->h() > this->slotHeading()
+ || p->h() < 0
+ )
))
) {
+ if (tmpc.size() == 0) {
+ i = 0;
+ p = this->getFP();
+ }
bool end = false;
std::vector<RRTEdge *> eds = p->frame();
for (auto o: co)
&& p->h() < this->slotHeading()
))
) {
+ if (tmpc.size() == 0) {
+ i = 0;
+ p = this->getFPf();
+ }
bool end = false;
std::vector<RRTEdge *> eds = p->frame();
for (auto o: co)
float x = this->slot().bnodes()[0]->x();
float y = this->slot().bnodes()[0]->y();
float h = this->slotHeading();
+ float ph = this->poseHeading();
float nx;
float ny;
if (this->slotType() == PARALLEL) {
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);
+ * cos(ph + M_PI);
ny = y + (BCAR_LENGTH + BCAR_WHEEL_BASE) / 2
- * sin(h + M_PI);
- x = nx + (BCAR_DIAG_RRADI) * cos(h + M_PI / 2);
- y = ny + (BCAR_DIAG_RRADI) * sin(h + M_PI / 2);
+ * sin(ph + M_PI);
+ x = nx + (BCAR_DIAG_RRADI) * cos(h);
+ y = ny + (BCAR_DIAG_RRADI) * sin(h);
} else {
- h += M_PI / 2;
nx = x + (BCAR_LENGTH + BCAR_WHEEL_BASE) / 2
- * cos(h - M_PI);
+ * cos(ph + M_PI);
ny = y + (BCAR_LENGTH + BCAR_WHEEL_BASE) / 2
- * sin(h - M_PI);
- x = nx + (BCAR_DIAG_RRADI) * cos(h - M_PI / 2);
- y = ny + (BCAR_DIAG_RRADI) * sin(h - M_PI / 2);
+ * sin(ph + M_PI);
+ x = nx + (BCAR_DIAG_RRADI) * cos(h);
+ y = ny + (BCAR_DIAG_RRADI) * sin(h);
}
}
- return new BicycleCar(x, y, h);
+ return new BicycleCar(x, y, ph);
}
BicycleCar *ParallelSlot::getISPP(BicycleCar *B)
{
+ // rigt side (for right parking slot)
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 x1;
+ float y1;
+ if (this->slotSide() == LEFT) {
+ x1 = B->ccl()->x();
+ y1 = B->ccl()->y();
+ } else {
+ x1 = B->ccr()->x();
+ y1 = 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 b = (x1 - x) * 2 * cos(B->h()) + (y1 - y) * 2 * sin(B->h());
+ float c = pow(x - x1, 2) + pow(y - y1, 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());
+ float delta;
+ delta = -b - sqrt(D);
+ delta /= 2 * a;
+ float delta_1 = delta;
+ // left front (for right parking slot)
+ x = this->slot().bnodes().front()->x();
+ y = this->slot().bnodes().front()->y();
+ IR = BCAR_OUT_RADI;
+ a = 1;
+ b = (x1 - x) * 2 * cos(B->h()) + (y1 - y) * 2 * sin(B->h());
+ c = pow(x - x1, 2) + pow(y - y1, 2) - pow(IR, 2);
+ D = pow(b, 2) - 4 * a * c;
+ //delta = -b + sqrt(D);
+ //delta /= 2 * a;
+ float delta_2 = delta;
+ delta = -b - sqrt(D);
+ delta /= 2 * a;
+ float delta_3 = delta;
+ delta = std::max(delta_1, std::max(delta_2, delta_3));
+ return new BicycleCar(
+ B->x() + delta * cos(B->h()),
+ B->y() + delta * sin(B->h()),
+ B->h()
+ );
}
BicycleCar *ParallelSlot::getFPf()
float x = this->slot().bnodes().front()->x();
float y = this->slot().bnodes().front()->y();
float h = this->slotHeading();
+ float ph = this->poseHeading();
+ ph += M_PI;
+ while (ph > M_PI)
+ ph -= 2 * M_PI;
+ while (ph <= -M_PI)
+ ph += 2 * M_PI;
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);
+ nx = x + (BCAR_LENGTH - BCAR_WHEEL_BASE) / 2 * cos(ph);
+ ny = y + (BCAR_LENGTH - BCAR_WHEEL_BASE) / 2 * sin(ph);
+ x = nx + (BCAR_DIAG_RRADI) * cos(h);
+ y = ny + (BCAR_DIAG_RRADI) * sin(h);
+ return new BicycleCar(x, y, ph);
}
BicycleCar *ParallelSlot::getISPPf(BicycleCar *B)
{
+ // right rear (for right parking slot)
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 x1;
+ float y1;
+ if (this->slotSide() == LEFT) {
+ x1 = B->ccl()->x();
+ y1 = B->ccl()->y();
+ } else {
+ x1 = B->ccr()->x();
+ y1 = 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 b = (x - x1) * 2 * cos(B->h()) + (y - y1) * 2 * sin(B->h());
+ float c = pow(x - x1, 2) + pow(y - y1, 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
+ float delta;
+ delta = -b - sqrt(D); // TODO why this works?
+ delta /= 2 * a;
+ float delta_1 = delta;
+ // left front (for right parking slot)
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);
+ b = (x - x1) * 2 * cos(B->h()) + (y - y1) * 2 * sin(B->h());
+ c = pow(x - x1, 2) + pow(y - y1, 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());
+ delta = -b + sqrt(D);
+ delta /= 2 * a;
+ float delta_2 = delta;
+ delta = -b - sqrt(D);
+ delta /= 2 * a;
+ float delta_3 = delta;
+ delta = std::max(delta_1, std::max(delta_2, delta_3));
+ return new BicycleCar(
+ B->x() - delta * cos(B->h()),
+ B->y() - delta * sin(B->h()),
+ B->h()
+ );
}
bool ParallelSlot::isInside(BicycleCar *c)
{
struct SamplingInfo si;
RRTNode *n = this->getMidd();
+ if (n == nullptr)
+ return si;
+ BicycleCar *bc = new BicycleCar(n->x(), n->y(), n->h());
+ RRTNode *cc;
+ if (this->slotSide() == LEFT)
+ cc = bc->ccl();
+ else
+ cc = bc->ccr();
if (this->slotType() == PARALLEL) {
- 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();
- }
+ BicycleCar *nbc = bc->move(cc, this->slotHeading() - n->h());
+ si.x0 = nbc->x();
+ si.y0 = nbc->y();
+ si.h0 = nbc->h();
si.x = BCAR_WIDTH;
si.y = BCAR_WIDTH;
si.h = M_PI / 8;
} else {
- // TODO
+ BicycleCar *nbc;
+ if (this->slotSide() == LEFT)
+ nbc = bc->move(cc, M_PI/4);
+ else
+ nbc = bc->move(cc, -M_PI/4);
+ si.x0 = nbc->x();
+ si.y0 = nbc->y();
+ si.h0 = nbc->h();
+ si.x = BCAR_WIDTH;
+ si.y = BCAR_WIDTH;
+ si.h = M_PI / 8;
}
return si;
}