CARLA
 
载入中...
搜索中...
未找到
InMemoryMap.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/Logging.h"
8
11#include <boost/geometry/geometries/box.hpp>
12// 定义在carla命名空间下的traffic_manager命名空间
13namespace carla {
14namespace traffic_manager {
15//为carla::geom命名空间定义别名cg
16 namespace cg = carla::geom;
17 // 引入constants::Map命名空间内的元素到当前作用域
18 using namespace constants::Map;
19// 定义拓扑列表类型
20 using TopologyList = std::vector<std::pair<WaypointPtr, WaypointPtr>>;
21 // 定义原始节点列表类型
22 using RawNodeList = std::vector<WaypointPtr>;
23// InMemoryMap类的构造函数,接受一个WorldMap类型的参数
24// 用于初始化类中的_world_map变量
25 InMemoryMap::InMemoryMap(WorldMap world_map) : _world_map(world_map) {}
26// InMemoryMap类的析构函数
28// 获取给定路点对应的路段ID
29//假设SegmentId类型是std::tuple或者类似可容纳这几个ID的类型
31 return std::make_tuple(wp->GetRoadId(), wp->GetLaneId(), wp->GetSectionId());
32 }
33//获取SimpleWaypoint对应路段
34// 再调用上面的GetSegmentId函数来获取相应的路段ID
36 return GetSegmentId(swp->GetWaypoint());
37 }
38// 获取给定路段ID的后继节点列表(NodeList)
39// 参数说明:
40// segment_id:要查找后继节点的路段ID
41// segment_topology:记录各路段之间的连接拓扑情况
42// segment_map:路段地图
44 const SegmentTopology &segment_topology,
45 const SegmentMap &segment_map) {
46 NodeList result;
47 if (segment_topology.find(segment_id) == segment_topology.end()) {
48 return result;
49 }
50
51 for (const auto &successor_segment_id : segment_topology.at(segment_id).second) {
52 if (segment_map.find(successor_segment_id) == segment_map.end()) {
53 auto successors = GetSuccessors(successor_segment_id, segment_topology, segment_map);
54 result.insert(result.end(), successors.begin(), successors.end());
55 } else {
56 result.emplace_back(segment_map.at(successor_segment_id).front());
57 }
58 }
59 return result;
60 }
61
63 const SegmentTopology &segment_topology,
64 const SegmentMap &segment_map) {
65 NodeList result;
66 if (segment_topology.find(segment_id) == segment_topology.end()) {
67 return result;
68 }
69
70 for (const auto &predecessor_segment_id : segment_topology.at(segment_id).first) {
71 if (segment_map.find(predecessor_segment_id) == segment_map.end()) {
72 auto predecessors = GetPredecessors(predecessor_segment_id, segment_topology, segment_map);
73 result.insert(result.end(), predecessors.begin(), predecessors.end());
74 } else {
75 result.emplace_back(segment_map.at(predecessor_segment_id).back());
76 }
77 }
78 return result;
79 }
80
81 void InMemoryMap::Cook(WorldMap world_map, const std::string& path) {
82 InMemoryMap local_map(world_map);
83 local_map.SetUp();
84 local_map.Save(path);
85 }
86
87 void InMemoryMap::Save(const std::string& path) {
88 std::string filename;
89 if (path.empty()) {
90 filename = this->GetMapName() + ".bin";
91 } else {
92 filename = path;
93 }
94
95 std::ofstream out_file;
96 out_file.open(filename, std::ios::binary);
97 if (!out_file.is_open()) {
98 log_error("Could not open binary file");
99 return;
100 }
101
102 // 将所有记录的总数写入文件中
103 uint32_t total = static_cast<uint32_t>(dense_topology.size());
104 out_file.write(reinterpret_cast<const char *>(&total), sizeof(uint32_t));
105
106 // 创建或记录一些基本的导航点
107 std::unordered_set<uint64_t> used_ids;
108 for (auto& wp: dense_topology) {
109 if (used_ids.find(wp->GetId()) != used_ids.end()) {
110 log_error("Could not generate the binary file. There are repeated waypoints");
111 }
112 CachedSimpleWaypoint cached_wp(wp);
113 cached_wp.Write(out_file);
114
115 used_ids.insert(wp->GetId());
116 }
117
118 out_file.close();
119 return;
120 }
121
122 bool InMemoryMap::Load(const std::vector<uint8_t>& content) {
123 unsigned long pos = 0;
124 std::vector<CachedSimpleWaypoint> cached_waypoints;
125 std::unordered_map<uint64_t, uint32_t> id2index;
126
127 // 读取总记录数
128 uint32_t total;
129 memcpy(&total, &content[pos], sizeof(total));
130 pos += sizeof(total);
131
132 // 读取简单航点
133 for (uint32_t i=0; i < total; i++) {
134 CachedSimpleWaypoint cached_wp;
135 cached_wp.Read(content, pos);
136 cached_waypoints.push_back(cached_wp);
137 id2index.insert({cached_wp.waypoint_id, i});
138
139 WaypointPtr waypoint_ptr = _world_map->GetWaypointXODR(cached_wp.road_id, cached_wp.lane_id, cached_wp.s);
140 SimpleWaypointPtr wp = std::make_shared<SimpleWaypoint>(waypoint_ptr);
141 wp->SetGeodesicGridId(cached_wp.geodesic_grid_id);
142 wp->SetIsJunction(cached_wp.is_junction);
143 wp->SetRoadOption(static_cast<RoadOption>(cached_wp.road_option));
144 dense_topology.push_back(wp);
145 }
146
147 // 连接航点
148 for (uint32_t i=0; i < dense_topology.size(); i++) {
149 auto wp = dense_topology.at(i);
150 auto cached_wp = cached_waypoints.at(i);
151
152 std::vector<SimpleWaypointPtr> next_waypoints;
153 for (auto id : cached_wp.next_waypoints) {
154 next_waypoints.push_back(dense_topology.at(id2index.at(id)));
155 }
156 std::vector<SimpleWaypointPtr> previous_waypoints;
157 for (auto id : cached_wp.previous_waypoints) {
158 previous_waypoints.push_back(dense_topology.at(id2index.at(id)));
159 }
160 wp->SetNextWaypoint(next_waypoints);
161 wp->SetPreviousWaypoint(previous_waypoints);
162 if (cached_wp.next_left_waypoint > 0) {
163 wp->SetLeftWaypoint(dense_topology.at(id2index.at(cached_wp.next_left_waypoint)));
164 }
165 if (cached_wp.next_right_waypoint > 0) {
166 wp->SetRightWaypoint(dense_topology.at(id2index.at(cached_wp.next_right_waypoint)));
167 }
168 }
169
170 // 创建空间树
172
173 return true;
174 }
175
177
178 // 1. 构建路段拓扑(即,定义路段的前驱和后继集合)
179 assert(_world_map != nullptr && "No map reference found.");
180 auto waypoint_topology = _world_map->GetTopology();
181
182 SegmentTopology segment_topology;
183 std::unordered_map<int64_t, std::pair<std::set<crd::RoadId>, std::set<crd::RoadId>>> std_road_connectivity;
184 std::unordered_map<crd::RoadId, bool> is_real_junction;
185
186 for (auto &connection : waypoint_topology) {
187 auto &waypoint = connection.first;
188 auto &successor = connection.second;
189
190 // 设置段落的前驱和后继
191 SegmentId waypoint_segment_id = GetSegmentId(connection.first);
192 SegmentId successor_segment_id = GetSegmentId(connection.second);
193 if (waypoint_segment_id == successor_segment_id){
194 // 如果两个拓扑航点位于同一段,则忽略它们
195 // 这种情况发生在没有后继或前驱连接的车道上
196 continue;
197 }
198 using SegIdVectorPair = std::pair<std::vector<SegmentId>, std::vector<SegmentId>>;
199 SegIdVectorPair &connection_first = segment_topology[waypoint_segment_id];
200 SegIdVectorPair &connection_second = segment_topology[successor_segment_id];
201 connection_first.second.push_back(successor_segment_id);
202 connection_second.first.push_back(waypoint_segment_id);
203
204 // 从路径到标准道路
205 bool waypoint_is_junction = waypoint->IsJunction();
206 bool successor_is_junction = successor->IsJunction();
207 if (waypoint_is_junction && !successor_is_junction) {
208 crd::RoadId path_id = waypoint->GetRoadId();
209 int64_t std_road_id = static_cast<int64_t>(successor->GetRoadId());
210 std_road_id = (successor->GetLaneId() < 0) ? -1 * std_road_id : std_road_id;
211
212 std::set<crd::RoadId> &in_paths = std_road_connectivity[std_road_id].first;
213 in_paths.insert(path_id);
214
215 if (in_paths.size() >= 2) {
216 for (auto &in_path_id: in_paths) {
217 is_real_junction[in_path_id] = true;
218 }
219 }
220 }
221
222 // 从标准道路到小径
223 if (!waypoint_is_junction && successor_is_junction) {
224 crd::RoadId path_id = successor->GetRoadId();
225 int64_t std_road_id = static_cast<int64_t>(waypoint->GetRoadId());
226 std_road_id = (waypoint->GetLaneId() < 0) ? -1 * std_road_id : std_road_id;
227
228 std::set<crd::RoadId> &out_paths = std_road_connectivity[std_road_id].second;
229 out_paths.insert(path_id);
230
231 if (out_paths.size() >= 2) {
232 for (auto &out_path_id: out_paths) {
233 is_real_junction[out_path_id] = true;
234 }
235 }
236 }
237 }
238
239 // 2. 将cc::Map中的原始密集拓扑消费到SimpleWaypoints中
240 SegmentMap segment_map;
241 assert(_world_map != nullptr && "No map reference found.");
242 auto raw_dense_topology = _world_map->GenerateWaypoints(MAP_RESOLUTION);
243 for (auto &waypoint_ptr: raw_dense_topology) {
244 if (waypoint_ptr->GetLaneWidth() > MIN_LANE_WIDTH){
245 // 避免让车辆通过非常狭窄的车道
246 segment_map[GetSegmentId(waypoint_ptr)].emplace_back(std::make_shared<SimpleWaypoint>(waypoint_ptr));
247 }
248 }
249
250 // 3. 处理航点
251 auto distance_squared = [](cg::Location l1, cg::Location l2) {
252 return cg::Math::DistanceSquared(l1, l2);
253 };
254 auto square = [](float input) {return std::pow(input, 2);};
255 auto compare_s = [](const SimpleWaypointPtr &swp1, const SimpleWaypointPtr &swp2) {
256 return (swp1->GetWaypoint()->GetDistance() < swp2->GetWaypoint()->GetDistance());
257 };
258 auto wpt_angle = [](cg::Vector3D l1, cg::Vector3D l2) {
259 return cg::Math::GetVectorAngle(l1, l2);
260 };
261 auto max = [](int16_t x, int16_t y) {
262 return x ^ ((x ^ y) & -(x < y));
263 };
264
265 GeoGridId geodesic_grid_id_counter = -1;
266 for (auto &segment: segment_map) {
267 auto &segment_waypoints = segment.second;
268
269 // 生成测地线网格ID
270 ++geodesic_grid_id_counter;
271
272 // 根据道路方向排序航点
273 std::sort(segment_waypoints.begin(), segment_waypoints.end(), compare_s);
274 auto lane_id = segment_waypoints.front()->GetWaypoint()->GetLaneId();
275 if (lane_id > 0) {
276 std::reverse(segment_waypoints.begin(), segment_waypoints.end());
277 }
278
279 // 如果角度太紧或航点之间的距离太远,则添加更多航点
280 for (std::size_t i = 0; i < segment_waypoints.size() - 1; ++i) {
281 double distance = std::abs(segment_waypoints.at(i)->GetWaypoint()->GetDistance() - segment_waypoints.at(i+1)->GetWaypoint()->GetDistance());
282 double angle = wpt_angle(segment_waypoints.at(i)->GetTransform().GetForwardVector(), segment_waypoints.at(i+1)->GetTransform().GetForwardVector());
283 int16_t angle_splits = static_cast<int16_t>(angle/MAX_WPT_RADIANS);
284 int16_t distance_splits = static_cast<int16_t>((distance*distance)/MAX_WPT_DISTANCE);
285 auto max_splits = max(angle_splits, distance_splits);
286 if (max_splits >= 1) {
287 // 计算我们需要生成多少个航点
288 for (uint16_t j = 0; j < max_splits; ++j) {
289 auto next_waypoints = segment_waypoints.at(i)->GetWaypoint()->GetNext(distance/(max_splits+1));
290 if (next_waypoints.size() != 0) {
291 auto new_waypoint = next_waypoints.front();
292 i++;
293 segment_waypoints.insert(segment_waypoints.begin()+static_cast<int64_t>(i), std::make_shared<SimpleWaypoint>(new_waypoint));
294 } else {
295 // 到达路的尽头
296 break;
297 }
298 }
299 }
300 }
301
302 // 放置段内连接
303 cg::Location grid_edge_location = segment_waypoints.front()->GetLocation();
304 for (std::size_t i = 0; i < segment_waypoints.size() - 1; ++i) {
305 SimpleWaypointPtr current_waypoint = segment_waypoints.at(i);
306 SimpleWaypointPtr next_waypoint = segment_waypoints.at(i+1);
307 // 分配网格ID
308 if (distance_squared(grid_edge_location, current_waypoint->GetLocation()) >
309 square(MAX_GEODESIC_GRID_LENGTH)) {
310 ++geodesic_grid_id_counter;
311 grid_edge_location = current_waypoint->GetLocation();
312 }
313 current_waypoint->SetGeodesicGridId(geodesic_grid_id_counter);
314
315 current_waypoint->SetNextWaypoint({next_waypoint});
316 next_waypoint->SetPreviousWaypoint({current_waypoint});
317
318 }
319 segment_waypoints.back()->SetGeodesicGridId(geodesic_grid_id_counter);
320
321 // 在处理后的密集拓扑中添加简单的航点
322 for (auto swp: segment_waypoints) {
323 // 检查航点是否位于实际的交叉路口
324 auto wpt = swp->GetWaypoint();
325 auto road_id = wpt->GetRoadId();
326 if (wpt->IsJunction() && !is_real_junction.count(road_id)) {
327 swp->SetIsJunction(false);
328 } else {
329 swp->SetIsJunction(swp->GetWaypoint()->IsJunction());
330 }
331
332 dense_topology.push_back(swp);
333 }
334 }
335
337
338 // 放置段间连接
339 for (auto &segment : segment_map) {
340 SegmentId segment_id = segment.first;
341 auto &segment_waypoints = segment.second;
342
343 auto successors = GetSuccessors(segment_id, segment_topology, segment_map);
344 auto predecessors = GetPredecessors(segment_id, segment_topology, segment_map);
345
346 segment_waypoints.front()->SetPreviousWaypoint(predecessors);
347 segment_waypoints.back()->SetNextWaypoint(successors);
348 }
349
350 // 连接车道变更连接
351 for (auto &swp : dense_topology) {
352 if (!swp->CheckJunction()) {
354 }
355 }
356
357 // 连接任何未连接的线段
358 for (auto &swp : dense_topology) {
359 if (swp->GetNextWaypoint().empty()) {
360 auto neighbour = swp->GetRightWaypoint();
361 if (!neighbour) {
362 neighbour = swp->GetLeftWaypoint();
363 }
364
365 if (neighbour) {
366 swp->SetNextWaypoint(neighbour->GetNextWaypoint());
367 for (auto next_waypoint : neighbour->GetNextWaypoint()) {
368 next_waypoint->SetPreviousWaypoint({swp});
369 }
370 }
371 }
372 }
373
374 // 为每个 SimpleWaypoint 指定一个 RoadOption
376 }
377
379 for (auto &simple_waypoint: dense_topology) {
380 if (simple_waypoint != nullptr) {
381 const cg::Location loc = simple_waypoint->GetLocation();
382 Point3D point(loc.x, loc.y, loc.z);
383 rtree.insert(std::make_pair(point, simple_waypoint));
384 }
385 }
386 }
387
389 for (auto &swp : dense_topology) {
390 std::vector<SimpleWaypointPtr> next_waypoints = swp->GetNextWaypoint();
391 std::size_t next_swp_size = next_waypoints.size();
392
393 if (next_swp_size == 0) {
394 // 没有下一个航点意味着这是路的尽头
395 swp->SetRoadOption(RoadOption::RoadEnd);
396 }
397
398 else if (next_swp_size > 1 || (!swp->CheckJunction() && next_waypoints.front()->CheckJunction())) {
399 // 为了确认我们是否真的在一个交叉路口,而不是在高速公路上,我们尝试查看
400 // 如果附近有交通灯、停车标志或让行标志等类型的地标
401 bool found_landmark= false;
402 if (next_swp_size <= 1) {
403
404 auto all_landmarks = swp->GetWaypoint()->GetAllLandmarksInDistance(15.0);
405
406 if (all_landmarks.empty()) {
407 // 未发现地标,这不是一个交叉口
408 swp->SetRoadOption(RoadOption::LaneFollow);
409 } else {
410 for (auto &landmark : all_landmarks) {
411 auto landmark_type = landmark->GetType();
412 if (landmark_type == "1000001" || landmark_type == "206" || landmark_type == "205") {
413 // 我们发现了一个地标
414 found_landmark= true;
415 break;
416 }
417 }
418 if (!found_landmark) {
419 swp->SetRoadOption(RoadOption::LaneFollow);
420 }
421 }
422 }
423
424 // 如果我们确实找到了一个地标,或者在另一种情况下,找到了所有的航点
425 // 在交汇处并分配正确的道路选项
426 if (found_landmark || next_swp_size > 1) {
427 swp->SetRoadOption(RoadOption::LaneFollow);
428 for (auto &next_swp : next_waypoints) {
429 std::vector<SimpleWaypointPtr> traversed_waypoints;
430 SimpleWaypointPtr junction_end_waypoint;
431
432 if (next_swp_size > 1) {
433 junction_end_waypoint = next_swp;
434 } else {
435 junction_end_waypoint = next_waypoints.front();
436 }
437
438 while (junction_end_waypoint->CheckJunction()){
439 traversed_waypoints.push_back(junction_end_waypoint);
440 std::vector<SimpleWaypointPtr> temp = junction_end_waypoint->GetNextWaypoint();
441 if (temp.empty()) {
442 break;
443 }
444 junction_end_waypoint = temp.front();
445 }
446
447 // 计算连接点首尾两点之间的夹角
448 int16_t current_angle = static_cast<int16_t>(traversed_waypoints.front()->GetTransform().rotation.yaw);
449 int16_t junction_end_angle = static_cast<int16_t>(traversed_waypoints.back()->GetTransform().rotation.yaw);
450 int16_t diff_angle = (junction_end_angle - current_angle) % 360;
451 bool straight = (diff_angle < STRAIGHT_DEG && diff_angle > -STRAIGHT_DEG) ||
452 (diff_angle > 360-STRAIGHT_DEG && diff_angle <= 360) ||
453 (diff_angle < -360+STRAIGHT_DEG && diff_angle >= -360);
454 bool right = (diff_angle >= STRAIGHT_DEG && diff_angle <= 180) ||
455 (diff_angle <= -180 && diff_angle >= -360+STRAIGHT_DEG);
456
457 auto assign_option = [](RoadOption ro, std::vector<SimpleWaypointPtr> traversed_waypoints) {
458 for (auto &twp : traversed_waypoints) {
459 twp->SetRoadOption(ro);
460 }
461 };
462
463 // 根据角度分配道路选项
464 if (straight) assign_option(RoadOption::Straight, traversed_waypoints);
465 else if (right) assign_option(RoadOption::Right, traversed_waypoints);
466 else assign_option(RoadOption::Left, traversed_waypoints);
467 }
468 }
469 }
470 else if (next_swp_size == 1 && swp->GetRoadOption() == RoadOption::Void) {
471 swp->SetRoadOption(RoadOption::LaneFollow);
472 }
473 }
474 }
475
477
478 Point3D query_point(loc.x, loc.y, loc.z);
479 std::vector<SpatialTreeEntry> result_1;
480
481 rtree.query(bgi::nearest(query_point, 1), std::back_inserter(result_1));
482
483 SpatialTreeEntry &closest_entry = result_1.front();
484 SimpleWaypointPtr &closest_point = closest_entry.second;
485
486 return closest_point;
487 }
488
489 NodeList InMemoryMap::GetWaypointsInDelta(const cg::Location loc, const uint16_t n_points, const float random_sample) const {
490 Point3D query_point(loc.x, loc.y, loc.z);
491
492 Point3D lower_p1(loc.x + random_sample, loc.y + random_sample, loc.z + Z_DELTA);
493 Point3D lower_p2(loc.x - random_sample, loc.y - random_sample, loc.z - Z_DELTA);
494 Point3D upper_p1(loc.x + random_sample + DELTA, loc.y + random_sample + DELTA, loc.z + Z_DELTA);
495 Point3D upper_p2(loc.x - random_sample - DELTA, loc.y - random_sample - DELTA, loc.z - Z_DELTA);
496
497 Box lower_query_box(lower_p2, lower_p1);
498 Box upper_query_box(upper_p2, upper_p1);
499
500 NodeList result;
501 uint8_t x = 0;
502 for (Rtree::const_query_iterator
503 it = rtree.qbegin(bgi::within(upper_query_box)
504 && !bgi::within(lower_query_box)
505 && bgi::satisfies([&](SpatialTreeEntry const& v) { return !v.second->CheckJunction();}));
506 it != rtree.qend();
507 ++it) {
508 x++;
509 result.push_back(it->second);
510 if (x >= n_points)
511 break;
512 }
513
514 return result;
515 }
516
520
522
523 const WaypointPtr raw_waypoint = reference_waypoint->GetWaypoint();
524 const crd::element::LaneMarking::LaneChange lane_change = raw_waypoint->GetLaneChange();
525
526 /// 检查过境
527 switch(lane_change)
528 {
529 /// 左转航路点仅存在
530 case crd::element::LaneMarking::LaneChange::Left:
531 {
532 const WaypointPtr left_waypoint = raw_waypoint->GetLeft();
533 if (left_waypoint != nullptr &&
534 left_waypoint->GetType() == crd::Lane::LaneType::Driving &&
535 (left_waypoint->GetLaneId() * raw_waypoint->GetLaneId() > 0)) {
536
537 SimpleWaypointPtr closest_simple_waypoint = GetWaypoint(left_waypoint->GetTransform().location);
538 reference_waypoint->SetLeftWaypoint(closest_simple_waypoint);
539 }
540 }
541 break;
542
543 /// 仅显示正确的航路点
544 case crd::element::LaneMarking::LaneChange::Right:
545 {
546 const WaypointPtr right_waypoint = raw_waypoint->GetRight();
547 if(right_waypoint != nullptr &&
548 right_waypoint->GetType() == crd::Lane::LaneType::Driving &&
549 (right_waypoint->GetLaneId() * raw_waypoint->GetLaneId() > 0)) {
550
551 SimpleWaypointPtr closest_simple_waypoint = GetWaypoint(right_waypoint->GetTransform().location);
552 reference_waypoint->SetRightWaypoint(closest_simple_waypoint);
553 }
554 }
555 break;
556
557 /// 左右两侧均显示交通状况
558 case crd::element::LaneMarking::LaneChange::Both:
559 {
560 /// 右转航路点
561 const WaypointPtr right_waypoint = raw_waypoint->GetRight();
562 if (right_waypoint != nullptr &&
563 right_waypoint->GetType() == crd::Lane::LaneType::Driving &&
564 (right_waypoint->GetLaneId() * raw_waypoint->GetLaneId() > 0)) {
565
566 SimpleWaypointPtr closest_simple_waypointR = GetWaypoint(right_waypoint->GetTransform().location);
567 reference_waypoint->SetRightWaypoint(closest_simple_waypointR);
568 }
569
570 /// 左转航路点
571 const WaypointPtr left_waypoint = raw_waypoint->GetLeft();
572 if (left_waypoint != nullptr &&
573 left_waypoint->GetType() == crd::Lane::LaneType::Driving &&
574 (left_waypoint->GetLaneId() * raw_waypoint->GetLaneId() > 0)) {
575
576 SimpleWaypointPtr closest_simple_waypointL = GetWaypoint(left_waypoint->GetTransform().location);
577 reference_waypoint->SetLeftWaypoint(closest_simple_waypointL);
578 }
579 }
580 break;
581
582 /// 无中转航点(左或右)
583 default: break;
584 }
585 }
586
588 assert(_world_map != nullptr && "No map reference found.");
589 return _world_map->GetName();
590 }
591
592 const cc::Map& InMemoryMap::GetMap() const {
593 return *_world_map;
594 }
595
596
597} // namespace traffic_manager
598} // namespace carla
void Read(const std::vector< uint8_t > &content, unsigned long &start)
void Write(std::ofstream &out_file)
此类构建一个离散的本地地图缓存。 使用世界实例化该类并运行SetUp()构造本地地图。
Definition InMemoryMap.h:62
bool Load(const std::vector< uint8_t > &content)
WorldMap _world_map
保存构造函数接收的世界地图对象。
Definition InMemoryMap.h:67
void FindAndLinkLaneChange(SimpleWaypointPtr reference_waypoint)
此方法用于查找和链接车道变更连接。
NodeList GetPredecessors(const SegmentId segment_id, const SegmentTopology &segment_topology, const SegmentMap &segment_map)
static void Cook(WorldMap world_map, const std::string &path)
SegmentId GetSegmentId(const WaypointPtr &wp) const
计算给定路径点的段ID。 ID考虑了OpenDrive的道路ID、车道ID和分段ID。
NodeList GetDenseTopology() const
此方法返回本地缓存中离散样本的完整列表。
void SetUp()
此方法以采样分辨率构建本地地图。
NodeList GetWaypointsInDelta(const cg::Location loc, const uint16_t n_points, const float random_sample) const
此方法返回与自我车辆距离一定范围内的n个路径点。
NodeList GetSuccessors(const SegmentId segment_id, const SegmentTopology &segment_topology, const SegmentMap &segment_map)
SimpleWaypointPtr GetWaypoint(const cg::Location loc) const
此方法返回给定位置上最近的路径点。
Rtree rtree
用于索引和查询路径点的空间二维R树。
Definition InMemoryMap.h:71
NodeList dense_topology
存储所有自定义路径点对象的结构,经过稀疏拓扑插值处理。
Definition InMemoryMap.h:69
void Save(const std::string &path)
uint32_t RoadId
Definition RoadTypes.h:20
static const float MAX_GEODESIC_GRID_LENGTH
Definition Constants.h:99
std::map< SegmentId, std::vector< SimpleWaypointPtr > > SegmentMap
Definition InMemoryMap.h:57
carla::SharedPtr< cc::Waypoint > WaypointPtr
Waypoint的智能指针类型别名。
Definition InMemoryMap.h:45
std::vector< SimpleWaypointPtr > NodeList
Definition InMemoryMap.h:47
bg::model::box< Point3D > Box
Definition InMemoryMap.h:52
bg::model::point< float, 3, bg::cs::cartesian > Point3D
Definition InMemoryMap.h:51
carla::SharedPtr< const cc::Map > WorldMap
Definition InMemoryMap.h:49
std::map< SegmentId, std::pair< std::vector< SegmentId >, std::vector< SegmentId > > > SegmentTopology
Definition InMemoryMap.h:56
std::vector< WaypointPtr > RawNodeList
std::shared_ptr< SimpleWaypoint > SimpleWaypointPtr
std::tuple< crd::RoadId, crd::LaneId, crd::SectionId > SegmentId
Definition InMemoryMap.h:55
std::vector< std::pair< WaypointPtr, WaypointPtr > > TopologyList
std::pair< Point3D, SimpleWaypointPtr > SpatialTreeEntry
Definition InMemoryMap.h:53
CARLA模拟器的主命名空间。
Definition Carla.cpp:139
static void log_error(Args &&... args)
Definition Logging.h:115