IF(USE_GL)
ADD_DEFINITIONS(-DUSE_GL=1)
ENDIF(USE_GL)
+IF(USE_SLOTPLANNER)
+ ADD_DEFINITIONS(-DUSE_SLOTPLANNER=1)
+ENDIF(USE_SLOTPLANNER)
find_package(OpenMP)
if (OPENMP_FOUND)
- `Klamm2015` - RRT*-Connect planner.
- `TMAX` - Specify the upper time bound in seconds.
- `USE_GL` - Specify if GL is going to be used to plot the algorithm.
+- `USE_SLOTPLANNER` - Specify if slot planner is going to be used.
Implemented Steering procedures:
- `st1` - Steer directly to goal, no constraints.
//#define USE_PTHREAD
#endif
-// enable
-//#define USE_SLOTPLANNER
-
std::chrono::high_resolution_clock::time_point TSTART_;
std::chrono::high_resolution_clock::time_point TEND_;
float TELAPSED = 0;
p.ocost(p.goal());
ParallelSlot ps = ParallelSlot();
+ if (
+ jvi["slot"] != Json::nullValue &&
+ jvi["slot"]["polygon"] != Json::nullValue
+ ) {
+ for (auto xy: jvi["slot"]["polygon"]) {
+ ps.slot().add_bnode(new RRTNode(
+ xy[0].asFloat(),
+ xy[1].asFloat()
+ ));
+ }
+ }
+ if (ps.slot().bnodes().size() > 0) {
+ ps.setAll();
+ p.samplingInfo_ = ps.getSamplingInfo();
+ }
#ifdef USE_SLOTPLANNER
TSTART();
- for (auto xy: jvi["slot"]["polygon"]) {
- ps.slot().add_bnode(new RRTNode(
- xy[0].asFloat(),
- xy[1].asFloat()
- ));
- }
- ps.setAll();
- p.samplingInfo_ = ps.getSamplingInfo();
if (ps.slot().bnodes().size() > 0)
ps.fipr(ps.getFP());
TEND();
// RRT Framework
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
+ if (
+ this->samplingInfo_.dx &&
+ this->samplingInfo_.dy &&
+ this->samplingInfo_.dh
+ ) {
+ float x = this->samplingInfo_.x;
+ float y = this->samplingInfo_.y;
+ float h = 0;
+ std::normal_distribution<float> xdist(
+ 0,
+ (this->samplingInfo_.r)
+ ?this->samplingInfo_.r
+ :BCAR_WIDTH * 2
+ );
+ std::normal_distribution<float> hdist(
+ 0,
+ this->samplingInfo_.h
+ );
+ std::normal_distribution<float> ydist(
+ 0,
+ (this->samplingInfo_.r)
+ ?this->samplingInfo_.h / 2
+ :BCAR_LENGTH / 3
+ );
+ if (!this->samplingInfo_.r) {
+ float dx = BCAR_WIDTH / 2 +
+ std::abs(xdist(this->gen_));
+ x += dx * cos(
+ this->samplingInfo_.sh +
+ this->samplingInfo_.dx * M_PI / 2
+ );
+ y += dx * cos(
+ this->samplingInfo_.sh +
+ this->samplingInfo_.dx * M_PI / 2
+ );
+ float dy = ydist(this->gen_);
+ x += dy * cos(this->samplingInfo_.sh);
+ y += dy * sin(this->samplingInfo_.sh);
+ h = std::abs(hdist(this->gen_));
+ } else {
+ float dr = std::abs(xdist(this->gen_));
+ float dh = hdist(this->gen_);
+ x += dr * cos(
+ this->samplingInfo_.sh +
+ this->samplingInfo_.dh * M_PI / 2 +
+ dh
+ );
+ y += dr * sin(
+ this->samplingInfo_.sh +
+ this->samplingInfo_.dh * M_PI / 2 +
+ dh
+ );
+ h = std::abs(ydist(this->gen_));
+ }
+ return new RRTNode(
+ x,
+ y,
+ this->samplingInfo_.sh + this->samplingInfo_.dh * h
+ );
+ } else {
+ return sa1();
+ }
}
float RRTBase::cost(RRTNode *init, RRTNode *goal)
float RRTNode::h() const
{
- return this->h_;
+ float h = this->h_;
+ while (h > M_PI)
+ h -= 2 * M_PI;
+ while (h <= -M_PI)
+ h += 2 * M_PI;
+ return h;
}
float RRTNode::t() const
std::swap(q, empty);
}
+void ParallelSlot::fipr(RRTNode *n)
+{
+ return this->fipr(new BicycleCar(n->x(), n->y(), n->h()));
+}
+
void ParallelSlot::fipr(BicycleCar *B)
{
std::vector<RRTNode *> cusp;
if (this->slotSide() == LEFT)
di = -1;
if (this->slotType() == PERPENDICULAR) {
- cusp.push_back(new RRTNode(
- B->x() - di * B->length(),
- B->y(),
- B->h()
- ));
+ this->DH(di * 0.01 / B->out_radi()); // TODO car in slot h()
+ RRTNode *cc;
+ if (this->slotSide() == LEFT)
+ 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->slot().collide(p)
+ ) {
+ 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->slot().collide(p)
+ ) {
+ delete p;
+ i += 1;
+ p = B->move(cc, i * this->DH());
+ }
+ i -= 1;
+ p = B->move(cc, i * this->DH());
+ cusp.push_back(new RRTNode(p->x(), p->y(), p->h()));
std::reverse(cusp.begin(), cusp.end());
this->cusp().push_back(cusp);
return;
* 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);
+ 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 - 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);
+ 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);
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();
si.dy = -1;
si.dh = -1;
}
- si.r = CC->diag_radi();
si.sh = this->slotHeading();
if (this->slotType() == PARALLEL) {
si.h = this->slotHeading() - acos(EDIST(
this->slot().bnodes()[1]
) / BCAR_LENGTH);
} else {
- si.h = M_PI /2;
+ si.h = M_PI / 2 / 3;
+ }
+#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;
+ } else {
+ si.dx = -1;
+ si.dy = -1;
+ si.dh = -1;
}
+ si.r = EDIST(this->slot().bnodes()[0], this->slot().bnodes()[3]) / 2;
+ si.r *= 2;
+ si.sh = this->slotHeading();
+ si.h = M_PI / 4;
+#endif
return si;
}
#define BCAR_TURNING_RADIUS 10.820
#define BCAR_WHEEL_BASE 2.450
#define BCAR_WIDTH 1.625
+#define BCAR_DIST_REAR ((BCAR_LENGTH - BCAR_WHEEL_BASE) / 2)
+#define BCAR_DIST_FRONT (BCAR_LENGTH - BCAR_DIST_REAR)
+#define BCAR_DIAG_RADI pow(pow(BCAR_DIST_FRONT, 2) + pow(BCAR_WIDTH/2, 2), 0.5)
+#define BCAR_DIAG_RRADI pow(pow(BCAR_DIST_REAR, 2) + pow(BCAR_WIDTH/2, 2), 0.5)
+#define BCAR_OUT_RADI pow( \
+ pow(BCAR_TURNING_RADIUS + BCAR_WIDTH/2, 2) + \
+ pow(BCAR_DIST_FRONT, 2), 0.5)
#define MAXSTEER(wb, tr) ((wb) / (tr))
/** Return distance from wheelbase center to top corner */
float diag_radi();
+ /** Return distance from wheelbase center to rear corner */
+ float diag_rradi();
/** Outer radius of the farthest point */
float out_radi();
/** Angle between wheelbase line and outer radius */
@param B Last pose of vehicle when it is parked.
*/
+ void fipr(RRTNode *n);
void fipr(BicycleCar *B);
/** _Find Last Not Colliding for Reverse_ BicycleCar pose
return pow(xx + yy, 0.5);
}
+float BicycleCar::diag_rradi()
+{
+ float xx = pow(this->dr(), 2);
+ float yy = pow(this->width_ / 2, 2);
+ return pow(xx + yy, 0.5);
+}
+
float BicycleCar::out_radi()
{
return pow((pow(this->turning_radius_ + this->width_ / 2, 2) +