26#include "modules/common_msgs/planning_msgs/sl_boundary.pb.h"
44 const std::vector<const Obstacle*>& obstacles,
45 const std::vector<PathPoint>& discretized_ref_points,
47 const double s_end,
const double t_start,
const double t_end,
48 const std::array<double, 3>& init_d) {
49 CHECK_LT(s_start, s_end);
50 CHECK_LT(t_start, t_end);
51 path_range_.first = s_start;
52 path_range_.second = s_end;
53 time_range_.first = t_start;
54 time_range_.second = t_end;
55 ptr_reference_line_info_ = ptr_reference_line_info;
58 SetupObstacles(obstacles, discretized_ref_points);
61SLBoundary PathTimeGraph::ComputeObstacleBoundary(
62 const std::vector<common::math::Vec2d>& vertices,
63 const std::vector<PathPoint>& discretized_ref_points)
const {
64 double start_s(std::numeric_limits<double>::max());
65 double end_s(std::numeric_limits<double>::lowest());
66 double start_l(std::numeric_limits<double>::max());
67 double end_l(std::numeric_limits<double>::lowest());
69 for (
const auto& point : vertices) {
71 point.x(), point.y());
72 start_s = std::fmin(start_s, sl_point.first);
73 end_s = std::fmax(end_s, sl_point.first);
74 start_l = std::fmin(start_l, sl_point.second);
75 end_l = std::fmax(end_l, sl_point.second);
78 SLBoundary sl_boundary;
79 sl_boundary.set_start_s(start_s);
80 sl_boundary.set_end_s(end_s);
81 sl_boundary.set_start_l(start_l);
82 sl_boundary.set_end_l(end_l);
87void PathTimeGraph::SetupObstacles(
88 const std::vector<const Obstacle*>& obstacles,
89 const std::vector<PathPoint>& discretized_ref_points) {
90 for (
const Obstacle* obstacle : obstacles) {
91 if (obstacle->IsVirtual()) {
94 if (!obstacle->HasTrajectory()) {
95 SetStaticObstacle(obstacle, discretized_ref_points);
97 SetDynamicObstacle(obstacle, discretized_ref_points);
101 std::sort(static_obs_sl_boundaries_.begin(), static_obs_sl_boundaries_.end(),
102 [](
const SLBoundary& sl0,
const SLBoundary& sl1) {
103 return sl0.start_s() < sl1.start_s();
106 for (
auto& path_time_obstacle : path_time_obstacle_map_) {
107 path_time_obstacles_.push_back(path_time_obstacle.second);
111void PathTimeGraph::SetStaticObstacle(
112 const Obstacle* obstacle,
113 const std::vector<PathPoint>& discretized_ref_points) {
114 const Polygon2d& polygon = obstacle->PerceptionPolygon();
116 std::string obstacle_id = obstacle->Id();
117 SLBoundary sl_boundary =
118 ComputeObstacleBoundary(polygon.GetAllVertices(), discretized_ref_points);
120 double left_width = FLAGS_default_reference_line_width * 0.5;
121 double right_width = FLAGS_default_reference_line_width * 0.5;
123 sl_boundary.start_s(), &left_width, &right_width);
124 if (sl_boundary.start_s() > path_range_.second ||
125 sl_boundary.end_s() < path_range_.first ||
126 sl_boundary.start_l() > left_width ||
127 sl_boundary.end_l() < -right_width) {
128 ADEBUG <<
"Obstacle [" << obstacle_id <<
"] is out of range.";
132 path_time_obstacle_map_[obstacle_id].set_id(obstacle_id);
133 path_time_obstacle_map_[obstacle_id].set_bottom_left_point(
134 SetPathTimePoint(obstacle_id, sl_boundary.start_s(), 0.0));
135 path_time_obstacle_map_[obstacle_id].set_bottom_right_point(SetPathTimePoint(
136 obstacle_id, sl_boundary.start_s(), FLAGS_trajectory_time_length));
137 path_time_obstacle_map_[obstacle_id].set_upper_left_point(
138 SetPathTimePoint(obstacle_id, sl_boundary.end_s(), 0.0));
139 path_time_obstacle_map_[obstacle_id].set_upper_right_point(SetPathTimePoint(
140 obstacle_id, sl_boundary.end_s(), FLAGS_trajectory_time_length));
141 static_obs_sl_boundaries_.push_back(std::move(sl_boundary));
142 ADEBUG <<
"ST-Graph mapping static obstacle: " << obstacle_id
143 <<
", start_s : " << sl_boundary.start_s()
144 <<
", end_s : " << sl_boundary.end_s()
145 <<
", start_l : " << sl_boundary.start_l()
146 <<
", end_l : " << sl_boundary.end_l();
149void PathTimeGraph::SetDynamicObstacle(
150 const Obstacle* obstacle,
151 const std::vector<PathPoint>& discretized_ref_points) {
152 double relative_time = time_range_.first;
153 while (relative_time < time_range_.second) {
154 TrajectoryPoint point = obstacle->GetPointAtTime(relative_time);
155 Box2d box = obstacle->GetBoundingBox(point);
156 SLBoundary sl_boundary =
157 ComputeObstacleBoundary(box.GetAllCorners(), discretized_ref_points);
159 double left_width = FLAGS_default_reference_line_width * 0.5;
160 double right_width = FLAGS_default_reference_line_width * 0.5;
162 sl_boundary.start_s(), &left_width, &right_width);
165 if (sl_boundary.start_s() > path_range_.second ||
166 sl_boundary.end_s() < path_range_.first ||
167 sl_boundary.start_l() > left_width ||
168 sl_boundary.end_l() < -right_width) {
169 if (path_time_obstacle_map_.find(obstacle->Id()) !=
170 path_time_obstacle_map_.end()) {
173 relative_time += FLAGS_trajectory_time_resolution;
177 if (path_time_obstacle_map_.find(obstacle->Id()) ==
178 path_time_obstacle_map_.end()) {
179 path_time_obstacle_map_[obstacle->Id()].set_id(obstacle->Id());
181 path_time_obstacle_map_[obstacle->Id()].set_bottom_left_point(
182 SetPathTimePoint(obstacle->Id(), sl_boundary.start_s(),
184 path_time_obstacle_map_[obstacle->Id()].set_upper_left_point(
185 SetPathTimePoint(obstacle->Id(), sl_boundary.end_s(), relative_time));
188 path_time_obstacle_map_[obstacle->Id()].set_bottom_right_point(
189 SetPathTimePoint(obstacle->Id(), sl_boundary.start_s(), relative_time));
190 path_time_obstacle_map_[obstacle->Id()].set_upper_right_point(
191 SetPathTimePoint(obstacle->Id(), sl_boundary.end_s(), relative_time));
192 relative_time += FLAGS_trajectory_time_resolution;
196STPoint PathTimeGraph::SetPathTimePoint(
const std::string& obstacle_id,
197 const double s,
const double t)
const {
198 STPoint path_time_point(s, t);
199 return path_time_point;
203 return path_time_obstacles_;
208 if (path_time_obstacle_map_.find(obstacle_id) ==
209 path_time_obstacle_map_.end()) {
212 *path_time_obstacle = path_time_obstacle_map_[obstacle_id];
217 const double t)
const {
218 ACHECK(time_range_.first <= t && t <= time_range_.second);
219 std::vector<std::pair<double, double>> intervals;
220 for (
const auto& pt_obstacle : path_time_obstacles_) {
221 if (t > pt_obstacle.max_t() || t < pt_obstacle.min_t()) {
224 double s_upper = lerp(pt_obstacle.upper_left_point().s(),
225 pt_obstacle.upper_left_point().t(),
226 pt_obstacle.upper_right_point().s(),
227 pt_obstacle.upper_right_point().t(), t);
229 double s_lower = lerp(pt_obstacle.bottom_left_point().s(),
230 pt_obstacle.bottom_left_point().t(),
231 pt_obstacle.bottom_right_point().s(),
232 pt_obstacle.bottom_right_point().t(), t);
234 intervals.emplace_back(s_lower, s_upper);
239std::vector<std::vector<std::pair<double, double>>>
242 const double t_resolution) {
243 std::vector<std::vector<std::pair<double, double>>> intervals;
244 for (
double t = t_start; t <= t_end; t += t_resolution) {
259 const std::string& obstacle_id,
const double s_dist,
260 const double t_min_density)
const {
261 ACHECK(t_min_density > 0.0);
262 std::vector<STPoint> pt_pairs;
263 if (path_time_obstacle_map_.find(obstacle_id) ==
264 path_time_obstacle_map_.end()) {
268 const auto& pt_obstacle = path_time_obstacle_map_.at(obstacle_id);
276 s0 = pt_obstacle.upper_left_point().s();
277 s1 = pt_obstacle.upper_right_point().s();
279 t0 = pt_obstacle.upper_left_point().t();
280 t1 = pt_obstacle.upper_right_point().t();
282 s0 = pt_obstacle.bottom_left_point().s();
283 s1 = pt_obstacle.bottom_right_point().s();
285 t0 = pt_obstacle.bottom_left_point().t();
286 t1 = pt_obstacle.bottom_right_point().t();
289 double time_gap = t1 - t0;
290 ACHECK(time_gap > -FLAGS_numerical_epsilon);
291 time_gap = std::fabs(time_gap);
293 size_t num_sections =
static_cast<size_t>(time_gap / t_min_density + 1);
294 double t_interval = time_gap /
static_cast<double>(num_sections);
296 for (
size_t i = 0; i <= num_sections; ++i) {
297 double t = t_interval *
static_cast<double>(i) + t0;
298 double s = lerp(s0, t0, s1, t1, t) + s_dist;
303 pt_pairs.push_back(std::move(ptt));
310 return path_time_obstacle_map_.find(obstacle_id) !=
311 path_time_obstacle_map_.end();
315 const double s_start,
const double s_end,
const double s_resolution) {
316 CHECK_LT(s_start, s_end);
317 CHECK_GT(s_resolution, FLAGS_numerical_epsilon);
318 std::vector<std::pair<double, double>> bounds;
319 std::vector<double> discretized_path;
320 double s_range = s_end - s_start;
321 double s_curr = s_start;
322 size_t num_bound =
static_cast<size_t>(s_range / s_resolution);
324 const auto& vehicle_config =
325 common::VehicleConfigHelper::Instance()->GetConfig();
326 double ego_width = vehicle_config.vehicle_param().width();
329 for (
size_t i = 0; i < num_bound; ++i) {
330 double left_width = FLAGS_default_reference_line_width / 2.0;
331 double right_width = FLAGS_default_reference_line_width / 2.0;
334 double ego_d_lower = init_d_[0] - ego_width / 2.0;
335 double ego_d_upper = init_d_[0] + ego_width / 2.0;
337 std::min(-right_width, ego_d_lower - FLAGS_bound_buffer),
338 std::max(left_width, ego_d_upper + FLAGS_bound_buffer));
339 discretized_path.push_back(s_curr);
340 s_curr += s_resolution;
343 for (
const SLBoundary& static_sl_boundary : static_obs_sl_boundaries_) {
344 UpdateLateralBoundsByObstacle(static_sl_boundary, discretized_path, s_start,
348 for (
size_t i = 0; i < bounds.size(); ++i) {
349 bounds[i].first += ego_width / 2.0;
350 bounds[i].second -= ego_width / 2.0;
351 if (bounds[i].first >= bounds[i].second) {
352 bounds[i].first = 0.0;
353 bounds[i].second = 0.0;
359void PathTimeGraph::UpdateLateralBoundsByObstacle(
360 const SLBoundary& sl_boundary,
const std::vector<double>& discretized_path,
361 const double s_start,
const double s_end,
362 std::vector<std::pair<double, double>>*
const bounds) {
363 if (sl_boundary.
start_s() > s_end || sl_boundary.
end_s() < s_start) {
366 auto start_iter = std::lower_bound(
367 discretized_path.begin(), discretized_path.end(), sl_boundary.
start_s());
368 auto end_iter = std::upper_bound(
369 discretized_path.begin(), discretized_path.end(), sl_boundary.
start_s());
370 size_t start_index = start_iter - discretized_path.begin();
371 size_t end_index = end_iter - discretized_path.begin();
372 if (sl_boundary.
end_l() > -FLAGS_numerical_epsilon &&
373 sl_boundary.
start_l() < FLAGS_numerical_epsilon) {
374 for (
size_t i = start_index; i < end_index; ++i) {
375 bounds->operator[](i).first = -FLAGS_numerical_epsilon;
376 bounds->operator[](i).second = FLAGS_numerical_epsilon;
380 if (sl_boundary.
end_l() < FLAGS_numerical_epsilon) {
381 for (
size_t i = start_index; i < std::min(end_index + 1, bounds->size());
383 bounds->operator[](i).first =
384 std::max(bounds->operator[](i).first,
385 sl_boundary.
end_l() + FLAGS_nudge_buffer);
389 if (sl_boundary.
start_l() > -FLAGS_numerical_epsilon) {
390 for (
size_t i = start_index; i < std::min(end_index + 1, bounds->size());
392 bounds->operator[](i).second =
393 std::min(bounds->operator[](i).second,
394 sl_boundary.
start_l() - FLAGS_nudge_buffer);
Rectangular (undirected) bounding box in 2-D.
static std::pair< double, double > GetPathFrenetCoordinate(const std::vector< PathPoint > &reference_line, const double x, const double y)
The class of polygon in 2-D.
std::vector< STPoint > GetObstacleSurroundingPoints(const std::string &obstacle_id, const double s_dist, const double t_density) const
std::vector< std::pair< double, double > > GetPathBlockingIntervals(const double t) const
PathTimeGraph(const std::vector< const Obstacle * > &obstacles, const std::vector< common::PathPoint > &discretized_ref_points, const ReferenceLineInfo *ptr_reference_line_info, const double s_start, const double s_end, const double t_start, const double t_end, const std::array< double, 3 > &init_d)
std::pair< double, double > get_path_range() const
bool GetPathTimeObstacle(const std::string &obstacle_id, STBoundary *path_time_obstacle)
bool IsObstacleInGraph(const std::string &obstacle_id)
std::vector< std::pair< double, double > > GetLateralBounds(const double s_start, const double s_end, const double s_resolution)
std::pair< double, double > get_time_range() const
const std::vector< STBoundary > & GetPathTimeObstacles() const
ReferenceLineInfo holds all data for one reference line.
const ReferenceLine & reference_line() const
bool GetLaneWidth(const double s, double *const lane_left_width, double *const lane_right_width) const
void set_s(const double s)
void set_t(const double t)
Planning module main class.
Linear interpolation functions.
T lerp(const T &x0, const double t0, const T &x1, const double t1, const double t)
Linear interpolation between two points of type T.