CARLA
Loading...
Searching...
No Matches
client/Waypoint.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
9#include "carla/client/Map.h"
12#include "carla/client/Lane.h"
13#include "carla/client/Road.h"
14
15#include <unordered_set>
16
17namespace carla {
18namespace client {
19
21 : _parent(std::move(parent)),
22 _waypoint(std::move(waypoint)),
23 _transform(_parent->GetMap().ComputeTransform(_waypoint)),
24 _mark_record(_parent->GetMap().GetMarkRecord(_waypoint)) {}
25
26 Waypoint::~Waypoint() = default;
27
29 return _parent->GetMap().GetJunctionId(_waypoint.road_id);
30 }
31
32 bool Waypoint::IsJunction() const {
33 return _parent->GetMap().IsJunction(_waypoint.road_id);
34 }
35
37 if (IsJunction()) {
38 return _parent->GetJunction(*this);
39 }
40 return nullptr;
41 }
42
46
48 return _parent->GetRoad(_waypoint.road_id);
49 }
50
51 double Waypoint::GetLaneWidth() const {
52 return _parent->GetMap().GetLaneWidth(_waypoint);
53
54 }
55
57 return _parent->GetMap().GetLaneType(_waypoint);
58 }
59
60 std::vector<SharedPtr<Waypoint>> Waypoint::GetNext(double distance) const {
61 auto waypoints = _parent->GetMap().GetNext(_waypoint, distance);
62 std::vector<SharedPtr<Waypoint>> result;
63 result.reserve(waypoints.size());
64 for (auto &waypoint : waypoints) {
65 result.emplace_back(SharedPtr<Waypoint>(new Waypoint(_parent, std::move(waypoint))));
66 }
67 return result;
68 }
69
70 std::vector<SharedPtr<Waypoint>> Waypoint::GetPrevious(double distance) const {
71 auto waypoints = _parent->GetMap().GetPrevious(_waypoint, distance);
72 std::vector<SharedPtr<Waypoint>> result;
73 result.reserve(waypoints.size());
74 for (auto &waypoint : waypoints) {
75 result.emplace_back(SharedPtr<Waypoint>(new Waypoint(_parent, std::move(waypoint))));
76 }
77 return result;
78 }
79
80 std::vector<SharedPtr<Waypoint>> Waypoint::GetNextUntilLaneEnd(double distance) const {
81 std::vector<SharedPtr<Waypoint>> result;
82 std::vector<SharedPtr<Waypoint>> next = GetNext(distance);
83
84 while (next.size() == 1 && next.front()->GetRoadId() == GetRoadId()) {
85 result.emplace_back(next.front());
86 next = result.back()->GetNext(distance);
87 }
88 double current_s = GetDistance();
89 if(result.size()) {
90 current_s = result.back()->GetDistance();
91 }
92 double remaining_length;
93 double road_length = _parent->GetMap().GetLane(_waypoint).GetRoad()->GetLength();
95 remaining_length = road_length - current_s;
96 } else {
97 remaining_length = current_s;
98 }
99 remaining_length -= std::numeric_limits<double>::epsilon();
100 if(result.size()) {
101 result.emplace_back(result.back()->GetNext(remaining_length).front());
102 } else {
103 result.emplace_back(GetNext(remaining_length).front());
104 }
105
106 return result;
107 }
108
109 std::vector<SharedPtr<Waypoint>> Waypoint::GetPreviousUntilLaneStart(double distance) const {
110 std::vector<SharedPtr<Waypoint>> result;
111 std::vector<SharedPtr<Waypoint>> prev = GetPrevious(distance);
112
113 while (prev.size() == 1 && prev.front()->GetRoadId() == GetRoadId()) {
114 result.emplace_back(prev.front());
115 prev = result.back()->GetPrevious(distance);
116 }
117
118 double current_s = GetDistance();
119 if(result.size()) {
120 current_s = result.back()->GetDistance();
121 }
122
123 double remaining_length;
124 double road_length = _parent->GetMap().GetLane(_waypoint).GetRoad()->GetLength();
125 if(IsPositiveDirection()) {
126 remaining_length = road_length - current_s;
127 } else {
128 remaining_length = current_s;
129 }
130 remaining_length -= std::numeric_limits<double>::epsilon();
131 if(result.size()) {
132 result.emplace_back(result.back()->GetPrevious(remaining_length).front());
133 } else {
134 result.emplace_back(GetPrevious(remaining_length).front());
135 }
136
137 return result;
138 }
139
141 auto right_lane_waypoint =
142 _parent->GetMap().GetRight(_waypoint);
143 if (right_lane_waypoint.has_value()) {
144 return SharedPtr<Waypoint>(new Waypoint(_parent, std::move(*right_lane_waypoint)));
145 }
146 return nullptr;
147 }
148
150 auto left_lane_waypoint =
151 _parent->GetMap().GetLeft(_waypoint);
152 if (left_lane_waypoint.has_value()) {
153 return SharedPtr<Waypoint>(new Waypoint(_parent, std::move(*left_lane_waypoint)));
154 }
155 return nullptr;
156 }
157
158 std::optional<road::element::LaneMarking> Waypoint::GetRightLaneMarking() const {
159 auto road = _parent->GetMap().GetLane(_waypoint).GetRoad();
160 const auto lane_marking_right_info = road->IsRHT() ? _mark_record.first : _mark_record.second;
161 if (lane_marking_right_info != nullptr) {
162 return road::element::LaneMarking(*lane_marking_right_info);
163 }
164 return std::optional<road::element::LaneMarking>{};
165 }
166
167 std::optional<road::element::LaneMarking> Waypoint::GetLeftLaneMarking() const {
168 auto road = _parent->GetMap().GetLane(_waypoint).GetRoad();
169 const auto lane_marking_left_info = road->IsRHT() ? _mark_record.second : _mark_record.first;
170 if (lane_marking_left_info != nullptr) {
171 return road::element::LaneMarking(*lane_marking_left_info);
172 }
173 return std::optional<road::element::LaneMarking>{};
174 }
175
176 template <typename EnumT>
177 static EnumT operator&(EnumT lhs, EnumT rhs) {
178 return static_cast<EnumT>(
179 static_cast<typename std::underlying_type<EnumT>::type>(lhs) &
180 static_cast<typename std::underlying_type<EnumT>::type>(rhs));
181 }
182
183 template <typename EnumT>
184 static EnumT operator|(EnumT lhs, EnumT rhs) {
185 return static_cast<EnumT>(
186 static_cast<typename std::underlying_type<EnumT>::type>(lhs) |
187 static_cast<typename std::underlying_type<EnumT>::type>(rhs));
188 }
189
191 using lane_change_type = road::element::LaneMarking::LaneChange;
192
193 auto road = _parent->GetMap().GetLane(_waypoint).GetRoad();
194
195 const auto lane_change_right_info = road->IsRHT() ? _mark_record.first : _mark_record.second;
196 lane_change_type c_right;
197 if (lane_change_right_info != nullptr) {
198 const auto lane_change_right = lane_change_right_info->GetLaneChange();
199 c_right = static_cast<lane_change_type>(lane_change_right);
200 } else {
201 c_right = lane_change_type::Both;
202 }
203
204 const auto lane_change_left_info = road->IsRHT() ? _mark_record.second : _mark_record.first;
205 lane_change_type c_left;
206 if (lane_change_left_info != nullptr) {
207 const auto lane_change_left = lane_change_left_info->GetLaneChange();
208 c_left = static_cast<lane_change_type>(lane_change_left);
209 } else {
210 c_left = lane_change_type::Both;
211 }
212
213 if (!IsPositiveDirection()) {
214 // if road goes backward
215 if (c_right == lane_change_type::Right) {
216 c_right = lane_change_type::Left;
217 } else if (c_right == lane_change_type::Left) {
218 c_right = lane_change_type::Right;
219 }
220 }
221
222 if (((!IsPositiveDirection()) ? _waypoint.lane_id - 1 : _waypoint.lane_id + 1) < 0) {
223 // if road goes backward
224 if (c_left == lane_change_type::Right) {
225 c_left = lane_change_type::Left;
226 } else if (c_left == lane_change_type::Left) {
227 c_left = lane_change_type::Right;
228 }
229 }
230
231 return (c_right & lane_change_type::Right) | (c_left & lane_change_type::Left);
232 }
233
234 std::vector<SharedPtr<Landmark>> Waypoint::GetAllLandmarksInDistance(
235 double distance, bool stop_at_junction) const {
236 std::vector<SharedPtr<Landmark>> result;
237 auto signals = _parent->GetMap().GetSignalsInDistance(
238 _waypoint, distance, stop_at_junction);
239 std::unordered_set<const road::element::RoadInfoSignal*> added_signals; // check for repeated signals
240 for(auto &signal_data : signals){
241 if(added_signals.count(signal_data.signal) > 0) {
242 continue;
243 }
244 added_signals.insert(signal_data.signal);
245 auto waypoint = SharedPtr<Waypoint>(new Waypoint(_parent, signal_data.waypoint));
246 result.emplace_back(
247 new Landmark(waypoint, _parent, signal_data.signal, signal_data.accumulated_s));
248 }
249 return result;
250 }
251
252 std::vector<SharedPtr<Landmark>> Waypoint::GetLandmarksOfTypeInDistance(
253 double distance, std::string filter_type, bool stop_at_junction) const {
254 std::vector<SharedPtr<Landmark>> result;
255 std::unordered_set<const road::element::RoadInfoSignal*> added_signals; // check for repeated signals
256 auto signals = _parent->GetMap().GetSignalsInDistance(
257 _waypoint, distance, stop_at_junction);
258 for(auto &signal_data : signals){
259 if(signal_data.signal->GetSignal()->GetType() == filter_type) {
260 if(added_signals.count(signal_data.signal) > 0) {
261 continue;
262 }
263 auto waypoint = SharedPtr<Waypoint>(new Waypoint(_parent, signal_data.waypoint));
264 result.emplace_back(
265 new Landmark(waypoint, _parent, signal_data.signal, signal_data.accumulated_s));
266 }
267 }
268 return result;
269 }
270
272 return _parent->GetMap().GetLane(_waypoint).IsPositiveDirection();
273 }
274
275 bool Waypoint::IsRHT() const {
276 return _parent->GetMap().GetLane(_waypoint).GetRoad()->IsRHT();
277 }
278
279} // namespace client
280} // namespace carla
float distance
std::map< long long, long long > _parent
Definition LaneGraph.cpp:78
std::map< std::string, unsigned int > road
Class containing a reference to RoadInfoSignal.
Definition Landmark.h:22
SharedPtr< Waypoint > GetLeft() const
std::vector< SharedPtr< Landmark > > GetLandmarksOfTypeInDistance(double distance, std::string filter_type, bool stop_at_junction=false) const
Returns a list of landmarks from the current position to a certain distance Filters by specified type...
road::element::Waypoint _waypoint
SharedPtr< Waypoint > GetRight() const
std::optional< road::element::LaneMarking > GetLeftLaneMarking() const
SharedPtr< const Map > _parent
road::JuncId GetJunctionId() const
std::optional< road::element::LaneMarking > GetRightLaneMarking() const
SharedPtr< Lane > GetLane() const
The lane this waypoint samples.
std::vector< SharedPtr< Waypoint > > GetPrevious(double distance) const
Waypoint(SharedPtr< const Map > parent, road::element::Waypoint waypoint)
road::element::LaneMarking::LaneChange GetLaneChange() const
std::vector< SharedPtr< Waypoint > > GetNext(double distance) const
SharedPtr< Junction > GetJunction() const
std::vector< SharedPtr< Waypoint > > GetNextUntilLaneEnd(double distance) const
Returns a list of waypoints separated by distance from the current waypoint to the end of the lane.
std::vector< SharedPtr< Landmark > > GetAllLandmarksInDistance(double distance, bool stop_at_junction=false) const
Returns a list of landmarks from the current position to a certain distance.
std::vector< SharedPtr< Waypoint > > GetPreviousUntilLaneStart(double distance) const
Returns a list of waypoints separated by distance from the current waypoint to the start of the lane.
std::pair< const road::element::RoadInfoMarkRecord *, const road::element::RoadInfoMarkRecord * > _mark_record
SharedPtr< Road > GetRoad() const
The road this waypoint samples.
road::Lane::LaneType GetType() const
LaneType
Can be used as flags.
Definition road/Lane.h:29
static EnumT operator&(EnumT lhs, EnumT rhs)
static EnumT operator|(EnumT lhs, EnumT rhs)
int32_t JuncId
Definition RoadTypes.h:17
This file contains definitions of common data structures used in traffic manager.
std::shared_ptr< T > SharedPtr
Definition Memory.h:15
LaneChange
Can be used as flags.
Definition LaneMarking.h:50