35 const std::vector<std::pair<STPoint, STPoint>>& point_pairs,
36 bool is_accurate_boundary) {
37 ACHECK(IsValid(point_pairs)) <<
"The input point_pairs are NOT valid";
39 std::vector<std::pair<STPoint, STPoint>> reduced_pairs(point_pairs);
40 if (!is_accurate_boundary) {
41 RemoveRedundantPoints(&reduced_pairs);
44 for (
const auto& item : reduced_pairs) {
46 const double t = item.first.t();
47 lower_points_.emplace_back(item.first.s(), t);
48 upper_points_.emplace_back(item.second.s(), t);
51 for (
const auto& point : lower_points_) {
52 points_.emplace_back(point.t(), point.s());
54 for (
auto rit = upper_points_.rbegin(); rit != upper_points_.rend(); ++rit) {
55 points_.emplace_back(rit->t(), rit->s());
60 for (
const auto& point : lower_points_) {
61 min_s_ = std::fmin(min_s_, point.s());
63 for (
const auto& point : upper_points_) {
64 max_s_ = std::fmax(max_s_, point.s());
66 min_t_ = lower_points_.front().t();
67 max_t_ = lower_points_.back().t();
69 obstacle_road_right_ending_t_ = std::numeric_limits<double>::lowest();
73 const std::vector<STPoint>& lower_points,
74 const std::vector<STPoint>& upper_points) {
79 std::vector<std::pair<STPoint, STPoint>> point_pairs;
81 point_pairs.emplace_back(
89 const std::vector<STPoint>& lower_points,
90 const std::vector<STPoint>& upper_points) {
95 std::vector<std::pair<STPoint, STPoint>> point_pairs;
97 point_pairs.emplace_back(
118 AWARN <<
"Unknown boundary type " <<
static_cast<int>(type)
119 <<
", treated as UNKNOWN";
124 double* s_lower)
const {
125 CHECK_NOTNULL(s_upper);
126 CHECK_NOTNULL(s_lower);
128 *s_upper = FLAGS_speed_lon_decision_horizon;
130 if (curr_time < min_t_ || curr_time > max_t_) {
136 if (!GetIndexRange(lower_points_, curr_time, &left, &right)) {
137 AERROR <<
"Fail to get index range.";
141 if (curr_time > upper_points_[right].t()) {
148 : (curr_time - upper_points_[left].t()) /
149 (upper_points_[right].t() - upper_points_[left].t()));
151 double upper_cross_s =
152 upper_points_[left].s() +
153 r * (upper_points_[right].s() - upper_points_[left].s());
154 double lower_cross_s =
155 lower_points_[left].s() +
156 r * (lower_points_[right].s() - lower_points_[left].s());
161 *s_upper = lower_cross_s;
163 *s_lower = std::fmax(*s_lower, upper_cross_s);
165 ADEBUG <<
"boundary_type is not supported. boundary_type: "
166 <<
static_cast<int>(boundary_type_);
173 double* s_lower)
const {
174 CHECK_NOTNULL(s_upper);
175 CHECK_NOTNULL(s_lower);
176 if (curr_time < min_t_ || curr_time > max_t_) {
182 if (!GetIndexRange(lower_points_, curr_time, &left, &right)) {
183 AERROR <<
"Fail to get index range.";
189 : (curr_time - upper_points_[left].t()) /
190 (upper_points_[right].t() - upper_points_[left].t()));
192 *s_upper = upper_points_[left].s() +
193 r * (upper_points_[right].s() - upper_points_[left].s());
194 *s_lower = lower_points_[left].s() +
195 r * (lower_points_[right].s() - lower_points_[left].s());
197 *s_upper = std::fmin(*s_upper, FLAGS_speed_lon_decision_horizon);
198 *s_lower = std::fmax(*s_lower, 0.0);
203 double* ds_lower)
const {
204 if (ds_upper ==
nullptr || ds_lower ==
nullptr) {
207 if (curr_time < min_t_ || curr_time > max_t_) {
211 static constexpr double kTimeIncrement = 0.05;
212 double t_prev = curr_time - kTimeIncrement;
213 double prev_s_upper = 0.0;
214 double prev_s_lower = 0.0;
216 double t_next = curr_time + kTimeIncrement;
217 double next_s_upper = 0.0;
218 double next_s_lower = 0.0;
220 double curr_s_upper = 0.0;
221 double curr_s_lower = 0.0;
223 if (!has_prev && !has_next) {
226 if (has_prev && has_next) {
227 *ds_upper = ((next_s_upper - curr_s_upper) / kTimeIncrement +
228 (curr_s_upper - prev_s_upper) / kTimeIncrement) *
230 *ds_lower = ((next_s_lower - curr_s_lower) / kTimeIncrement +
231 (curr_s_lower - prev_s_lower) / kTimeIncrement) *
236 *ds_upper = (curr_s_upper - prev_s_upper) / kTimeIncrement;
237 *ds_lower = (curr_s_lower - prev_s_lower) / kTimeIncrement;
239 *ds_upper = (next_s_upper - curr_s_upper) / kTimeIncrement;
240 *ds_lower = (next_s_lower - curr_s_lower) / kTimeIncrement;
246 if (st_point.
t() <= min_t_ || st_point.
t() >= max_t_) {
251 if (!GetIndexRange(lower_points_, st_point.
t(), &left, &right)) {
252 AERROR <<
"failed to get index range.";
256 st_point, upper_points_[left], upper_points_[right]);
258 st_point, lower_points_[left], lower_points_[right]);
260 return (check_upper * check_lower < 0);
264 if (lower_points_.empty()) {
267 std::vector<std::pair<STPoint, STPoint>> point_pairs;
268 for (
size_t i = 0; i < lower_points_.size(); ++i) {
269 point_pairs.emplace_back(
270 STPoint(lower_points_[i].s() - s, lower_points_[i].t()),
271 STPoint(upper_points_[i].s() + s, upper_points_[i].t()));
277 if (lower_points_.empty()) {
278 AERROR <<
"The current st_boundary has NO points.";
282 std::vector<std::pair<STPoint, STPoint>> point_pairs;
284 const double left_delta_t = lower_points_[1].t() - lower_points_[0].t();
285 const double lower_left_delta_s = lower_points_[1].s() - lower_points_[0].s();
286 const double upper_left_delta_s = upper_points_[1].s() - upper_points_[0].s();
288 point_pairs.emplace_back(
289 STPoint(lower_points_[0].s() - t * lower_left_delta_s / left_delta_t,
290 lower_points_[0].t() - t),
291 STPoint(upper_points_[0].s() - t * upper_left_delta_s / left_delta_t,
292 upper_points_.front().t() - t));
294 const double kMinSEpsilon = 1e-3;
295 point_pairs.front().first.set_s(
296 std::fmin(point_pairs.front().second.s() - kMinSEpsilon,
297 point_pairs.front().first.s()));
299 for (
size_t i = 0; i < lower_points_.size(); ++i) {
300 point_pairs.emplace_back(lower_points_[i], upper_points_[i]);
303 size_t length = lower_points_.size();
304 DCHECK_GE(length, 2U);
306 const double right_delta_t =
307 lower_points_[length - 1].t() - lower_points_[length - 2].t();
308 const double lower_right_delta_s =
309 lower_points_[length - 1].s() - lower_points_[length - 2].s();
310 const double upper_right_delta_s =
311 upper_points_[length - 1].s() - upper_points_[length - 2].s();
313 point_pairs.emplace_back(
STPoint(lower_points_.back().s() +
314 t * lower_right_delta_s / right_delta_t,
315 lower_points_.back().t() + t),
316 STPoint(upper_points_.back().s() +
317 t * upper_right_delta_s / right_delta_t,
318 upper_points_.back().t() + t));
319 point_pairs.back().second.set_s(
320 std::fmax(point_pairs.back().second.s(),
321 point_pairs.back().first.s() + kMinSEpsilon));
327 return boundary_type_;
338 return characteristic_length_;
353 for (
size_t i = 0; i < lower_points_.size() && i < upper_points_.size();
355 if (lower_points_[i].t() < t) {
365 DCHECK(!upper_points_.empty()) <<
"StBoundary has zero points.";
366 return upper_points_.front();
370 DCHECK(!upper_points_.empty()) <<
"StBoundary has zero points.";
371 return upper_points_.back();
375 DCHECK(!lower_points_.empty()) <<
"StBoundary has zero points.";
376 return lower_points_.front();
380 DCHECK(!lower_points_.empty()) <<
"StBoundary has zero points.";
381 return lower_points_.back();
385 upper_left_point_ = std::move(st_point);
389 upper_right_point_ = std::move(st_point);
393 bottom_left_point_ = std::move(st_point);
397 bottom_right_point_ = std::move(st_point);
403bool STBoundary::IsValid(
404 const std::vector<std::pair<STPoint, STPoint>>& point_pairs)
const {
405 if (point_pairs.size() < 2) {
406 AERROR <<
"point_pairs.size() must >= 2, but current point_pairs.size() = "
407 << point_pairs.size();
411 static constexpr double kStBoundaryEpsilon = 1e-9;
412 static constexpr double kMinDeltaT = 1e-6;
413 for (
size_t i = 0; i < point_pairs.size(); ++i) {
414 const auto& curr_lower = point_pairs[i].first;
415 const auto& curr_upper = point_pairs[i].second;
416 if (curr_upper.s() < curr_lower.s()) {
417 AERROR <<
"ST-boundary's upper-s must >= lower-s";
420 if (std::fabs(curr_lower.t() - curr_upper.t()) > kStBoundaryEpsilon) {
421 AERROR <<
"Points in every ST-point pair should be at the same time.";
424 if (i + 1 != point_pairs.size()) {
425 const auto& next_lower = point_pairs[i + 1].first;
426 const auto& next_upper = point_pairs[i + 1].second;
427 if (std::fmax(curr_lower.t(), curr_upper.t()) + kMinDeltaT >=
428 std::fmin(next_lower.t(), next_upper.t())) {
429 AERROR <<
"Latter points should have larger t: "
430 <<
"curr_lower[" << curr_lower.DebugString() <<
"] curr_upper["
431 << curr_upper.DebugString() <<
"] next_lower["
432 << next_lower.DebugString() <<
"] next_upper["
433 << next_upper.DebugString() <<
"]";
441bool STBoundary::IsPointNear(
const common::math::LineSegment2d& seg,
442 const Vec2d& point,
const double max_dist) {
443 return seg.DistanceSquareTo(point) < max_dist * max_dist;
446void STBoundary::RemoveRedundantPoints(
447 std::vector<std::pair<STPoint, STPoint>>* point_pairs) {
448 if (!point_pairs || point_pairs->size() <= 2) {
452 const double kMaxDist = 0.1;
456 while (i < point_pairs->size() && j + 1 < point_pairs->size()) {
457 LineSegment2d lower_seg(point_pairs->at(i).first,
458 point_pairs->at(j + 1).first);
459 LineSegment2d upper_seg(point_pairs->at(i).second,
460 point_pairs->at(j + 1).second);
461 if (!IsPointNear(lower_seg, point_pairs->at(j).first, kMaxDist) ||
462 !IsPointNear(upper_seg, point_pairs->at(j).second, kMaxDist)) {
465 point_pairs->at(i) = point_pairs->at(j);
470 point_pairs->at(++i) = point_pairs->back();
471 point_pairs->resize(i + 1);
474bool STBoundary::GetIndexRange(
const std::vector<STPoint>& points,
475 const double t,
size_t* left,
476 size_t* right)
const {
478 CHECK_NOTNULL(right);
480 AERROR <<
"t is out of range. t = " << t;
483 auto comp = [](
const STPoint& p,
const double t) {
return p.t() < t; };
484 auto first_ge = std::lower_bound(
points.begin(),
points.end(), t, comp);
485 size_t index = std::distance(
points.begin(), first_ge);
488 }
else if (first_ge ==
points.end()) {
489 *left = *right =
points.size() - 1;
498 std::string type_name =
TypeName(boundary_type_);
499 std::string key_name = type_name + id_ + suffix;
501 if (lower_points_.empty() || upper_points_.empty()) {
504 for (
auto pt : lower_points_) {
507 for (
auto iter = upper_points_.rbegin(); iter != upper_points_.rend();
509 debug.
AddPoint(iter->t(), iter->s());
511 debug.
AddPoint(lower_points_.front().t(), lower_points_.front().s());
std::vector< Vec2d > points_
const std::vector< Vec2d > & points() const
Get the vertices of the polygon.
void BuildFromPoints(bool check_area=true)
Implements a class of 2-dimensional vectors.
void PrintToLog()
print curve to log
void AddPoint(double x, double y)
add points to curve
void set_bottom_right_point(STPoint st_point)
bool GetUnblockSRange(const double curr_time, double *s_upper, double *s_lower) const
const std::string & id() const
static std::string TypeName(BoundaryType type)
bool GetBoundarySlopes(const double curr_time, double *ds_upper, double *ds_lower) const
void set_id(const std::string &id)
STBoundary()=default
Constructors: STBoundary must be initialized with a vector of ST-point pairs.
static STBoundary CreateInstance(const std::vector< STPoint > &lower_points, const std::vector< STPoint > &upper_points)
Wrapper of the constructor (old).
void set_bottom_left_point(STPoint st_point)
void SetCharacteristicLength(const double characteristic_length)
std::vector< STPoint > lower_points() const
std::vector< STPoint > upper_points() const
BoundaryType boundary_type() const
STBoundary ExpandByT(const double t) const
void PrintDebug(std::string suffix="") const
static STBoundary CreateInstanceAccurate(const std::vector< STPoint > &lower_points, const std::vector< STPoint > &upper_points)
Wrapper of the constructor.
STBoundary ExpandByS(const double s) const
void set_upper_right_point(STPoint st_point)
STPoint bottom_right_point() const
bool IsPointInBoundary(const STPoint &st_point) const
bool GetBoundarySRange(const double curr_time, double *s_upper, double *s_lower) const
STPoint bottom_left_point() const
STBoundary CutOffByT(const double t) const
STPoint upper_right_point() const
void SetBoundaryType(const BoundaryType &boundary_type)
void set_upper_left_point(STPoint st_point)
STPoint upper_left_point() const
double characteristic_length() const
Planning module main class.
Math-related util functions.
double CrossProd(const Vec2d &start_point, const Vec2d &end_point_1, const Vec2d &end_point_2)
Cross product between two 2-D vectors from the common start point, and end at two other points.