CARLA
Loading...
Searching...
No Matches
MapBuilder.cpp
Go to the documentation of this file.
1// Copyright (c) 2026 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/StringUtil.h"
28#include "carla/road/Signal.h"
30
31#include <iterator>
32#include <memory>
33#include <algorithm>
34
35using namespace carla::road::element;
36
37namespace carla {
38namespace road {
39
40 std::optional<Map> MapBuilder::Build() {
41
44
45 for (auto &&info : _temp_road_info_container) {
46 DEBUG_ASSERT(info.first != nullptr);
47 info.first->_info = InformationSet(std::move(info.second));
48 }
49
50 for (auto &&info : _temp_lane_info_container) {
51 DEBUG_ASSERT(info.first != nullptr);
52 info.first->_info = InformationSet(std::move(info.second));
53 }
54
55 // compute transform requires the roads to have the RoadInfo
58
60
61 // remove temporal already used information
64
65 // _map_data is a memeber of MapBuilder so you must especify if
66 // you want to keep it (will return copy -> Map(const Map &))
67 // or move it (will return move -> Map(Map &&))
68 Map map(std::move(_map_data));
72
73 return map;
74 }
75
76 // called from profiles parser
78 Road *road,
79 const double s,
80 const double a,
81 const double b,
82 const double c,
83 const double d) {
84 DEBUG_ASSERT(road != nullptr);
85 auto elevation = std::make_unique<RoadInfoElevation>(s, a, b, c, d);
86 _temp_road_info_container[road].emplace_back(std::move(elevation));
87 }
88
90 Road *road,
91 const double s,
92 const double a,
93 const double b,
94 const double c,
95 const double d,
96 const double t) {
97 DEBUG_ASSERT(road != nullptr);
98 auto shape = std::make_unique<RoadInfoLateralShape>(s, t, a, b, c, d);
99 _temp_road_info_container[road].emplace_back(std::move(shape));
100 }
101
103 Road *road,
104 const std::string name,
105 const double s,
106 const double t,
107 const double zOffset,
108 const double hdg,
109 const double pitch,
110 const double roll,
111 const std::string orientation,
112 const double width,
113 const double length,
114 const std::vector<road::element::CrosswalkPoint> points) {
115 DEBUG_ASSERT(road != nullptr);
116 auto cross = std::make_unique<RoadInfoCrosswalk>(s, name, t, zOffset, hdg, pitch, roll, std::move(orientation), width, length, std::move(points));
117 _temp_road_info_container[road].emplace_back(std::move(cross));
118 }
119
120 // called from lane parser
122 Lane *lane,
123 const double s,
124 const std::string restriction) {
125 DEBUG_ASSERT(lane != nullptr);
126 _temp_lane_info_container[lane].emplace_back(std::make_unique<RoadInfoLaneAccess>(s, restriction));
127 }
128
130 Lane *lane,
131 const double s,
132 const double a,
133 const double b,
134 const double c,
135 const double d) {
136 DEBUG_ASSERT(lane != nullptr);
137 _temp_lane_info_container[lane].emplace_back(std::make_unique<RoadInfoLaneBorder>(s, a, b, c, d));
138 }
139
141 Lane *lane,
142 const double s,
143 const double inner,
144 const double outer) {
145 DEBUG_ASSERT(lane != nullptr);
146 _temp_lane_info_container[lane].emplace_back(std::make_unique<RoadInfoLaneHeight>(s, inner, outer));
147 }
148
150 Lane *lane,
151 const double s,
152 const std::string surface,
153 const double friction,
154 const double roughness) {
155 DEBUG_ASSERT(lane != nullptr);
156 _temp_lane_info_container[lane].emplace_back(std::make_unique<RoadInfoLaneMaterial>(s, surface, friction,
157 roughness));
158 }
159
161 Lane *lane,
162 const double s,
163 const std::string value) {
164 DEBUG_ASSERT(lane != nullptr);
165 _temp_lane_info_container[lane].emplace_back(std::make_unique<RoadInfoLaneRule>(s, value));
166 }
167
169 Lane *lane,
170 const double s,
171 const double forward,
172 const double back,
173 const double left,
174 const double right) {
175 DEBUG_ASSERT(lane != nullptr);
176 _temp_lane_info_container[lane].emplace_back(std::make_unique<RoadInfoLaneVisibility>(s, forward, back,
177 left, right));
178 }
179
181 Lane *lane,
182 const double s,
183 const double a,
184 const double b,
185 const double c,
186 const double d) {
187 DEBUG_ASSERT(lane != nullptr);
188 _temp_lane_info_container[lane].emplace_back(std::make_unique<RoadInfoLaneWidth>(s, a, b, c, d));
189 }
190
192 Lane *lane,
193 const int road_mark_id,
194 const double s,
195 const std::string type,
196 const std::string weight,
197 const std::string color,
198 const std::string material,
199 const double width,
200 std::string lane_change,
201 const double height,
202 const std::string type_name,
203 const double type_width,
204 bool is_rht) {
205 DEBUG_ASSERT(lane != nullptr);
207
208 StringUtil::ToLower(lane_change);
209
210 if (lane_change == "increase") {
211 lc = RoadInfoMarkRecord::LaneChange::Increase;
212 } else if (lane_change == "decrease") {
213 lc = RoadInfoMarkRecord::LaneChange::Decrease;
214 } else if (lane_change == "none") {
215 lc = RoadInfoMarkRecord::LaneChange::None;
216 } else {
217 lc = RoadInfoMarkRecord::LaneChange::Both;
218 }
219 _temp_lane_info_container[lane].emplace_back(std::make_unique<RoadInfoMarkRecord>(s, road_mark_id, type,
220 weight, color,
221 material, width, lc, height, type_name, type_width, is_rht));
222 }
223
225 Lane *lane,
226 const int road_mark_id,
227 const double length,
228 const double space,
229 const double tOffset,
230 const double s,
231 const std::string rule,
232 const double width) {
233 DEBUG_ASSERT(lane != nullptr);
234 auto it = MakeRoadInfoIterator<RoadInfoMarkRecord>(_temp_lane_info_container[lane]);
235 for (; !it.IsAtEnd(); ++it) {
236 if (it->GetRoadMarkId() == road_mark_id) {
237 it->GetLines().emplace_back(std::make_unique<RoadInfoMarkTypeLine>(s, road_mark_id, length, space,
238 tOffset, rule, width));
239 break;
240 }
241 }
242
243 }
244
246 Lane *lane,
247 const double s,
248 const double max,
249 const std::string /*unit*/) {
250 DEBUG_ASSERT(lane != nullptr);
251 _temp_lane_info_container[lane].emplace_back(std::make_unique<RoadInfoSpeed>(s, max));
252 }
253
254
256 Road* road,
257 const SignId signal_id,
258 const double s,
259 const double t,
260 const std::string name,
261 const std::string dynamic,
262 const std::string orientation,
263 const double zOffset,
264 const std::string country,
265 const std::string type,
266 const std::string subtype,
267 const double value,
268 const std::string unit,
269 const double height,
270 const double width,
271 const std::string text,
272 const double hOffset,
273 const double pitch,
274 const double roll) {
275 _temp_signal_container[signal_id] = std::make_unique<Signal>(
276 road->GetId(),
277 signal_id,
278 s,
279 t,
280 name,
281 dynamic,
282 orientation,
283 zOffset,
284 country,
285 type,
286 subtype,
287 value,
288 unit,
289 height,
290 width,
291 text,
292 hOffset,
293 pitch,
294 roll);
295
296 return AddSignalReference(road, signal_id, s, t, orientation);
297 }
298
300 const SignId signal_id,
301 const double x,
302 const double y,
303 const double z,
304 const double hdg,
305 const double pitch,
306 const double roll) {
307 std::unique_ptr<Signal> &signal = _temp_signal_container[signal_id];
308 signal->_using_inertial_position = true;
309 geom::Location location = geom::Location(static_cast<float>(x), static_cast<float>(-y), static_cast<float>(z));
310 signal->_transform = geom::Transform (location, geom::Rotation(
311 geom::Math::ToDegrees(static_cast<float>(pitch)),
312 geom::Math::ToDegrees(static_cast<float>(-hdg)),
313 geom::Math::ToDegrees(static_cast<float>(roll))));
314 }
315
317 const SignId signal_id,
318 const RoadId road_id,
319 const double s,
320 const double t,
321 const double zOffset,
322 const double hOffset,
323 const double pitch,
324 const double roll) {
325 std::unique_ptr<Signal> &signal = _temp_signal_container[signal_id];
326 signal->_road_id = road_id;
327 signal->_s = s;
328 signal->_t = t;
329 signal->_zOffset = zOffset;
330 signal->_hOffset = hOffset;
331 signal->_pitch = pitch;
332 signal->_roll = roll;
333 }
334
336 Road* road,
337 const SignId signal_id,
338 const double s_position,
339 const double t_position,
340 const std::string signal_reference_orientation) {
341
342 const double epsilon = 0.00001;
343 RELEASE_ASSERT(s_position >= 0.0);
344 // Prevent s_position from being equal to the road length
345 double fixed_s = geom::Math::Clamp(s_position, 0.0, road->GetLength() - epsilon);
346 _temp_road_info_container[road].emplace_back(std::make_unique<element::RoadInfoSignal>(
347 signal_id, road->GetId(), fixed_s, t_position, signal_reference_orientation));
348 auto road_info_signal = static_cast<element::RoadInfoSignal*>(
349 _temp_road_info_container[road].back().get());
350 _temp_signal_reference_container.emplace_back(road_info_signal);
351 return road_info_signal;
352 }
353
355 element::RoadInfoSignal* signal_reference,
356 const LaneId from_lane,
357 const LaneId to_lane) {
358 signal_reference->_validities.emplace_back(LaneValidity(from_lane, to_lane));
359 }
360
362 const SignId signal_id,
363 const std::string dependency_id,
364 const std::string dependency_type) {
365 _temp_signal_container[signal_id]->_dependencies.emplace_back(
366 SignalDependency(dependency_id, dependency_type));
367 }
368
370 Road* road,
371 const StencilId stencil_id,
372 const double s,
373 const double t,
374 const std::string name,
375 const std::string orientation,
376 const std::string type,
377 const double zOffset,
378 const double heading,
379 const double length,
380 const double width,
381 const double pitch,
382 const double roll) {
383
384 // Create the stencil object
385 _temp_stencil_container[stencil_id] = std::make_unique<Stencil>(
386 road->GetId(),
387 stencil_id,
388 s,
389 t,
390 name,
391 orientation,
392 type,
393 zOffset,
394 heading,
395 length,
396 width,
397 pitch,
398 roll);
399
400 const double epsilon = 0.00001;
401 RELEASE_ASSERT(s >= 0.0);
402 // Prevent s_position from being equal to the road length
403 double fixed_s = geom::Math::Clamp(s, 0.0, road->GetLength() - epsilon);
404 _temp_road_info_container[road].emplace_back(std::make_unique<element::RoadInfoStencil>(
405 stencil_id, road->GetId(), fixed_s, t, orientation));
406 auto road_info_stencil = static_cast<element::RoadInfoStencil*>(
407 _temp_road_info_container[road].back().get());
408 _temp_stencil_reference_container.emplace_back(road_info_stencil);
409 return road_info_stencil;
410 }
411
412 // build road objects
414 const RoadId road_id,
415 const std::string name,
416 const double length,
417 const JuncId junction_id,
418 const RoadId predecessor,
419 const RoadId successor,
420 const bool is_rht)
421 {
422
423 // add it
424 auto road = &(_map_data._roads.emplace(road_id, Road()).first->second);
425
426 // set road data
427 road->_map_data = &_map_data;
428 road->_id = road_id;
429 road->_name = name;
430 road->_length = length;
431 road->_junction_id = junction_id;
432 (junction_id != -1) ? road->_is_junction = true : road->_is_junction = false;
433 road->_is_rht = is_rht;
434 road->_successor = successor;
435 road->_predecessor = predecessor;
436
437 return road;
438 }
439
441 Road *road,
442 const SectionId id,
443 const double s) {
444 DEBUG_ASSERT(road != nullptr);
445 carla::road::LaneSection &sec = road->_lane_sections.Emplace(id, s);
446 sec._road = road;
447 return &sec;
448 }
449
452 const int32_t lane_id,
453 const uint32_t lane_type,
454 const bool lane_level,
455 const int32_t predecessor,
456 const int32_t successor) {
457 DEBUG_ASSERT(section != nullptr);
458
459 // add the lane
460 auto *lane = &((section->_lanes.emplace(lane_id, Lane()).first)->second);
461
462 // set lane data
463 lane->_id = lane_id;
464 lane->_lane_section = section;
465 lane->_level = lane_level;
466 lane->_type = static_cast<carla::road::Lane::LaneType>(lane_type);
467 lane->_successor = successor;
468 lane->_predecessor = predecessor;
469
470 return lane;
471 }
472
474 Road *road,
475 const double s,
476 const double x,
477 const double y,
478 const double hdg,
479 const double length) {
480 DEBUG_ASSERT(road != nullptr);
481 const geom::Location location(static_cast<float>(x), static_cast<float>(y), 0.0f);
482 auto line_geometry = std::make_unique<GeometryLine>(
483 s,
484 length,
485 hdg,
486 location);
487
488 _temp_road_info_container[road].emplace_back(std::unique_ptr<RoadInfo>(new RoadInfoGeometry(s,
489 std::move(line_geometry))));
490 }
491
493 Road *road,
494 const double s,
495 const std::string /*type*/,
496 const double max,
497 const std::string /*unit*/) {
498 DEBUG_ASSERT(road != nullptr);
499 _temp_road_info_container[road].emplace_back(std::make_unique<RoadInfoSpeed>(s, max));
500 }
501
503 Road *road,
504 const double s,
505 const double a,
506 const double b,
507 const double c,
508 const double d) {
509 DEBUG_ASSERT(road != nullptr);
510 _temp_road_info_container[road].emplace_back(std::make_unique<RoadInfoLaneOffset>(s, a, b, c, d));
511 }
512
514 Road *road,
515 const double s,
516 const double x,
517 const double y,
518 const double hdg,
519 const double length,
520 const double curvature) {
521 DEBUG_ASSERT(road != nullptr);
522 const geom::Location location(static_cast<float>(x), static_cast<float>(y), 0.0f);
523 auto arc_geometry = std::make_unique<GeometryArc>(
524 s,
525 length,
526 hdg,
527 location,
528 curvature);
529
530 _temp_road_info_container[road].emplace_back(std::unique_ptr<RoadInfo>(new RoadInfoGeometry(s,
531 std::move(arc_geometry))));
532 }
533
535 Road * road,
536 const double s,
537 const double x,
538 const double y,
539 const double hdg,
540 const double length,
541 const double curvStart,
542 const double curvEnd) {
543 //throw_exception(std::runtime_error("geometry spiral not supported"));
544 DEBUG_ASSERT(road != nullptr);
545 const geom::Location location(static_cast<float>(x), static_cast<float>(y), 0.0f);
546 auto spiral_geometry = std::make_unique<GeometrySpiral>(
547 s,
548 length,
549 hdg,
550 location,
551 curvStart,
552 curvEnd);
553
554 _temp_road_info_container[road].emplace_back(std::unique_ptr<RoadInfo>(new RoadInfoGeometry(s,
555 std::move(spiral_geometry))));
556 }
557
559 Road * road,
560 const double s,
561 const double x,
562 const double y,
563 const double hdg,
564 const double length,
565 const double a,
566 const double b,
567 const double c,
568 const double d) {
569 //throw_exception(std::runtime_error("geometry poly3 not supported"));
570 DEBUG_ASSERT(road != nullptr);
571 const geom::Location location(static_cast<float>(x), static_cast<float>(y), 0.0f);
572 auto poly3_geometry = std::make_unique<GeometryPoly3>(
573 s,
574 length,
575 hdg,
576 location,
577 a,
578 b,
579 c,
580 d);
581 _temp_road_info_container[road].emplace_back(std::unique_ptr<RoadInfo>(new RoadInfoGeometry(s,
582 std::move(poly3_geometry))));
583 }
584
586 Road * road,
587 const double s,
588 const double x,
589 const double y,
590 const double hdg,
591 const double length,
592 const double aU,
593 const double bU,
594 const double cU,
595 const double dU,
596 const double aV,
597 const double bV,
598 const double cV,
599 const double dV,
600 const std::string p_range) {
601 //throw_exception(std::runtime_error("geometry poly3 not supported"));
602 bool arcLength;
603 if(p_range == "arcLength"){
604 arcLength = true;
605 }else{
606 arcLength = false;
607 }
608 DEBUG_ASSERT(road != nullptr);
609 const geom::Location location(static_cast<float>(x), static_cast<float>(y), 0.0f);
610 auto parampoly3_geometry = std::make_unique<GeometryParamPoly3>(
611 s,
612 length,
613 hdg,
614 location,
615 aU,
616 bU,
617 cU,
618 dU,
619 aV,
620 bV,
621 cV,
622 dV,
623 arcLength);
624 _temp_road_info_container[road].emplace_back(std::unique_ptr<RoadInfo>(new RoadInfoGeometry(s,
625 std::move(parampoly3_geometry))));
626 }
627
628 void MapBuilder::AddJunction(const int32_t id, const std::string name) {
629 _map_data.GetJunctions().emplace(id, Junction(id, name));
630 }
631
633 const JuncId junction_id,
634 const ConId connection_id,
635 const RoadId incoming_road,
636 const RoadId connecting_road) {
637 DEBUG_ASSERT(_map_data.GetJunction(junction_id) != nullptr);
638 _map_data.GetJunction(junction_id)->GetConnections().emplace(connection_id,
639 Junction::Connection(connection_id, incoming_road, connecting_road));
640 }
641
643 const JuncId junction_id,
644 const ConId connection_id,
645 const LaneId from,
646 const LaneId to) {
647 DEBUG_ASSERT(_map_data.GetJunction(junction_id) != nullptr);
648 _map_data.GetJunction(junction_id)->GetConnection(connection_id)->AddLaneLink(from, to);
649 }
650
652 const JuncId junction_id,
653 std::set<road::ContId>&& controllers) {
654 DEBUG_ASSERT(_map_data.GetJunction(junction_id) != nullptr);
655 _map_data.GetJunction(junction_id)->_controllers = std::move(controllers);
656 }
657
659 const RoadId road_id,
660 const LaneId lane_id,
661 const double s) {
662 return &_map_data.GetRoad(road_id).GetLaneByDistance(s, lane_id);
663 }
664
666 const RoadId road_id) {
667 return &_map_data.GetRoad(road_id);
668 }
669
670 // return the pointer to a lane object
672
674 return nullptr;
675 }
677
678 // Not very pretty as it repeats the IsPositiveDirection logic of the Lane class
679 bool from_start = false;
680 if (road.IsRHT() && lane_id <= 0){
681 from_start = true;
682 } else if (!road.IsRHT() && lane_id >= 0){
683 from_start = true;
684 }
685
686 // get the lane section
687 LaneSection *section;
688 if (from_start) {
689 section = road.GetStartSection(lane_id);
690 } else {
691 section = road.GetEndSection(lane_id);
692 }
693
694 // get the lane
695 DEBUG_ASSERT(section != nullptr);
696 return section->GetLane(lane_id);
697 }
698
699 // return a list of pointers to all lanes from a lane (using road and junction
700 // info)
701 std::vector<Lane *> MapBuilder::GetLaneNext(
703 SectionId section_id,
704 LaneId lane_id) {
705 std::vector<Lane *> result;
706
708 return result;
709 }
711
712 // get the section
713 LaneSection &section = road._lane_sections.GetById(section_id);
714
715 // get the lane
716 Lane *lane = section.GetLane(lane_id);
717 DEBUG_ASSERT(lane != nullptr);
718
719 // successor and predecessor (road and lane)
720 LaneId next;
721 RoadId next_road;
722 if (lane->IsPositiveDirection()) {
723 next_road = road.GetSuccessor();
724 next = lane->GetSuccessor();
725 } else {
726 next_road = road.GetPredecessor();
727 next = lane->GetPredecessor();
728 }
729
730 // check to see if next is a road or a junction
731 bool next_is_junction = !_map_data.ContainsRoad(next_road);
732 double s = section.GetDistance();
733
734 // check if we are in a lane section in the middle
735 if ((!lane->IsPositiveDirection() && s > 0) ||
736 (lane->IsPositiveDirection() && road._lane_sections.upper_bound(s) != road._lane_sections.end())) {
737 // check if lane has a next link (if not, it deads in the middle section)
738 if (next != 0 || (lane_id == 0 && next == 0)) {
739 // change to next / prev section
740 if (lane->IsPositiveDirection()) {
741 result.push_back(road.GetNextLane(s, next));
742 } else {
743 result.push_back(road.GetPrevLane(s, next));
744 }
745 }
746 } else if (!next_is_junction) {
747 // change to another road / junction
748 if (next != 0 || (lane_id == 0 && next == 0)) {
749 // single road
750 result.push_back(GetEdgeLanePointer(next_road, next));
751 }
752 } else {
753 // several roads (junction)
754
755 /// @todo Is it correct to use a road id as section id? (NS: I just added
756 /// this cast to avoid compiler warnings).
757 auto next_road_as_junction = static_cast<JuncId>(next_road);
758 auto options = GetJunctionLanes(next_road_as_junction, road_id, lane_id);
759 for (auto opt : options) {
760 /// @todo: Find a better way to change from 'const Lane*' to 'Lane*' and use opt.second
761 result.push_back(GetEdgeLanePointer(opt.first, opt.second->GetId()));
762 }
763 }
764
765 return result;
766 }
767
768 std::vector<std::pair<RoadId, const Lane*>> MapBuilder::GetJunctionLanes(
769 JuncId junction_id,
771 LaneId lane_id) {
772 std::vector<std::pair<RoadId, const Lane*>> result;
773
774 // get the junction
775 Junction *junction = _map_data.GetJunction(junction_id);
776 if (junction == nullptr) {
777 return result;
778 }
779
780 // Completely remade, as the junctions have incoming roads, but not "exitting" ones
781 for (auto con : junction->_connections) {
782 auto conn_road = GetRoad(con.second.connecting_road);
783 auto conn_id = conn_road->_id;
784
785 auto road_pred = conn_road->_predecessor;
786 auto road_succ = conn_road->_successor;
787 if (road_id == road_pred) {
788 for (auto lane : conn_road->GetLanesAt(0)){
789 if (lane_id == lane.second->_predecessor){
790 result.push_back(std::make_pair(conn_id, lane.second));
791 }
792 }
793 }
794
795 if (road_id == road_succ) {
796 for (auto lane : conn_road->GetLanesAt(conn_road->GetLength())){
797 if (lane_id == lane.second->_successor){
798 result.push_back(std::make_pair(conn_id, lane.second));
799 }
800 }
801 }
802 }
803
804 return result;
805}
806
807 // assign pointers to the next lanes
809 // process each lane to define its nexts
810 for (auto &road : _map_data._roads) {
811 for (auto &section : road.second._lane_sections) {
812 for (auto &lane : section.second._lanes) {
813
814 // assign the next lane pointers
815 lane.second._next_lanes = GetLaneNext(road.first, section.second._id, lane.first);
816
817 // add to each lane found, this as its predecessor
818 for (auto next_lane : lane.second._next_lanes) {
819 // add as previous
820 DEBUG_ASSERT(next_lane != nullptr);
821 next_lane->_prev_lanes.push_back(&lane.second);
822 }
823
824 }
825 }
826 }
827
828 // process each lane to define its nexts
829 for (auto &road : _map_data._roads) {
830 for (auto &section : road.second._lane_sections) {
831 for (auto &lane : section.second._lanes) {
832
833 // add next roads
834 for (auto next_lane : lane.second._next_lanes) {
835 DEBUG_ASSERT(next_lane != nullptr);
836 // avoid same road
837 if (next_lane->GetRoad() != &road.second) {
838 if (std::find(road.second._nexts.begin(), road.second._nexts.end(),
839 next_lane->GetRoad()) == road.second._nexts.end()) {
840 road.second._nexts.push_back(next_lane->GetRoad());
841 }
842 }
843 }
844
845 // add prev roads
846 for (auto prev_lane : lane.second._prev_lanes) {
847 DEBUG_ASSERT(prev_lane != nullptr);
848 // avoid same road
849 if (prev_lane->GetRoad() != &road.second) {
850 if (std::find(road.second._prevs.begin(), road.second._prevs.end(),
851 prev_lane->GetRoad()) == road.second._prevs.end()) {
852 road.second._prevs.push_back(prev_lane->GetRoad());
853 }
854 }
855 }
856
857 }
858 }
859 }
860 // DebugRoadConnections();
861 }
862
864 for (auto &road : _map_data._roads) {
865 for (auto &section : road.second._lane_sections) {
866 for (auto &lane : section.second._lanes) {
867 std::cout << "\nLane: " << road.first << "_" << section.first << "_" << lane.first << std::endl;
868 for (auto next_lane : lane.second._next_lanes) {
869 std::cout << "Next lane: " << next_lane->GetRoad()->GetId() << "_" << next_lane->GetLaneSection()->_id << "_" << next_lane->_id << std::endl;
870 }
871 for (auto prev_lanes : lane.second._prev_lanes) {
872 std::cout << "Prev lane: " << prev_lanes->GetRoad()->GetId() << "_" << prev_lanes->GetLaneSection()->_id << "_" << prev_lanes->_id << std::endl;
873 }
874 }
875 }
876 }
877 }
878
879 geom::Transform MapBuilder::ComputeSignalTransform(std::unique_ptr<Signal> &signal, MapData &data) {
880 DirectedPoint point = data.GetRoad(signal->_road_id).GetDirectedPointInNoLaneOffset(signal->_s);
881 point.ApplyLateralOffset(static_cast<float>(-signal->_t));
882 point.location.y *= -1; // Unreal Y axis hack
883 point.location.z += static_cast<float>(signal->_zOffset);
884 geom::Transform transform(point.location, geom::Rotation(
885 geom::Math::ToDegrees(static_cast<float>(signal->_pitch)),
886 geom::Math::ToDegrees(static_cast<float>(-(point.tangent + signal->_hOffset))),
887 geom::Math::ToDegrees(static_cast<float>(signal->_roll))));
888 return transform;
889 }
890
891 geom::Transform MapBuilder::ComputeStencilTransform(std::unique_ptr<Stencil> &stencil, MapData &data) {
892 DirectedPoint point = data.GetRoad(stencil->GetRoadId()).GetDirectedPointInNoLaneOffset(stencil->GetS());
893 point.ApplyLateralOffset(static_cast<float>(-stencil->GetT()));
894 point.location.y *= -1; // Unreal Y axis hack
895 point.location.z += static_cast<float>(stencil->GetZOffset());
896 geom::Transform transform(point.location, geom::Rotation(
897 geom::Math::ToDegrees(static_cast<float>(stencil->GetPitch())),
898 geom::Math::ToDegrees(static_cast<float>(-(point.tangent + stencil->GetHeading()))),
899 geom::Math::ToDegrees(static_cast<float>(stencil->GetRoll()))));
900 return transform;
901 }
902
904 for(auto signal_reference : _temp_signal_reference_container){
905 signal_reference->_signal =
906 _temp_signal_container[signal_reference->_signal_id].get();
907 }
908
909 for(auto& signal_pair : _temp_signal_container) {
910 auto& signal = signal_pair.second;
911 if (signal->_using_inertial_position) {
912 continue;
913 }
914 auto transform = ComputeSignalTransform(signal, _map_data);
915 if (SignalType::IsTrafficLight(signal->GetType())) {
916 transform.location = transform.location +
917 geom::Location(transform.GetForwardVector()*0.25);
918 }
919 signal->_transform = transform;
920 }
921
923
925 }
926
928 // Link stencil references to actual stencils
929 for(auto stencil_reference : _temp_stencil_reference_container){
930 stencil_reference->_stencil =
931 _temp_stencil_container[stencil_reference->_stencil_id].get();
932 }
933
934 // Compute transforms for stencils
935 for(auto& stencil_pair : _temp_stencil_container) {
936 auto& stencil = stencil_pair.second;
937 auto transform = ComputeStencilTransform(stencil, _map_data);
938 stencil->_transform = transform;
939 }
940
941 // Move stencils to map data
943 }
944
946 for(const auto& junction : _map_data._junctions) {
947 for(const auto& controller : junction.second._controllers) {
948 auto it = _map_data._controllers.find(controller);
949 if(it != _map_data._controllers.end()){
950 if( it->second != nullptr ){
951 it->second->_junctions.insert(junction.first);
952 for(const auto & signal : it->second->_signals) {
953 auto signal_it = _map_data._signals.find(signal);
954 if( signal_it->second != nullptr ){
955 signal_it->second->_controllers.insert(controller);
956 }
957 }
958 }
959 }
960 }
961 }
962 }
963
965 for (auto &junctionpair : map._data.GetJunctions()) {
966 auto* junction = map.GetJunction(junctionpair.first);
967 auto waypoints = map.GetJunctionWaypoints(junction->GetId(), Lane::LaneType::Any);
968 const int number_intervals = 10;
969
970 float minx = std::numeric_limits<float>::max();
971 float miny = std::numeric_limits<float>::max();
972 float minz = std::numeric_limits<float>::max();
973 float maxx = -std::numeric_limits<float>::max();
974 float maxy = -std::numeric_limits<float>::max();
975 float maxz = -std::numeric_limits<float>::max();
976
977 auto get_min_max = [&](geom::Location position) {
978 if (position.x < minx) {
979 minx = position.x;
980 }
981 if (position.y < miny) {
982 miny = position.y;
983 }
984 if (position.z < minz) {
985 minz = position.z;
986 }
987
988 if (position.x > maxx) {
989 maxx = position.x;
990 }
991 if (position.y > maxy) {
992 maxy = position.y;
993 }
994 if (position.z > maxz) {
995 maxz = position.z;
996 }
997 };
998
999 for (auto &waypoint_p : waypoints) {
1000 auto &waypoint_start = waypoint_p.first;
1001 auto &waypoint_end = waypoint_p.second;
1002 double interval = (waypoint_end.s - waypoint_start.s) / static_cast<double>(number_intervals);
1003 auto next_wp = waypoint_end;
1004 auto location = map.ComputeTransform(next_wp).location;
1005
1006 get_min_max(location);
1007
1008 next_wp = waypoint_start;
1009 location = map.ComputeTransform(next_wp).location;
1010
1011 get_min_max(location);
1012
1013 for (int i = 0; i < number_intervals; ++i) {
1014 if (interval < std::numeric_limits<double>::epsilon())
1015 break;
1016 auto next = map.GetNext(next_wp, interval);
1017 if(next.size()){
1018 next_wp = next.back();
1019 }
1020
1021 location = map.ComputeTransform(next_wp).location;
1022 get_min_max(location);
1023 }
1024 }
1025 carla::geom::Location location(0.5f * (maxx + minx), 0.5f * (maxy + miny), 0.5f * (maxz + minz));
1026 carla::geom::Vector3D extent(0.5f * (maxx - minx), 0.5f * (maxy - miny), 0.5f * (maxz - minz));
1027
1028 junction->_bounding_box = carla::geom::BoundingBox(location, extent);
1029 }
1030 }
1031
1033 const ContId controller_id,
1034 const std::string controller_name,
1035 const uint32_t controller_sequence,
1036 const std::set<road::SignId>&& signals) {
1037
1038 // Add the Controller to MapData
1039 auto controller_pair = _map_data._controllers.emplace(
1040 std::make_pair(
1041 controller_id,
1042 std::make_unique<Controller>(controller_id, controller_name, controller_sequence)));
1043
1044 DEBUG_ASSERT(controller_pair.first != _map_data._controllers.end());
1045 DEBUG_ASSERT(controller_pair.first->second);
1046
1047 // Add the signals owned by the controller
1048 controller_pair.first->second->_signals = std::move(signals);
1049
1050 // Add ContId to the signal owned by this Controller
1051 auto& signals_map = _map_data._signals;
1052 for(auto signal: signals) {
1053 auto it = signals_map.find(signal);
1054 if(it != signals_map.end()) {
1055 it->second->_controllers.insert(signal);
1056 }
1057 }
1058}
1059
1061 for (auto &junctionpair : map._data.GetJunctions()) {
1062 auto& junction = junctionpair.second;
1063 junction._road_conflicts = (map.ComputeJunctionConflicts(junction.GetId()));
1064 }
1065 }
1066
1068 for (auto * signal_reference : _temp_signal_reference_container) {
1069 if (signal_reference->_validities.size() == 0) {
1070 Road* road = GetRoad(signal_reference->GetRoadId());
1071 auto lanes = road->GetLanesByDistance(signal_reference->GetS());
1072 switch (signal_reference->GetOrientation()) {
1074 LaneId min_lane = 1;
1075 LaneId max_lane = 0;
1076 for (const auto* lane : lanes) {
1077 auto lane_id = lane->GetId();
1078 if(lane_id > max_lane) {
1079 max_lane = lane_id;
1080 }
1081 }
1082 if(min_lane <= max_lane) {
1083 AddValidityToSignalReference(signal_reference, min_lane, max_lane);
1084 }
1085 break;
1086 }
1088 LaneId min_lane = 0;
1089 LaneId max_lane = -1;
1090 for (const auto* lane : lanes) {
1091 auto lane_id = lane->GetId();
1092 if(lane_id < min_lane) {
1093 min_lane = lane_id;
1094 }
1095 }
1096 if(min_lane <= max_lane) {
1097 AddValidityToSignalReference(signal_reference, min_lane, max_lane);
1098 }
1099 break;
1100 }
1102 // Get positive lanes
1103 LaneId min_lane = 1;
1104 LaneId max_lane = 0;
1105 for (const auto* lane : lanes) {
1106 auto lane_id = lane->GetId();
1107 if(lane_id > max_lane) {
1108 max_lane = lane_id;
1109 }
1110 }
1111 if(min_lane <= max_lane) {
1112 AddValidityToSignalReference(signal_reference, min_lane, max_lane);
1113 }
1114
1115 // get negative lanes
1116 min_lane = 0;
1117 max_lane = -1;
1118 for (const auto* lane : lanes) {
1119 auto lane_id = lane->GetId();
1120 if(lane_id < min_lane) {
1121 min_lane = lane_id;
1122 }
1123 }
1124 if(min_lane <= max_lane) {
1125 AddValidityToSignalReference(signal_reference, min_lane, max_lane);
1126 }
1127 break;
1128 }
1129 }
1130 }
1131 }
1132 }
1133
1135 std::vector<element::RoadInfoSignal*> elements_to_remove;
1136 for (auto * signal_reference : _temp_signal_reference_container) {
1137 bool should_remove = true;
1138 for (auto & lane_validity : signal_reference->_validities) {
1139 if ( (lane_validity._from_lane != 0) ||
1140 (lane_validity._to_lane != 0)) {
1141 should_remove = false;
1142 break;
1143 }
1144 }
1145 if (signal_reference->_validities.size() == 0) {
1146 should_remove = false;
1147 }
1148 if (should_remove) {
1149 elements_to_remove.push_back(signal_reference);
1150 }
1151 }
1152 for (auto* element : elements_to_remove) {
1153 auto road_id = element->GetRoadId();
1154 auto& road_info = _temp_road_info_container[GetRoad(road_id)];
1155 road_info.erase(std::remove_if(road_info.begin(), road_info.end(),
1156 [=] (auto& info_ptr) {
1157 return (info_ptr.get() == element);
1158 }), road_info.end());
1160 _temp_signal_reference_container.end(), element),
1162 }
1163 }
1164
1166 for (auto& signal_pair : map._data._signals) {
1167 auto& signal = signal_pair.second;
1168 auto signal_position = signal->GetTransform().location;
1169 auto signal_rotation = signal->GetTransform().rotation;
1170 auto closest_waypoint_to_signal =
1171 map.GetClosestWaypointOnRoad(signal_position,
1172 static_cast<int32_t>(carla::road::Lane::LaneType::Shoulder) | static_cast<int32_t>(carla::road::Lane::LaneType::Driving));
1173 // workarround to not move stencil stop
1174 if (
1175 signal->GetName().find("Stencil_STOP") != std::string::npos ||
1176 signal->GetName().find("STATIC") != std::string::npos ||
1177 signal->_using_inertial_position) {
1178 continue;
1179 }
1180 if(closest_waypoint_to_signal) {
1181 auto road_transform = map.ComputeTransform(closest_waypoint_to_signal.value());
1182 auto distance_to_road = (road_transform.location -signal_position).Length();
1183 double lane_width = map.GetLaneWidth(closest_waypoint_to_signal.value());
1184 bool is_rht = map.GetLane(closest_waypoint_to_signal.value()).GetRoad()->IsRHT();
1185 int displacement_direction = 1;
1186 int iter = 0;
1187 int MaxIter = 10;
1188 // Displaces signal until it finds a suitable spot
1189 while(distance_to_road < (lane_width * 0.7) && iter < MaxIter && displacement_direction != 0) {
1190 if(iter == 0) {
1191 log_debug("Traffic sign",
1192 signal->GetSignalId(),
1193 "overlaps a driving lane. Moving out of the road...");
1194 }
1195
1196 auto right_waypoint = map.GetRight(closest_waypoint_to_signal.value());
1197 auto right_lane_type = (right_waypoint) ? map.GetLaneType(right_waypoint.value()) : carla::road::Lane::LaneType::None;
1198
1199 auto left_waypoint = map.GetLeft(closest_waypoint_to_signal.value());
1200 auto left_lane_type = (left_waypoint) ? map.GetLaneType(left_waypoint.value()) : carla::road::Lane::LaneType::None;
1201
1202 if (is_rht) {
1203 // Move to the right if possible, then left
1204 if (right_lane_type != carla::road::Lane::LaneType::Driving) {
1205 displacement_direction = 1;
1206 } else if (left_lane_type != carla::road::Lane::LaneType::Driving) {
1207 displacement_direction = -1;
1208 } else {
1209 displacement_direction = 0;
1210 }
1211 } else {
1212 // Move to the left if possible, then right
1213 if (left_lane_type != carla::road::Lane::LaneType::Driving) {
1214 displacement_direction = -1;
1215 } else if (right_lane_type != carla::road::Lane::LaneType::Driving) {
1216 displacement_direction = 1;
1217 } else {
1218 displacement_direction = 0;
1219 }
1220 }
1221
1222 geom::Vector3D displacement = 1.f*(road_transform.GetRightVector()) *
1223 static_cast<float>(abs(lane_width))*0.2f;
1224 signal_position += (displacement * static_cast<float>(displacement_direction));
1225 signal_rotation = road_transform.rotation;
1226 closest_waypoint_to_signal =
1227 map.GetClosestWaypointOnRoad(signal_position,
1228 static_cast<int32_t>(carla::road::Lane::LaneType::Shoulder) | static_cast<int32_t>(carla::road::Lane::LaneType::Driving));
1229 distance_to_road =
1230 (map.ComputeTransform(closest_waypoint_to_signal.value()).location -
1231 signal_position).Length();
1232 lane_width = map.GetLaneWidth(closest_waypoint_to_signal.value());
1233 iter++;
1234 }
1235 if(iter == MaxIter) {
1236 log_debug("Failed to find suitable place for signal.");
1237 } else {
1238 // Only perform the displacement if a good location has been found
1239 signal->_transform.location = signal_position;
1240 signal->_transform.rotation = signal_rotation;
1241 }
1242 }
1243 }
1244 }
1245
1246} // namespace road
1247} // namespace carla
float elevation
float y
float x
float z
#define DEBUG_ASSERT(predicate)
Definition Debug.h:66
#define RELEASE_ASSERT(pred)
Definition Debug.h:84
geom::Point point
Definition LaneGraph.cpp:41
double heading
Definition LaneGraph.cpp:42
std::string road_id
Definition LaneGraph.cpp:39
std::map< std::string, unsigned int > road
std::map< std::string, unsigned int > junction
static void ToLower(WritableRangeT &str)
Definition StringUtil.h:36
static constexpr T ToDegrees(T rad)
Definition Math.h:37
static constexpr T Clamp(T a, T min=T(0), T max=T(1))
Definition Math.h:49
Euler angles of a rotation in CARLA's / Unreal's left-handed frame: x forward, y right,...
Definition Rotation.h:45
A rigid transform in CARLA's / Unreal's left-handed frame: x forward, y right, z up,...
Connection * GetConnection(ConId id)
std::set< ContId > _controllers
std::unordered_map< ConId, Connection > & GetConnections()
Lane * GetLane(const LaneId id)
std::map< LaneId, Lane > _lanes
LaneType
Can be used as flags.
Definition road/Lane.h:29
LaneId GetPredecessor() const
Definition road/Lane.h:102
LaneId GetSuccessor() const
Definition road/Lane.h:98
bool IsPositiveDirection() const
std::unordered_map< SignId, std::unique_ptr< Signal > > _temp_signal_container
Definition MapBuilder.h:461
Lane * GetEdgeLanePointer(RoadId road_id, LaneId lane_id)
Return the pointer to a lane object.
void AddRoadGeometryArc(carla::road::Road *road, const double s, const double x, const double y, const double hdg, const double length, const double curvature)
std::vector< element::RoadInfoStencil * > _temp_stencil_reference_container
Definition MapBuilder.h:468
element::RoadInfoStencil * AddStencil(Road *road, const StencilId stencil_id, const double s, const double t, const std::string name, const std::string orientation, const std::string type, const double zOffset, const double heading, const double length, const double width, const double pitch, const double roll)
void CreateController(const ContId controller_id, const std::string controller_name, const uint32_t controller_sequence, const std::set< road::SignId > &&signals)
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 SolveStencilReferencesAndTransforms()
Solves the stencil references in the road.
void AddSignalPositionRoad(const SignId signal_id, const RoadId road_id, const double s, const double t, const double zOffset, const double hOffset, const double pitch, const double roll)
void AddSignalPositionInertial(const SignId signal_id, const double x, const double y, const double z, const double hdg, const double pitch, const double roll)
void CreateRoadSpeed(Road *road, const double s, const std::string type, const double max, const std::string unit)
void DebugRoadConnections()
Debug the built connections through the terminal.
void CreateSectionOffset(Road *road, const double s, const double a, const double b, const double c, const double d)
void AddJunctionController(const JuncId junction_id, std::set< ContId > &&controllers)
carla::road::LaneSection * AddRoadSection(carla::road::Road *road, const SectionId id, const double s)
void CreateRoadMark(Lane *lane, const int road_mark_id, const double s, const std::string type, const std::string weight, const std::string color, const std::string material, const double width, const std::string lane_change, const double height, const std::string type_name, const double type_width, const bool is_rht)
void CreateLaneAccess(Lane *lane, const double s, const std::string restriction)
void AddRoadLateralShape(Road *road, const double s, const double a, const double b, const double c, const double d, const double t)
void AddRoadObjectCrosswalk(Road *road, const std::string name, const double s, const double t, const double zOffset, const double hdg, const double pitch, const double roll, const std::string orientation, const double width, const double length, const std::vector< road::element::CrosswalkPoint > points)
geom::Transform ComputeStencilTransform(std::unique_ptr< Stencil > &stencil, MapData &data)
void CreateLaneHeight(Lane *lane, const double s, const double inner, const double outer)
geom::Transform ComputeSignalTransform(std::unique_ptr< Signal > &signal, MapData &data)
Lane * GetLane(const RoadId road_id, const LaneId lane_id, const double s)
void CreateLaneBorder(Lane *lane, const double s, const double a, const double b, const double c, const double d)
std::unordered_map< StencilId, std::unique_ptr< Stencil > > _temp_stencil_container
Definition MapBuilder.h:466
void ComputeJunctionRoadConflicts(Map &map)
Compute the conflicts of the roads (intersecting roads)
void AddValidityToSignalReference(element::RoadInfoSignal *signal_reference, const LaneId from_lane, const LaneId to_lane)
std::optional< Map > Build()
void CreateLaneRule(Lane *lane, const double s, const std::string value)
void SolveControllerAndJuntionReferences()
Solve the references between Controllers and Juntions.
void AddRoadElevationProfile(Road *road, const double s, const double a, const double b, const double c, const double d)
void AddJunction(const JuncId id, const std::string name)
void CreateLaneSpeed(Lane *lane, const double s, const double max, const std::string unit)
std::unordered_map< Road *, std::vector< std::unique_ptr< element::RoadInfo > > > _temp_road_info_container
Map to temporary store all the road and lane infos until the map is built, so they can be added all t...
Definition MapBuilder.h:455
void AddLaneLink(const JuncId junction_id, const ConId connection_id, const LaneId from, const LaneId to)
void AddDependencyToSignal(const SignId signal_id, const std::string dependency_id, const std::string dependency_type)
void AddRoadGeometryParamPoly3(carla::road::Road *road, const double s, const double x, const double y, const double hdg, const double length, const double aU, const double bU, const double cU, const double dU, const double aV, const double bV, const double cV, const double dV, const std::string p_range)
void RemoveZeroLaneValiditySignalReferences()
Removes signal references with lane validity equal to [0,0] as they have no effect on any road.
void CreateRoadMarkTypeLine(Lane *lane, const int road_mark_id, const double length, const double space, const double tOffset, const double s, const std::string rule, const double width)
void CreateJunctionBoundingBoxes(Map &map)
Create the bounding boxes of each junction.
element::RoadInfoSignal * AddSignalReference(Road *road, const SignId signal_id, const double s_position, const double t_position, const std::string signal_reference_orientation)
std::unordered_map< Lane *, std::vector< std::unique_ptr< element::RoadInfo > > > _temp_lane_info_container
Definition MapBuilder.h:458
std::vector< element::RoadInfoSignal * > _temp_signal_reference_container
Definition MapBuilder.h:463
void AddRoadGeometryPoly3(carla::road::Road *road, const double s, const double x, const double y, const double hdg, const double length, const double a, const double b, const double c, const double d)
void GenerateDefaultValiditiesForSignalReferences()
Generates a default validity field for signal references with missing validity record in OpenDRIVE.
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, const bool is_rht)
void AddConnection(const JuncId junction_id, const ConId connection_id, const RoadId incoming_road, const RoadId connecting_road)
element::RoadInfoSignal * AddSignal(Road *road, const SignId signal_id, const double s, const double t, const std::string name, const std::string dynamic, const std::string orientation, const double zOffset, const std::string country, const std::string type, const std::string subtype, const double value, const std::string unit, const double height, const double width, const std::string text, const double hOffset, const double pitch, const double roll)
std::vector< Lane * > GetLaneNext(RoadId road_id, SectionId section_id, LaneId lane_id)
Return a list of pointers to all lanes from a lane (using road and junction info).
void CreateLaneWidth(Lane *lane, const double s, const double a, const double b, const double c, const double d)
std::vector< std::pair< RoadId, const Lane * > > GetJunctionLanes(JuncId junction_id, RoadId road_id, LaneId lane_id)
void SolveSignalReferencesAndTransforms()
Solves the signal references in the road.
void CreateLaneVisibility(Lane *lane, const double s, const double forward, const double back, const double left, const double right)
void CreatePointersBetweenRoadSegments()
Create the pointers between RoadSegments based on the ids.
Road * GetRoad(const RoadId road_id)
void CreateLaneMaterial(Lane *lane, const double s, const std::string surface, const double friction, const double roughness)
void CheckSignalsOnRoads(Map &map)
Checks signals overlapping driving lanes and emits a warning.
void AddRoadGeometrySpiral(carla::road::Road *road, const double s, const double x, const double y, const double hdg, const double length, const double curvStart, const double curvEnd)
void AddRoadGeometryLine(carla::road::Road *road, const double s, const double x, const double y, const double hdg, const double length)
std::unordered_map< RoadId, Road > _roads
Definition MapData.h:106
std::unordered_map< StencilId, std::unique_ptr< Stencil > > _stencils
Definition MapData.h:114
Road & GetRoad(const RoadId id)
Definition MapData.cpp:21
std::unordered_map< ContId, std::unique_ptr< Controller > > _controllers
Definition MapData.h:112
std::unordered_map< JuncId, Junction > _junctions
Definition MapData.h:108
bool ContainsRoad(RoadId id) const
Definition MapData.h:54
std::unordered_map< JuncId, Junction > & GetJunctions()
Definition MapData.cpp:17
Junction * GetJunction(JuncId id)
Definition MapData.cpp:29
std::unordered_map< SignId, std::unique_ptr< Signal > > _signals
Definition MapData.h:110
std::optional< Waypoint > GetLeft(Waypoint waypoint) const
Return a waypoint at the lane of waypoint's left lane.
Definition road/Map.cpp:789
Lane::LaneType GetLaneType(Waypoint waypoint) const
Definition road/Map.cpp:286
double GetLaneWidth(Waypoint waypoint) const
Definition road/Map.cpp:290
std::vector< Waypoint > GetNext(Waypoint waypoint, double distance) const
Return the list of waypoints at distance such that a vehicle at waypoint could drive to.
Definition road/Map.cpp:669
std::optional< Waypoint > GetRight(Waypoint waypoint) const
Return a waypoint at the lane of waypoint's right lane.
Definition road/Map.cpp:767
Junction * GetJunction(JuncId id)
std::optional< element::Waypoint > GetClosestWaypointOnRoad(const geom::Location &location, int32_t lane_type=static_cast< int32_t >(Lane::LaneType::Driving)) const
========================================================================
Definition road/Map.cpp:170
geom::Transform ComputeTransform(Waypoint waypoint) const
Definition road/Map.cpp:278
std::vector< std::pair< Waypoint, Waypoint > > GetJunctionWaypoints(JuncId id, Lane::LaneType lane_type) const
Generate waypoints of the junction.
Definition road/Map.cpp:907
std::unordered_map< road::RoadId, std::unordered_set< road::RoadId > > ComputeJunctionConflicts(JuncId id) const
Definition road/Map.cpp:924
const Lane & GetLane(Waypoint waypoint) const
========================================================================
Definition road/Map.cpp:994
Lane & GetLaneByDistance(double s, LaneId lane_id)
Definition road/Road.cpp:80
bool IsRHT() const
Definition road/Road.cpp:52
element::DirectedPoint GetDirectedPointInNoLaneOffset(const double s) const
Returns a directed point on the center of the road (lane 0), with the corresponding laneOffset and el...
static bool IsTrafficLight(const std::string &type)
std::vector< LaneValidity > _validities
std::string StencilId
Definition RoadTypes.h:27
int32_t JuncId
Definition RoadTypes.h:17
std::string ContId
Definition RoadTypes.h:31
std::string SignId
Definition RoadTypes.h:25
uint32_t RoadId
Definition RoadTypes.h:15
int32_t LaneId
Definition RoadTypes.h:19
uint32_t ConId
Definition RoadTypes.h:29
uint32_t SectionId
Definition RoadTypes.h:21
This file contains definitions of common data structures used in traffic manager.
static void log_debug(Args &&... args)
Definition Logging.h:68
void AddLaneLink(LaneId from, LaneId to)