26#include <unordered_map>
39 static constexpr double EPSILON = 10.0 * std::numeric_limits<double>::epsilon();
47 static std::vector<T> ConcatVectors(std::vector<T> dst, std::vector<T> src) {
48 if (src.size() > dst.size()) {
49 return ConcatVectors(src, dst);
53 std::make_move_iterator(src.begin()),
54 std::make_move_iterator(src.end()));
59 static double GetDistanceAtStartOfLane(
const Lane &lane) {
60 if (lane.
GetId() <= 0) {
68 static double GetDistanceAtEndOfLane(
const Lane &lane) {
69 if (lane.
GetId() > 0) {
77 template <
typename FuncT>
78 static void ForEachDrivableLaneImpl(
83 for (
const auto &pair : lane_section.GetLanes()) {
84 const auto &lane = pair.second;
85 if (lane.
GetId() == 0) {
93 distance < 0.0 ? GetDistanceAtStartOfLane(lane) : distance});
99 template <
typename FuncT>
100 static void ForEachLaneImpl(
106 for (
const auto &pair : lane_section.GetLanes()) {
107 const auto &lane = pair.second;
108 if (lane.
GetId() == 0) {
111 if ((
static_cast<int32_t
>(lane.
GetType()) &
static_cast<int32_t
>(lane_type)) > 0) {
114 lane_section.
GetId(),
116 distance < 0.0 ? GetDistanceAtStartOfLane(lane) : distance});
122 template <
typename FuncT>
123 static void ForEachDrivableLane(
const Road &road, FuncT &&func) {
124 for (
const auto &lane_section : road.GetLaneSections()) {
125 ForEachDrivableLaneImpl(
129 std::forward<FuncT>(func));
134template <
typename FuncT>
136 for (
const auto &lane_section : road.GetLaneSections()) {
142 std::forward<FuncT>(func));
147template <
typename FuncT>
148static void ForEachDrivableLaneAt(
const Road &road,
double distance, FuncT &&func) {
149 for (
const auto &lane_section : road.GetLaneSectionsAt(distance)) {
150 ForEachDrivableLaneImpl(
154 std::forward<FuncT>(func));
170 int32_t lane_type)
const {
171 std::vector<Rtree::TreeElement> query_result =
174 const Lane &lane = GetLane(element.second.first);
175 return (lane_type & static_cast<int32_t>(lane.GetType())) > 0;
178 if (query_result.size() == 0) {
179 return boost::optional<Waypoint>{};
189 Waypoint result_start = query_result.front().second.first;
190 Waypoint result_end = query_result.front().second.second;
192 if (result_start.
lane_id < 0) {
193 double delta_s = distance_to_segment.first;
194 double final_s = result_start.
s + delta_s;
195 if (final_s >= result_end.
s) {
197 }
else if (delta_s <= 0) {
200 return GetNext(result_start, delta_s).front();
203 double delta_s = distance_to_segment.first;
204 double final_s = result_start.
s - delta_s;
205 if (final_s <= result_end.
s) {
207 }
else if (delta_s <= 0) {
210 return GetNext(result_start, delta_s).front();
217 int32_t lane_type)
const {
220 if (!w.has_value()) {
226 const auto half_lane_width =
229 if (dist < half_lane_width) {
233 return boost::optional<Waypoint>{};
249 return boost::optional<Waypoint>{};
256 return boost::optional<Waypoint>{};
260bool lane_found =
false;
261for (
auto §ion : road.GetLaneSectionsAt(s)) {
262 if (section.ContainsLane(lane_id)) {
271 return boost::optional<Waypoint>{};
287 const auto s = waypoint.
s;
289 const auto &lane =
GetLane(waypoint);
296 return lane_width_info->GetPolynomial().Evaluate(s);
310std::pair<const RoadInfoMarkRecord *, const RoadInfoMarkRecord *>
314 return std::make_pair(
nullptr,
nullptr);
316 const auto s = waypoint.
s;
318 const auto ¤t_lane =
GetLane(waypoint);
322 const auto inner_lane_id = waypoint.
lane_id < 0 ?
326 const auto &inner_lane = current_lane.GetRoad()->GetLaneById(waypoint.
section_id, inner_lane_id);
331 return std::make_pair(current_lane_info, inner_lane_info);
336 Waypoint waypoint,
double distance,
bool stop_at_junction)
const {
338 const auto &lane =
GetLane(waypoint);
339 const bool forward = (waypoint.
lane_id <= 0);
340 const double signed_distance = forward ? distance : -distance;
341 const double relative_s = waypoint.
s - lane.
GetDistance();
342 const double remaining_lane_length = forward ? lane.
GetLength() - relative_s : relative_s;
346 std::vector<SignalSearchData> result;
349 if (distance <= remaining_lane_length) {
351 waypoint.
s, waypoint.
s + signed_distance);
352 for(
auto* signal : signals){
353 double distance_to_signal = 0;
355 distance_to_signal = signal->GetDistance() - waypoint.
s;
357 distance_to_signal = waypoint.
s - signal->GetDistance();
360 bool is_valid =
false;
361 for (
auto &validity : signal->GetValidities()) {
362 if (waypoint.
lane_id >= validity._from_lane &&
363 waypoint.
lane_id <= validity._to_lane) {
371if (distance_to_signal == 0) {
372 result.emplace_back(SignalSearchData
374 distance_to_signal});
376 result.emplace_back(SignalSearchData
377 {signal,
GetNext(waypoint, distance_to_signal).front(),
378 distance_to_signal});
384const double signed_remaining_length = forward ? remaining_lane_length : -remaining_lane_length;
389 waypoint.
s, waypoint.
s + signed_remaining_length);
390for(
auto* signal : signals){
391 double distance_to_signal = 0;
393 distance_to_signal = signal->GetDistance() - waypoint.
s;
395 distance_to_signal = waypoint.
s - signal->GetDistance();
398 bool is_valid =
false;
399 for (
auto &validity : signal->GetValidities()) {
400 if (waypoint.
lane_id >= validity._from_lane &&
401 waypoint.
lane_id <= validity._to_lane) {
409 if (distance_to_signal == 0) {
410 result.emplace_back(SignalSearchData
412 distance_to_signal});
414 result.emplace_back(SignalSearchData
415 {signal,
GetNext(waypoint, distance_to_signal).front(),
416 distance_to_signal});
426 GetLaneByDistance(successor.s, successor.lane_id);
427 if (successor.lane_id < 0) {
428 successor.s = sucessor_lane.GetDistance();
430 successor.s = sucessor_lane.GetDistance() + sucessor_lane.GetLength();
433 successor, distance - remaining_lane_length, stop_at_junction);
434 for(
auto& signal : sucessor_signals){
435 signal.accumulated_s += remaining_lane_length;
437 result = ConcatVectors(result, sucessor_signals);
442std::vector<const element::RoadInfoSignal*>
444 std::vector<const element::RoadInfoSignal*> result;
445 for (
const auto& road_pair :
_data.GetRoads()) {
446 const auto &road = road_pair.second;
448 for(
const auto* road_info : road_infos) {
449 result.push_back(road_info);
458 return LaneCrossingCalculator::Calculate(*
this, origin, destination);
463 std::vector<geom::Location> result;
465 for (
const auto &pair :
_data.GetRoads()) {
466 const auto &road = pair.second;
468 if (crosswalks.size() > 0) {
469 for (
auto crosswalk : crosswalks) {
470 std::vector<geom::Location> points;
473 for (
const auto §ion : road.GetLaneSectionsAt(crosswalk->GetS())) {
474 for (
const auto &lane : section.GetLanes()) {
475 if (lane.first == 0) {
479 waypoint.
s = crosswalk->GetS();
487 pivot.
rotation.
yaw -= geom::Math::ToDegrees<float>(
static_cast<float>(crosswalk->GetHeading()));
489 geom::Vector3D v(
static_cast<float>(crosswalk->GetT()), 0.0f, 0.0f);
494 pivot.
rotation.
yaw -= geom::Math::ToDegrees<float>(
static_cast<float>(crosswalk->GetHeading()));
497 for (
auto corner : crosswalk->GetPoints()) {
499 static_cast<float>(corner.u),
500 static_cast<float>(corner.v),
501 static_cast<float>(corner.z));
509 result.push_back(v2);
523 std::vector<Waypoint> result;
524 result.reserve(next_lanes.size());
525 for (
auto *next_lane : next_lanes) {
527 const auto lane_id = next_lane->GetId();
529 const auto *section = next_lane->GetLaneSection();
531 const auto *road = next_lane->GetRoad();
533 const auto distance = GetDistanceAtStartOfLane(*next_lane);
534 result.emplace_back(
Waypoint{road->
GetId(), section->GetId(), lane_id, distance});
541 std::vector<Waypoint> result;
542 result.reserve(prev_lanes.size());
543 for (
auto *next_lane : prev_lanes) {
545 const auto lane_id = next_lane->GetId();
547 const auto *section = next_lane->GetLaneSection();
549 const auto *road = next_lane->GetRoad();
551 const auto distance = GetDistanceAtEndOfLane(*next_lane);
552 result.emplace_back(
Waypoint{road->
GetId(), section->GetId(), lane_id, distance});
559 const double distance)
const {
561 if (distance <= EPSILON) {
564 const auto &lane =
GetLane(waypoint);
565 const bool forward = (waypoint.
lane_id <= 0);
566 const double signed_distance = forward ? distance : -distance;
567 const double relative_s = waypoint.
s - lane.
GetDistance();
568 const double remaining_lane_length = forward ? lane.
GetLength() - relative_s : relative_s;
572 if (distance <= remaining_lane_length) {
574 result.
s += signed_distance;
575 result.
s += forward ? -EPSILON : EPSILON;
581 std::vector<Waypoint> result;
584 successor.road_id != waypoint.
road_id ||
585 successor.section_id != waypoint.
section_id ||
586 successor.lane_id != waypoint.
lane_id);
587 result = ConcatVectors(result,
GetNext(successor, distance - remaining_lane_length));
594 const double distance)
const {
596 if (distance <= EPSILON) {
599 const auto &lane =
GetLane(waypoint);
600 const bool forward = !(waypoint.
lane_id <= 0);
601 const double signed_distance = forward ? distance : -distance;
602 const double relative_s = waypoint.
s - lane.
GetDistance();
603 const double remaining_lane_length = forward ? lane.
GetLength() - relative_s : relative_s;
607 if (distance <= remaining_lane_length) {
609 result.
s += signed_distance;
610 result.
s += forward ? -EPSILON : EPSILON;
616 std::vector<Waypoint> result;
619 successor.road_id != waypoint.
road_id ||
620 successor.section_id != waypoint.
section_id ||
621 successor.lane_id != waypoint.
lane_id);
622 result = ConcatVectors(result,
GetPrevious(successor, distance - remaining_lane_length));
634 return IsLanePresent(
_data, waypoint) ? waypoint : boost::optional<Waypoint>{};
639 if (std::abs(waypoint.
lane_id) == 1) {
641 }
else if (waypoint.
lane_id > 0) {
646 return IsLanePresent(
_data, waypoint) ? waypoint : boost::optional<Waypoint>{};
651 std::vector<Waypoint> result;
652 for (
const auto &pair :
_data.GetRoads()) {
653 const auto &road = pair.second;
654 for (
double s = EPSILON; s < (road.
GetLength() - EPSILON); s += distance) {
655 ForEachDrivableLaneAt(road, s, [&](
auto &&waypoint) {
656 result.emplace_back(waypoint);
664 std::vector<Waypoint> result;
665 for (
const auto &pair :
_data.GetRoads()) {
666 const auto &road = pair.second;
668 for (
const auto &lane_section : road.GetLaneSectionsAt(0.0)) {
669 for (
const auto &lane : lane_section.GetLanes()) {
671 if (lane.first < 0 &&
672 static_cast<int32_t
>(lane.second.
GetType()) &
static_cast<int32_t
>(lane_type)) {
679 for (
const auto &lane_section : road.GetLaneSectionsAt(road_len)) {
680 for (
const auto &lane : lane_section.GetLanes()) {
682 if (lane.first > 0 &&
683 static_cast<int32_t
>(lane.second.
GetType()) &
static_cast<int32_t
>(lane_type)) {
696 std::vector<Waypoint> result;
700 for (
const auto &lane_section : road.GetLaneSectionsAt(0.0)) {
701 for (
const auto &lane : lane_section.GetLanes()) {
703 if (lane.first < 0 &&
704 static_cast<int32_t
>(lane.second.
GetType()) &
static_cast<int32_t
>(lane_type)) {
711 for (
const auto &lane_section : road.GetLaneSectionsAt(road_len)) {
712 for (
const auto &lane : lane_section.GetLanes()) {
714 if (lane.first > 0 &&
715 static_cast<int32_t
>(lane.second.
GetType()) &
static_cast<int32_t
>(lane_type)) {
726 std::vector<std::pair<Waypoint, Waypoint>> result;
727 for (
const auto &pair :
_data.GetRoads()) {
728 const auto &road = pair.second;
729 ForEachDrivableLane(road, [&](
auto &&waypoint) {
731 if (successors.size() == 0) {
732 auto distance =
static_cast<float>(GetDistanceAtEndOfLane(
GetLane(waypoint)));
734 if (last_waypoint.has_value()) {
735 result.push_back({waypoint, *last_waypoint});
739 result.push_back({waypoint, successor});
749 std::vector<std::pair<Waypoint, Waypoint>> result;
752 for(
auto &connections : junction->GetConnections()) {
754 ForEachLane(road, lane_type, [&](
auto &&waypoint) {
755 const auto& lane =
GetLane(waypoint);
756 const double final_s = GetDistanceAtEndOfLane(lane);
758 lane_end.s = final_s;
759 result.push_back({waypoint, lane_end});
765std::unordered_map<road::RoadId, std::unordered_set<road::RoadId>>
767 const float epsilon = 0.0001f;
769 std::unordered_map<road::RoadId, std::unordered_set<road::RoadId>> conflicts;
772 typedef boost::geometry::model::point<float, 2, boost::geometry::cs::cartesian> Point2d;
773 typedef boost::geometry::model::segment<Point2d> Segment2d;
774 typedef boost::geometry::model::box<Rtree::BPoint>
Box;
780 bbox_pos.x - bbox_ext.x,
781 bbox_pos.y - bbox_ext.y,
782 bbox_pos.z - bbox_ext.z - epsilon);
784 bbox_pos.x + bbox_ext.x,
785 bbox_pos.y + bbox_ext.y,
786 bbox_pos.z + bbox_ext.z + epsilon);
787 Box box({min_corner.x, min_corner.y, min_corner.z},
788 {max_corner.x, max_corner.y, max_corner.z});
791 for (
size_t i = 0; i < segments.size(); ++i) {
792 auto &segment1 = segments[i];
793 auto waypoint1 = segment1.second.first;
799 Segment2d seg1{{segment1.first.first.get<0>(), segment1.first.first.get<1>()},
800 {segment1.first.second.get<0>(), segment1.first.second.get<1()}};
801 for (
size_t j = i + 1; j < segments.size(); ++j) {
802 auto &segment2 = segments[j];
803 auto waypoint2 = segment2.second.first;
810 if(waypoint1.road_id == waypoint2.road_id) {
813 Segment2d seg2{{segment2.first.first.get<0>(), segment2.first.first.get<1>()},
814 {segment2.first.second.get<0>(), segment2.first.second.get<1>()}};
816 double distance = boost::geometry::distance(seg1, seg2);
821 if(conflicts[waypoint1.road_id].count(waypoint2.road_id) == 0) {
822 conflicts[waypoint1.road_id].insert(waypoint2.road_id);
824 if(conflicts[waypoint2.road_id].count(waypoint1.road_id) == 0) {
825 conflicts[waypoint2.road_id].insert(waypoint1.road_id);
843 std::vector<Rtree::TreeElement> &rtree_elements,
862 std::make_pair(current_waypoint, next_waypoint)));
867 std::vector<Rtree::TreeElement> &rtree_elements,
875 current_waypoint, next_waypoint);
877 current_waypoint = next_waypoint;
878 current_transform = next_transform;
882double GetRemainingLength(
const Lane &lane,
double current_s) {
883 if (lane.
GetId() < 0) {
894 const double epsilon = 0.000001;
895 const double min_delta_s = 1;
898 constexpr double angle_threshold = geom::Math::Pi<double>() / 100.0;
900 constexpr double max_segment_length = 100.0;
903 std::vector<Waypoint> topology;
904 for (
const auto &pair :
_data.GetRoads()) {
905 const auto &road = pair.second;
909 topology.push_back(waypoint);
916std::vector<Rtree::TreeElement> rtree_elements;
919for (
auto &waypoint : topology) {
920 auto &lane_start_waypoint = waypoint;
922 auto current_waypoint = lane_start_waypoint;
930 double delta_s = min_delta_s;
931 double remaining_length = GetRemainingLength(lane, current_waypoint.
s);
932 remaining_length -= epsilon;
933 delta_s = remaining_length;
934 if (delta_s < epsilon) {
937 auto next =
GetNext(current_waypoint, delta_s);
941 auto next_waypoint = next.front();
950 auto next_waypoint = current_waypoint;
955 double delta_s = min_delta_s;
956 double remaining_length = GetRemainingLength(lane, next_waypoint.
s);
957 remaining_length -= epsilon;
958 delta_s = std::min(delta_s, remaining_length);
960 if (delta_s < epsilon) {
969 auto next =
GetNext(next_waypoint, delta_s);
970 if (next.size() != 1 ||
971 current_waypoint.
section_id != next.front().section_id) {
980 next_waypoint = next.front();
985 if (std::abs(angle) > angle_threshold ||
986 std::abs(current_waypoint.
s - next_waypoint.
s) > max_segment_length) {
993 current_waypoint = next_waypoint;
994 current_transform = next_transform;
1013 const double distance,
1014 const float extra_width,
1015 const bool smooth_junctions)
const {
1025 for (
auto &&pair :
_data.GetRoads()) {
1026 const auto &road = pair.second;
1030 out_mesh += *mesh_factory.
Generate(road);
1034 for (
const auto &junc_pair :
_data.GetJunctions()) {
1035 const auto &junction = junc_pair.second;
1036 std::vector<std::unique_ptr<geom::Mesh>> lane_meshes;
1039 for(
const auto &connection_pair : junction.GetConnections()) {
1040 const auto &connection = connection_pair.second;
1041 const auto &road =
_data.
GetRoads().at(connection.connecting_road);
1044 for (
auto &&lane_section : road.GetLaneSections()) {
1045 for (
auto &&lane_pair : lane_section.GetLanes()) {
1046 lane_meshes.push_back(mesh_factory.
Generate(lane_pair.second));
1052 if(smooth_junctions) {
1056 for(
auto& lane : lane_meshes) {
1057 junction_mesh += *lane;
1059 out_mesh += junction_mesh;
1070 std::vector<std::unique_ptr<geom::Mesh>> out_mesh_list;
1072 std::unordered_map<JuncId, geom::Mesh> junction_map;
1073 for (
auto &&pair :
_data.GetRoads()) {
1074 const auto &road = pair.second;
1076 std::vector<std::unique_ptr<geom::Mesh>> road_mesh_list =
1080 out_mesh_list.insert(
1081 out_mesh_list.end(),
1082 std::make_move_iterator(road_mesh_list.begin()),
1083 std::make_move_iterator(road_mesh_list.end()));
1088 for (
const auto &junc_pair :
_data.GetJunctions()) {
1089 const auto &junction = junc_pair.second;
1090 std::vector<std::unique_ptr<geom::Mesh>> lane_meshes;
1091 std::vector<std::unique_ptr<geom::Mesh>> sidewalk_lane_meshes;
1092 for(
const auto &connection_pair : junction.GetConnections()) {
1093 const auto &connection = connection_pair.second;
1094 const auto &road =
_data.
GetRoads().at(connection.connecting_road);
1095 for (
auto &&lane_section : road.GetLaneSections()) {
1096 for (
auto &&lane_pair : lane_section.GetLanes()) {
1097 const auto &lane = lane_pair.second;
1099 lane_meshes.push_back(mesh_factory.
Generate(lane));
1101 sidewalk_lane_meshes.push_back(mesh_factory.
Generate(lane));
1108 for(
auto& lane : sidewalk_lane_meshes) {
1109 *merged_mesh += *lane;
1111 out_mesh_list.push_back(std::move(merged_mesh));
1113 std::unique_ptr<geom::Mesh> junction_mesh = std::make_unique<geom::Mesh>();
1114 for(
auto& lane : lane_meshes) {
1115 *junction_mesh += *lane;
1117 for(
auto& lane : sidewalk_lane_meshes) {
1118 *junction_mesh += *lane;
1120 out_mesh_list.push_back(std::move(junction_mesh));
1126 out_mesh_list.front()->GetVertices().front().x,
1127 out_mesh_list.front()->GetVertices().front().y);
1128 auto max_pos = min_pos;
1129 for (
auto & mesh : out_mesh_list) {
1130 auto vertex = mesh->GetVertices().front();
1131 min_pos.x = std::min(min_pos.x, vertex.x);
1132 min_pos.y = std::min(min_pos.y, vertex.y);
1133 max_pos.x = std::max(max_pos.x, vertex.x);
1134 max_pos.y = std::max(max_pos.y, vertex.y);
1136 size_t mesh_amount_x =
static_cast<size_t>((max_pos.x - min_pos.x)/params.
max_road_length) + 1;
1137 size_t mesh_amount_y =
static_cast<size_t>((max_pos.y - min_pos.y)/params.
max_road_length) + 1;
1138 std::vector<std::unique_ptr<geom::Mesh>> result;
1139 result.reserve(mesh_amount_x*mesh_amount_y);
1140 for (
size_t i = 0; i < mesh_amount_x*mesh_amount_y; ++i) {
1141 result.emplace_back(std::make_unique<geom::Mesh>());
1143 for (
auto & mesh : out_mesh_list) {
1144 auto vertex = mesh->GetVertices().front();
1145 size_t x_pos =
static_cast<size_t>((vertex.x - min_pos.x) / params.
max_road_length);
1146 size_t y_pos =
static_cast<size_t>((vertex.y - min_pos.y) / params.
max_road_length);
1147 *(result[x_pos + mesh_amount_x*y_pos]) += *mesh;
1153 std::map<road::Lane::LaneType , std::vector<std::unique_ptr<geom::Mesh>>>
1159 std::map<road::Lane::LaneType, std::vector<std::unique_ptr<geom::Mesh>>> road_out_mesh_list;
1160 std::map<road::Lane::LaneType, std::vector<std::unique_ptr<geom::Mesh>>> junction_out_mesh_list;
1164 minpos, maxpos, &junction_out_mesh_list);
1169 size_t num_roads = RoadsIDToGenerate.size();
1170 size_t num_roads_per_thread = 30;
1171 size_t num_threads = (num_roads / num_roads_per_thread) + 1;
1172 num_threads = num_threads > 1 ? num_threads : 1;
1173 std::vector<std::thread> workers;
1174 std::mutex write_mutex;
1175 std::cout <<
"Generating " << std::to_string(num_roads) <<
" roads" << std::endl;
1177 for (
size_t i = 0; i < num_threads; ++i) {
1178 std::thread new_worker(
1179 [
this, &write_mutex, &mesh_factory, &RoadsIDToGenerate, &road_out_mesh_list, i, num_roads_per_thread]() {
1181 std::map<road::Lane::LaneType, std::vector<std::unique_ptr<geom::Mesh>>> Current =
1184 std::lock_guard<std::mutex> guard(write_mutex);
1186 for (
auto&& pair : Current) {
1187 if (road_out_mesh_list.find(pair.first) != road_out_mesh_list.end()) {
1189 road_out_mesh_list[pair.first].insert(road_out_mesh_list[pair.first].end(),
1190 std::make_move_iterator(pair.second.begin()),
1191 std::make_move_iterator(pair.second.end()));
1194 road_out_mesh_list[pair.first] = std::move(pair.second);
1198 workers.push_back(std::move(new_worker));
1201 for (
size_t i = 0; i < workers.size(); ++i) {
1205 for (
size_t i = 0; i < workers.size(); ++i) {
1206 if (workers[i].joinable()) {
1211 junction_thread.join();
1212 for (
auto&& pair : junction_out_mesh_list) {
1213 if (road_out_mesh_list.find(pair.first) != road_out_mesh_list.end()) {
1215 road_out_mesh_list[pair.first].insert(road_out_mesh_list[pair.first].end(),
1216 std::make_move_iterator(pair.second.begin()),
1217 std::make_move_iterator(pair.second.end()));
1220 road_out_mesh_list[pair.first] = std::move(pair.second);
1223 std::cout <<
"Generated " << std::to_string(num_roads) <<
" roads" << std::endl;
1225 return road_out_mesh_list;
1232 float distancebetweentrees,
1233 float distancefromdrivinglineborder,
1234 float s_offset)
const {
1236 std::vector<std::pair<geom::Transform, std::string>> transforms;
1239 for (
RoadId id : RoadsIDToGenerate ) {
1242 for (
auto &&lane_section : road.GetLaneSections()) {
1244 for (
auto &pairlane : lane_section.GetLanes()) {
1246 min_lane = pairlane.first;
1252 double s_current = lane_section.
GetDistance() + s_offset;
1254 while(s_current < s_end){
1255 if(lane->
GetWidth(s_current) != 0.0f){
1257 if (edges.first == edges.second)
continue;
1264 transforms.push_back(std::make_pair(treeTransform, roadinfo->
GetType()));
1266 transforms.push_back(std::make_pair(treeTransform,
"urban"));
1269 s_current += distancebetweentrees;
1285 if (crosswalk_vertex.empty()) {
1291 size_t start_vertex_index = 0;
1293 std::vector<geom::Vector3D> vertices;
1298 if (i != 0 && crosswalk_vertex[start_vertex_index] == crosswalk_vertex[i]) {
1303 if (i >= crosswalk_vertex.size() - 1) {
1306 start_vertex_index = ++i;
1309 vertices.push_back(crosswalk_vertex[i++]);
1310 }
while (i < crosswalk_vertex.size());
1321 std::vector<std::string>& outinfo )
const
1323 std::vector<std::unique_ptr<geom::Mesh>> LineMarks;
1328 for (
RoadId id : RoadsIDToGenerate ) {
1335 return std::move(LineMarks);
1340 std::vector<carla::geom::BoundingBox> returning;
1341 for (
const auto& junc_pair :
_data.GetJunctions() ) {
1342 const auto& junction = junc_pair.second;
1343 float box_extraextension_factor = 1.5f;
1345 bb.
extent *= box_extraextension_factor;
1346 returning.push_back(bb);
1356 std::map<road::Lane::LaneType, std::vector<std::unique_ptr<geom::Mesh>>>
1358 const std::vector<RoadId>& RoadsId,
1359 const size_t index,
const size_t number_of_roads_per_thread)
const
1361 std::map<road::Lane::LaneType, std::vector<std::unique_ptr<geom::Mesh>>> out;
1363 size_t start = index * number_of_roads_per_thread;
1364 size_t endoffset = (index+1) * number_of_roads_per_thread;
1365 size_t end = RoadsId.size();
1367 for (
int i = start; i < endoffset && i <
end; ++i) {
1373 std::cout <<
"Generated roads from " + std::to_string(index * number_of_roads_per_thread) +
" to " + std::to_string((index+1) * number_of_roads_per_thread ) << std::endl;
1382 std::vector<std::unique_ptr<geom::Mesh>>>* junction_out_mesh_list)
const {
1385 size_t num_junctions = JunctionsToGenerate.size();
1386 std::cout <<
"Generating " << std::to_string(num_junctions) <<
" junctions" << std::endl;
1387 size_t junctionindex = 0;
1388 size_t num_junctions_per_thread = 5;
1389 size_t num_threads = (num_junctions / num_junctions_per_thread) + 1;
1390 num_threads = num_threads > 1 ? num_threads : 1;
1391 std::vector<std::thread> workers;
1392 std::mutex write_mutex;
1394 for (
size_t i = 0; i < num_threads; ++i ) {
1395 std::thread neworker(
1396 [
this, &write_mutex, &mesh_factory, &junction_out_mesh_list, JunctionsToGenerate, i, num_junctions_per_thread, num_junctions]() {
1398 std::vector<std::unique_ptr<geom::Mesh>>> junctionsofthisthread;
1401 if( (i + 1) * num_junctions_per_thread < num_junctions ){
1402 minimum = (i + 1) * num_junctions_per_thread;
1404 minimum = num_junctions;
1406 std::cout <<
"Generating Junctions between " << std::to_string(i * num_junctions_per_thread) <<
" and " << std::to_string(minimum) << std::endl;
1408 for (
size_t junctionindex = i * num_junctions_per_thread;
1409 junctionindex < minimum;
1414 std::cout <<
"Generated Junctions between " << std::to_string(i * num_junctions_per_thread) <<
" and " << std::to_string(minimum) << std::endl;
1415 std::lock_guard<std::mutex> guard(write_mutex);
1416 for (
auto&& pair : junctionsofthisthread ) {
1417 if ((*junction_out_mesh_list).find(pair.first) != (*junction_out_mesh_list).end()) {
1418 (*junction_out_mesh_list)[pair.first].insert((*junction_out_mesh_list)[pair.first].end(),
1419 std::make_move_iterator(pair.second.begin()),
1420 std::make_move_iterator(pair.second.end()));
1422 (*junction_out_mesh_list)[pair.first] = std::move(pair.second);
1426 workers.push_back(std::move(neworker));
1429 for (
size_t i = 0; i < workers.size(); ++i) {
1433 for (
size_t i = 0; i < workers.size(); ++i) {
1434 if (workers[i].joinable()) {
1443 std::cout <<
"Filtered from " + std::to_string(
_data.
GetJunctions().size() ) +
" junctions " << std::endl;
1444 std::vector<JuncId> ToReturn;
1445 for(
auto& junction :
_data.GetJunctions() ){
1447 if( minpos.
x < junctionLocation.
x && junctionLocation.
x < maxpos.
x &&
1448 minpos.
y > junctionLocation.
y && junctionLocation.
y > maxpos.
y ) {
1449 ToReturn.push_back(junction.first);
1452 std::cout <<
"To " + std::to_string(ToReturn.size() ) +
" junctions " << std::endl;
1461 std::vector<RoadId> ToReturn;
1462 std::cout <<
"Filtered from " + std::to_string(
_data.
GetRoads().size() ) +
" roads " << std::endl;
1463 for(
auto& road :
_data.GetRoads() ){
1469 if( minpos.
x < roadLocation.
x && roadLocation.
x < maxpos.
x &&
1470 minpos.
y > roadLocation.
y && roadLocation.
y > maxpos.
y ) {
1471 ToReturn.push_back(road.first);
1475 std::cout <<
"To " + std::to_string(ToReturn.size() ) +
" roads " << std::endl;
1480 const std::vector<geom::Vector3D>& sdfinput,
1481 int grid_cells_per_dim)
const {
1483 int junctionid = jinput.
GetId();
1484 float box_extraextension_factor = 1.2f;
1485 const double CubeSize = 0.5;
1495 if (CheckingWaypoint) {
1509 if (Distance.Length2D() < CubeSize * 1.1 && pos.
z < 0.2) {
1512 return Distance.
Length() * -1.0;
1515 double gridsizeindouble = grid_cells_per_dim;
1517 domain.
min = { MinOffset.
x, MinOffset.
y, MinOffset.
z };
1518 domain.
size = { bb.
extent.
x * box_extraextension_factor * 2, bb.
extent.
y * box_extraextension_factor * 2, 0.4 };
1526 for (
auto& cv : mesh.vertices) {
1535 for (
auto ct : mesh.triangles) {
1541 for (
auto& cv : out_mesh.GetVertices() ) {
1543 if (!CheckingWaypoint) {
1552 return std::make_unique<geom::Mesh>(out_mesh);
1558 junction_out_mesh_list)
const {
1562 std::vector<std::unique_ptr<geom::Mesh>> lane_meshes;
1563 std::vector<std::unique_ptr<geom::Mesh>> sidewalk_lane_meshes;
1564 std::vector<carla::geom::Vector3D> perimeterpoints;
1566 auto pmesh =
SDFToMesh(junction, perimeterpoints, 75);
1569 for (
const auto& connection_pair : junction.GetConnections()) {
1570 const auto& connection = connection_pair.second;
1571 const auto& road =
_data.
GetRoads().at(connection.connecting_road);
1572 for (
auto&& lane_section : road.GetLaneSections()) {
1573 for (
auto&& lane_pair : lane_section.GetLanes()) {
1574 const auto& lane = lane_pair.second;
1576 boost::optional<element::Waypoint> sw =
1586 std::unique_ptr<geom::Mesh> sidewalk_mesh = std::make_unique<geom::Mesh>();
1587 for (
auto& lane : sidewalk_lane_meshes) {
1588 *sidewalk_mesh += *lane;
1592 std::vector<std::unique_ptr<geom::Mesh>> lane_meshes;
1593 std::vector<std::unique_ptr<geom::Mesh>> sidewalk_lane_meshes;
1594 for (
const auto& connection_pair : junction.GetConnections()) {
1595 const auto& connection = connection_pair.second;
1596 const auto& road =
_data.
GetRoads().at(connection.connecting_road);
1597 for (
auto&& lane_section : road.GetLaneSections()) {
1598 for (
auto&& lane_pair : lane_section.GetLanes()) {
1599 const auto& lane = lane_pair.second;
1609 std::unique_ptr<geom::Mesh> merged_mesh = std::make_unique<geom::Mesh>();
1610 for (
auto& lane : lane_meshes) {
1611 *merged_mesh += *lane;
1613 std::unique_ptr<geom::Mesh> sidewalk_mesh = std::make_unique<geom::Mesh>();
1614 for (
auto& lane : sidewalk_lane_meshes) {
1615 *sidewalk_mesh += *lane;
auto end() const noexcept
#define DEBUG_ASSERT(predicate)
#define RELEASE_ASSERT(pred)
Location location
边界框的中心位置(本地坐标系下)
Vector3D extent
边界框的半尺寸(本地坐标系下,表示在每个轴方向上的半宽、半高和半深)
Rotation rotation
边界框的旋转(本地坐标系下)
value_type Evaluate(const value_type &x) const
评估 f(x) = a + bx + cx^2 + dx^3
static double GetVectorAngle(const Vector3D &a, const Vector3D &b)
返回两个向量之间的夹角(弧度)
static auto Distance2D(const Vector3D &a, const Vector3D &b)
static std::pair< float, float > DistanceSegmentToPoint(const Vector3D &p, const Vector3D &v, const Vector3D &w)
计算点到线段的距离 返回一个包含:
std::unique_ptr< Mesh > GenerateSidewalk(const road::LaneSection &lane_section) const
生成车道段的人行道网格
std::unique_ptr< Mesh > MergeAndSmooth(std::vector< std::unique_ptr< Mesh > > &lane_meshes) const
合并并平滑多个车道网格
void GenerateLaneMarkForRoad(const road::Road &road, std::vector< std::unique_ptr< Mesh > > &inout, std::vector< std::string > &outinfo) const
为道路生成车道标记
RoadParameters road_param
std::unique_ptr< Mesh > Generate(const road::Road &road) const
生成定义一条道路的网格
std::unique_ptr< Mesh > GenerateTesselated(const road::Lane &lane, const double s_start, const double s_end) const
用更高的细分生成从给定的s起始和结束的车道网格
std::vector< std::unique_ptr< Mesh > > GenerateAllWithMaxLen(const road::Road &road) const
生成带有所有模拟所需特性的分块道路
void GenerateAllOrderedWithMaxLen(const road::Road &road, std::map< road::Lane::LaneType, std::vector< std::unique_ptr< Mesh > > > &roads) const
生成按顺序排列的道路网格,限制最大长度
void AddIndex(index_type index)
将索引附加到索引列表。
void AddVertex(vertex_type vertex)
将顶点附加到顶点列表。
void AddMaterial(const std::string &material_name)
开始将新材质应用到新添加的三角形。
void EndMaterial()
停止将材质应用到新添加的三角形。
void AddTriangleFan(const std::vector< vertex_type > &vertices)
向网格添加三角形扇形,顶点顺序为逆时针。
const std::vector< vertex_type > & GetVertices() const
boost::geometry::model::point< float, 3, boost::geometry::cs::cartesian > BPoint
boost::geometry::model::segment< BPoint > BSegment
std::vector< TreeElement > GetNearestNeighboursWithFilter(const Geometry &geometry, Filter filter, size_t number_neighbours=1) const
返回带有用户定义过滤器的最近邻元素。 过滤器接收一个 TreeElement 值作为参数,并且需要 返回一个布尔值以接受或拒绝该值 示例过滤器:[&](Rtree::TreeElement const ...
std::pair< BSegment, std::pair< Waypoint, Waypoint > > TreeElement
std::vector< TreeElement > GetIntersections(const Geometry &geometry) const
返回与指定几何形状相交的线段。 警告:Boost 库没有实现3D线段间的交集计算。
void InsertElements(const std::vector< TreeElement > &elements)
Vector3D MakeUnitVector() const
std::unordered_map< ConId, Connection > & GetConnections()
carla::geom::BoundingBox GetBoundingBox() const
double GetDistance() const
Lane * GetLane(const LaneId id)
bool ContainsLane(LaneId id) const
bool IsStraight() const
检查几何形状是否是直线
const std::vector< Lane * > & GetNextLanes() const
double GetWidth(const double s) const
返回给定位置s的车道总宽度
geom::Transform ComputeTransform(const double s) const
const T * GetInfo(const double s) const
double GetDistance() const
std::pair< geom::Vector3D, geom::Vector3D > GetCornerPositions(const double s, const float extra_width=0.f) const
计算给定位置s的车道边缘位置
const std::vector< Lane * > & GetPreviousLanes() const
std::unordered_map< RoadId, Road > & GetRoads()
Road & GetRoad(const RoadId id)
bool ContainsRoad(RoadId id) const
std::unordered_map< JuncId, Junction > & GetJunctions()
Junction * GetJunction(JuncId id)
std::vector< std::pair< Waypoint, Waypoint > > GenerateTopology() const
生成定义 map 拓扑结构的最小路点集。 路点放置在每个车道入口处。
JuncId GetJunctionId(RoadId road_id) const
std::vector< Waypoint > GetPrevious(Waypoint waypoint, double distance) const
返回距离 waypoint distance 的路点列表, 使得车辆可以反向驶向这些路点。
bool IsJunction(RoadId road_id) const
Lane::LaneType GetLaneType(Waypoint waypoint) const
boost::optional< element::Waypoint > GetClosestWaypointOnRoad(const geom::Location &location, int32_t lane_type=static_cast< int32_t >(Lane::LaneType::Driving)) const
========================================================================
std::unique_ptr< geom::Mesh > SDFToMesh(const road::Junction &jinput, const std::vector< geom::Vector3D > &sdfinput, int grid_cells_per_dim) const
std::vector< std::pair< geom::Transform, std::string > > GetTreesTransform(const geom::Vector3D &minpos, const geom::Vector3D &maxpos, float distancebetweentrees, float distancefromdrivinglineborder, float s_offset=0) const
double GetLaneWidth(Waypoint waypoint) const
std::vector< SignalSearchData > GetSignalsInDistance(Waypoint waypoint, double distance, bool stop_at_junction=false) const
从初始路点搜索信号,直到定义的距离。
std::vector< RoadId > FilterRoadsByPosition(const geom::Vector3D &minpos, const geom::Vector3D &maxpos) const
void AddElementToRtreeAndUpdateTransforms(std::vector< Rtree::TreeElement > &rtree_elements, geom::Transform ¤t_transform, Waypoint ¤t_waypoint, Waypoint &next_waypoint)
std::vector< Waypoint > GenerateWaypointsOnRoadEntries(Lane::LaneType lane_type=Lane::LaneType::Driving) const
在每个 lane 的入口处生成路点, 默认是行驶车道类型。
std::vector< geom::Location > GetAllCrosswalkZones() const
返回定义二维区域的位置信息,重复位置表示一个区域结束
std::vector< carla::geom::BoundingBox > GetJunctionsBoundingBoxes() const
boost::optional< Waypoint > GetRight(Waypoint waypoint) const
返回 waypoint 右侧车道的路点。
std::vector< JuncId > FilterJunctionsByPosition(const geom::Vector3D &minpos, const geom::Vector3D &maxpos) const
std::map< road::Lane::LaneType, std::vector< std::unique_ptr< geom::Mesh > > > GenerateRoadsMultithreaded(const carla::geom::MeshFactory &mesh_factory, const std::vector< RoadId > &RoadsID, const size_t index, const size_t number_of_roads_per_thread) const
std::vector< element::LaneMarking > CalculateCrossedLanes(const geom::Location &origin, const geom::Location &destination) const
boost::optional< Waypoint > GetLeft(Waypoint waypoint) const
返回 waypoint 左侧车道的路点。
std::pair< const element::RoadInfoMarkRecord *, const element::RoadInfoMarkRecord * > GetMarkRecord(Waypoint waypoint) const
geom::Mesh GetAllCrosswalkMesh() const
Buids a mesh of all crosswalks based on the OpenDRIVE // 基于OpenDRIVE构建所有人行横道的网格
std::vector< Waypoint > GetNext(Waypoint waypoint, double distance) const
返回距离 waypoint distance 的路点列表, 使得车辆可以驶向这些路点。
Junction * GetJunction(JuncId id)
boost::optional< element::Waypoint > GetWaypoint(const geom::Location &location, int32_t lane_type=static_cast< int32_t >(Lane::LaneType::Driving)) const
void GenerateJunctions(const carla::geom::MeshFactory &mesh_factory, const rpc::OpendriveGenerationParameters ¶ms, const geom::Vector3D &minpos, const geom::Vector3D &maxpos, std::map< road::Lane::LaneType, std::vector< std::unique_ptr< geom::Mesh > > > *juntion_out_mesh_list) const
std::vector< Waypoint > GenerateWaypointsInRoad(RoadId road_id, Lane::LaneType lane_type=Lane::LaneType::Driving) const
在指定道路的每个车道入口处生成路点。
std::vector< std::unique_ptr< geom::Mesh > > GenerateChunkedMesh(const rpc::OpendriveGenerationParameters ¶ms) const
geom::Transform ComputeTransform(Waypoint waypoint) const
std::map< road::Lane::LaneType, std::vector< std::unique_ptr< geom::Mesh > > > GenerateOrderedChunkedMeshInLocations(const rpc::OpendriveGenerationParameters ¶ms, const geom::Vector3D &minpos, const geom::Vector3D &maxpos) const
void GenerateSingleJunction(const carla::geom::MeshFactory &mesh_factory, const JuncId Id, std::map< road::Lane::LaneType, std::vector< std::unique_ptr< geom::Mesh > > > *junction_out_mesh_list) const
std::vector< Waypoint > GenerateWaypoints(double approx_distance) const
在 map 中生成所有路点,路点之间相隔 approx_distance。
std::vector< Waypoint > GetPredecessors(Waypoint waypoint) const
std::vector< Waypoint > GetSuccessors(Waypoint waypoint) const
========================================================================
std::vector< std::unique_ptr< geom::Mesh > > GenerateLineMarkings(const rpc::OpendriveGenerationParameters ¶ms, const geom::Vector3D &minpos, const geom::Vector3D &maxpos, std::vector< std::string > &outinfo) const
float GetZPosInDeformation(float posx, float posy) const
void AddElementToRtree(std::vector< Rtree::TreeElement > &rtree_elements, geom::Transform ¤t_transform, geom::Transform &next_transform, Waypoint ¤t_waypoint, Waypoint &next_waypoint)
std::vector< const element::RoadInfoSignal * > GetAllSignalReferences() const
返回地图中的所有 RoadInfoSignal
std::vector< std::pair< Waypoint, Waypoint > > GetJunctionWaypoints(JuncId id, Lane::LaneType lane_type) const
生成交叉口的路点。
std::unordered_map< road::RoadId, std::unordered_set< road::RoadId > > ComputeJunctionConflicts(JuncId id) const
const Lane & GetLane(Waypoint waypoint) const
========================================================================
geom::Mesh GenerateMesh(const double distance, const float extra_width=0.6f, const bool smooth_junctions=true) const
基于 OpenDRIVE 构建网格
std::vector< const T * > GetInfos() const
std::vector< const T * > GetInfosInRange(const double min_s, const double max_s) const
Lane & GetLaneById(SectionId section_id, LaneId lane_id)
auto GetLaneSections() const
JuncId GetJunctionId() const
LaneSection & GetLaneSectionById(SectionId id)
车道宽度记录:道路上每个交叉部分的车道可以提供多个宽度条目。 每个车道至少必须定义一个条目,除了按照惯例中心车道宽度为零。 每个条目在定义新条目之前都是有效的。如果为一个车道定义了多个条目, 它们必须按...
const geom::CubicPolynomial & GetPolynomial() const
每条车道在道路横截面内可以提供多个道路标记条目。 道路标记信息定义了车道外边界的线条样式。 对于左侧车道,这是左边界;对于右侧车道,这是右边界。 左右车道之间的分隔线样式由零号车道(即中央车道)的道路标...
std::string GetType() const
Mesh MarchCube(Fun3s const &sdf, Rect3 const &domain)
使用 Marching Cube 从给定的有向距离函数重建三角形网格。
bg::model::box< Point3D > Box
Seting for map generation from opendrive without additional geometry