// resented as a point + radius. usually tools that generate polygons should be
// constructed so they do not output polygons with too many verts.
// Note: polygons in cute_c2 are all *convex*.
-#define C2_MAX_POLYGON_VERTS 8
+#define C2_MAX_POLYGON_VERTS 12
// 2d vector
typedef struct
/*! \brief Reeds & Shepp (build) and Euclidean + abs angle (search).
*
* Use Reeds & Shepp path length for building tree data structure and Euclidean
- * distance plus (abs) heading difference for searching it.
+ * distance + (abs) heading difference + 0.1 * backward-forward direction
+ * changes for searching it.
*
* \ingroup ext-cost
* \see https://doi.org/10.1109/TITS.2015.2477355
double c_ = 0.0;
double cc_ = 0.0;
RRTNode* p_ = nullptr;
+ unsigned int cusp_ = 0;
public:
/*! Get cost to parent. */
double c() const;
/*! Set parent node. */
void p(RRTNode& p);
+ /*! Get number of backward-forward direction changes. */
+ unsigned int cusp() const;
+
+ /*! Set number of backward-forward direction changes. */
+ void cusp(RRTNode const& p);
+
bool operator==(RRTNode const& n);
};
double
RRTExt10::cost_search(RRTNode const& f, RRTNode const& t) const
{
- return f.edist(t) + std::abs(t.h() - f.h());
+ double cost = f.edist(t);
+ double heur = std::min(std::abs(t.h() - f.h()),
+ 2 * M_PI - std::abs(t.h() - f.h()));
+ heur *= this->bc_.mtr();
+ cost = std::max(cost, heur);
+ return cost + f.cusp() * 0.1;
}
} // namespace rrts
if (this->goal_.cc() == 0.0 || this->path_.size() == 0) {
return;
}
-#if 0 // TODO 0.59 should work for sc4-1-0 only.
- if (this->goal_.cc() * 0.59 > this->last_goal_cc_
+#if 1 // TODO 0.59 should work for sc4-1-0 only.
+ if (this->goal_.cc() * 0.8 > this->last_goal_cc_
&& this->last_goal_cc_ != 0.0) {
return;
}
RRTExt2::json(Json::Value jvi)
{
RRTS::json(jvi);
- if (jvi["obst"] == Json::nullValue) {
- return;
- }
+ assert(jvi["obst"] != Json::nullValue);
for (auto& o: jvi["obst"]) {
assert(o.size() < C2_MAX_POLYGON_VERTS);
c2Poly c2tmp;
}
}
+unsigned int
+RRTNode::cusp() const
+{
+ return this->cusp_;
+}
+
+void
+RRTNode::cusp(RRTNode const& p)
+{
+ this->cusp_ = p.cusp();
+ if (this->sp() != p.sp() || this->sp() == 0.0) {
+ this->cusp_++;
+ }
+}
+
bool
RRTNode::operator==(RRTNode const& n)
{
RRTNode* t = &this->nodes_.back();
t->p(*f);
t->c(this->cost_build(*f, *t));
+ t->cusp(*f);
this->steered_.erase(this->steered_.begin());
f = t;
}
t = &this->nodes_.back();
t->p(*f);
t->c(this->cost_build(*f, *t));
+ t->cusp(*f);
this->steered_.erase(this->steered_.begin());
return true;
}
{
assert(jvi["init"] != Json::nullValue);
assert(jvi["goal"] != Json::nullValue);
- assert(jvi["obst"] != Json::nullValue);
this->nodes_.front().x(jvi["init"][0].asDouble());
this->nodes_.front().y(jvi["init"][1].asDouble());
this->nodes_.front().h(jvi["init"][2].asDouble());