CARLA
Loading...
Searching...
No Matches
Junction.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
8#include "carla/client/Lane.h"
9#include "carla/client/Map.h"
10#include "carla/client/Road.h"
12
13#include <algorithm>
14#include <unordered_set>
15
16namespace carla {
17namespace client {
18
19 Junction::Junction(SharedPtr<const Map> parent, const road::Junction *junction) : _parent(parent) {
20 _bounding_box = junction->GetBoundingBox();
21 _id = junction->GetId();
22 }
23
24 std::vector<std::pair<SharedPtr<Waypoint>, SharedPtr<Waypoint>>> Junction::GetWaypoints(
25 road::Lane::LaneType type) const {
26 return _parent->GetJunctionWaypoints(GetId(), type);
27 }
28
29 geom::BoundingBox Junction::GetBoundingBox() const {
30 return _bounding_box;
31 }
32
33 std::vector<SharedPtr<Road>> Junction::GetConnectingRoads() const {
34 std::vector<SharedPtr<Road>> result;
35 std::unordered_set<road::RoadId> seen;
36 const road::Junction *junction = _parent->GetMap().GetJunction(_id);
37 if (junction == nullptr) {
38 return result;
39 }
40 for (const auto &pair : junction->GetConnections()) {
41 const road::RoadId road_id = pair.second.connecting_road;
42 if (!seen.insert(road_id).second) {
43 continue;
44 }
46 if (road != nullptr) {
47 result.emplace_back(std::move(road));
48 }
49 }
50 return result;
51 }
52
53 std::vector<SharedPtr<Road>> Junction::GetAdjacentRoads() const {
54 std::vector<SharedPtr<Road>> result;
55 std::unordered_set<road::RoadId> seen;
56 const road::Junction *junction = _parent->GetMap().GetJunction(_id);
57 if (junction == nullptr) {
58 return result;
59 }
60 for (const auto &pair : junction->GetConnections()) {
61 const road::RoadId road_id = pair.second.incoming_road;
62 if (!seen.insert(road_id).second) {
63 continue;
64 }
66 if (road != nullptr) {
67 result.emplace_back(std::move(road));
68 }
69 }
70 return result;
71 }
72
73 // Entry and exit lanes are found by walking the lane graph out of each
74 // connecting lane rather than by reading Connection::lane_links, because the
75 // graph already resolves which end of the adjacent road the junction meets
76 // and which lane section applies there. Lanes still inside the junction are
77 // dropped, so what comes back is always on an adjacent road.
78 std::vector<SharedPtr<Lane>> Junction::GetNeighbourLanes(
80 bool entering) const {
81 std::vector<SharedPtr<Lane>> result;
82 std::unordered_set<uint64_t> seen;
83 for (const auto &pair : GetWaypoints(type)) {
84 const SharedPtr<Waypoint> &waypoint = entering ? pair.first : pair.second;
85 if (waypoint == nullptr) {
86 continue;
87 }
88 SharedPtr<Lane> lane = waypoint->GetLane();
89 if (lane == nullptr) {
90 continue;
91 }
92 const auto neighbours = entering ? lane->GetPreviousLanes() : lane->GetNextLanes();
93 for (const SharedPtr<Lane> &neighbour : neighbours) {
94 if (neighbour == nullptr) {
95 continue;
96 }
97 SharedPtr<Road> road = neighbour->GetRoad();
98 // Skip anything still inside this junction.
99 if (road == nullptr || road->GetJunctionId() == _id) {
100 continue;
101 }
102 if (!seen.insert(neighbour->GetUniqueId()).second) {
103 continue;
104 }
105 result.emplace_back(neighbour);
106 }
107 }
108 return result;
109 }
110
111 std::vector<SharedPtr<Lane>> Junction::GetEntryLanes(road::Lane::LaneType type) const {
112 return GetNeighbourLanes(type, true);
113 }
114
115 std::vector<SharedPtr<Lane>> Junction::GetExitLanes(road::Lane::LaneType type) const {
116 return GetNeighbourLanes(type, false);
117 }
118
119 // The end of a lane that touches the junction. An entry lane carries traffic
120 // into the junction, so the junction sits at its downstream end; an exit lane
121 // carries traffic away, so the junction sits at its upstream end. Which end
122 // that is in road coordinates depends on the lane's direction.
123 static double JunctionSideDistance(const Lane &lane, bool entering) {
124 // Kept a hair inside the lane so the waypoint is always valid rather than
125 // landing exactly on the boundary.
126 constexpr double kEpsilon = 1e-3;
127 const double start = lane.GetDistance();
128 const double end = start + lane.GetLength();
129 const bool downstream = entering;
130 const bool at_end = lane.IsPositiveDirection() == downstream;
131 if (at_end) {
132 return std::max(start, end - kEpsilon);
133 }
134 return std::min(end, start + kEpsilon);
135 }
136
137 std::vector<SharedPtr<Waypoint>> Junction::GetNeighbourWaypoints(
139 bool entering) const {
140 std::vector<SharedPtr<Waypoint>> result;
141 for (const SharedPtr<Lane> &lane : GetNeighbourLanes(type, entering)) {
142 SharedPtr<Waypoint> waypoint = lane->GetWaypoint(JunctionSideDistance(*lane, entering));
143 if (waypoint != nullptr) {
144 result.emplace_back(std::move(waypoint));
145 }
146 }
147 return result;
148 }
149
150 std::vector<SharedPtr<Waypoint>> Junction::GetEntryWaypoints(road::Lane::LaneType type) const {
151 return GetNeighbourWaypoints(type, true);
152 }
153
154 std::vector<SharedPtr<Waypoint>> Junction::GetExitWaypoints(road::Lane::LaneType type) const {
155 return GetNeighbourWaypoints(type, false);
156 }
157
158} // namespace client
159} // namespace carla
std::map< long long, long long > _parent
Definition LaneGraph.cpp:78
std::string road_id
Definition LaneGraph.cpp:39
std::map< std::string, unsigned int > road
std::map< std::string, unsigned int > junction
std::vector< SharedPtr< Lane > > GetNeighbourLanes(road::Lane::LaneType type, bool entering) const
Shared implementation of GetEntryLanes / GetExitLanes.
Definition Junction.cpp:78
std::vector< std::pair< SharedPtr< Waypoint >, SharedPtr< Waypoint > > > GetWaypoints(road::Lane::LaneType type=road::Lane::LaneType::Driving) const
Definition Junction.cpp:24
std::vector< SharedPtr< Waypoint > > GetNeighbourWaypoints(road::Lane::LaneType type, bool entering) const
Shared implementation of GetEntryWaypoints / GetExitWaypoints.
Definition Junction.cpp:137
carla::road::JuncId GetId() const
geom::BoundingBox _bounding_box
SharedPtr< const Map > _parent
A single OpenDRIVE lane, identified by (road id, lane section id, lane id).
Definition client/Lane.h:37
double GetDistance() const
The s coordinate, along the road, at which this lane's section begins.
double GetLength() const
Length of the lane, in metres.
bool IsPositiveDirection() const
Whether the lane runs along increasing s (a right-hand lane, id < 0).
LaneType
Can be used as flags.
Definition road/Lane.h:29
static double JunctionSideDistance(const Lane &lane, bool entering)
Definition Junction.cpp:123
uint32_t RoadId
Definition RoadTypes.h:15
This file contains definitions of common data structures used in traffic manager.
std::shared_ptr< T > SharedPtr
Definition Memory.h:15