28#include "absl/strings/str_cat.h"
33#include "modules/common_msgs/map_msgs/map_lane.pb.h"
37namespace relative_map {
43using apollo::common::util::operator+;
58bool CreateSingleLaneMap(
59 const NaviPathTuple &navi_path_tuple,
const MapGenerationParam &map_config,
60 const perception::PerceptionObstacles &perception_obstacles,
61 hdmap::Map *
const hdmap,
62 google::protobuf::Map<std::string, NavigationPath> *
const navigation_path) {
64 CHECK_NOTNULL(navigation_path);
66 const auto &navi_path = std::get<3>(navi_path_tuple);
67 const auto &path = navi_path->path();
68 if (path.path_point_size() < 2) {
69 AERROR <<
"The path length of line index is invalid";
72 auto *lane = hdmap->add_lane();
73 lane->mutable_id()->set_id(
74 absl::StrCat(navi_path->path_priority(),
"_", path.name()));
75 (*navigation_path)[lane->id().id()] = *navi_path;
81 lane->set_speed_limit(map_config.default_speed_limit());
84 auto *curve_segment = lane->mutable_central_curve()->add_segment();
85 curve_segment->set_heading(path.path_point(0).theta());
86 auto *line_segment = curve_segment->mutable_line_segment();
89 hdmap::LineSegment *left_segment =
nullptr;
90 if (FLAGS_relative_map_generate_left_boundray) {
91 auto *left_boundary = lane->mutable_left_boundary();
92 auto *left_boundary_type = left_boundary->add_boundary_type();
93 left_boundary->set_virtual_(
false);
94 left_boundary_type->set_s(0.0);
95 left_boundary_type->add_types(
96 perception_obstacles.lane_marker().left_lane_marker().lane_type());
98 left_boundary->mutable_curve()->add_segment()->mutable_line_segment();
102 auto *right_boundary = lane->mutable_right_boundary();
103 auto *right_boundary_type = right_boundary->add_boundary_type();
104 right_boundary->set_virtual_(
false);
105 right_boundary_type->set_s(0.0);
106 right_boundary_type->add_types(
107 perception_obstacles.lane_marker().right_lane_marker().lane_type());
108 auto *right_segment =
109 right_boundary->mutable_curve()->add_segment()->mutable_line_segment();
111 const double lane_left_width = std::get<1>(navi_path_tuple);
112 const double lane_right_width = std::get<2>(navi_path_tuple);
114 for (
const auto &path_point : path.path_point()) {
115 auto *point = line_segment->add_point();
116 point->set_x(path_point.x());
117 point->set_y(path_point.y());
118 point->set_z(path_point.z());
119 if (FLAGS_relative_map_generate_left_boundray) {
120 auto *left_sample = lane->add_left_sample();
121 left_sample->set_s(path_point.s());
122 left_sample->set_width(lane_left_width);
123 left_segment->add_point()->CopyFrom(
124 *point + lane_left_width *
128 auto *right_sample = lane->add_right_sample();
129 right_sample->set_s(path_point.s());
130 right_sample->set_width(lane_right_width);
131 right_segment->add_point()->CopyFrom(
148 vehicle_state_provider_ = vehicle_state_provider;
153 navigation_info_ = navigation_path;
154 last_project_index_map_.clear();
155 navigation_path_list_.clear();
156 current_navi_path_tuple_ = std::make_tuple(-1, -1.0, -1.0,
nullptr);
157 if (FLAGS_enable_cyclic_rerouting) {
158 UpdateStitchIndexInfo();
163 navigation_path_list_.clear();
164 current_navi_path_tuple_ = std::make_tuple(-1, -1.0, -1.0,
nullptr);
169 int navigation_line_num = navigation_info_.navigation_path_size();
170 const auto &lane_marker = perception_obstacles_.
lane_marker();
172 auto generate_path_on_perception_func = [
this, &lane_marker]() {
173 auto current_navi_path = std::make_shared<NavigationPath>();
174 auto *path = current_navi_path->mutable_path();
175 ConvertLaneMarkerToPath(lane_marker, path);
176 current_navi_path->set_path_priority(0);
177 double left_width = perceived_left_width_ > 0.0 ? perceived_left_width_
178 : default_left_width_;
179 double right_width = perceived_right_width_ > 0.0 ? perceived_right_width_
180 : default_right_width_;
181 current_navi_path_tuple_ =
182 std::make_tuple(0, left_width, right_width, current_navi_path);
185 ADEBUG <<
"Beginning of NavigationLane::GeneratePath().";
186 ADEBUG <<
"navigation_line_num: " << navigation_line_num;
190 navigation_line_num > 0) {
194 for (
int i = 0; i < navigation_line_num; ++i) {
195 auto current_navi_path = std::make_shared<NavigationPath>();
196 auto *path = current_navi_path->mutable_path();
197 if (ConvertNavigationLineToPath(i, path)) {
198 current_navi_path->set_path_priority(
200 navigation_path_list_.emplace_back(
201 i, default_left_width_, default_right_width_, current_navi_path);
207 if (navigation_path_list_.empty()) {
208 generate_path_on_perception_func();
218 navigation_path_list_.sort(
220 double left_y = std::get<3>(left)->path().path_point(0).y();
221 double right_y = std::get<3>(right)->path().path_point(0).y();
222 return left_y > right_y;
226 double min_d = std::numeric_limits<double>::max();
227 for (
const auto &navi_path_tuple : navigation_path_list_) {
228 int current_line_index = std::get<0>(navi_path_tuple);
229 ADEBUG <<
"Current navigation path index is: " << current_line_index;
230 double current_d = std::numeric_limits<double>::max();
231 auto item_iter = last_project_index_map_.find(current_line_index);
232 if (item_iter != last_project_index_map_.end()) {
233 current_d = item_iter->second.second;
235 if (current_d < min_d) {
237 current_navi_path_tuple_ = navi_path_tuple;
243 auto *path = std::get<3>(current_navi_path_tuple_)->mutable_path();
244 MergeNavigationLineAndLaneMarker(std::get<0>(current_navi_path_tuple_),
248 double left_width = perceived_left_width_ > 0.0 ? perceived_left_width_
249 : default_left_width_;
250 double right_width = perceived_right_width_ > 0.0 ? perceived_right_width_
251 : default_right_width_;
252 if (!IsFloatEqual(left_width, default_left_width_) &&
253 !IsFloatEqual(right_width, default_right_width_)) {
254 left_width = left_width > default_left_width_ ? left_width - min_d
255 : left_width + min_d;
256 right_width = right_width > default_right_width_ ? right_width - min_d
257 : right_width + min_d;
260 ADEBUG <<
"The left width of current lane is: " << left_width
261 <<
" and the right width of current lane is: " << right_width;
263 std::get<1>(current_navi_path_tuple_) = left_width;
264 std::get<2>(current_navi_path_tuple_) = right_width;
265 auto curr_navi_path_iter = std::find_if(
266 std::begin(navigation_path_list_), std::end(navigation_path_list_),
268 return std::get<0>(item) == std::get<0>(current_navi_path_tuple_);
270 if (curr_navi_path_iter != std::end(navigation_path_list_)) {
271 std::get<1>(*curr_navi_path_iter) = left_width;
272 std::get<2>(*curr_navi_path_iter) = right_width;
280 int average_point_size = 5;
281 for (
auto iter = navigation_path_list_.begin();
282 iter != navigation_path_list_.end(); ++iter) {
283 const auto &curr_path = std::get<3>(*iter)->path();
286 auto prev_iter = std::prev(iter);
287 if (prev_iter != navigation_path_list_.end()) {
288 const auto &prev_path = std::get<3>(*prev_iter)->path();
289 average_point_size = std::min(
291 std::min(curr_path.path_point_size(), prev_path.path_point_size()));
292 double lateral_distance_sum = 0.0;
293 for (
int i = 0; i < average_point_size; ++i) {
294 lateral_distance_sum +=
295 fabs(curr_path.path_point(i).y() - prev_path.path_point(i).y());
297 double width = lateral_distance_sum /
298 static_cast<double>(average_point_size) / 2.0;
302 auto &curr_left_width = std::get<1>(*iter);
303 auto &prev_right_width = std::get<2>(*prev_iter);
304 if (std::get<0>(*iter) == std::get<0>(current_navi_path_tuple_)) {
305 prev_right_width = 2.0 * width - curr_left_width;
307 curr_left_width = width;
308 prev_right_width = width;
312 auto next_iter = std::next(iter);
313 if (next_iter != navigation_path_list_.end()) {
314 const auto &next_path = std::get<3>(*next_iter)->path();
315 average_point_size = std::min(
317 std::min(curr_path.path_point_size(), next_path.path_point_size()));
318 double lateral_distance_sum = 0.0;
319 for (
int i = 0; i < average_point_size; ++i) {
320 lateral_distance_sum +=
321 fabs(curr_path.path_point(i).y() - next_path.path_point(i).y());
323 double width = lateral_distance_sum /
324 static_cast<double>(average_point_size) / 2.0;
328 auto &curr_right_width = std::get<2>(*iter);
329 auto &next_left_width = std::get<1>(*next_iter);
330 if (std::get<0>(*iter) == std::get<0>(current_navi_path_tuple_)) {
331 next_left_width = 2.0 * width - curr_right_width;
333 next_left_width = width;
334 curr_right_width = width;
344 generate_path_on_perception_func();
348double NavigationLane::EvaluateCubicPolynomial(
const double c0,
const double c1,
349 const double c2,
const double c3,
350 const double x)
const {
351 return ((c3 * x + c2) * x + c1) * x + c0;
354void NavigationLane::MergeNavigationLineAndLaneMarker(
360 if (path->path_point_size() < 2) {
362 ConvertNavigationLineToPath(line_index, path);
367 if (path->path_point_size() < 2) {
369 ConvertLaneMarkerToPath(perception_obstacles_.
lane_marker(), path);
373 common::Path lane_marker_path;
374 ConvertLaneMarkerToPath(perception_obstacles_.
lane_marker(),
379 if (lane_marker_path.path_point_size() < 2) {
383 int lane_marker_index = 0;
385 for (
int i = 0; i < path->path_point_size(); ++i) {
386 auto *point = path->mutable_path_point(i);
387 double s = point->s();
388 auto lane_maker_point = GetPathPointByS(lane_marker_path, lane_marker_index,
389 s, &lane_marker_index);
393 const int marker_size = lane_marker_path.path_point_size();
394 if (lane_marker_index < 0 || lane_marker_index > (marker_size - 1)) {
395 point->set_y(navigation_line_weight * point->y() +
396 (1 - navigation_line_weight) * lane_maker_point.y());
397 lane_marker_index = 0;
401 *point, lane_maker_point, navigation_line_weight,
402 1 - navigation_line_weight);
406common::PathPoint NavigationLane::GetPathPointByS(
const common::Path &path,
407 const int start_index,
409 int *
const matched_index) {
410 CHECK_NOTNULL(matched_index);
411 const int size = path.path_point_size();
413 if (start_index < 0 || s < path.path_point(start_index).s()) {
415 return path.path_point(0);
418 if (s > path.path_point(size - 1).s() || start_index > (size - 1)) {
419 *matched_index = size;
420 return path.path_point(size - 1);
423 static constexpr double kEpsilon = 1e-9;
424 if (std::fabs(path.path_point(start_index).s() - s) < kEpsilon) {
425 *matched_index = start_index;
426 return path.path_point(start_index);
429 while (i + 1 < size && path.path_point(i + 1).s() < s) {
435 const double r = (s - path.path_point(i).s()) /
436 (path.path_point(i + 1).s() - path.path_point(i).s());
438 path.path_point(i), path.path_point(i + 1), 1 - r, r);
442bool NavigationLane::ConvertNavigationLineToPath(
const int line_index,
443 common::Path *
const path) {
451 path->set_name(absl::StrCat(
"Path from navigation line index ", line_index));
452 const auto &navigation_path =
454 auto proj_index_pair = UpdateProjectionIndex(navigation_path, line_index);
457 int current_project_index = proj_index_pair.first;
458 if (current_project_index < 0 ||
459 current_project_index >= navigation_path.path_point_size()) {
460 AERROR <<
"Invalid projection index " << current_project_index
461 <<
" in line " << line_index;
462 last_project_index_map_.erase(line_index);
465 last_project_index_map_[line_index] = proj_index_pair;
469 const double dx = -original_pose_.
position().
x();
470 const double dy = -original_pose_.
position().
y();
471 auto enu_to_flu_func = [
this, dx, dy](
const double enu_x,
const double enu_y,
472 const double enu_theta,
double *flu_x,
473 double *flu_y,
double *flu_theta) {
474 if (flu_x !=
nullptr && flu_y !=
nullptr) {
476 {enu_x + dx, enu_y + dy}, -original_pose_.
heading());
478 *flu_x = flu_coordinate.x();
479 *flu_y = flu_coordinate.y();
482 if (flu_theta !=
nullptr) {
488 auto gen_navi_path_loop_func =
489 [
this, &navigation_path, &enu_to_flu_func](
490 const int start,
const int end,
const double ref_s_base,
491 const double max_length, common::Path *path) {
493 const double ref_s = navigation_path.path_point(start).s();
494 for (
int i = start; i < end; ++i) {
495 auto *point = path->add_path_point();
496 point->CopyFrom(navigation_path.path_point(i));
500 double flu_theta = 0.0;
501 enu_to_flu_func(point->x(), point->y(), point->theta(), &flu_x,
506 point->set_theta(flu_theta);
507 const double accumulated_s =
508 navigation_path.path_point(i).s() - ref_s + ref_s_base;
509 point->set_s(accumulated_s);
511 if (accumulated_s > max_length) {
517 double dist = navigation_path.path_point().rbegin()->s() -
518 navigation_path.path_point(current_project_index).s();
520 if (FLAGS_enable_cyclic_rerouting &&
522 auto item_iter = stitch_index_map_.find(line_index);
523 if (item_iter != stitch_index_map_.end()) {
524 int stitch_start_index =
525 std::max(item_iter->second.first, item_iter->second.second);
526 stitch_start_index = std::max(current_project_index, stitch_start_index);
528 std::min(navigation_path.path_point_size() - 1, stitch_start_index);
530 int stitch_end_index =
531 std::min(item_iter->second.first, item_iter->second.second);
532 stitch_end_index = std::max(0, stitch_end_index);
533 stitch_end_index = std::min(current_project_index, stitch_end_index);
535 ADEBUG <<
"The stitch_start_index is: " << stitch_start_index <<
"; "
536 <<
"the stitch_end_index is: " << stitch_end_index <<
"; "
537 <<
"the current_project_index is: " << current_project_index
538 <<
" for the navigation line: " << line_index;
540 double length = navigation_path.path_point(stitch_start_index).s() -
541 navigation_path.path_point(current_project_index).s();
542 gen_navi_path_loop_func(std::max(0, current_project_index - 3),
543 stitch_start_index + 1, 0.0, length, path);
547 gen_navi_path_loop_func(stitch_end_index,
548 navigation_path.path_point_size(), length,
557 gen_navi_path_loop_func(std::max(0, current_project_index - 3),
558 navigation_path.path_point_size(), 0.0,
564ProjIndexPair NavigationLane::UpdateProjectionIndex(
const common::Path &path,
565 const int line_index) {
566 if (path.path_point_size() < 2) {
567 return std::make_pair(-1, std::numeric_limits<double>::max());
570 double min_d = std::numeric_limits<double>::max();
571 const int path_size = path.path_point_size();
572 int current_project_index = 0;
573 auto item_iter = last_project_index_map_.find(line_index);
574 if (item_iter != last_project_index_map_.end()) {
575 current_project_index = std::max(0, item_iter->second.first);
580 auto check_distance_func = [
this, &path, &path_size](
581 const int project_index,
582 double *project_distance) {
592 if (project_index < 0 || project_index > path_size - 1) {
595 double enu_x = path.path_point(project_index).x();
596 double enu_y = path.path_point(project_index).y();
597 double x_shift = original_pose_.
position().
x();
598 double y_shift = original_pose_.
position().
y();
599 double cos_angle = std::cos(original_pose_.
heading());
600 double sin_angle = std::sin(original_pose_.
heading());
602 (enu_x - x_shift) * cos_angle + (enu_y - y_shift) * sin_angle;
604 (enu_y - y_shift) * cos_angle - (enu_x - x_shift) * sin_angle;
606 if (project_distance !=
nullptr) {
607 *project_distance = std::fabs(flu_y);
618 for (
int i = current_project_index; i + 1 < path_size; ++i) {
624 const double kMaxDistance = 50.0;
625 if (current_project_index != 0 && d > kMaxDistance) {
630 if (check_distance_func(index, &min_d)) {
631 if (FLAGS_enable_cyclic_rerouting) {
637 auto item_iter = stitch_index_map_.find(line_index);
638 if (item_iter != stitch_index_map_.end()) {
640 std::max(item_iter->second.first, item_iter->second.second);
642 std::min(item_iter->second.first, item_iter->second.second);
643 int index_diff = index - start_index;
644 if (index_diff >= 0) {
645 index = std::min(end_index + index_diff, start_index);
650 return std::make_pair(index, min_d);
653 return std::make_pair(-1, std::numeric_limits<double>::max());
656double NavigationLane::GetKappa(
const double c1,
const double c2,
657 const double c3,
const double x) {
658 const double dy = 3 * c3 * x * x + 2 * c2 * x + c1;
659 const double d2y = 6 * c3 * x + 2 * c2;
660 return d2y / std::pow((1 + dy * dy), 1.5);
663void NavigationLane::ConvertLaneMarkerToPath(
664 const perception::LaneMarkers &lane_marker, common::Path *
const path) {
667 path->set_name(
"Path from lane markers.");
668 const auto &left_lane = lane_marker.left_lane_marker();
669 const auto &right_lane = lane_marker.right_lane_marker();
671 double path_c0 = (left_lane.c0_position() + right_lane.c0_position()) / 2.0;
674 (left_lane.c1_heading_angle() + right_lane.c1_heading_angle()) / 2.0;
676 double path_c2 = (left_lane.c2_curvature() + right_lane.c2_curvature()) / 2.0;
678 double path_c3 = (left_lane.c3_curvature_derivative() +
679 right_lane.c3_curvature_derivative()) /
682 const double current_speed =
692 const double unit_z = 1.0;
693 const double start_s = -2.0;
694 double accumulated_s = start_s;
695 for (
double z = start_s; z <= path_range; z += unit_z) {
700 y1 = EvaluateCubicPolynomial(path_c0, path_c1, path_c2, path_c3, z);
702 auto *point = path->add_path_point();
706 if (path->path_point_size() > 1) {
707 auto &pre_point = path->path_point(path->path_point_size() - 2);
708 accumulated_s += std::hypot(x1 - pre_point.x(), y1 - pre_point.y());
710 point->set_s(accumulated_s);
712 std::atan2(3 * path_c3 * x1 * x1 + 2 * path_c2 * x1 + path_c1, 1));
713 point->set_kappa(GetKappa(path_c1, path_c2, path_c3, x1));
715 const double k1 = GetKappa(path_c1, path_c2, path_c3, x1 - 0.0001);
716 const double k2 = GetKappa(path_c1, path_c2, path_c3, x1 + 0.0001);
717 point->set_dkappa((k2 - k1) / 0.0002);
720 perceived_left_width_ = std::fabs(left_lane.c0_position());
721 perceived_right_width_ = std::fabs(right_lane.c0_position());
724 double perceived_lane_width = perceived_left_width_ + perceived_right_width_;
727 perceived_left_width_ = default_left_width_;
728 perceived_right_width_ = default_right_width_;
733 MapMsg *
const map_msg)
const {
734 auto *navigation_path = map_msg->mutable_navigation_path();
735 auto *hdmap = map_msg->mutable_hdmap();
736 auto *lane_marker = map_msg->mutable_lane_marker();
738 lane_marker->CopyFrom(perception_obstacles_.
lane_marker());
743 if (navigation_path_list_.empty()) {
744 if (std::get<3>(current_navi_path_tuple_) !=
nullptr) {
745 FLAGS_relative_map_generate_left_boundray =
true;
746 return CreateSingleLaneMap(current_navi_path_tuple_, map_config,
747 perception_obstacles_, hdmap, navigation_path);
754 FLAGS_relative_map_generate_left_boundray =
true;
755 for (
auto iter = navigation_path_list_.cbegin();
756 iter != navigation_path_list_.cend(); ++iter) {
757 std::size_t index = std::distance(navigation_path_list_.cbegin(), iter);
758 if (!CreateSingleLaneMap(*iter, map_config, perception_obstacles_, hdmap,
760 AWARN <<
"Failed to generate lane: " << index;
762 FLAGS_relative_map_generate_left_boundray =
true;
765 FLAGS_relative_map_generate_left_boundray =
false;
769 int lane_index =
static_cast<int>(index) - fail_num;
770 if (lane_index > 0) {
771 auto *left_boundary =
772 hdmap->mutable_lane(lane_index)->mutable_left_boundary();
773 left_boundary->CopyFrom(hdmap->lane(lane_index - 1).right_boundary());
775 hdmap->mutable_lane(lane_index)->mutable_left_sample();
776 left_sample->CopyFrom(hdmap->lane(lane_index - 1).right_sample());
780 int lane_num = hdmap->lane_size();
781 ADEBUG <<
"The Lane number is: " << lane_num;
784 auto *road = hdmap->add_road();
785 road->mutable_id()->set_id(
"road_" + hdmap->lane(0).id().id());
786 auto *section = road->add_section();
787 for (
int i = 0; i < lane_num; ++i) {
788 auto *lane_id = section->add_lane_id();
789 lane_id->CopyFrom(hdmap->lane(0).id());
791 auto *outer_polygon = section->mutable_boundary()->mutable_outer_polygon();
792 auto *left_edge = outer_polygon->add_edge();
794 left_edge->mutable_curve()->CopyFrom(hdmap->lane(0).left_boundary().curve());
796 auto *right_edge = outer_polygon->add_edge();
798 right_edge->mutable_curve()->CopyFrom(
799 hdmap->lane(lane_num - 1).right_boundary().curve());
805 for (
int i = 0; i < lane_num; ++i) {
806 auto *lane = hdmap->mutable_lane(i);
808 lane->add_left_neighbor_forward_lane_id()->CopyFrom(
809 hdmap->lane(i - 1).id());
810 ADEBUG <<
"Left neighbor is: " << hdmap->lane(i - 1).id().id();
812 if (i < lane_num - 1) {
813 lane->add_right_neighbor_forward_lane_id()->CopyFrom(
814 hdmap->lane(i + 1).id());
815 ADEBUG <<
"Right neighbor is: " << hdmap->lane(i + 1).id().id();
821void NavigationLane::UpdateStitchIndexInfo() {
822 stitch_index_map_.clear();
824 int navigation_line_num = navigation_info_.navigation_path_size();
825 if (navigation_line_num <= 0) {
829 static constexpr int kMinPathPointSize = 10;
830 for (
int i = 0; i < navigation_line_num; ++i) {
833 navigation_path.path_point_size() < kMinPathPointSize) {
837 double min_distance = std::numeric_limits<double>::max();
840 int path_size = navigation_path.path_point_size();
841 const double start_s = navigation_path.path_point(0).s();
842 const double end_s = navigation_path.path_point(path_size - 1).s();
843 for (
int m = 0; m < path_size; ++m) {
844 double forward_s = navigation_path.path_point(m).s() - start_s;
849 for (
int n = path_size - 1; n >= 0; --n) {
850 double reverse_s = end_s - navigation_path.path_point(n).s();
858 double current_distance =
DistanceXY(navigation_path.path_point(m),
859 navigation_path.path_point(n));
860 if (current_distance < min_distance) {
861 min_distance = current_distance;
862 min_index_pair = std::make_pair(m, n);
868 AINFO <<
"The stitching pair is: (" << min_index_pair.first <<
", "
869 << min_index_pair.second <<
") for the navigation line: " << i;
870 stitch_index_map_[i] = min_index_pair;
The class of vehicle state.
const localization::Pose & original_pose() const
const VehicleState & vehicle_state() const
Implements a class of 2-dimensional vectors.
static Vec2d CreateUnitVec2d(const double angle)
Creates a unit-vector with a given angle to the positive x semi-axis
void SetConfig(const NavigationLaneConfig &config)
Set the configuration information required by the NavigationLane.
bool GeneratePath()
Generate a suitable path (i.e.
void SetVehicleStateProvider(common::VehicleStateProvider *vehicle_state_provider)
bool CreateMap(const MapGenerationParam &map_config, MapMsg *const map_msg) const
Generate a real-time relative map of approximately 250 m in length based on several navigation line s...
void UpdateNavigationInfo(const NavigationInfo &navigation_info)
Update navigation line information.
Math-related util functions.
T Clamp(const T value, T bound1, T bound2)
Clamp a value between two bounds.
double NormalizeAngle(const double angle)
Normalize angle to [-PI, PI).
Eigen::Vector2d RotateVector2d(const Eigen::Vector2d &v_in, const double theta)
double DistanceXY(const U &u, const V &v)
calculate the distance beteween Point u and Point v, which are all have member function x() and y() i...
std::enable_if<!std::numeric_limits< T >::is_integer, bool >::type IsFloatEqual(T x, T y, int ulp=2)
PathPoint GetWeightedAverageOfTwoPathPoints(const PathPoint &p1, const PathPoint &p2, const double w1, const double w2)
std::tuple< int, double, double, std::shared_ptr< NavigationPath > > NaviPathTuple
std::pair< int, double > ProjIndexPair
std::pair< int, int > StitchIndexPair
This file provides the declaration of the class NavigationLane.
optional double linear_velocity
optional apollo::common::PointENU position
optional LaneMarkers lane_marker
repeated NavigationPath navigation_path
optional double lane_marker_weight
optional double max_lane_half_width
optional double min_view_range_to_use_lane_marker
optional double max_len_for_navigation_lane
optional double min_len_for_navigation_lane
optional LaneSource lane_source
optional double min_lane_half_width
optional double ratio_navigation_lane_len_to_speed
optional double max_distance_to_navigation_line
optional double max_len_from_navigation_line
optional uint32 path_priority
optional apollo::common::Path path