CARLA
 
载入中...
搜索中...
未找到
test_opendrive.cpp
浏览该文件的文档.
1// Copyright (c) 2017 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 "test.h" /// @brief 包含测试相关的头文件(假设用于单元测试或示例代码)。
8#include "OpenDrive.h"/// @brief 包含OpenDrive相关的自定义头文件(可能是封装了OpenDrive解析的类)。
9#include "Random.h"/// @brief 包含随机数生成相关的头文件。
10
11#include <carla/StopWatch.h> /// @brief 包含CARLA的计时器类,用于性能测量。
12#include <carla/ThreadPool.h>/// @brief 包含CARLA的线程池类,用于并行处理任务。
13#include <carla/geom/Location.h>/// @brief 包含地理位置相关的类,如点、向量等。
14#include <carla/geom/Math.h>/// @brief 包含几何数学运算相关的函数和类。
15#include <carla/opendrive/OpenDriveParser.h>/// @brief 包含OpenDrive解析器类,用于解析OpenDrive格式的地图文件。
16#include <carla/road/MapBuilder.h>/// @brief 包含CARLA的路网构建器类,用于构建路网。
17#include <carla/road/element/RoadInfoElevation.h>/// @brief 包含道路高程信息相关的类。
18#include <carla/road/element/RoadInfoGeometry.h>/// @brief 包含道路几何信息相关的类。
19#include <carla/road/element/RoadInfoMarkRecord.h>/// @brief 包含道路标记记录信息相关的类
20#include <carla/road/element/RoadInfoVisitor.h>/// @brief 包含道路信息访问者模式的基类,用于遍历路网元素。
21
22#include <pugixml/pugixml.hpp>/// @brief 包含pugixml库的头文件,用于XML解析和生成。
23
24#include <fstream>/// @brief 包含C++标准库的文件流类,用于文件读写。
25#include <string>/// @brief 包含C++标准库的字符串类。
26
27using namespace carla::road;/// 导入CARLA的路面相关命名空间,包括道路定义和元素。
28using namespace carla::road::element;/// 导入CARLA的路面元素相关的命名空间,包括具体的道路元素定义。
29using namespace carla::geom;/// 导入CARLA的几何相关命名空间,包括位置、方向和形状的定义。
30using namespace carla::opendrive;/// 导入CARLA的OpenDRIVE数据模型相关的命名空间,用于处理道路网络数据。
31using namespace util;/// 导入CARLA的实用工具命名空间,包含常用的功能函数和类。
32/**
33 * @brief 定义了OpenDrive XML文件的基本路径。
34 */
35const std::string BASE_PATH = LIBCARLA_TEST_CONTENT_FOLDER "/OpenDrive/";
36
37// 静态函数,用于测试道路海拔相关情况,接收XML文档和地图(可选)引用
38static void test_road_elevation(const pugi::xml_document &xml, boost::optional<Map>& map) {
39 // 获取XML中"OpenDRIVE"节点
40 pugi::xml_node open_drive_node = xml.child("OpenDRIVE");
41
42 // 遍历"OpenDRIVE"下的"road"节点
43 for (pugi::xml_node road_node : open_drive_node.children("road")) {
44 // 获取道路id
45 RoadId road_id = road_node.attribute("id").as_uint();
46 // 获取此道路下的"elevationProfile"节点们
47 auto elevation_profile_nodes = road_node.children("elevationProfile");
48
49 // 遍历各"elevationProfile"节点
50 for (pugi::xml_node elevation_profile_node : elevation_profile_nodes) {
51 // 统计有效海拔数量的计数器
52 auto total_elevations = 0;
53 // 获取"elevation"节点们
54 auto elevation_nodes = elevation_profile_node.children("elevation");
55 // 计算"elevation"节点总数
56 auto total_elevation_parser = std::distance(elevation_nodes.begin(), elevation_nodes.end());
57
58 // 遍历"elevation"节点
59 for (pugi::xml_node elevation_node : elevation_nodes) {
60 // 获取节点中表示位置的属性值
61 float s = elevation_node.attribute("s").as_float();
62 // 尝试获取地图中对应道路位置的海拔信息
63 const auto elevation = map->GetMap().GetRoad(road_id).GetInfo<RoadInfoElevation>(s);
64 if (elevation != nullptr)
65 ++total_elevations;
66 }// 验证获取到的海拔数量与解析出的节点数量是否一致
67 ASSERT_EQ(total_elevations, total_elevation_parser);
68 }
69 }
70}
71
72
73static void test_geometry(const pugi::xml_document &xml, boost::optional<Map>& map) {
74 pugi::xml_node open_drive_node = xml.child("OpenDRIVE");
75
76 for (pugi::xml_node road_node : open_drive_node.children("road")) {
77 RoadId road_id = road_node.attribute("id").as_uint();
78
79 for (pugi::xml_node plan_view_nodes : road_node.children("planView")) {
80 auto geometries_parser = plan_view_nodes.children("geometry");
81 auto total_geometries_parser = std::distance(geometries_parser.begin(), geometries_parser.end());
82 auto total_geometries = 0;
83 for (pugi::xml_node geometry_node : plan_view_nodes.children("geometry")){
84 float s = geometry_node.attribute("s").as_float();
85 auto geometry = map->GetMap().GetRoad(road_id).GetInfo<RoadInfoGeometry>(s);
86 if (geometry != nullptr)
87 ++total_geometries;
88 }
89 ASSERT_EQ(total_geometries, total_geometries_parser);
90 }
91 }
92}
93
94/// \brief 获取车道节点中所有道路标记的总数,并对比解析得到的道路标记数量。
95///
96/// 该函数遍历给定的车道节点范围,对每个车道节点中的道路标记进行解析和验证。
97/// 它计算了两种道路标记的总数:一种是实际解析得到的道路标记数量,另一种是
98/// 根据道路信息记录验证得到的道路标记数量。
99///
100/// \param lane_nodes 车道节点的范围,这些节点包含了道路标记信息。
101/// \param lane_section 车道段对象,用于获取具体的车道信息。
102/// \return 返回一个包含两个整数的pair,第一个整数是验证得到的道路标记总数,
103/// 第二个整数是解析得到的道路标记总数。
104///
105/// \note 使用Google Test的EXPECT宏进行断言验证。
106///
109 LaneSection& lane_section) {
110 /// 定义一个极小的误差值,用于浮点数比较。
111 constexpr auto error = 1e-5;
112 /// 用于存储验证得到的道路标记总数。
113 auto total_road_mark = 0;
114 /// 用于存储解析得到的道路标记总数。
115 auto total_road_mark_parser = 0;
116 /// 遍历车道节点范围。
117 for (pugi::xml_node lane_node : lane_nodes) {
118
119 auto road_mark_nodes = lane_node.children("roadMark");
120 /// 计算并累加解析得到的道路标记数量。
121 total_road_mark_parser += std::distance(road_mark_nodes.begin(), road_mark_nodes.end());
122 /// 获取当前车道节点的ID。
123 const int lane_id = lane_node.attribute("id").as_int();
124 Lane* lane = nullptr;
125 /// 根据车道ID获取对应的车道对象。
126 lane = lane_section.GetLane(lane_id);
127 /// 断言车道对象不为空。
128 EXPECT_NE(lane, nullptr);
129
130 /// 遍历当前车道节点中的所有道路标记节点。
131 for (pugi::xml_node road_mark_node : road_mark_nodes) {
132 const auto s_offset = road_mark_node.attribute("sOffset").as_double();/// 获取道路标记的sOffset属性值。
133 const auto type = road_mark_node.attribute("type").as_string();/// 获取道路标记的type属性值。
134 const auto material = road_mark_node.attribute("material").as_string();/// 获取道路标记的material属性值。
135 const auto color = road_mark_node.attribute("color").as_string();/// 获取道路标记的color属性值。
136 const auto road_mark = lane->GetInfo<RoadInfoMarkRecord>(lane->GetDistance() + s_offset);/// 根据距离和sOffset获取对应的道路信息记录。
137 /// 如果道路信息记录不为空,则进行验证。
138 if (road_mark != nullptr) {
139 EXPECT_NEAR(lane->GetDistance() + s_offset, road_mark->GetDistance(), error); /// 断言距离误差在允许范围内。
140 EXPECT_EQ(type, road_mark->GetType());/// 断言道路标记类型相同。
141 EXPECT_EQ(material, road_mark->GetMaterial());/// 断言道路标记材料相同。
142 EXPECT_EQ(color, road_mark->GetColor());/// 断言道路标记颜色相同。
143 ++total_road_mark;/// 累加验证得到的道路标记数量。
144 }
145 }
146 }/// 返回一个包含两个整数的pair,分别表示验证和解析得到的道路标记总数。
147 return std::make_pair(total_road_mark, total_road_mark_parser);
148}
149
150/// 定义一个名为test_roads的函数,它接受一个const引用的pugi::xml_document对象和一个boost::optional<Map>对象作为参数
151static void test_roads(const pugi::xml_document &xml, boost::optional<Map>& map) {
152 /// 从XML文档中获取名为"OpenDRIVE"的子节点
153 pugi::xml_node open_drive_node = xml.child("OpenDRIVE");
154
155 // 解析"OpenDRIVE"节点下所有的"road"子节点,并计算它们的数量
156 auto roads_parser = open_drive_node.children("road");
157 auto total_roads_parser = std::distance(roads_parser.begin(), roads_parser.end());
158 auto total_roads = map->GetMap().GetRoads().size();/// 从Map对象中获取当前存储的道路数量。
159 ASSERT_EQ(total_roads, total_roads_parser);///用于验证XML中的道路数量与Map中存储的道路数量是否一致。
160// 遍历每一个"road"节点
161 for (pugi::xml_node road_node : roads_parser) {
162 RoadId road_id = road_node.attribute("id").as_uint();
163// 遍历该道路下的所有"lanes"子节点
164 for (pugi::xml_node lanes_node : road_node.children("lanes")) {
165
166 // 解析"lanes"节点下所有的"laneSection"子节点,并计算它们的数量
167 auto lane_sections_parser = lanes_node.children("laneSection");
168 auto total_lane_sections_parser = std::distance(lane_sections_parser.begin(), lane_sections_parser.end());
169 auto total_lane_sections = map->GetMap().GetRoad(road_id).GetLaneSections().size(); /// 从Map对象中获取当前道路的所有车道段数量
170 ASSERT_EQ(total_lane_sections, total_lane_sections_parser);
171
172 for (pugi::xml_node lane_section_node : lane_sections_parser) {
173
174 // Check total Lanes
175 const double s = lane_section_node.attribute("s").as_double();/// 从"laneSection"节点中获取s属性
176 auto lane_section = map->GetMap().GetRoad(road_id).GetLaneSectionsAt(s); // 从Map对象中获取对应位置的车道段
177 size_t total_lanes = 0u;/// 初始化车道总数为0
178 //遍历车道段中的每一个车道组
179 for (auto it = lane_section.begin(); it != lane_section.end(); ++it) {
180 total_lanes = it->GetLanes().size(); // 更新车道总数为当前车道组中的车道数量
181 }
182 // 解析"laneSection"节点下的"left"、"center"和"right"子节点中的"lane"子节点数量
183 auto left_nodes = lane_section_node.child("left").children("lane");
184 auto center_nodes = lane_section_node.child("center").children("lane");
185 auto right_nodes = lane_section_node.child("right").children("lane");
186 auto total_lanes_parser = std::distance(left_nodes.begin(), left_nodes.end());
187 total_lanes_parser += std::distance(right_nodes.begin(), right_nodes.end());
188 total_lanes_parser += std::distance(center_nodes.begin(), center_nodes.end());
189
190 ASSERT_EQ(total_lanes, total_lanes_parser);//用于验证XML中的车道数量与Map中存储的车道数量是否一致
191
192 // 初始化道路标记总数为0
193 auto total_road_mark = 0;
194 auto total_road_mark_parser = 0;
195 // 遍历车道段中的每一个车道组
196 for (auto it = lane_section.begin(); it != lane_section.end(); ++it) {
197 // 计算左侧、中心和右侧车道中的道路标记总数
198 auto total_left = get_total_road_marks(left_nodes, *it);
199 auto total_center = get_total_road_marks(center_nodes, *it);
200 auto total_right = get_total_road_marks(right_nodes, *it);
201 total_road_mark = total_left.first + total_center.first + total_right.first;
202 total_road_mark_parser = total_left.first + total_center.first + total_right.first;
203 }
204 ASSERT_EQ(total_road_mark, total_road_mark_parser);
205 }
206 }
207 }
208}
209
210// 定义一个测试函数,用于验证XML文档中的交叉路口数据与Map对象中的交叉路口数据是否一致
211static void test_junctions(const pugi::xml_document &xml, boost::optional<Map>& map) {
212 pugi::xml_node open_drive_node = xml.child("OpenDRIVE"); // 从XML文档中获取OpenDRIVE根节点
213
214 // 获取Map对象中的交叉路口集合,并检查XML文档中声明的交叉路口总数是否与Map对象中的一致
215 auto& junctions = map->GetMap().GetJunctions();
216 // 计算XML文档中声明的交叉路口总数
217 auto total_junctions_parser = std::distance(open_drive_node.children("junction").begin(), open_drive_node.children("junction").end());
218 // 使用ASSERT_EQ宏来断言两者数量相等
219 ASSERT_EQ(junctions.size(), total_junctions_parser);
220 // 遍历XML文档中的每一个交叉路口节点
221 for (pugi::xml_node junction_node : open_drive_node.children("junction")) {
222 // 检查当前交叉路口的连接总数是否与XML文档中声明的连接总数一致
223 auto total_connections_parser = std::distance(junction_node.children("connection").begin(), junction_node.children("connection").end());
224 // 从交叉路口节点的id属性中获取交叉路口ID
225 JuncId junction_id = junction_node.attribute("id").as_int();
226 auto& junction = junctions.find(junction_id)->second; // 在Map对象的交叉路口集合中查找对应的交叉路口
227 // 获取当前交叉路口的连接集合
228 auto& connections = junction.GetConnections();
229 // 使用ASSERT_EQ宏来断言两者数量相等
230 ASSERT_EQ(connections.size(), total_connections_parser);
231// 遍历当前交叉路口的每一个连接节点
232 for (pugi::xml_node connection_node : junction_node.children("connection")) {
233 // 检查当前连接的车道链接总数是否与XML文档中声明的车道链接总数一致
234 auto total_lane_links_parser = std::distance(connection_node.children("laneLink").begin(), connection_node.children("laneLink").end());
235 // 从连接节点的id属性中获取连接ID
236 ConId connection_id = connection_node.attribute("id").as_uint();
237 // 在当前交叉路口的连接集合中查找对应的连接
238 auto& connection = connections.find(connection_id)->second;
239 // 获取当前连接的车道链接集合
240 auto& lane_links = connection.lane_links;
241 // 使用ASSERT_EQ宏来断言两者数量相等
242 ASSERT_EQ(lane_links.size(), total_lane_links_parser);
243
244 }
245 }
246}
247// 定义一个名为 test_road_links 的函数,它接受一个 boost::optional<Map> 类型的引用作为参数
248static void test_road_links(boost::optional<Map>& map) {
249
250 // 使用 for 循环遍历 map 中的所有道路
251 for (auto &road : map->GetMap().GetRoads()) {
252 // 对于每条道路,遍历其所有的车道段section
253 for (auto &section : road.second.GetLaneSections()) {
254 // 对于每个车道段,遍历其所有的车道lane
255 for (auto &lane : section.GetLanes()) {
256 // 对于每个车道,检查其所有后续车道next lanes
257 for (auto link : lane.second.GetNextLanes()) {
258 ASSERT_TRUE(link != nullptr);
259 }
260 // 对于每个车道,检查其所有前置车道previous lanes
261 for (auto link : lane.second.GetPreviousLanes()) {
262 ASSERT_TRUE(link != nullptr);// 每个车道都应该有一个有效的前置车道链接
263 }
264 }
265 }
266 }
267}
268// 定义一个测试用例
269TEST(road, parse_files) {
270 // 使用 util::OpenDrive::Load 函数加载文件
271 for (const auto &file : util::OpenDrive::GetAvailableFiles()) {
272 // std::cerr << file << std::endl;
274 // 使用 ASSERT_TRUE 断言来确保 map 不是 nullptr
275 ASSERT_TRUE(map);
276 // print_roads(map, file);
277 }
278}
279
280TEST(road, parse_road_links) {
281 for (const auto &file : util::OpenDrive::GetAvailableFiles()) {
282 // std::cerr << file << std::endl;
284 ASSERT_TRUE(map);
285 test_road_links(map);
286 }
287}
288
289TEST(road, parse_junctions) {
290 for (const auto& file : util::OpenDrive::GetAvailableFiles()) {
292 ASSERT_TRUE(map.has_value());
293
294 const std::string full_path = BASE_PATH + file;
296
297 pugi::xml_parse_result result = xml.load_file( full_path.c_str());
298 ASSERT_TRUE(result);
299
300 test_junctions(xml, map);
301 }
302
303}
304
305TEST(road, parse_road) {
306 for (const auto& file : util::OpenDrive::GetAvailableFiles()) {
308 ASSERT_TRUE(map.has_value());
309
310 const std::string full_path = BASE_PATH + file;
312 pugi::xml_parse_result result = xml.load_file( full_path.c_str());
313 ASSERT_TRUE(result);
314
315 test_roads(xml, map);
316 }
317
318}
319
320TEST(road, parse_road_elevation) {
321 for (const auto& file : util::OpenDrive::GetAvailableFiles()) {
323 ASSERT_TRUE(map.has_value());
324
325 const std::string full_path = BASE_PATH + file;
327 pugi::xml_parse_result result = xml.load_file( full_path.c_str());
328 ASSERT_TRUE(result);
329
330 test_road_elevation(xml, map);
331 }
332
333}
334
335TEST(road, parse_geometry) {
336 for (const auto& file : util::OpenDrive::GetAvailableFiles()) {
338 ASSERT_TRUE(map.has_value());
339
340 const std::string full_path = BASE_PATH + file;
342 pugi::xml_parse_result result = xml.load_file( full_path.c_str());
343 ASSERT_TRUE(result);
344
345 test_geometry(xml, map);
346 }
347
348}
349
350TEST(road, iterate_waypoints) {
351 // 创建一个线程池
353 pool.AsyncRun();
354 // 用于存储异步任务结果的向量
355 std::vector<std::future<void>> results;
356 // 遍历所有可用的OpenDrive文件
357 for (const auto& file : util::OpenDrive::GetAvailableFiles()) {
358 carla::logging::log("Parsing", file);// 日志记录开始解析的文件名
359 // 向线程池提交一个异步任务,任务内容是解析和验证地图
360 results.push_back(pool.Post([file]() {
361 carla::StopWatch stop_watch; // 创建一个计时器,用于测量解析和验证地图所需的时间
362 auto m = OpenDriveParser::Load(util::OpenDrive::Load(file)); // 加载OpenDrive文件并解析为地图
363 ASSERT_TRUE(m.has_value()); // 断言解析成功,m不为空
364 auto &map = *m;
365 // 生成地图的拓扑结构,并断言拓扑不为空
366 const auto topology = map.GenerateTopology();
367 ASSERT_FALSE(topology.empty());
368 auto count = 0u;
369 // 生成地图的轨迹点(waypoints),每个轨迹点间隔0.5米
370 auto waypoints = map.GenerateWaypoints(0.5);
371 ASSERT_FALSE(waypoints.empty());
372 // 随机打乱轨迹点顺序
373 Random::Shuffle(waypoints);
374 // 确定要探索的轨迹点数量,最多2000个
375 const auto number_of_waypoints_to_explore =
376 std::min<size_t>(2000u, waypoints.size());
377 // 遍历选定的轨迹点进行探索
378 for (auto i = 0u; i < number_of_waypoints_to_explore; ++i) {
379 auto wp = waypoints[i];
380 // 计算轨迹点的变换
381 map.ComputeTransform(wp);
382 // 对于非第一个轨迹点,断言它与第一个轨迹点不同
383 if (i != 0u) {
384 ASSERT_NE(wp, waypoints[0u]);
385 }
386 // 遍历当前轨迹点的所有后继轨迹点
387 for (auto &&successor : map.GetSuccessors(wp)) {
388 ASSERT_TRUE(
389 successor.road_id != wp.road_id ||
390 successor.section_id != wp.section_id ||
391 successor.lane_id != wp.lane_id ||
392 successor.s != wp.s);
393 }
394 auto origin = wp;
395 // 从当前轨迹点出发,探索最多200次后续轨迹点
396 for (auto j = 0u; j < 200u; ++j) {
397 // 获取从当前轨迹点出发,在0.0001到150米范围内的后续轨迹点
398 auto next_wps = map.GetNext(origin, Random::Uniform(0.0001, 150.0));
399 if (next_wps.empty()) {
400 break;
401 }
402 // 确定要探索的后续轨迹点数量,最多10个
403 const auto number_of_next_wps_to_explore =
404 std::min<size_t>(10u, next_wps.size());
405 // 随机打乱后续轨迹点顺序
406 Random::Shuffle(next_wps);
407 // 遍历选定的后续轨迹点进行探索
408 for (auto k = 0u; k < number_of_next_wps_to_explore; ++k) {
409 auto next = next_wps[k];
410 ++count;
411 // 断言后续轨迹点与当前轨迹点至少有一个属性不同
412 ASSERT_TRUE(
413 next.road_id != wp.road_id ||
414 next.section_id != wp.section_id ||
415 next.lane_id != wp.lane_id ||
416 next.s != wp.s);
417 // 获取当前后续轨迹点的右侧轨迹点
418 auto right = map.GetRight(next);
419 if (right.has_value()) {
420 ASSERT_EQ(right->road_id, next.road_id);
421 ASSERT_EQ(right->section_id, next.section_id);
422 ASSERT_NE(right->lane_id, next.lane_id);
423 ASSERT_EQ(right->s, next.s);
424 }
425 // 获取当前后续轨迹点的左侧轨迹点
426 auto left = map.GetLeft(next);
427 if (left.has_value()) {
428 // 断言左侧轨迹点与当前后续轨迹点在同一道路和路段,但车道不同
429 ASSERT_EQ(left->road_id, next.road_id);
430 ASSERT_EQ(left->section_id, next.section_id);
431 ASSERT_NE(left->lane_id, next.lane_id);
432 ASSERT_EQ(left->s, next.s);
433 }
434 }
435 origin = next_wps[0u]; // 将下一个探索的起点设置为当前探索的后续轨迹点中的第一个
436 }
437 }
438 ASSERT_GT(count, 0u);// 断言至少探索了一个轨迹点
439 float seconds = 1e-3f * stop_watch.GetElapsedTime(); // 获取解析和验证地图所需的时间,并记录日志
440 carla::logging::log(file, "done in", seconds, "seconds.");
441 }));
442 }
443 // 等待所有异步任务完成
444 for (auto &result : results) {
445 result.get();
446 }
447}
448
449TEST(road, get_waypoint) {
450 // 创建一个线程池
452 // 启动线程池中的异步任务执行
453 pool.AsyncRun();
454 // 创建一个容器来存储异步任务的返回值
455 std::vector<std::future<void>> results;
456 // 遍历所有可用的OpenDrive文件
457 for (const auto& file : util::OpenDrive::GetAvailableFiles()) {
458 carla::logging::log("Parsing", file);
459 results.push_back(pool.Post([file]() {
460 // 创建一个计时器,用于测量任务执行时间
461 carla::StopWatch stop_watch;
462 // 使用OpenDriveParser加载OpenDrive文件
463 auto m = OpenDriveParser::Load(util::OpenDrive::Load(file));
464 ASSERT_TRUE(m.has_value());// 确保地图被成功加载
465 auto &map = *m;// 获取地图的引用
466 // 进行10000次随机位置测试
467 for (auto i = 0u; i < 10'000u; ++i) {
468 const auto location = Random::Location(-500.0f, 500.0f); // 在指定的范围内生成一个随机位置
469 auto owp = map.GetClosestWaypointOnRoad(location); // 在地图上找到离该位置最近的道路点
470 ASSERT_TRUE(owp.has_value());
471 auto &wp = *owp;// 获取道路点的引用
472 // 获取当前道路点的下一个道路点
473 for (auto &next : map.GetNext(wp, 0.5)) {
474 ASSERT_TRUE(
475 next.road_id != wp.road_id ||
476 next.section_id != wp.section_id ||
477 next.lane_id != wp.lane_id ||
478 next.s != wp.s);
479 }
480 // 获取当前道路点的左侧相邻道路点
481 auto left = map.GetLeft(wp);
482 if (left.has_value()) {
483 ASSERT_EQ(left->road_id, wp.road_id);
484 ASSERT_EQ(left->section_id, wp.section_id);
485 ASSERT_NE(left->lane_id, wp.lane_id);
486 ASSERT_EQ(left->s, wp.s);
487 }
488 // 获取当前道路点的右侧相邻道路点
489 auto right = map.GetRight(wp);
490 if (right.has_value()) {
491 ASSERT_EQ(right->road_id, wp.road_id);
492 ASSERT_EQ(right->section_id, wp.section_id);
493 ASSERT_NE(right->lane_id, wp.lane_id);
494 ASSERT_EQ(right->s, wp.s);
495 }
496 }
497 // 计算并记录任务执行时间
498 float seconds = 1e-3f * stop_watch.GetElapsedTime();
499 carla::logging::log(file, "done in", seconds, "seconds.");
500 }));
501 }
502 // 等待所有异步任务完成
503 for (auto &result : results) {
504 result.get();
505 }
506}
基于Boost.Asio的上下文
Definition ThreadPool.h:24
void AsyncRun(size_t worker_threads)
Definition ThreadPool.h:62
std::future< ResultT > Post(FunctorT &&functor)
Definition ThreadPool.h:41
static boost::optional< road::Map > Load(const std::string &opendrive)
Lane * GetLane(const LaneId id)
const T * GetInfo(const double s) const
Definition Lane.h:79
double GetDistance() const
每条车道在道路横截面内可以提供多个道路标记条目。 道路标记信息定义了车道外边界的线条样式。 对于左侧车道,这是左边界;对于右侧车道,这是右边界。 左右车道之间的分隔线样式由零号车道(即中央车道)的道路标...
unsigned int as_uint(unsigned int def=0) const
Definition pugixml.cpp:5368
xml_parse_result load_file(const char *path, unsigned int options=parse_default, xml_encoding encoding=encoding_auto)
Definition pugixml.cpp:7303
xml_node child(const char_t *name) const
Definition pugixml.cpp:5685
xml_object_range< xml_node_iterator > children() const
Definition pugixml.cpp:5620
xml_attribute attribute(const char_t *name) const
Definition pugixml.cpp:5695
static std::vector< std::string > GetAvailableFiles()
static std::string Load(const std::string &filename)
static void log(Args &&... args)
Definition Logging.h:61
OpenDriveʽͼݵռ
Carlaе·عܵռ
int32_t JuncId
Definition RoadTypes.h:23
uint32_t RoadId
Definition RoadTypes.h:20
uint32_t ConId
Definition RoadTypes.h:38
const std::string BASE_PATH
导入CARLA的实用工具命名空间,包含常用的功能函数和类。
static void test_roads(const pugi::xml_document &xml, boost::optional< Map > &map)
定义一个名为test_roads的函数,它接受一个const引用的pugi::xml_document对象和一个boost::optional<Map>对象作为参数
static void test_road_links(boost::optional< Map > &map)
static void test_junctions(const pugi::xml_document &xml, boost::optional< Map > &map)
static void test_road_elevation(const pugi::xml_document &xml, boost::optional< Map > &map)
TEST(road, parse_files)
static auto get_total_road_marks(pugi::xml_object_range< pugi::xml_named_node_iterator > &lane_nodes, LaneSection &lane_section)
获取车道节点中所有道路标记的总数,并对比解析得到的道路标记数量。
static void test_geometry(const pugi::xml_document &xml, boost::optional< Map > &map)