CARLA
 
载入中...
搜索中...
未找到
RoadParser.cpp
浏览该文件的文档.
1// Copyright (c) 2017 Computer Vision Center (CVC) at the Universitat Autonoma
2// de Barcelona (UAB).
3//
4// 参考:http://hdmap.geomatics.ncku.edu.tw/assets/docs/20200612_TAICS%20TS-0024%20v1.01-%E9%AB%98%E7%B2%BE%E5%9C%B0%E5%9C%96%E5%9C%96%E8%B3%87%E5%85%A7%E5%AE%B9%E5%8F%8A%E6%A0%BC%E5%BC%8F%E6%A8%99%E6%BA%96.pdf
5//
6// This work is licensed under the terms of the MIT license.
7// For a copy, see <https://opensource.org/licenses/MIT>.
8
10
11#include "carla/Logging.h"
12#include "carla/StringUtil.h"
15
16#include <pugixml/pugixml.hpp>
17
18namespace carla {
19namespace opendrive {
20namespace parser {
21
22 using RoadId = road::RoadId;
25
26 // 三次多项式的线性 v_{local} = a + b * du + c * du^2 + d * du^3
27 struct Polynomial {
28 double s;
29 double a, b, c, d;
30 };
31
39
40 struct LaneOffset {
41 double s;
42 double a, b, c, d;
43 };
44
45 struct LaneSection {
46 double s;
47 std::vector<Lane> lanes;
48 };
49
51 // s 表示道路的某个位置(例如,位置坐标),类型为 double。
52 double s;
53
54 // type 表示道路类型的字符串(例如,城市道路、高速公路等),类型为 std::string。
55 std::string type;
56
57 // max 表示该道路类型的最大允许速度,类型为 double。
58 double max;
59
60 // unit 表示速度单位的字符串(例如 "km/h" 或 "m/s"),类型为 std::string。
61 std::string unit;
62 };
63
64
65 struct Road {
66 // id 表示道路的唯一标识符,类型为 RoadId。通常是一个整数或字符串,用于唯一标识一条道路。
68
69 // name 表示道路的名称,类型为 std::string。这个字段存储道路的名字,便于识别。
70 std::string name;
71
72 // length 表示道路的长度,类型为 double。通常单位为米(m)。
73 double length;
74
75 // junction_id 表示道路连接的交叉口的标识符,类型为 JuncId。
76 // 交叉口通常是两个或多个道路相交的地方,这个字段指向该道路所连接的交叉口。
78
79 // predecessor 表示前继道路的标识符,类型为 RoadId。前继道路是指行驶方向上的上一条道路。
81
82 // successor 表示后继道路的标识符,类型为 RoadId。后继道路是指行驶方向上的下一条道路。
84
85 // speed 是一个 std::vector<RoadTypeSpeed>,表示道路上的速度限制信息。
86 // 它包含多个不同类型的速度限制,可能针对不同类型的道路部分设置不同的速度限制。
87 std::vector<RoadTypeSpeed> speed;
88
89 // section_offsets 是一个 std::vector<LaneOffset>,表示道路各车道的偏移量。
90 // 这个字段可以用来表示道路车道的具体位置和相对位置,通常用于精确地图绘制。
91 std::vector<LaneOffset> section_offsets;
92
93 // sections 是一个 std::vector<LaneSection>,表示道路的多个车道段。
94 // 每个车道段可以包含多个车道,车道段的顺序通常对应道路的实际布局或设计。
95 std::vector<LaneSection> sections;
96 };
97
98
99 // 字符串转车道类型
100 static road::Lane::LaneType StringToLaneType(std::string &&str) {
102 if (str == "driving") { // 车道
104 } else if (str == "stop") { // 禁止进入
106 } else if (str == "shoulder") { // 路肩
108 } else if (str == "biking") { // 自行车专用道
110 } else if (str == "sidewalk") { // 人行道
112 } else if (str == "border") { // 边界,车道之间的界限
114 } else if (str == "restricted") { // 限制
116 } else if (str == "parking") { // 路边停车带
118 } else if (str == "bidirectional") { // 双向行驶的车道,通常为狭窄道路的情况
120 } else if (str == "median") { // 中央分隔带
122 } else if (str == "special1") { // 特殊1
124 } else if (str == "special2") { // 特殊2
126 } else if (str == "special3") { // 特殊3
128 } else if (str == "roadworks") { // 道路施工
130 } else if (str == "tram") { // 轻轨电车专用道
132 } else if (str == "rail") { // 铁路
134 } else if (str == "entry") { // 入口
136 } else if (str == "exit") { // 出口
138 } else if (str == "offramp") { // 出口匝道
140 } else if (str == "onramp") { // 入口匝道
142 } else {
144 }
145 }
146
148 const pugi::xml_document &xml,
149 carla::road::MapBuilder &map_builder) {
150
151 std::vector<Road> roads;
152
153 for (pugi::xml_node node_road : xml.child("OpenDRIVE").children("road")) {
154 Road road { 0, "", 0.0, -1, 0, 0, {}, {}, {} };
155
156 // 属性
157 road.id = node_road.attribute("id").as_uint();
158 road.name = node_road.attribute("name").value();
159 road.length = node_road.attribute("length").as_double();
160 road.junction_id = node_road.attribute("junction").as_int();
161
162 // 连接
163 pugi::xml_node link = node_road.child("link");
164 if (link) {
165 if (link.child("predecessor")) {
166 road.predecessor = link.child("predecessor").attribute("elementId").as_uint();
167 }
168 if (link.child("successor")) {
169 road.successor = link.child("successor").attribute("elementId").as_uint();
170 }
171 }
172
173 // 类别
174 for (pugi::xml_node node_type : node_road.children("type")) {
175 RoadTypeSpeed type { 0.0, "", 0.0, "" };
176
177 type.s = node_type.attribute("s").as_double();
178 type.type = node_type.attribute("type").value();
179
180 // 速度类别
181 pugi::xml_node speed = node_type.child("speed");
182 if (speed) {
183 type.max = speed.attribute("max").as_double();
184 type.unit = speed.attribute("unit").value();
185 }
186
187 // 添加它
188 road.speed.emplace_back(type);
189 }
190
191 // section offsets
192 for (pugi::xml_node node_offset : node_road.child("lanes").children("laneOffset")) {
193 LaneOffset offset { 0.0, 0.0, 0.0, 0.0, 0.0 };
194 offset.s = node_offset.attribute("s").as_double();
195 offset.a = node_offset.attribute("a").as_double();
196 offset.b = node_offset.attribute("b").as_double();
197 offset.c = node_offset.attribute("c").as_double();
198 offset.d = node_offset.attribute("d").as_double();
199 road.section_offsets.emplace_back(offset);
200 }
201 // 如果没有找到,则添加默认的车道偏移量
202 if(road.section_offsets.size() == 0) {
203 LaneOffset offset { 0.0, 0.0, 0.0, 0.0, 0.0 };
204 road.section_offsets.emplace_back(offset);
205 }
206
207 // lane sections
208 for (pugi::xml_node node_section : node_road.child("lanes").children("laneSection")) {
209 LaneSection section { 0.0, {} };
210
211 section.s = node_section.attribute("s").as_double();
212
213 // left lanes
214 for (pugi::xml_node node_lane : node_section.child("left").children("lane")) {
215 Lane lane { 0, road::Lane::LaneType::None, false, 0, 0 };
216
217 lane.id = node_lane.attribute("id").as_int();
218 lane.type = StringToLaneType(node_lane.attribute("type").value());
219 lane.level = node_lane.attribute("level").as_bool();
220
221 // link
222 pugi::xml_node link2 = node_lane.child("link");
223 if (link2) {
224 if (link2.child("predecessor")) {
225 lane.predecessor = link2.child("predecessor").attribute("id").as_int();
226 }
227 if (link2.child("successor")) {
228 lane.successor = link2.child("successor").attribute("id").as_int();
229 }
230 }
231
232 // add it
233 section.lanes.emplace_back(lane);
234 }
235
236 // 中央车道
237 for (pugi::xml_node node_lane : node_section.child("center").children("lane")) {
238 Lane lane { 0, road::Lane::LaneType::None, false, 0, 0 };
239
240 lane.id = node_lane.attribute("id").as_int();
241 lane.type = StringToLaneType(node_lane.attribute("type").value());
242 lane.level = node_lane.attribute("level").as_bool();
243
244 // 连接(可能根本不存在)
245 pugi::xml_node link2 = node_lane.child("link");
246 if (link2) {
247 if (link2.child("predecessor")) {
248 lane.predecessor = link2.child("predecessor").attribute("id").as_int();
249 }
250 if (link2.child("successor")) {
251 lane.successor = link2.child("successor").attribute("id").as_int();
252 }
253 }
254
255 // 添加它
256 section.lanes.emplace_back(lane);
257 }
258
259 // right lane
260 for (pugi::xml_node node_lane : node_section.child("right").children("lane")) {
261 Lane lane { 0, road::Lane::LaneType::None, false, 0, 0 };
262
263 lane.id = node_lane.attribute("id").as_int();
264 lane.type = StringToLaneType(node_lane.attribute("type").value());
265 lane.level = node_lane.attribute("level").as_bool();
266
267 // link
268 pugi::xml_node link2 = node_lane.child("link");
269 if (link2) {
270 if (link2.child("predecessor")) {
271 lane.predecessor = link2.child("predecessor").attribute("id").as_int();
272 }
273 if (link2.child("successor")) {
274 lane.successor = link2.child("successor").attribute("id").as_int();
275 }
276 }
277
278 // 添加它
279 section.lanes.emplace_back(lane);
280 }
281
282 // add section
283 road.sections.emplace_back(section);
284 }
285
286 // 添加路
287 roads.emplace_back(road);
288 }
289
290 // test print
291 /*
292 printf("Roads: %d\n", roads.size());
293 for (auto const r : roads) {
294 printf("Road: %d\n", r.id);
295 printf(" Name: %s\n", r.name.c_str());
296 printf(" Length: %e\n", r.length);
297 printf(" JunctionId: %d\n", r.junction_id);
298 printf(" Predecessor: %d\n", r.predecessor);
299 printf(" Successor: %d\n", r.successor);
300 printf(" Speed: %d\n", r.speed.size());
301 for (auto const s : r.speed) {
302 printf(" S offset: %e\n", s.s);
303 printf(" Type: %s\n", s.type.c_str());
304 printf(" Max: %e\n", s.max);
305 printf(" Unit: %s\n", s.unit.c_str());
306 }
307 printf("LaneSections: %d\n", r.sections.size());
308 for (auto const s : r.sections) {
309 printf(" S offset: %e\n", s.s);
310 printf(" a,b,c,d: %e,%e,%e,%e\n", s.a, s.b, s.c, s.d);
311 printf(" Lanes: %d\n", s.lanes.size());
312 for (auto const l : s.lanes) {
313 printf(" Id: %d\n", l.id);
314 printf(" Type: %s\n", l.type.c_str());
315 printf(" Level: %d\n", l.level);
316 printf(" Predecessor: %d\n", l.predecessor);
317 printf(" Successor: %d\n", l.successor);
318 }
319 }
320 }
321 */
322
323 // 调用地图构建器 map_builder
324 for (auto const r : roads) {
325 carla::road::Road *road = map_builder.AddRoad(r.id,
326 r.name,
327 r.length,
328 r.junction_id,
329 r.predecessor,
330 r.successor);
331
332 // type speed
333 for (auto const s : r.speed) {
334 map_builder.CreateRoadSpeed(road, s.s, s.type, s.max, s.unit);
335 }
336
337 // section offsets
338 for (auto const s : r.section_offsets) {
339 map_builder.CreateSectionOffset(road, s.s, s.a, s.b, s.c, s.d);
340 }
341
342 // lane sections
343 road::SectionId i = 0;
344 for (auto const s : r.sections) {
345 carla::road::LaneSection *section = map_builder.AddRoadSection(road, i++, s.s);
346
347 // lanes
348 for (auto const l : s.lanes) {
349 /*carla::road::Lane *lane = */ map_builder.AddRoadSectionLane(section, l.id,
350 static_cast<uint32_t>(l.type), l.level, l.predecessor, l.successor);
351 }
352 }
353 }
354 }
355
356} // namespace parser
357} // namespace opendrive
358} // namespace carla
static void ToLower(WritableRangeT &str)
Definition StringUtil.h:40
static void Parse(const pugi::xml_document &xml, carla::road::MapBuilder &map_builder)
解析XML文档中的道路信息,并将其用于构建道路地图 该函数读取XML文档中的道路数据,如道路几何形状、车道信息、交叉口等 并使用这些数据来构建或更新道路地图
LaneType
可以作为标志使用
Definition Lane.h:29
carla::road::Lane * AddRoadSectionLane(carla::road::LaneSection *section, const LaneId lane_id, const uint32_t lane_type, const bool lane_level, const LaneId predecessor, const LaneId successor)
void CreateRoadSpeed(Road *road, const double s, const std::string type, const double max, const std::string unit)
carla::road::Road * AddRoad(const RoadId road_id, const std::string name, const double length, const JuncId junction_id, const RoadId predecessor, const RoadId successor)
void CreateSectionOffset(Road *road, const double s, const double a, const double b, const double c, const double d)
carla::road::LaneSection * AddRoadSection(carla::road::Road *road, const SectionId id, const double s)
int as_int(int def=0) const
Definition pugixml.cpp:5363
double as_double(double def=0) const
Definition pugixml.cpp:5373
unsigned int as_uint(unsigned int def=0) const
Definition pugixml.cpp:5368
const char_t * value() const
Definition pugixml.cpp:5410
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 road::Lane::LaneType StringToLaneType(std::string &&str)
uint32_t SectionId
Definition RoadTypes.h:29
int32_t JuncId
Definition RoadTypes.h:23
int32_t LaneId
Definition RoadTypes.h:26
uint32_t RoadId
Definition RoadTypes.h:20
CARLA模拟器的主命名空间。
Definition Carla.cpp:139
road::Lane::LaneType type
std::vector< LaneOffset > section_offsets
std::vector< RoadTypeSpeed > speed
std::vector< LaneSection > sections