CARLA
 
载入中...
搜索中...
未找到
road/Map.cpp
浏览该文件的文档.
1// Copyright (c) 2020 Computer Vision Center (CVC) at the Universitat Autonoma
2// de Barcelona (UAB).
3//
4// This work is licensed under the terms of the MIT license.
5// For a copy, see <https://opensource.org/licenses/MIT>.
6
7#include "carla/road/Map.h" // 导入地图相关的头文件
8#include "carla/Exception.h" // 导入异常处理的头文件
9#include "carla/geom/Math.h" // 导入数学计算相关的头文件
10#include "carla/geom/Vector3D.h" // 导入三维向量相关的头文件
11#include "carla/road/MeshFactory.h" // 导入网格工厂的头文件
12#include "carla/road/Deformation.h" // 导入变形相关的头文件
13#include "carla/road/element/LaneCrossingCalculator.h" // 导入车道交叉计算器的头文件
14#include "carla/road/element/RoadInfoCrosswalk.h" // 导入人行横道信息的头文件
15#include "carla/road/element/RoadInfoElevation.h" // 导入道路高度信息的头文件
16#include "carla/road/element/RoadInfoGeometry.h" // 导入道路几何信息的头文件
17#include "carla/road/element/RoadInfoLaneOffset.h" // 导入车道偏移信息的头文件
18#include "carla/road/element/RoadInfoLaneWidth.h" // 导入车道宽度信息的头文件
19#include "carla/road/element/RoadInfoMarkRecord.h" // 导入道路标记记录信息的头文件
20#include "carla/road/element/RoadInfoSpeed.h" // 导入道路速度信息的头文件
21#include "carla/road/element/RoadInfoSignal.h" // 导入道路信号信息的头文件
22
23#include "marchingcube/MeshReconstruction.h" // 导入网格重建的头文件
24
25#include <vector> // 导入向量库
26#include <unordered_map> // 导入无序映射库
27#include <stdexcept> // 导入标准异常库
28#include <chrono> // 导入时间相关库
29#include <thread> // 导入线程相关库
30#include <iomanip> // 导入格式化输入输出库
31#include <cmath> // 导入数学库
32
33namespace carla {
34namespace road {
35
36 using namespace carla::road::element; // 使用carla::road::element命名空间中的内容
37
38 /// 我们使用这个epsilon值将路径点从车道边缘移动开,以避免浮点精度错误。
39 static constexpr double EPSILON = 10.0 * std::numeric_limits<double>::epsilon();
40
41 // ===========================================================================
42 // -- 静态本地方法 ----------------------------------------------------------
43 // ===========================================================================
44
45 // 合并两个向量
46 template <typename T>
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); // 递归调用合并源和目标
50 }
51 dst.insert(
52 dst.end(), // 在目标向量末尾插入源向量的元素
53 std::make_move_iterator(src.begin()), // 移动源向量的开始迭代器
54 std::make_move_iterator(src.end())); // 移动源向量的结束迭代器
55 return dst; // 返回合并后的向量
56 }
57
58 // 获取车道开始位置的距离
59 static double GetDistanceAtStartOfLane(const Lane &lane) {
60 if (lane.GetId() <= 0) { // 如果车道ID小于等于0
61 return lane.GetDistance() + 10.0 * EPSILON; // 返回距离加上一个小的偏移量
62 } else {
63 return lane.GetDistance() + lane.GetLength() - 10.0 * EPSILON; // 返回距离加上车道长度减去偏移量
64 }
65 }
66
67 // 获取车道结束位置的距离
68 static double GetDistanceAtEndOfLane(const Lane &lane) {
69 if (lane.GetId() > 0) { // 如果车道ID大于0
70 return lane.GetDistance() + 10.0 * EPSILON; // 返回距离加上一个小的偏移量
71 } else {
72 return lane.GetDistance() + lane.GetLength() - 10.0 * EPSILON; // 返回距离加上车道长度减去偏移量
73 }
74 }
75
76 /// 返回每个可行驶车道的路径点 @a lane_section.
77 template <typename FuncT>
78 static void ForEachDrivableLaneImpl(
79 RoadId road_id, // 道路ID
80 const LaneSection &lane_section, // 车道段
81 double distance, // 距离
82 FuncT &&func) { // 函数对象
83 for (const auto &pair : lane_section.GetLanes()) { // 遍历车道
84 const auto &lane = pair.second; // 获取车道
85 if (lane.GetId() == 0) { // 如果车道ID为0,跳过
86 continue;
87 }
88 if ((static_cast<uint32_t>(lane.GetType()) & static_cast<uint32_t>(Lane::LaneType::Driving)) > 0) { // 如果是可驾驶类型的车道
89 std::forward<FuncT>(func)(Waypoint{ // 调用传入的函数
90 road_id, // 道路ID
91 lane_section.GetId(), // 车道段ID
92 lane.GetId(), // 车道ID
93 distance < 0.0 ? GetDistanceAtStartOfLane(lane) : distance}); // 计算距离
94 }
95 }
96 }
97
98 // 遍历指定类型的车道
99 template <typename FuncT>
100 static void ForEachLaneImpl(
101 RoadId road_id, // 道路ID
102 const LaneSection &lane_section, // 车道段
103 double distance, // 距离
104 Lane::LaneType lane_type, // 车道类型
105 FuncT &&func) { // 函数对象
106 for (const auto &pair : lane_section.GetLanes()) { // 遍历车道
107 const auto &lane = pair.second; // 获取车道
108 if (lane.GetId() == 0) { // 如果车道ID为0,跳过
109 continue;
110 }
111 if ((static_cast<int32_t>(lane.GetType()) & static_cast<int32_t>(lane_type)) > 0) { // 如果是指定类型的车道
112 std::forward<FuncT>(func)(Waypoint{ // 调用传入的函数
113 road_id, // 道路ID
114 lane_section.GetId(), // 车道段ID
115 lane.GetId(), // 车道ID
116 distance < 0.0 ? GetDistanceAtStartOfLane(lane) : distance}); // 计算距离
117 }
118 }
119 }
120
121 /// 返回每个可行驶车道的路径点,遍历所有车道段 @a road.
122 template <typename FuncT>
123 static void ForEachDrivableLane(const Road &road, FuncT &&func) {
124 for (const auto &lane_section : road.GetLaneSections()) { // 遍历道路的所有车道段
125 ForEachDrivableLaneImpl( // 调用实现函数
126 road.GetId(), // 道路ID
127 lane_section, // 车道段
128 -1.0, // 在车道起点位置
129 std::forward<FuncT>(func)); // 调用传入的函数
130 }
131 }
132
133 /// 对于每个指定类型的车道,返回该道路的每个车道段的一个航点
134template <typename FuncT>
135static void ForEachLane(const Road &road, Lane::LaneType lane_type, FuncT &&func) {
136 for (const auto &lane_section : road.GetLaneSections()) { // 遍历道路的每个车道段
137 ForEachLaneImpl(
138 road.GetId(), // 获取道路ID
139 lane_section, // 当前车道段
140 -1.0, // 在车道起始位置
141 lane_type, // 指定的车道类型
142 std::forward<FuncT>(func)); // 执行提供的函数
143 }
144}
145
146/// 返回在指定距离上每个可驾驶车道的一个航点
147template <typename FuncT>
148static void ForEachDrivableLaneAt(const Road &road, double distance, FuncT &&func) {
149 for (const auto &lane_section : road.GetLaneSectionsAt(distance)) { // 遍历指定距离的每个车道段
150 ForEachDrivableLaneImpl(
151 road.GetId(), // 获取道路ID
152 lane_section, // 当前车道段
153 distance, // 指定的距离
154 std::forward<FuncT>(func)); // 执行提供的函数
155 }
156}
157
158/// 假定 road_id 和 section_id 是有效的
159static bool IsLanePresent(const MapData &data, Waypoint waypoint) {
160 const auto &section = data.GetRoad(waypoint.road_id).GetLaneSectionById(waypoint.section_id); // 获取指定的车道段
161 return section.ContainsLane(waypoint.lane_id); // 检查车道是否存在
162}
163
164// ===========================================================================
165// -- 地图: 几何 -------------------------------------------------------------
166// ===========================================================================
167
168boost::optional<Waypoint> Map::GetClosestWaypointOnRoad(
169 const geom::Location &pos,
170 int32_t lane_type) const {
171 std::vector<Rtree::TreeElement> query_result =
172 _rtree.GetNearestNeighboursWithFilter(Rtree::BPoint(pos.x, pos.y, pos.z), // 获取与位置最近的邻居节点
173 [&](Rtree::TreeElement const &element) {
174 const Lane &lane = GetLane(element.second.first); // 获取车道
175 return (lane_type & static_cast<int32_t>(lane.GetType())) > 0; // 检查车道类型是否匹配
176 });
177
178 if (query_result.size() == 0) { // 如果没有找到结果
179 return boost::optional<Waypoint>{}; // 返回空的航点
180 }
181
182 Rtree::BSegment segment = query_result.front().first; // 获取最近的线段
183 Rtree::BPoint s1 = segment.first; // 线段的起点
184 Rtree::BPoint s2 = segment.second; // 线段的终点
185 auto distance_to_segment = geom::Math::DistanceSegmentToPoint(pos,
186 geom::Vector3D(s1.get<0>(), s1.get<1>(), s1.get<2>()), // 计算点到线段的距离
187 geom::Vector3D(s2.get<0>(), s2.get<1>(), s2.get<2>()));
188
189 Waypoint result_start = query_result.front().second.first; // 最近的起始航点
190 Waypoint result_end = query_result.front().second.second; // 最近的结束航点
191
192 if (result_start.lane_id < 0) { // 如果起始航点的车道ID小于0
193 double delta_s = distance_to_segment.first; // 计算距离差
194 double final_s = result_start.s + delta_s; // 计算最终的s值
195 if (final_s >= result_end.s) { // 如果超出结束航点的s值
196 return result_end; // 返回结束航点
197 } else if (delta_s <= 0) { // 如果距离差小于等于0
198 return result_start; // 返回起始航点
199 } else {
200 return GetNext(result_start, delta_s).front(); // 返回下一个航点
201 }
202 } else { // 如果起始航点的车道ID大于等于0
203 double delta_s = distance_to_segment.first; // 计算距离差
204 double final_s = result_start.s - delta_s; // 计算最终的s值
205 if (final_s <= result_end.s) { // 如果不超过结束航点的s值
206 return result_end; // 返回结束航点
207 } else if (delta_s <= 0) { // 如果距离差小于等于0
208 return result_start; // 返回起始航点
209 } else {
210 return GetNext(result_start, delta_s).front(); // 返回下一个航点
211 }
212 }
213}
214
215boost::optional<Waypoint> Map::GetWaypoint(
216 const geom::Location &pos,
217 int32_t lane_type) const {
218 boost::optional<Waypoint> w = GetClosestWaypointOnRoad(pos, lane_type); // 获取最近的航点
219
220 if (!w.has_value()) { // 如果没有找到航点
221 return w; // 返回空
222 }
223
224 const auto dist = geom::Math::Distance2D(ComputeTransform(*w).location, pos); // 计算输入位置与航点之间的距离
225 const auto lane_width_info = GetLane(*w).GetInfo<RoadInfoLaneWidth>(w->s); // 获取车道宽度信息
226 const auto half_lane_width =
227 lane_width_info->GetPolynomial().Evaluate(w->s) * 0.5; // 计算车道的一半宽度
228
229 if (dist < half_lane_width) { // 如果距离小于半车道宽度
230 return w; // 返回航点
231 }
232
233 return boost::optional<Waypoint>{}; // 否则返回空
234}
235
236boost::optional<Waypoint> Map::GetWaypoint(
237 RoadId road_id,
238 LaneId lane_id,
239 float s) const {
240
241 // 用已知参数定义航点
242 Waypoint waypoint;
243 waypoint.road_id = road_id; // 设置道路ID
244 waypoint.lane_id = lane_id; // 设置车道ID
245 waypoint.s = s; // 设置s参数
246
247 // 检查道路
248 if (!_data.ContainsRoad(waypoint.road_id)) { // 如果数据中不包含该道路
249 return boost::optional<Waypoint>{}; // 返回空航点
250 }
251 const Road &road = _data.GetRoad(waypoint.road_id); // 获取对应道路
252
253
254// 检查's'的距离
255if (s < 0.0f || s >= road.GetLength()) {
256 return boost::optional<Waypoint>{}; // 如果s不在有效范围内,返回空的Waypoint
257}
258
259// 检查车道段
260bool lane_found = false; // 初始化车道找到标志为false
261for (auto &section : road.GetLaneSectionsAt(s)) { // 遍历道路中指定位置的车道段
262 if (section.ContainsLane(lane_id)) { // 检查当前段是否包含特定车道
263 waypoint.section_id = section.GetId(); // 设置Waypoint的段ID
264 lane_found = true; // 找到车道,标志设为true
265 break; // 结束循环
266 }
267}
268
269// 检查车道ID
270if (!lane_found) { // 如果没有找到车道
271 return boost::optional<Waypoint>{}; // 返回空的Waypoint
272}
273
274return waypoint; // 返回找到的Waypoint
275
276// ===========================================================================
277// -- Map: 地图信息 -----------------------------------------------------------
278// ===========================================================================
279
280// 获取车道类型
281Lane::LaneType Map::GetLaneType(const Waypoint waypoint) const {
282 return GetLane(waypoint).GetType(); // 返回指定Waypoint的车道类型
283}
284
285// 获取车道宽度
286double Map::GetLaneWidth(const Waypoint waypoint) const {
287 const auto s = waypoint.s; // 从Waypoint中获取s值
288
289 const auto &lane = GetLane(waypoint); // 获取对应的车道
290 RELEASE_ASSERT(lane.GetRoad() != nullptr); // 确保车道存在
291 RELEASE_ASSERT(s <= lane.GetRoad()->GetLength()); // 确保s在车道长度范围内
292
293 const auto lane_width_info = lane.GetInfo<RoadInfoLaneWidth>(s); // 获取车道宽度信息
294 RELEASE_ASSERT(lane_width_info != nullptr); // 确保车道宽度信息存在
295
296 return lane_width_info->GetPolynomial().Evaluate(s); // 计算并返回车道宽度
297}
298
299// 获取交叉口ID
300JuncId Map::GetJunctionId(RoadId road_id) const {
301 return _data.GetRoad(road_id).GetJunctionId(); // 返回指定道路的交叉口ID
302}
303
304// 检查是否为交叉口
305bool Map::IsJunction(RoadId road_id) const {
306 return _data.GetRoad(road_id).IsJunction(); // 返回指定道路是否为交叉口
307}
308
309// 获取标记记录
310std::pair<const RoadInfoMarkRecord *, const RoadInfoMarkRecord *>
311 Map::GetMarkRecord(const Waypoint waypoint) const {
312 // 如果车道ID为0,返回一对空指针
313 if (waypoint.lane_id == 0)
314 return std::make_pair(nullptr, nullptr);
315
316 const auto s = waypoint.s; // 从Waypoint中获取s值
317
318 const auto &current_lane = GetLane(waypoint); // 获取当前车道
319 RELEASE_ASSERT(current_lane.GetRoad() != nullptr); // 确保车道存在
320 RELEASE_ASSERT(s <= current_lane.GetRoad()->GetLength()); // 确保s在车道长度范围内
321
322 const auto inner_lane_id = waypoint.lane_id < 0 ?
323 waypoint.lane_id + 1 : // 计算内侧车道ID
324 waypoint.lane_id - 1;
325
326 const auto &inner_lane = current_lane.GetRoad()->GetLaneById(waypoint.section_id, inner_lane_id); // 获取内侧车道
327
328 auto current_lane_info = current_lane.GetInfo<RoadInfoMarkRecord>(s); // 获取当前车道的标记记录
329 auto inner_lane_info = inner_lane.GetInfo<RoadInfoMarkRecord>(s); // 获取内侧车道的标记记录
330
331 return std::make_pair(current_lane_info, inner_lane_info); // 返回一对标记记录
332}
333
334// 获取指定距离内的信号
335std::vector<Map::SignalSearchData> Map::GetSignalsInDistance(
336 Waypoint waypoint, double distance, bool stop_at_junction) const {
337
338 const auto &lane = GetLane(waypoint); // 获取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(); // 计算相对s
342 const double remaining_lane_length = forward ? lane.GetLength() - relative_s : relative_s; // 计算剩余车道长度
343 DEBUG_ASSERT(remaining_lane_length >= 0.0); // 确保剩余长度非负
344
345 auto &road =_data.GetRoad(waypoint.road_id); // 获取对应的道路
346 std::vector<SignalSearchData> result; // 存储结果信号数据的向量
347
348 // 如果减去距离后仍在同一车道,则返回同一Waypoint和额外距离
349 if (distance <= remaining_lane_length) {
350 auto signals = road.GetInfosInRange<RoadInfoSignal>(
351 waypoint.s, waypoint.s + signed_distance); // 在指定范围内获取信号信息
352 for(auto* signal : signals){ // 遍历所有信号
353 double distance_to_signal = 0;
354 if (waypoint.lane_id < 0){ // 判断车道方向
355 distance_to_signal = signal->GetDistance() - waypoint.s; // 计算信号与Waypoint的距离
356 } else {
357 distance_to_signal = waypoint.s - signal->GetDistance(); // 计算信号与Waypoint的距离
358 }
359 // 检查信号是否影响Waypoint
360 bool is_valid = false; // 初始化有效性标志为false
361 for (auto &validity : signal->GetValidities()) { // 遍历信号的有效性范围
362 if (waypoint.lane_id >= validity._from_lane && // 检查Waypoint的lane_id是否在有效范围内
363 waypoint.lane_id <= validity._to_lane) {
364 is_valid = true; // 有效性标志设为true
365 break; // 结束循环
366 }
367 }
368 if(!is_valid){ // 如果信号不有效
369 continue; // 跳过当前循环,继续下一个信号
370}
371if (distance_to_signal == 0) { // 如果信号与Waypoint的距离为0
372 result.emplace_back(SignalSearchData // 添加信号数据到结果中
373 {signal, waypoint, // 将信号和Waypoint放入SignalSearchData结构中
374 distance_to_signal}); // 记录距离为0
375} else {
376 result.emplace_back(SignalSearchData // 添加信号数据到结果中
377 {signal, GetNext(waypoint, distance_to_signal).front(), // 获取下一个Waypoint并存储
378 distance_to_signal}); // 记录与信号的距离
379}
380
381}
382return result; // 返回结果
383
384const double signed_remaining_length = forward ? remaining_lane_length : -remaining_lane_length; // 根据方向设置带符号的剩余长度
385
386//result = road.GetInfosInRange<RoadInfoSignal>(waypoint.s, waypoint.s + signed_remaining_length); // 注释掉的代码:获取信号信息
387
388auto signals = road.GetInfosInRange<RoadInfoSignal>( // 在指定范围内获取信号信息
389 waypoint.s, waypoint.s + signed_remaining_length);
390for(auto* signal : signals){ // 遍历所有信号
391 double distance_to_signal = 0; // 初始化信号与Waypoint的距离
392 if (waypoint.lane_id < 0){ // 判断车道方向
393 distance_to_signal = signal->GetDistance() - waypoint.s; // 计算信号与Waypoint的距离
394 } else {
395 distance_to_signal = waypoint.s - signal->GetDistance(); // 计算信号与Waypoint的距离
396 }
397 // 检查信号是否影响Waypoint
398 bool is_valid = false; // 初始化有效性标志为false
399 for (auto &validity : signal->GetValidities()) { // 遍历信号的有效性范围
400 if (waypoint.lane_id >= validity._from_lane && // 检查Waypoint的lane_id是否在有效范围内
401 waypoint.lane_id <= validity._to_lane) {
402 is_valid = true; // 有效性标志设为true
403 break; // 结束循环
404 }
405 }
406 if(!is_valid){ // 如果信号无效
407 continue; // 跳过当前信号
408 }
409 if (distance_to_signal == 0) { // 如果信号与Waypoint的距离为0
410 result.emplace_back(SignalSearchData // 添加信号数据到结果中
411 {signal, waypoint, // 将信号和Waypoint放入SignalSearchData结构中
412 distance_to_signal}); // 记录距离为0
413 } else {
414 result.emplace_back(SignalSearchData // 添加信号数据到结果中
415 {signal, GetNext(waypoint, distance_to_signal).front(), // 获取下一个Waypoint并存储
416 distance_to_signal}); // 记录与信号的距离
417 }
418}
419
420// 如果剩余车道长度用尽,必须查看后继
421for (auto &successor : GetSuccessors(waypoint)) { // 遍历Waypoint的后继节点
422 if(_data.GetRoad(successor.road_id).IsJunction() && stop_at_junction){ // 如果后继是交叉口并且需要停止
423 continue; // 跳过此后继
424 }
425 auto& sucessor_lane = _data.GetRoad(successor.road_id). // 获取后继车道
426 GetLaneByDistance(successor.s, successor.lane_id);
427 if (successor.lane_id < 0) { // 如果后继车道ID为负
428 successor.s = sucessor_lane.GetDistance(); // 设置后继s为车道的起始距离
429 } else {
430 successor.s = sucessor_lane.GetDistance() + sucessor_lane.GetLength(); // 设置后继s为车道的结束距离
431 }
432 auto sucessor_signals = GetSignalsInDistance( // 获取后继信号在指定距离内的信号
433 successor, distance - remaining_lane_length, stop_at_junction);
434 for(auto& signal : sucessor_signals){ // 遍历后继信号
435 signal.accumulated_s += remaining_lane_length; // 更新累积的s值
436 }
437 result = ConcatVectors(result, sucessor_signals); // 合并结果信号和后继信号
438}
439return result; // 返回结果
440}
441
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; // 获取道路对象
447 auto road_infos = road.GetInfos<element::RoadInfoSignal>(); // 获取道路上的信号信息
448 for(const auto* road_info : road_infos) { // 遍历所有信号信息
449 result.push_back(road_info); // 将信号信息添加到结果向量中
450 }
451 }
452 return result; // 返回所有信号引用
453}
454
455std::vector<LaneMarking> Map::CalculateCrossedLanes( // 计算交叉的车道
456 const geom::Location &origin, // 起点位置
457 const geom::Location &destination) const { // 终点位置
458 return LaneCrossingCalculator::Calculate(*this, origin, destination); // 调用车道交叉计算器计算结果
459}
460
461
462std::vector<geom::Location> Map::GetAllCrosswalkZones() const {
463 std::vector<geom::Location> result; // 存储所有人行横道区域的位置
464
465 for (const auto &pair : _data.GetRoads()) { // 遍历所有道路
466 const auto &road = pair.second; // 获取道路信息
467 std::vector<const RoadInfoCrosswalk *> crosswalks = road.GetInfos<RoadInfoCrosswalk>(); // 获取道路上的人行横道信息
468 if (crosswalks.size() > 0) { // 如果存在人行横道
469 for (auto crosswalk : crosswalks) { // 遍历每个横道
470 std::vector<geom::Location> points; // 存储点的位置
471 Waypoint waypoint; // 创建一个航点
472 geom::Transform base; // 存储基准变换
473 for (const auto &section : road.GetLaneSectionsAt(crosswalk->GetS())) { // 获取横道位置的车道段
474 for (const auto &lane : section.GetLanes()) { // 遍历车道
475 if (lane.first == 0) { // 如果是中心线
476 waypoint.road_id = pair.first; // 设置道路ID
477 waypoint.section_id = section.GetId(); // 设置车道段ID
478 waypoint.lane_id = 0; // 设置车道ID为0(中心车道)
479 waypoint.s = crosswalk->GetS(); // 设置横道的S位置
480 base = ComputeTransform(waypoint); // 计算基准变换
481 }
482 }
483 }
484
485 // 移动到垂直方向('t')
486 geom::Transform pivot = base; // 复制基准变换
487 pivot.rotation.yaw -= geom::Math::ToDegrees<float>(static_cast<float>(crosswalk->GetHeading())); // 调整朝向
488 pivot.rotation.yaw -= 90; // 旋转90度,移动到横道的侧面
489 geom::Vector3D v(static_cast<float>(crosswalk->GetT()), 0.0f, 0.0f); // 创建一个向量
490 pivot.TransformPoint(v); // 转换该点
491 // 恢复支点位置和方向
492 pivot = base; // 恢复为基准变换
493 pivot.location = v; // 设置位置为刚才转换过的位置
494 pivot.rotation.yaw -= geom::Math::ToDegrees<float>(static_cast<float>(crosswalk->GetHeading())); // 再次调整朝向
495
496 // 计算所有的角落
497 for (auto corner : crosswalk->GetPoints()) { // 遍历横道的每一个角落
499 static_cast<float>(corner.u), // 获取角落的u坐标
500 static_cast<float>(corner.v), // 获取角落的v坐标
501 static_cast<float>(corner.z)); // 获取角落的z坐标
502 // 设置宽度以确保与人行道接触(以防有排水沟区域)
503 if (corner.u < 0) { // 如果u坐标小于0
504 v2.x -= 1.0f; // 向左扩展
505 } else { // 如果u坐标大于等于0
506 v2.x += 1.0f; // 向右扩展
507 }
508 pivot.TransformPoint(v2); // 转换角落的位置
509 result.push_back(v2); // 将角落位置添加到结果中
510 }
511 }
512 }
513 }
514 return result; // 返回所有人行横道区域的位置
515}
516
517// ===========================================================================
518// -- Map: 航点生成 ---------------------------------------------------------
519// ===========================================================================
520
521std::vector<Waypoint> Map::GetSuccessors(const Waypoint waypoint) const {
522 const auto &next_lanes = GetLane(waypoint).GetNextLanes(); // 获取下一个车道
523 std::vector<Waypoint> result; // 存储结果
524 result.reserve(next_lanes.size()); // 预留空间
525 for (auto *next_lane : next_lanes) { // 遍历每个下一个车道
526 RELEASE_ASSERT(next_lane != nullptr); // 确保车道不为空
527 const auto lane_id = next_lane->GetId(); // 获取车道ID
528 RELEASE_ASSERT(lane_id != 0); // 确保车道ID有效
529 const auto *section = next_lane->GetLaneSection(); // 获取车道段
530 RELEASE_ASSERT(section != nullptr); // 确保车道段不为空
531 const auto *road = next_lane->GetRoad(); // 获取道路
532 RELEASE_ASSERT(road != nullptr); // 确保道路不为空
533 const auto distance = GetDistanceAtStartOfLane(*next_lane); // 获取下一个车道起始位置的距离
534 result.emplace_back(Waypoint{road->GetId(), section->GetId(), lane_id, distance}); // 添加航点到结果中
535 }
536 return result; // 返回下一个航点
537}
538
539std::vector<Waypoint> Map::GetPredecessors(const Waypoint waypoint) const {
540 const auto &prev_lanes = GetLane(waypoint).GetPreviousLanes(); // 获取前一个车道
541 std::vector<Waypoint> result; // 存储结果
542 result.reserve(prev_lanes.size()); // 预留空间
543 for (auto *next_lane : prev_lanes) { // 遍历每个前一个车道
544 RELEASE_ASSERT(next_lane != nullptr); // 确保车道不为空
545 const auto lane_id = next_lane->GetId(); // 获取车道ID
546 RELEASE_ASSERT(lane_id != 0); // 确保车道ID有效
547 const auto *section = next_lane->GetLaneSection(); // 获取车道段
548 RELEASE_ASSERT(section != nullptr); // 确保车道段不为空
549 const auto *road = next_lane->GetRoad(); // 获取道路
550 RELEASE_ASSERT(road != nullptr); // 确保道路不为空
551 const auto distance = GetDistanceAtEndOfLane(*next_lane); // 获取前一个车道末端位置的距离
552 result.emplace_back(Waypoint{road->GetId(), section->GetId(), lane_id, distance}); // 添加航点到结果中
553 }
554 return result; // 返回前一个航点
555}
556
557std::vector<Waypoint> Map::GetNext(
558 const Waypoint waypoint,
559 const double distance) const {
560 RELEASE_ASSERT(distance > 0.0); // 确保距离大于0
561 if (distance <= EPSILON) { // 如果距离很小(近似为0)
562 return {waypoint}; // 返回当前的waypoint
563 }
564 const auto &lane = GetLane(waypoint); // 获取当前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(); // 计算相对位置s
568 const double remaining_lane_length = forward ? lane.GetLength() - relative_s : relative_s; // 剩余车道长度
569 DEBUG_ASSERT(remaining_lane_length >= 0.0); // 确保剩余车道长度非负
570
571 // 如果在同一车道内,返回增加了距离的waypoint
572 if (distance <= remaining_lane_length) {
573 Waypoint result = waypoint; // 创建结果waypoint
574 result.s += signed_distance; // 更新s值
575 result.s += forward ? -EPSILON : EPSILON; // 调整s值以避免浮点数精度问题
576 RELEASE_ASSERT(result.s > 0.0); // 确保s值大于0
577 return { result }; // 返回结果
578 }
579
580 // 如果没有剩余车道长度,则需要转到后继节点
581 std::vector<Waypoint> result; // 存储结果的vector
582 for (const auto &successor : GetSuccessors(waypoint)) { // 遍历所有后继waypoints
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)); // 递归获取下一个waypoint
588 }
589 return result; // 返回所有找到的waypoints
590 }
591
592 std::vector<Waypoint> Map::GetPrevious(
593 const Waypoint waypoint,
594 const double distance) const {
595 RELEASE_ASSERT(distance > 0.0); // 确保距离大于0
596 if (distance <= EPSILON) { // 如果距离很小(近似为0)
597 return {waypoint}; // 返回当前的waypoint
598 }
599 const auto &lane = GetLane(waypoint); // 获取当前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(); // 计算相对位置s
603 const double remaining_lane_length = forward ? lane.GetLength() - relative_s : relative_s; // 剩余车道长度
604 DEBUG_ASSERT(remaining_lane_length >= 0.0); // 确保剩余车道长度非负
605
606 // 如果在同一车道内,返回增加了距离的waypoint
607 if (distance <= remaining_lane_length) {
608 Waypoint result = waypoint; // 创建结果waypoint
609 result.s += signed_distance; // 更新s值
610 result.s += forward ? -EPSILON : EPSILON; // 调整s值以避免浮点数精度问题
611 RELEASE_ASSERT(result.s > 0.0); // 确保s值大于0
612 return { result }; // 返回结果
613 }
614
615 // 如果没有剩余车道长度,则需要转到前驱节点
616 std::vector<Waypoint> result; // 存储结果的vector
617 for (const auto &successor : GetPredecessors(waypoint)) { // 遍历所有前驱waypoints
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)); // 递归获取前一个waypoint
623 }
624 return result; // 返回所有找到的waypoints
625 }
626
627 boost::optional<Waypoint> Map::GetRight(Waypoint waypoint) const {
628 RELEASE_ASSERT(waypoint.lane_id != 0); // 确保车道ID不为0
629 if (waypoint.lane_id > 0) { // 如果当前车道ID为正
630 ++waypoint.lane_id; // 向右移动到下一个车道
631 } else {
632 --waypoint.lane_id; // 向左移动到下一个车道
633 }
634 return IsLanePresent(_data, waypoint) ? waypoint : boost::optional<Waypoint>{}; // 检查新车道是否存在
635 }
636
637 boost::optional<Waypoint> Map::GetLeft(Waypoint waypoint) const {
638 RELEASE_ASSERT(waypoint.lane_id != 0); // 确保车道ID不为0
639 if (std::abs(waypoint.lane_id) == 1) { // 如果当前车道ID绝对值为1
640 waypoint.lane_id *= -1; // 切换到另一侧的车道
641 } else if (waypoint.lane_id > 0) { // 如果当前车道ID为正
642 --waypoint.lane_id; // 向左移动到下一个车道
643 } else {
644 ++waypoint.lane_id; // 向右移动到下一个车道
645 }
646 return IsLanePresent(_data, waypoint) ? waypoint : boost::optional<Waypoint>{}; // 检查新车道是否存在
647 }
648
649 std::vector<Waypoint> Map::GenerateWaypoints(const double distance) const {
650 RELEASE_ASSERT(distance > 0.0); // 确保距离大于0
651 std::vector<Waypoint> result; // 存储生成的waypoints
652 for (const auto &pair : _data.GetRoads()) { // 遍历所有道路
653 const auto &road = pair.second; // 获取当前道路
654 for (double s = EPSILON; s < (road.GetLength() - EPSILON); s += distance) { // 从0到道路长度生成waypoints
655 ForEachDrivableLaneAt(road, s, [&](auto &&waypoint) { // 对每个可驾驶车道执行操作
656 result.emplace_back(waypoint); // 将waypoint添加到结果中
657 });
658 }
659 }
660 return result; // 返回生成的waypoints
661 }
662
663 std::vector<Waypoint> Map::GenerateWaypointsOnRoadEntries(Lane::LaneType lane_type) const {
664 std::vector<Waypoint> result; // 创建一个空的 Waypoint 向量来存储结果
665 for (const auto &pair : _data.GetRoads()) { // 遍历所有道路
666 const auto &road = pair.second; // 获取当前道路
667 // 右侧车道从 s = 0 开始
668 for (const auto &lane_section : road.GetLaneSectionsAt(0.0)) { // 在 s=0 处获取车道段
669 for (const auto &lane : lane_section.GetLanes()) { // 遍历当前车道段的车道
670 // 仅添加右侧(负值)车道
671 if (lane.first < 0 &&
672 static_cast<int32_t>(lane.second.GetType()) & static_cast<int32_t>(lane_type)) {
673 result.emplace_back(Waypoint{ road.GetId(), lane_section.GetId(), lane.second.GetId(), 0.0 }); // 添加到结果
674 }
675 }
676 }
677 // 左侧车道从 s = max 开始
678 const auto road_len = road.GetLength(); // 获取道路长度
679 for (const auto &lane_section : road.GetLaneSectionsAt(road_len)) { // 在 s=road_len 处获取车道段
680 for (const auto &lane : lane_section.GetLanes()) { // 遍历当前车道段的车道
681 // 仅添加左侧(正值)车道
682 if (lane.first > 0 &&
683 static_cast<int32_t>(lane.second.GetType()) & static_cast<int32_t>(lane_type)) {
684 result.emplace_back(
685 Waypoint{ road.GetId(), lane_section.GetId(), lane.second.GetId(), road_len }); // 添加到结果
686 }
687 }
688 }
689 }
690 return result; // 返回生成的 Waypoint 向量
691}
692
693std::vector<Waypoint> Map::GenerateWaypointsInRoad(
694 RoadId road_id,
695 Lane::LaneType lane_type) const {
696 std::vector<Waypoint> result; // 创建一个空的 Waypoint 向量来存储结果
697 if(_data.GetRoads().count(road_id)) { // 检查道路是否存在
698 const auto &road = _data.GetRoads().at(road_id); // 获取指定道路
699 // 右侧车道从 s = 0 开始
700 for (const auto &lane_section : road.GetLaneSectionsAt(0.0)) { // 在 s=0 处获取车道段
701 for (const auto &lane : lane_section.GetLanes()) { // 遍历当前车道段的车道
702 // 仅添加右侧(负值)车道
703 if (lane.first < 0 &&
704 static_cast<int32_t>(lane.second.GetType()) & static_cast<int32_t>(lane_type)) {
705 result.emplace_back(Waypoint{ road.GetId(), lane_section.GetId(), lane.second.GetId(), 0.0 }); // 添加到结果
706 }
707 }
708 }
709 // 左侧车道从 s = max 开始
710 const auto road_len = road.GetLength(); // 获取道路长度
711 for (const auto &lane_section : road.GetLaneSectionsAt(road_len)) { // 在 s=road_len 处获取车道段
712 for (const auto &lane : lane_section.GetLanes()) { // 遍历当前车道段的车道
713 // 仅添加左侧(正值)车道
714 if (lane.first > 0 &&
715 static_cast<int32_t>(lane.second.GetType()) & static_cast<int32_t>(lane_type)) {
716 result.emplace_back(
717 Waypoint{ road.GetId(), lane_section.GetId(), lane.second.GetId(), road_len }); // 添加到结果
718 }
719 }
720 }
721 }
722 return result; // 返回生成的 Waypoint 向量
723}
724
725std::vector<std::pair<Waypoint, Waypoint>> Map::GenerateTopology() const {
726 std::vector<std::pair<Waypoint, Waypoint>> result; // 创建一个空的 Waypoint 对向量来存储结果
727 for (const auto &pair : _data.GetRoads()) { // 遍历所有道路
728 const auto &road = pair.second; // 获取当前道路
729 ForEachDrivableLane(road, [&](auto &&waypoint) { // 对每个可驾驶车道执行操作
730 auto successors = GetSuccessors(waypoint); // 获取当前 waypoint 的后继 waypoint
731 if (successors.size() == 0) { // 如果没有后继
732 auto distance = static_cast<float>(GetDistanceAtEndOfLane(GetLane(waypoint))); // 获取车道末尾的距离
733 auto last_waypoint = GetWaypoint(waypoint.road_id, waypoint.lane_id, distance); // 获取最后一个 waypoint
734 if (last_waypoint.has_value()) { // 如果存在最后一个 waypoint
735 result.push_back({waypoint, *last_waypoint}); // 添加到结果
736 }
737 } else { // 如果有后继
738 for (auto &&successor : GetSuccessors(waypoint)) { // 遍历所有后继
739 result.push_back({waypoint, successor}); // 添加到结果
740 }
741 }
742 });
743 }
744 return result; // 返回生成的 waypoint 对向量
745}
746
747
748std::vector<std::pair<Waypoint, Waypoint>> Map::GetJunctionWaypoints(JuncId id, Lane::LaneType lane_type) const {
749 std::vector<std::pair<Waypoint, Waypoint>> result; // 存储结果的向量
750 const Junction * junction = GetJunction(id); // 获取指定ID的交叉口
751
752 for(auto &connections : junction->GetConnections()) { // 遍历交叉口的所有连接
753 const Road &road = _data.GetRoad(connections.second.connecting_road); // 获取连接的道路
754 ForEachLane(road, lane_type, [&](auto &&waypoint) { // 对于每条车道
755 const auto& lane = GetLane(waypoint); // 获取车道信息
756 const double final_s = GetDistanceAtEndOfLane(lane); // 计算车道末端的距离
757 Waypoint lane_end(waypoint); // 创建一个新的Waypoint对象
758 lane_end.s = final_s; // 设置新的Waypoint的s值为末端距离
759 result.push_back({waypoint, lane_end}); // 将原Waypoint和末端Waypoint存入结果向量
760 });
761 }
762 return result; // 返回结果
763}
764
765std::unordered_map<road::RoadId, std::unordered_set<road::RoadId>>
767 const float epsilon = 0.0001f; // 设置一个小的误差值,防止数值错误
768 const Junction *junction = GetJunction(id); // 获取指定ID的交叉口
769 std::unordered_map<road::RoadId, std::unordered_set<road::RoadId>> conflicts; // 存储冲突的道路ID
770
771 // 2D类型定义
772 typedef boost::geometry::model::point<float, 2, boost::geometry::cs::cartesian> Point2d; // 定义2D点
773 typedef boost::geometry::model::segment<Point2d> Segment2d; // 定义2D线段
774 typedef boost::geometry::model::box<Rtree::BPoint> Box; // 定义包围盒
775
776 // 计算包围盒范围
777 auto bbox_pos = junction->GetBoundingBox().location; // 获取交叉口的中心位置
778 auto bbox_ext = junction->GetBoundingBox().extent; // 获取交叉口的扩展范围
779 auto min_corner = geom::Vector3D( // 计算最小角点
780 bbox_pos.x - bbox_ext.x,
781 bbox_pos.y - bbox_ext.y,
782 bbox_pos.z - bbox_ext.z - epsilon);
783 auto max_corner = geom::Vector3D( // 计算最大角点
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});
789 auto segments = _rtree.GetIntersections(box); // 获取与包围盒相交的线段
790
791 for (size_t i = 0; i < segments.size(); ++i) { // 遍历所有线段
792 auto &segment1 = segments[i]; // 获取当前线段
793 auto waypoint1 = segment1.second.first; // 获取对应的第一个Waypoint
794 JuncId junc_id1 = _data.GetRoad(waypoint1.road_id).GetJunctionId(); // 获取该Waypoint所在道路的交叉口ID
795 // 只处理在当前交叉口的线段
796 if(junc_id1 != id) {
797 continue; // 如果不在当前交叉口则跳过
798 }
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; // 获取对应的Waypoint
804 JuncId junc_id2 = _data.GetRoad(waypoint2.road_id).GetJunctionId(); // 获取该Waypoint所在道路的交叉口ID
805 // 只处理在当前交叉口的线段
806 if(junc_id2 != id) {
807 continue; // 如果不在当前交叉口则跳过
808 }
809 // 排除同一路径
810 if(waypoint1.road_id == waypoint2.road_id) {
811 continue; // 如果是同一路段则跳过
812 }
813 Segment2d seg2{{segment2.first.first.get<0>(), segment2.first.first.get<1>()}, // 构建第二个线段
814 {segment2.first.second.get<0>(), segment2.first.second.get<1>()}};
815
816 double distance = boost::geometry::distance(seg1, seg2); // 计算两线段之间的距离
817 // 设定距离阈值
818 if(distance > 2.0) {
819 continue; // 如果距离大于2.0则跳过
820 }
821 if(conflicts[waypoint1.road_id].count(waypoint2.road_id) == 0) {
822 conflicts[waypoint1.road_id].insert(waypoint2.road_id); // 记录冲突
823 }
824 if(conflicts[waypoint2.road_id].count(waypoint1.road_id) == 0) {
825 conflicts[waypoint2.road_id].insert(waypoint1.road_id); // 记录冲突
826 }
827 }
828 }
829 return conflicts; // 返回所有冲突
830}
831
832const Lane &Map::GetLane(Waypoint waypoint) const {
833 // 根据给定的Waypoint获取对应的车道
834 return _data.GetRoad(waypoint.road_id).GetLaneById(waypoint.section_id, waypoint.lane_id);
835}
836
837// ===========================================================================
838// -- Map: Private functions -------------------------------------------------
839// ===========================================================================
840
841// 使用线段两端的Waypoints位置将新元素添加到R树元素列表中
843 std::vector<Rtree::TreeElement> &rtree_elements, // R树元素列表
844 geom::Transform &current_transform, // 当前变换
845 geom::Transform &next_transform, // 下一个变换
846 Waypoint &current_waypoint, // 当前Waypoint
847 Waypoint &next_waypoint) { // 下一个Waypoint
848 // 初始化点
849 Rtree::BPoint init =
851 current_transform.location.x,
852 current_transform.location.y,
853 current_transform.location.z);
854 // 结束点
857 next_transform.location.x,
858 next_transform.location.y,
859 next_transform.location.z);
860 // 将线段和相应的Waypoints加入R树元素列表
861 rtree_elements.emplace_back(std::make_pair(Rtree::BSegment(init, end),
862 std::make_pair(current_waypoint, next_waypoint)));
863}
864
865// 使用Waypoints的位置将新元素添加到R树元素列表中,并更新变换
867 std::vector<Rtree::TreeElement> &rtree_elements, // R树元素列表
868 geom::Transform &current_transform, // 当前变换
869 Waypoint &current_waypoint, // 当前Waypoint
870 Waypoint &next_waypoint) { // 下一个Waypoint
871 // 计算下一个Waypoint的变换
872 geom::Transform next_transform = ComputeTransform(next_waypoint);
873 // 添加元素到R树
874 AddElementToRtree(rtree_elements, current_transform, next_transform,
875 current_waypoint, next_waypoint);
876 // 更新当前Waypoint和变换
877 current_waypoint = next_waypoint;
878 current_transform = next_transform;
879}
880
881// 根据车道方向返回几何图形的剩余长度
882double GetRemainingLength(const Lane &lane, double current_s) {
883 if (lane.GetId() < 0) {
884 // 如果车道ID小于0,计算剩余长度
885 return (lane.GetDistance() + lane.GetLength() - current_s);
886 } else {
887 // 如果车道ID大于等于0,返回从当前s到车道起始位置的长度
888 return (current_s - lane.GetDistance());
889 }
890}
891
892// 创建R树
893void Map::CreateRtree() {
894 const double epsilon = 0.000001; // 设置一个小的增量以防止数值误差
895 const double min_delta_s = 1; // 每个段的最小长度为1米
896
897 // 1.8度,曲线中放置线段的最大角度阈值
898 constexpr double angle_threshold = geom::Math::Pi<double>() / 100.0;
899 // 线段的最大长度
900 constexpr double max_segment_length = 100.0;
901
902 // 在每条车道的起始位置生成Waypoints
903 std::vector<Waypoint> topology; // 存储所有Waypoints
904 for (const auto &pair : _data.GetRoads()) { // 遍历所有道路
905 const auto &road = pair.second; // 获取道路信息
906 // 对每条车道进行操作
907 ForEachLane(road, Lane::LaneType::Any, [&](auto &&waypoint) {
908 if(waypoint.lane_id != 0) { // 排除ID为0的车道
909 topology.push_back(waypoint); // 将Waypoint加入到topology中
910 }
911 });
912 }
913}
914
915// 段和路点的容器
916std::vector<Rtree::TreeElement> rtree_elements;
917
918// 遍历所有车道
919for (auto &waypoint : topology) {
920 auto &lane_start_waypoint = waypoint; // 车道起始路点
921
922 auto current_waypoint = lane_start_waypoint; // 当前路点
923
924 const Lane &lane = GetLane(current_waypoint); // 获取当前路点所在的车道
925
926 geom::Transform current_transform = ComputeTransform(current_waypoint); // 计算当前路点的变换
927
928 // 在直线段中节省计算时间
929 if (lane.IsStraight()) { // 如果车道是直的
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) { // 如果增量距离小于阈值
935 continue; // 跳过此轮
936 }
937 auto next = GetNext(current_waypoint, delta_s); // 获取下一个路点
938
939 RELEASE_ASSERT(next.size() == 1); // 确保下一个路点只有一个
940 RELEASE_ASSERT(next.front().road_id == current_waypoint.road_id); // 确保下一个路点在同一路段
941 auto next_waypoint = next.front(); // 下一个路点
942
943 AddElementToRtreeAndUpdateTransforms( // 添加元素到R树并更新变换
944 rtree_elements,
945 current_transform,
946 current_waypoint,
947 next_waypoint);
948 // 到达车道末尾
949 } else {
950 auto next_waypoint = current_waypoint; // 初始化下一个路点
951
952 // 循环直到车道末尾
953 // 按小的s增量前进
954 while (true) {
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); // 更新增量距离
959
960 if (delta_s < epsilon) { // 如果增量距离小于阈值
961 AddElementToRtreeAndUpdateTransforms( // 添加当前路点和下一个路点到R树
962 rtree_elements,
963 current_transform,
964 current_waypoint,
965 next_waypoint);
966 break; // 退出循环
967 }
968
969 auto next = GetNext(next_waypoint, delta_s); // 获取下一个路点
970 if (next.size() != 1 || // 如果下一个路点不止一个或在不同的区段
971 current_waypoint.section_id != next.front().section_id) {
972 AddElementToRtreeAndUpdateTransforms( // 添加当前和下一个路点到R树
973 rtree_elements,
974 current_transform,
975 current_waypoint,
976 next_waypoint);
977 break; // 退出循环
978 }
979
980 next_waypoint = next.front(); // 更新下一个路点
981 geom::Transform next_transform = ComputeTransform(next_waypoint); // 计算下一个路点的变换
982 double angle = geom::Math::GetVectorAngle( // 获取当前和下一个路点的角度
983 current_transform.GetForwardVector(), next_transform.GetForwardVector());
984
985 if (std::abs(angle) > angle_threshold || // 如果角度超过阈值
986 std::abs(current_waypoint.s - next_waypoint.s) > max_segment_length) { // 或者距离超过最大段长度
987 AddElementToRtree( // 将当前和下一个路点的变换添加到R树
988 rtree_elements,
989 current_transform,
990 next_transform,
991 current_waypoint,
992 next_waypoint);
993 current_waypoint = next_waypoint; // 更新当前路点
994 current_transform = next_transform; // 更新当前变换
995 }
996 }
997 }
998}
999
1000// 将段添加到R树
1001_rtree.InsertElements(rtree_elements);
1002
1003Junction* Map::GetJunction(JuncId id) { // 获取交叉口
1004 return _data.GetJunction(id); // 返回指定ID的交叉口
1005}
1006
1007const Junction* Map::GetJunction(JuncId id) const { // 获取交叉口(常量版本)
1008 return _data.GetJunction(id); // 返回指定ID的交叉口
1009}
1010
1011// 生成网格的函数,参数包括距离、额外宽度和是否平滑交叉口
1013 const double distance, // 距离参数
1014 const float extra_width, // 额外宽度参数
1015 const bool smooth_junctions) const { // 是否平滑交叉口的标志
1016 RELEASE_ASSERT(distance > 0.0); // 确保距离大于0
1017 geom::MeshFactory mesh_factory; // 创建网格工厂
1018 geom::Mesh out_mesh; // 输出网格
1019
1020 // 设置路参数
1021 mesh_factory.road_param.resolution = static_cast<float>(distance); // 设置分辨率为给定距离
1022 mesh_factory.road_param.extra_lane_width = extra_width; // 设置额外车道宽度
1023
1024 // 生成交叉口外的道路
1025 for (auto &&pair : _data.GetRoads()) { // 遍历所有道路
1026 const auto &road = pair.second; // 获取当前道路
1027 if (road.IsJunction()) { // 如果是交叉口,跳过
1028 continue; // 继续下一个循环
1029 }
1030 out_mesh += *mesh_factory.Generate(road); // 生成网格并添加到输出网格中
1031 }
1032
1033 // 生成交叉口内的道路并平滑处理
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; // 存储车道网格的指针
1037
1038 // 遍历交叉口的连接
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); // 获取连接的道路
1042
1043 // 遍历每个车道段的车道
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)); // 生成车道网格并添加到列表
1047 }
1048 }
1049 }
1050
1051 // 如果需要平滑交叉口
1052 if(smooth_junctions) {
1053 out_mesh += *mesh_factory.MergeAndSmooth(lane_meshes); // 合并并平滑车道网格
1054 } else {
1055 geom::Mesh junction_mesh; // 创建交叉口网格
1056 for(auto& lane : lane_meshes) { // 遍历车道网格
1057 junction_mesh += *lane; // 将车道网格添加到交叉口网格中
1058 }
1059 out_mesh += junction_mesh; // 将交叉口网格添加到输出网格
1060 }
1061 }
1062
1063 return out_mesh; // 返回生成的网格
1064 }
1065
1066
1067std::vector<std::unique_ptr<geom::Mesh>> Map::GenerateChunkedMesh(
1068 const rpc::OpendriveGenerationParameters& params) const {
1069 geom::MeshFactory mesh_factory(params); // 创建一个网格工厂,用于生成网格
1070 std::vector<std::unique_ptr<geom::Mesh>> out_mesh_list; // 定义输出网格列表
1071
1072 std::unordered_map<JuncId, geom::Mesh> junction_map; // 定义用于存储交叉口网格的哈希映射
1073 for (auto &&pair : _data.GetRoads()) { // 遍历所有道路
1074 const auto &road = pair.second; // 获取当前道路
1075 if (!road.IsJunction()) { // 如果该道路不是交叉口
1076 std::vector<std::unique_ptr<geom::Mesh>> road_mesh_list =
1077 mesh_factory.GenerateAllWithMaxLen(road); // 生成道路的所有网格
1078
1079 // 将生成的道路网格添加到输出网格列表中
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()));
1084 }
1085 }
1086
1087 // 生成交叉口内的道路并进行光滑处理
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; // 获取当前车道
1098 if (lane.GetType() != road::Lane::LaneType::Sidewalk) { // 如果车道不是人行道
1099 lane_meshes.push_back(mesh_factory.Generate(lane)); // 生成车道网格并添加
1100 } else {
1101 sidewalk_lane_meshes.push_back(mesh_factory.Generate(lane)); // 生成人行道网格并添加
1102 }
1103 }
1104 }
1105 }
1106 if(params.smooth_junctions) { // 如果需要光滑处理交叉口
1107 auto merged_mesh = mesh_factory.MergeAndSmooth(lane_meshes); // 合并并光滑车道网格
1108 for(auto& lane : sidewalk_lane_meshes) { // 遍历人行道网格
1109 *merged_mesh += *lane; // 将人行道网格添加到合并网格中
1110 }
1111 out_mesh_list.push_back(std::move(merged_mesh)); // 将合并后的网格添加到输出列表
1112 } else {
1113 std::unique_ptr<geom::Mesh> junction_mesh = std::make_unique<geom::Mesh>(); // 创建新的交叉口网格
1114 for(auto& lane : lane_meshes) { // 遍历车道网格
1115 *junction_mesh += *lane; // 将车道网格添加到交叉口网格中
1116 }
1117 for(auto& lane : sidewalk_lane_meshes) { // 遍历人行道网格
1118 *junction_mesh += *lane; // 将人行道网格添加到交叉口网格中
1119 }
1120 out_mesh_list.push_back(std::move(junction_mesh)); // 将交叉口网格添加到输出列表
1121 }
1122 }
1123
1124 // 找到输出网格的最小和最大位置
1125 auto min_pos = geom::Vector2D(
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); // 更新最小x坐标
1132 min_pos.y = std::min(min_pos.y, vertex.y); // 更新最小y坐标
1133 max_pos.x = std::max(max_pos.x, vertex.x); // 更新最大x坐标
1134 max_pos.y = std::max(max_pos.y, vertex.y); // 更新最大y坐标
1135 }
1136 size_t mesh_amount_x = static_cast<size_t>((max_pos.x - min_pos.x)/params.max_road_length) + 1; // 计算x方向的网格数量
1137 size_t mesh_amount_y = static_cast<size_t>((max_pos.y - min_pos.y)/params.max_road_length) + 1; // 计算y方向的网格数量
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>());
1142 }
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); // 计算x坐标在结果网格中的索引
1146 size_t y_pos = static_cast<size_t>((vertex.y - min_pos.y) / params.max_road_length); // 计算y坐标在结果网格中的索引
1147 *(result[x_pos + mesh_amount_x*y_pos]) += *mesh; // 将当前网格添加到对应的结果网格中
1148 }
1149
1150 return result; // 返回生成的结果网格列表
1151 }
1152
1153 std::map<road::Lane::LaneType , std::vector<std::unique_ptr<geom::Mesh>>>
1155 const geom::Vector3D& minpos,
1156 const geom::Vector3D& maxpos) const
1157{
1158 geom::MeshFactory mesh_factory(params); // 创建一个网格工厂,用于生成网格
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; // 存储交叉口类型对应的网格列表
1161
1162 // 创建一个线程来生成交叉口的网格
1163 std::thread junction_thread(&Map::GenerateJunctions, this, mesh_factory, params,
1164 minpos, maxpos, &junction_out_mesh_list);
1165
1166 // 根据位置过滤需要生成的道路ID
1167 const std::vector<RoadId> RoadsIDToGenerate = FilterRoadsByPosition(minpos, maxpos);
1168
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; // 输出生成道路数量
1176
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]() {
1180 // 生成当前线程的道路网格
1181 std::map<road::Lane::LaneType, std::vector<std::unique_ptr<geom::Mesh>>> Current =
1182 std::move(GenerateRoadsMultithreaded(mesh_factory, RoadsIDToGenerate, i, num_roads_per_thread));
1183
1184 std::lock_guard<std::mutex> guard(write_mutex); // 锁住互斥量以进行安全写入
1185
1186 for (auto&& pair : Current) { // 遍历当前线程生成的网格
1187 if (road_out_mesh_list.find(pair.first) != road_out_mesh_list.end()) { // 检查类型是否已存在
1188 // 如果已存在,合并网格
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()));
1192 } else {
1193 // 如果不存在,直接添加
1194 road_out_mesh_list[pair.first] = std::move(pair.second);
1195 }
1196 }
1197 });
1198 workers.push_back(std::move(new_worker)); // 将新线程添加到工作线程列表中
1199 }
1200
1201 for (size_t i = 0; i < workers.size(); ++i) { // 等待所有工作线程完成
1202 workers[i].join(); // 加入线程
1203 }
1204 workers.clear(); // 清空工作线程列表
1205 for (size_t i = 0; i < workers.size(); ++i) { // 再次检查线程并确保它们已加入
1206 if (workers[i].joinable()) {
1207 workers[i].join(); // 如果可加入则加入
1208 }
1209 }
1210
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()) { // 检查类型是否已存在
1214 // 如果已存在,合并交叉口网格
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()));
1218 } else {
1219 // 如果不存在,直接添加
1220 road_out_mesh_list[pair.first] = std::move(pair.second);
1221 }
1222 }
1223 std::cout << "Generated " << std::to_string(num_roads) << " roads" << std::endl; // 输出生成完成的信息
1224
1225 return road_out_mesh_list; // 返回生成的道路网格列表
1226}
1227
1228
1229 std::vector<std::pair<geom::Transform, std::string>> Map::GetTreesTransform(
1230 const geom::Vector3D& minpos, // 最小位置
1231 const geom::Vector3D& maxpos, // 最大位置
1232 float distancebetweentrees, // 树之间的距离
1233 float distancefromdrivinglineborder, // 从驾驶线边缘的距离
1234 float s_offset) const { // 偏移量
1235
1236 std::vector<std::pair<geom::Transform, std::string>> transforms; // 存储树的变换和类型的向量
1237
1238 const std::vector<RoadId> RoadsIDToGenerate = FilterRoadsByPosition(minpos, maxpos); // 根据位置过滤需要生成的道路ID
1239 for ( RoadId id : RoadsIDToGenerate ) { // 遍历每个需要生成的道路ID
1240 const auto& road = _data.GetRoads().at(id); // 获取对应的道路对象
1241 if (!road.IsJunction()) { // 如果不是交叉口
1242 for (auto &&lane_section : road.GetLaneSections()) { // 遍历道路的车道段
1243 LaneId min_lane = 0; // 初始化最小车道ID
1244 for (auto &pairlane : lane_section.GetLanes()) { // 遍历车道
1245 if (min_lane > pairlane.first && pairlane.second.GetType() == Lane::LaneType::Driving) { // 找到最小的驾驶车道
1246 min_lane = pairlane.first; // 更新最小车道ID
1247 }
1248 }
1249
1250 const road::Lane* lane = lane_section.GetLane(min_lane); // 获取最小车道
1251 if( lane ) { // 如果车道存在
1252 double s_current = lane_section.GetDistance() + s_offset; // 当前距离
1253 const double s_end = lane_section.GetDistance() + lane_section.GetLength(); // 结束距离
1254 while(s_current < s_end){ // 在车道范围内循环
1255 if(lane->GetWidth(s_current) != 0.0f){ // 如果宽度不为零
1256 const auto edges = lane->GetCornerPositions(s_current, 0); // 获取车道边缘位置
1257 if (edges.first == edges.second) continue; // 如果边缘相同,跳过
1258 geom::Vector3D director = edges.second - edges.first; // 计算方向向量
1259 geom::Vector3D treeposition = edges.first - director.MakeUnitVector() * distancefromdrivinglineborder; // 计算树的位置
1260 geom::Transform lanetransform = lane->ComputeTransform(s_current); // 计算车道的变换
1261 geom::Transform treeTransform(treeposition, lanetransform.rotation); // 创建树的变换
1262 const carla::road::element::RoadInfoSpeed* roadinfo = lane->GetInfo<carla::road::element::RoadInfoSpeed>(s_current); // 获取道路信息
1263 if(roadinfo){ // 如果有道路信息
1264 transforms.push_back(std::make_pair(treeTransform, roadinfo->GetType())); // 添加树的变换和类型
1265 }else{ // 如果没有道路信息
1266 transforms.push_back(std::make_pair(treeTransform, "urban")); // 默认类型为“城市”
1267 }
1268 }
1269 s_current += distancebetweentrees; // 更新当前距离,移动到下一个位置
1270 }
1271
1272 }
1273 }
1274 }
1275 }
1276 return transforms; // 返回生成的树的变换和类型
1277 }
1278
1279
1281 geom::Mesh out_mesh; // 创建一个输出网格对象
1282
1283 // 获取当前地图的斑马线顶点
1284 const std::vector<geom::Location> crosswalk_vertex = GetAllCrosswalkZones();
1285 if (crosswalk_vertex.empty()) { // 如果没有斑马线顶点,返回空网格
1286 return out_mesh;
1287 }
1288
1289 // 为斑马线添加材质
1290 out_mesh.AddMaterial("crosswalk");
1291 size_t start_vertex_index = 0; // 起始顶点索引
1292 size_t i = 0; // 当前顶点索引
1293 std::vector<geom::Vector3D> vertices; // 用于存储三角形扇的顶点
1294
1295 // 遍历顶点直到找到重复的顶点,表示三角形扇结束
1296 do {
1297 // 除了第一次迭代 && 三角形扇完成
1298 if (i != 0 && crosswalk_vertex[start_vertex_index] == crosswalk_vertex[i]) {
1299 // 创建实际的三角形扇
1300 out_mesh.AddTriangleFan(vertices);
1301 vertices.clear(); // 清空顶点容器
1302 // 如果 i 到达顶点列表的末尾,结束循环
1303 if (i >= crosswalk_vertex.size() - 1) {
1304 break;
1305 }
1306 start_vertex_index = ++i; // 更新起始顶点索引
1307 }
1308 // 添加新的 Vector3D 顶点到三角形扇
1309 vertices.push_back(crosswalk_vertex[i++]);
1310 } while (i < crosswalk_vertex.size()); // 继续遍历直到所有顶点处理完
1311
1312 out_mesh.EndMaterial(); // 结束当前材质
1313 return out_mesh; // 返回生成的斑马线网格
1314}
1315
1316/// 生成与线标相关的网格列表
1317std::vector<std::unique_ptr<geom::Mesh>> Map::GenerateLineMarkings(
1318 const rpc::OpendriveGenerationParameters& params, // 生成参数
1319 const geom::Vector3D& minpos, // 最小位置
1320 const geom::Vector3D& maxpos, // 最大位置
1321 std::vector<std::string>& outinfo ) const // 输出信息
1322{
1323 std::vector<std::unique_ptr<geom::Mesh>> LineMarks; // 存储线标网格的向量
1324 geom::MeshFactory mesh_factory(params); // 创建网格工厂
1325
1326 // 根据位置筛选要生成的道路ID
1327 const std::vector<RoadId> RoadsIDToGenerate = FilterRoadsByPosition(minpos, maxpos);
1328 for ( RoadId id : RoadsIDToGenerate ) { // 遍历每条道路ID
1329 const auto& road = _data.GetRoads().at(id); // 获取道路对象
1330 if (!road.IsJunction()) { // 如果不是交叉口
1331 mesh_factory.GenerateLaneMarkForRoad(road, LineMarks, outinfo); // 生成道路的线标
1332 }
1333 }
1334
1335 return std::move(LineMarks); // 移动并返回生成的线标网格
1336}
1337
1338
1339 std::vector<carla::geom::BoundingBox> Map::GetJunctionsBoundingBoxes() const {
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; // 定义边界框扩展因子
1344 carla::geom::BoundingBox bb = junction.GetBoundingBox(); // 获取交叉口的边界框
1345 bb.extent *= box_extraextension_factor; // 扩大边界框的范围
1346 returning.push_back(bb); // 将修改后的边界框添加到返回向量中
1347 }
1348 return returning; // 返回所有交叉口的边界框
1349 }
1350
1351 inline float Map::GetZPosInDeformation(float posx, float posy) const {
1352 return geom::deformation::GetZPosInDeformation(posx, posy) + // 获取在变形中的Z坐标
1353 geom::deformation::GetBumpDeformation(posx,posy); // 添加隆起变形的值
1354 }
1355
1356 std::map<road::Lane::LaneType, std::vector<std::unique_ptr<geom::Mesh>>>
1357 Map::GenerateRoadsMultithreaded( const carla::geom::MeshFactory& mesh_factory, // 定义生成道路的多线程函数
1358 const std::vector<RoadId>& RoadsId, // 输入的道路ID向量
1359 const size_t index, const size_t number_of_roads_per_thread) const
1360 {
1361 std::map<road::Lane::LaneType, std::vector<std::unique_ptr<geom::Mesh>>> out; // 输出的道路网格
1362
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(); // 获取道路ID的总数
1366
1367 for (int i = start; i < endoffset && i < end; ++i) { // 遍历当前线程负责的道路
1368 const auto& road = _data.GetRoads().at(RoadsId[i]); // 获取当前道路对象
1369 if (!road.IsJunction()) { // 如果当前道路不是交叉口
1370 mesh_factory.GenerateAllOrderedWithMaxLen(road, out); // 生成该道路的所有网格
1371 }
1372 }
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; // 输出生成的道路范围
1374 return out; // 返回生成的道路网格
1375 }
1376
1377 void Map::GenerateJunctions(const carla::geom::MeshFactory& mesh_factory, // 生成交叉口的函数,接受网格工厂参数
1378 const rpc::OpendriveGenerationParameters& params, // Opendrive生成参数
1379 const geom::Vector3D& minpos, // 最小位置
1380 const geom::Vector3D& maxpos, // 最大位置
1381 std::map<road::Lane::LaneType, // 输出的交叉口网格列表
1382 std::vector<std::unique_ptr<geom::Mesh>>>* junction_out_mesh_list) const {
1383
1384 std::vector<JuncId> JunctionsToGenerate = FilterJunctionsByPosition(minpos, maxpos); // 根据位置过滤交叉口
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; // 互斥锁用于保护共享资源
1393
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]() {
1397 std::map<road::Lane::LaneType, // 本线程内的交叉口列表
1398 std::vector<std::unique_ptr<geom::Mesh>>> junctionsofthisthread;
1399
1400 size_t minimum = 0; // 初始化最小值
1401 if( (i + 1) * num_junctions_per_thread < num_junctions ){ // 如果还有交叉口需要处理
1402 minimum = (i + 1) * num_junctions_per_thread; // 更新最小值
1403 }else{
1404 minimum = num_junctions; // 否则设置为总数量
1405 }
1406 std::cout << "Generating Junctions between " << std::to_string(i * num_junctions_per_thread) << " and " << std::to_string(minimum) << std::endl; // 输出当前线程处理的交叉口范围
1407
1408 for ( size_t junctionindex = i * num_junctions_per_thread; // 遍历本线程处理的交叉口
1409 junctionindex < minimum;
1410 ++junctionindex )
1411 {
1412 GenerateSingleJunction(mesh_factory, JunctionsToGenerate[junctionindex], &junctionsofthisthread); // 生成单个交叉口
1413 }
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()));
1421 } else {
1422 (*junction_out_mesh_list)[pair.first] = std::move(pair.second); // 否则直接移动到输出列表
1423 }
1424 }
1425 });
1426 workers.push_back(std::move(neworker)); // 将新线程添加到线程列表
1427 }
1428
1429 for (size_t i = 0; i < workers.size(); ++i) { // 等待所有线程完成
1430 workers[i].join();
1431 }
1432 workers.clear(); // 清空线程列表
1433 for (size_t i = 0; i < workers.size(); ++i) { // 检查并确保所有线程已加入
1434 if (workers[i].joinable()) {
1435 workers[i].join();
1436 }
1437 }
1438 }
1439
1440 std::vector<JuncId> Map::FilterJunctionsByPosition( const geom::Vector3D& minpos, // 根据位置过滤交叉口的函数
1441 const geom::Vector3D& maxpos ) const {
1442
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() ){ // 遍历所有交叉口
1446 geom::Location junctionLocation = junction.second.GetBoundingBox().location; // 获取交叉口位置
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); // 如果在范围内,添加到返回列表
1450 }
1451 }
1452 std::cout << "To " + std::to_string(ToReturn.size() ) + " junctions " << std::endl; // 输出符合条件的交叉口数量
1453
1454 return ToReturn; // 返回符合条件的交叉口列表
1455 }
1456
1457
1458std::vector<RoadId> Map::FilterRoadsByPosition( const geom::Vector3D& minpos, // 根据位置过滤道路的函数,接受最小和最大位置参数
1459 const geom::Vector3D& maxpos ) const {
1460
1461 std::vector<RoadId> ToReturn; // 存储符合条件的道路ID
1462 std::cout << "Filtered from " + std::to_string(_data.GetRoads().size() ) + " roads " << std::endl; // 输出初始道路数量
1463 for( auto& road : _data.GetRoads() ){ // 遍历所有道路
1464 auto &&lane_section = (*road.second.GetLaneSections().begin()); // 获取道路的第一个车道段
1465 const road::Lane* lane = lane_section.GetLane(-1); // 获取车道段的车道
1466 if( lane ) { // 如果车道存在
1467 const double s_check = lane_section.GetDistance() + lane_section.GetLength() * 0.5; // 计算检查点的位置
1468 geom::Location roadLocation = lane->ComputeTransform(s_check).location; // 获取道路在检查点的位置信息
1469 if( minpos.x < roadLocation.x && roadLocation.x < maxpos.x && // 检查x坐标是否在范围内
1470 minpos.y > roadLocation.y && roadLocation.y > maxpos.y ) { // 检查y坐标是否在范围内
1471 ToReturn.push_back(road.first); // 如果在范围内,添加道路ID到返回列表
1472 }
1473 }
1474 }
1475 std::cout << "To " + std::to_string(ToReturn.size() ) + " roads " << std::endl; // 输出符合条件的道路数量
1476 return ToReturn; // 返回符合条件的道路ID列表
1477}
1478
1479std::unique_ptr<geom::Mesh> Map::SDFToMesh(const road::Junction& jinput, // 定义函数,输入为交叉口和SDF点,以及每个维度的网格单元数
1480 const std::vector<geom::Vector3D>& sdfinput,
1481 int grid_cells_per_dim) const {
1482
1483 int junctionid = jinput.GetId(); // 获取交叉口ID
1484 float box_extraextension_factor = 1.2f; // 定义盒子扩展因子
1485 const double CubeSize = 0.5; // 定义立方体大小
1486 carla::geom::BoundingBox bb = jinput.GetBoundingBox(); // 获取交叉口的边界框
1487 carla::geom::Vector3D MinOffset = bb.location - geom::Location(bb.extent * box_extraextension_factor); // 计算最小偏移
1488 carla::geom::Vector3D MaxOffset = bb.location + geom::Location(bb.extent * box_extraextension_factor); // 计算最大偏移
1489 carla::geom::Vector3D OffsetPerCell = (bb.extent * box_extraextension_factor * 2) / grid_cells_per_dim; // 计算每个网格单元的偏移量
1490
1491 auto junctionsdf = [this, OffsetPerCell, CubeSize, MinOffset, junctionid](MeshReconstruction::Vec3 const& pos) // 定义Lambda函数处理SDF
1492 {
1493 geom::Vector3D worldloc(pos.x, pos.y, pos.z); // 将输入位置转换为世界坐标
1494 boost::optional<element::Waypoint> CheckingWaypoint = GetWaypoint(geom::Location(worldloc), 0x1 << 1); // 获取检查路点
1495 if (CheckingWaypoint) { // 如果找到了检查路点
1496 if (pos.z < 0.2) { // 如果z坐标小于0.2
1497 return 0.0; // 返回0值
1498 } else {
1499 return -abs(pos.z); // 返回负的z坐标绝对值
1500 }
1501 }
1502 boost::optional<element::Waypoint> InRoadWaypoint = GetClosestWaypointOnRoad(geom::Location(worldloc), 0x1 << 1); // 获取道路上的最近路点
1503 geom::Transform InRoadWPTransform = ComputeTransform(*InRoadWaypoint); // 计算该路点的变换
1504
1505 geom::Vector3D director = geom::Location(worldloc) - (InRoadWPTransform.location); // 计算从路点到位置的方向向量
1506 geom::Vector3D laneborder = InRoadWPTransform.location + geom::Location(director.MakeUnitVector() * GetLaneWidth(*InRoadWaypoint) * 0.5f); // 计算车道边界位置
1507
1508 geom::Vector3D Distance = laneborder - worldloc; // 计算当前位置与车道边界的距离
1509 if (Distance.Length2D() < CubeSize * 1.1 && pos.z < 0.2) { // 如果在2D距离内且z坐标小于0.2
1510 return 0.0; // 返回0值
1511 }
1512 return Distance.Length() * -1.0; // 返回距离的负值
1513 };
1514
1515 double gridsizeindouble = grid_cells_per_dim; // 网格大小,单位为双精度浮点数
1516 MeshReconstruction::Rect3 domain; // 定义一个矩形区域
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 }; // 设置区域的大小
1519
1520 MeshReconstruction::Vec3 cubeSize{ CubeSize, CubeSize, 0.2 }; // 定义立方体大小
1521 auto mesh = MeshReconstruction::MarchCube(junctionsdf, domain, cubeSize ); // 使用Marching Cubes算法生成网格
1522 carla::geom::Rotation inverse = bb.rotation; // 获取物体的旋转信息
1523 carla::geom::Vector3D trasltation = bb.location; // 获取物体的位置
1524 geom::Mesh out_mesh; // 创建一个输出网格
1525
1526 for (auto& cv : mesh.vertices) { // 遍历生成的网格顶点
1527 geom::Vector3D newvertex; // 新顶点
1528 newvertex.x = cv.x; // 设置新顶点的x坐标
1529 newvertex.y = cv.y; // 设置新顶点的y坐标
1530 newvertex.z = cv.z; // 设置新顶点的z坐标
1531 out_mesh.AddVertex(newvertex); // 将新顶点添加到输出网格
1532 }
1533
1534 auto finalvertices = out_mesh.GetVertices(); // 获取输出网格的所有顶点
1535 for (auto ct : mesh.triangles) { // 遍历生成的网格三角形
1536 out_mesh.AddIndex(ct[1] + 1); // 添加三角形的第二个顶点索引
1537 out_mesh.AddIndex(ct[0] + 1); // 添加三角形的第一个顶点索引
1538 out_mesh.AddIndex(ct[2] + 1); // 添加三角形的第三个顶点索引
1539 }
1540
1541 for (auto& cv : out_mesh.GetVertices() ) { // 遍历输出网格的顶点
1542 boost::optional<element::Waypoint> CheckingWaypoint = GetWaypoint(geom::Location(cv), 0x1 << 1); // 检查当前顶点是否为路点
1543 if (!CheckingWaypoint) { // 如果不是路点
1544 boost::optional<element::Waypoint> InRoadWaypoint = GetClosestWaypointOnRoad(geom::Location(cv), 0x1 << 1); // 获取离当前顶点最近的路点
1545 geom::Transform InRoadWPTransform = ComputeTransform(*InRoadWaypoint); // 计算路点的变换
1546
1547 geom::Vector3D director = geom::Location(cv) - (InRoadWPTransform.location); // 计算指向路点的方向
1548 geom::Vector3D laneborder = InRoadWPTransform.location + geom::Location(director.MakeUnitVector() * GetLaneWidth(*InRoadWaypoint) * 0.5f); // 计算车道边界位置
1549 cv = laneborder; // 更新顶点位置为车道边界
1550 }
1551 }
1552 return std::make_unique<geom::Mesh>(out_mesh); // 返回生成的网格
1553 }
1554
1555 void Map::GenerateSingleJunction(const carla::geom::MeshFactory& mesh_factory, // 生成单个交叉口
1556 const JuncId Id,
1557 std::map<road::Lane::LaneType, std::vector<std::unique_ptr<geom::Mesh>>>*
1558 junction_out_mesh_list) const {
1559
1560 const auto& junction = _data.GetJunctions().at(Id); // 获取指定ID的交叉口
1561 if (junction.GetConnections().size() > 2) { // 如果交叉口连接超过两个
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; // 存储周边点
1565
1566 auto pmesh = SDFToMesh(junction, perimeterpoints, 75); // 将SDF转换为网格
1567 (*junction_out_mesh_list)[road::Lane::LaneType::Driving].push_back(std::move(pmesh)); // 添加驾驶车道网格
1568
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; // 获取车道信息
1575 if ( lane.GetType() == road::Lane::LaneType::Sidewalk ) { // 如果车道类型是人行道
1576 boost::optional<element::Waypoint> sw = // 获取人行道的路点
1577 GetWaypoint(road.GetId(), lane_pair.first, lane.GetDistance() + (lane.GetLength() * 0.5f));
1578 if( GetWaypoint(ComputeTransform(*sw).location).get_ptr () == nullptr ){ // 如果路点不存在
1579 sidewalk_lane_meshes.push_back(mesh_factory.GenerateSidewalk(lane)); // 生成并添加人行道网格
1580 }
1581 }
1582 }
1583 }
1584 }
1585
1586 std::unique_ptr<geom::Mesh> sidewalk_mesh = std::make_unique<geom::Mesh>(); // 创建人行道网格的智能指针
1587 for (auto& lane : sidewalk_lane_meshes) { // 遍历所有人行道网格
1588 *sidewalk_mesh += *lane; // 将每个人行道网格合并到总的人行道网格中
1589 }
1590 (*junction_out_mesh_list)[road::Lane::LaneType::Sidewalk].push_back(std::move(sidewalk_mesh)); // 将合并的人行道网格添加到输出列表中
1591 } else {
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; // 获取车道信息
1600 if (lane.GetType() != road::Lane::LaneType::Sidewalk) { // 如果车道类型不是人行道
1601 lane_meshes.push_back(mesh_factory.GenerateTesselated(lane)); // 生成并添加车道网格
1602 }
1603 else { // 如果是人行道
1604 sidewalk_lane_meshes.push_back(mesh_factory.GenerateSidewalk(lane)); // 生成并添加人行道网格
1605 }
1606 }
1607 }
1608 }
1609 std::unique_ptr<geom::Mesh> merged_mesh = std::make_unique<geom::Mesh>(); // 创建合并车道网格的智能指针
1610 for (auto& lane : lane_meshes) { // 遍历所有车道网格
1611 *merged_mesh += *lane; // 将每个车道网格合并到总的车道网格中
1612 }
1613 std::unique_ptr<geom::Mesh> sidewalk_mesh = std::make_unique<geom::Mesh>(); // 创建人行道网格的智能指针
1614 for (auto& lane : sidewalk_lane_meshes) { // 遍历所有人行道网格
1615 *sidewalk_mesh += *lane; // 将每个人行道网格合并到总的人行道网格中
1616 }
1617
1618 (*junction_out_mesh_list)[road::Lane::LaneType::Driving].push_back(std::move(merged_mesh)); // 将合并的车道网格添加到输出列表中
1619 (*junction_out_mesh_list)[road::Lane::LaneType::Sidewalk].push_back(std::move(sidewalk_mesh)); // 将合并的人行道网格添加到输出列表中
1620 }
1621 }
1622
1623} // namespace road
1624} // namespace carla
1625
auto end() const noexcept
#define DEBUG_ASSERT(predicate)
Definition Debug.h:68
#define RELEASE_ASSERT(pred)
Definition Debug.h:94
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)
返回两个向量之间的夹角(弧度)
Definition Math.cpp:16
static auto Distance2D(const Vector3D &a, const Vector3D &b)
Definition Math.h:95
static std::pair< float, float > DistanceSegmentToPoint(const Vector3D &p, const Vector3D &v, const Vector3D &w)
计算点到线段的距离 返回一个包含:
Definition Math.cpp:24
Mesh辅助生成器
Definition MeshFactory.h:22
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
生成按顺序排列的道路网格,限制最大长度
网格数据容器、验证器和导出器。
Definition Mesh.h:43
void AddIndex(index_type index)
将索引附加到索引列表。
Definition Mesh.cpp:132
void AddVertex(vertex_type vertex)
将顶点附加到顶点列表。
Definition Mesh.cpp:120
void AddMaterial(const std::string &material_name)
开始将新材质应用到新添加的三角形。
Definition Mesh.cpp:144
void EndMaterial()
停止将材质应用到新添加的三角形。
Definition Mesh.cpp:160
void AddTriangleFan(const std::vector< vertex_type > &vertices)
向网格添加三角形扇形,顶点顺序为逆时针。
Definition Mesh.cpp:107
const std::vector< vertex_type > & GetVertices() const
Definition Mesh.cpp:284
boost::geometry::model::point< float, 3, boost::geometry::cs::cartesian > BPoint
Definition Rtree.h:93
boost::geometry::model::segment< BPoint > BSegment
Definition Rtree.h:94
std::vector< TreeElement > GetNearestNeighboursWithFilter(const Geometry &geometry, Filter filter, size_t number_neighbours=1) const
返回带有用户定义过滤器的最近邻元素。 过滤器接收一个 TreeElement 值作为参数,并且需要 返回一个布尔值以接受或拒绝该值 示例过滤器:[&](Rtree::TreeElement const ...
Definition Rtree.h:115
std::pair< BSegment, std::pair< Waypoint, Waypoint > > TreeElement
Definition Rtree.h:95
std::vector< TreeElement > GetIntersections(const Geometry &geometry) const
返回与指定几何形状相交的线段。 警告:Boost 库没有实现3D线段间的交集计算。
Definition Rtree.h:139
void InsertElements(const std::vector< TreeElement > &elements)
Definition Rtree.h:105
void TransformPoint(Vector3D &in_point) const
将此变换应用于 in_point(先平移然后旋转)。 具体操作是先根据当前的旋转信息对输入点进行旋转操作,然后再根据当前的位置信息进行平移操作,最终将结果赋值回输入点
Vector3D GetForwardVector() const
定义两个嵌套的命名空间:carla和geom。
Vector3D MakeUnitVector() const
JuncId GetId() const
std::unordered_map< ConId, Connection > & GetConnections()
carla::geom::BoundingBox GetBoundingBox() const
SectionId GetId() const
double GetDistance() const
Lane * GetLane(const LaneId id)
bool ContainsLane(LaneId id) const
Definition LaneSection.h:39
bool IsStraight() const
检查几何形状是否是直线
Road * GetRoad() const
const std::vector< Lane * > & GetNextLanes() const
Definition Lane.h:90
double GetWidth(const double s) const
返回给定位置s的车道总宽度
geom::Transform ComputeTransform(const double s) const
const T * GetInfo(const double s) const
Definition Lane.h:79
LaneType
可以作为标志使用
Definition Lane.h:29
LaneType GetType() const
double GetDistance() const
std::pair< geom::Vector3D, geom::Vector3D > GetCornerPositions(const double s, const float extra_width=0.f) const
计算给定位置s的车道边缘位置
LaneId GetId() const
const std::vector< Lane * > & GetPreviousLanes() const
Definition Lane.h:94
double GetLength() const
std::unordered_map< RoadId, Road > & GetRoads()
Definition MapData.cpp:13
Road & GetRoad(const RoadId id)
Definition MapData.cpp:21
bool ContainsRoad(RoadId id) const
Definition MapData.h:48
std::unordered_map< JuncId, Junction > & GetJunctions()
Definition MapData.cpp:17
Junction * GetJunction(JuncId id)
Definition MapData.cpp:29
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 &current_transform, Waypoint &current_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 &params, 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 &params) const
geom::Transform ComputeTransform(Waypoint waypoint) const
std::map< road::Lane::LaneType, std::vector< std::unique_ptr< geom::Mesh > > > GenerateOrderedChunkedMeshInLocations(const rpc::OpendriveGenerationParameters &params, 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 &params, 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 &current_transform, geom::Transform &next_transform, Waypoint &current_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
Definition Road.h:111
std::vector< const T * > GetInfosInRange(const double min_s, const double max_s) const
Definition Road.h:115
double GetLength() const
Lane & GetLaneById(SectionId section_id, LaneId lane_id)
RoadId GetId() const
auto GetLaneSections() const
Definition Road.h:120
JuncId GetJunctionId() const
bool IsJunction() const
LaneSection & GetLaneSectionById(SectionId id)
Definition Road.h:160
车道宽度记录:道路上每个交叉部分的车道可以提供多个宽度条目。 每个车道至少必须定义一个条目,除了按照惯例中心车道宽度为零。 每个条目在定义新条目之前都是有效的。如果为一个车道定义了多个条目, 它们必须按...
const geom::CubicPolynomial & GetPolynomial() const
每条车道在道路横截面内可以提供多个道路标记条目。 道路标记信息定义了车道外边界的线条样式。 对于左侧车道,这是左边界;对于右侧车道,这是右边界。 左右车道之间的分隔线样式由零号车道(即中央车道)的道路标...
Mesh MarchCube(Fun3s const &sdf, Rect3 const &domain)
使用 Marching Cube 从给定的有向距离函数重建三角形网格。
float GetBumpDeformation(float posx, float posy)
Definition Deformation.h:43
float GetZPosInDeformation(float posx, float posy)
Definition Deformation.h:23
int32_t JuncId
Definition RoadTypes.h:23
int32_t LaneId
Definition RoadTypes.h:26
uint32_t RoadId
Definition RoadTypes.h:20
bg::model::box< Point3D > Box
Definition InMemoryMap.h:52
CARLA模拟器的主命名空间。
Definition Carla.cpp:139
Seting for map generation from opendrive without additional geometry