CARLA
 
载入中...
搜索中...
未找到
Lane.cpp
浏览该文件的文档.
1// Copyright (c) 2020 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/road/Lane.h"
8
9#include <limits>
10
11#include "carla/Debug.h"
12#include "carla/geom/Math.h"
19#include "carla/road/MapData.h"
20#include "carla/road/Road.h"
21
22namespace carla {
23namespace road {
24
26 return _lane_section;
27 }
28
30 DEBUG_ASSERT(_lane_section != nullptr);
31 return _lane_section->GetRoad();
32 }
33
35 return _id;
36 }
37
39 return _type;
40 }
41
42 bool Lane::GetLevel() const {
43 return _level;
44 }
45
46 double Lane::GetDistance() const {
47 DEBUG_ASSERT(_lane_section != nullptr);
48 return _lane_section->GetDistance();
49 }
50
51 double Lane::GetLength() const {
52 const auto *road = GetRoad();
53 DEBUG_ASSERT(road != nullptr);
54 const auto s = GetDistance();
55 return road->UpperBound(s) - s;
56 }
57
58 double Lane::GetWidth(const double s) const {
60 const auto width_info = GetInfo<element::RoadInfoLaneWidth>(s);
61 if(width_info != nullptr){
62 return width_info->GetPolynomial().Evaluate(s);
63 }
64 return 0.0f;
65 }
66
67 bool Lane::IsStraight() const {
68 Road *road = GetRoad();
69 RELEASE_ASSERT(road != nullptr);
70 auto *geometry = road->GetInfo<element::RoadInfoGeometry>(GetDistance());
71 DEBUG_ASSERT(geometry != nullptr);
72 auto geometry_type = geometry->GetGeometry().GetType();
73 if (geometry_type != element::GeometryType::LINE) {
74 return false;
75 }
76 if(GetDistance() < geometry->GetDistance() ||
78 geometry->GetDistance() + geometry->GetGeometry().GetLength()) {
79 return false;
80 }
81 auto lane_offsets = GetInfos<element::RoadInfoLaneOffset>();
82 for (auto *lane_offset : lane_offsets) {
83 if (std::abs(lane_offset->GetPolynomial().GetC()) > 0 ||
84 std::abs(lane_offset->GetPolynomial().GetD()) > 0) {
85 return false;
86 }
87 }
88 auto elevations = road->GetInfos<element::RoadInfoElevation>();
89 for (auto *elevation : elevations) {
90 if (std::abs(elevation->GetPolynomial().GetC()) > 0 ||
91 std::abs(elevation->GetPolynomial().GetD()) > 0) {
92 return false;
93 }
94 }
95 return true;
96 }
97
98 /// Returns a pair containing first = width, second = tangent,
99 /// for an specific Lane given an s and a iterator over lanes
100 template <typename T>
101 static std::pair<double, double> ComputeTotalLaneWidth(
102 const T container,
103 const double s,
104 const LaneId lane_id) {
105
106 // lane_id can't be 0
107 RELEASE_ASSERT(lane_id != 0);
108
109 const bool negative_lane_id = lane_id < 0;
110 double dist = 0.0;
111 double tangent = 0.0;
112 for (const auto &lane : container) {
113 auto info = lane.second.template GetInfo<element::RoadInfoLaneWidth>(s);
114 RELEASE_ASSERT(info != nullptr);
115 const auto current_polynomial = info->GetPolynomial();
116 auto current_dist = current_polynomial.Evaluate(s);
117 auto current_tang = current_polynomial.Tangent(s);
118 if (lane.first != lane_id) {
119 dist += negative_lane_id ? current_dist : -current_dist;
120 tangent += negative_lane_id ? current_tang : -current_tang;
121 } else {
122 current_dist *= 0.5;
123 dist += negative_lane_id ? current_dist : -current_dist;
124 tangent += (negative_lane_id ? current_tang : -current_tang) * 0.5;
125 break;
126 }
127 }
128 return std::make_pair(dist, tangent);
129 }
130
132 const Road *road = GetRoad();
133 DEBUG_ASSERT(road != nullptr);
134
135 // must s be smaller (or eq) than road length and bigger (or eq) than 0?
136 RELEASE_ASSERT(s <= road->GetLength());
137 RELEASE_ASSERT(s >= 0.0);
138
139 const auto *lane_section = GetLaneSection();
140 DEBUG_ASSERT(lane_section != nullptr);
141 const std::map<LaneId, Lane> &lanes = lane_section->GetLanes();
142
143 // check that lane_id exists on the current s
144 RELEASE_ASSERT(!lanes.empty());
145 RELEASE_ASSERT(GetId() >= lanes.begin()->first);
146 RELEASE_ASSERT(GetId() <= lanes.rbegin()->first);
147
148 // These will accumulate the lateral offset (t) and lane heading of all
149 // the lanes in between the current lane and lane 0, where the main road
150 // geometry is described
151 float lane_t_offset = 0.0f;
152 float lane_tangent = 0.0f;
153
154 if (GetId() < 0) {
155 // right lane
156 const auto side_lanes = MakeListView(
157 std::make_reverse_iterator(lanes.lower_bound(0)), lanes.rend());
158 const auto computed_width =
159 ComputeTotalLaneWidth(side_lanes, s, GetId());
160 lane_t_offset = static_cast<float>(computed_width.first);
161 lane_tangent = static_cast<float>(computed_width.second);
162 } else if (GetId() > 0) {
163 // left lane
164 const auto side_lanes = MakeListView(lanes.lower_bound(1), lanes.end());
165 const auto computed_width =
166 ComputeTotalLaneWidth(side_lanes, s, GetId());
167 lane_t_offset = static_cast<float>(computed_width.first);
168 lane_tangent = static_cast<float>(computed_width.second);
169 }
170
171 // Compute the tangent of the road's (lane 0) "laneOffset" on the current s
172 const auto lane_offset_info = road->GetInfo<element::RoadInfoLaneOffset>(s);
173 const auto lane_offset_tangent =
174 static_cast<float>(lane_offset_info->GetPolynomial().Tangent(s));
175
176 // Update the road tangent with the "laneOffset" information at current s
177 lane_tangent -= lane_offset_tangent;
178
179 // Get a directed point on the center of the current lane given an s
181
182 // Transform from the center of the road to the center of the lane
183 dp.ApplyLateralOffset(lane_t_offset);
184
185 // Update the lane tangent with the road "laneOffset" at current s
186 dp.tangent -= lane_tangent;
187
188 // Unreal's Y axis hack
189 dp.location.y *= -1;
190 dp.tangent *= -1;
191
192 geom::Rotation rot(
193 geom::Math::ToDegrees(static_cast<float>(dp.pitch)),
194 geom::Math::ToDegrees(static_cast<float>(dp.tangent)),
195 0.0f);
196
197 // Fix the direction of the possitive lanes
198 if (GetId() > 0) {
199 rot.yaw += 180.0f;
200 rot.pitch = 360.0f - rot.pitch;
201 }
202
203 return geom::Transform(dp.location, rot);
204 }
205
206 std::pair<geom::Vector3D, geom::Vector3D> Lane::GetCornerPositions(
207 const double s, const float extra_width) const {
208 const Road *road = GetRoad();
209 DEBUG_ASSERT(road != nullptr);
210
211 const auto *lane_section = GetLaneSection();
212 DEBUG_ASSERT(lane_section != nullptr);
213 const std::map<LaneId, Lane> &lanes = lane_section->GetLanes();
214
215 // check that lane_id exists on the current s
216 RELEASE_ASSERT(!lanes.empty());
217 RELEASE_ASSERT(GetId() >= lanes.begin()->first);
218 RELEASE_ASSERT(GetId() <= lanes.rbegin()->first);
219
220 float lane_t_offset = 0.0f;
221
222 if (GetId() < 0) {
223 // right lane
224 const auto side_lanes = MakeListView(
225 std::make_reverse_iterator(lanes.lower_bound(0)), lanes.rend());
226 const auto computed_width =
227 ComputeTotalLaneWidth(side_lanes, s, GetId());
228 lane_t_offset = static_cast<float>(computed_width.first);
229 } else if (GetId() > 0) {
230 // left lane
231 const auto side_lanes = MakeListView(lanes.lower_bound(1), lanes.end());
232 const auto computed_width =
233 ComputeTotalLaneWidth(side_lanes, s, GetId());
234 lane_t_offset = static_cast<float>(computed_width.first);
235 }
236
237 float lane_width = static_cast<float>(GetWidth(s)) / 2.0f;
238 if (extra_width != 0.f && road->IsJunction() && GetType() == Lane::LaneType::Driving) {
239 lane_width += extra_width;
240 }
241
242 // Get two points on the center of the road on given s
243 element::DirectedPoint dp_r, dp_l;
244 dp_r = dp_l = road->GetDirectedPointIn(s);
245
246 // Transform from the center of the road to each of lane corners
247 dp_r.ApplyLateralOffset(lane_t_offset + lane_width);
248 dp_l.ApplyLateralOffset(lane_t_offset - lane_width);
249
250 // Unreal's Y axis hack
251 dp_r.location.y *= -1;
252 dp_l.location.y *= -1;
253
254 // Apply an offset to the Sidewalks
255 if (GetType() == LaneType::Sidewalk) {
256 // RoadRunner doesn't export it right now and as a workarround where 15.24 cm
257 // is the exact height that match with most of the RoadRunner sidewalks
258 dp_r.location.z += 0.1524f;
259 dp_l.location.z += 0.1524f;
260 /// @TODO: use the OpenDRIVE 5.3.7.2.1.1.9 Lane Height Record
261 }
262
263 return std::make_pair(dp_r.location, dp_l.location);
264 }
265
266} // road
267} // carla
#define DEBUG_ASSERT(predicate)
Definition Debug.h:66
#define RELEASE_ASSERT(pred)
Definition Debug.h:84
static constexpr T ToDegrees(T rad)
Definition Math.h:37
double GetDistance() const
bool IsStraight() const
Checks whether the geometry is straight or not
Definition Lane.cpp:67
Road * GetRoad() const
Definition Lane.cpp:29
LaneType GetType() const
Definition Lane.cpp:38
double GetWidth(const double s) const
Returns the total lane width given a s
Definition Lane.cpp:58
geom::Transform ComputeTransform(const double s) const
Definition Lane.cpp:131
const LaneSection * GetLaneSection() const
Definition Lane.cpp:25
LaneType
Can be used as flags
Definition Lane.h:29
bool GetLevel() const
Definition Lane.cpp:42
LaneSection * _lane_section
Definition Lane.h:126
double GetDistance() const
Definition Lane.cpp:46
std::pair< geom::Vector3D, geom::Vector3D > GetCornerPositions(const double s, const float extra_width=0.f) const
Computes the location of the edges given a s
Definition Lane.cpp:206
LaneId GetId() const
Definition Lane.cpp:34
double GetLength() const
Definition Lane.cpp:51
LaneType _type
Definition Lane.h:132
std::vector< const T * > GetInfos() const
Definition Road.h:118
const T * GetInfo(const double s) const
Definition Road.h:113
element::DirectedPoint GetDirectedPointIn(const double s) const
Returns a directed point on the center of the road (lane 0), with the corresponding laneOffset and el...
Definition Road.cpp:180
bool IsJunction() const
Definition Road.cpp:42
The lane offset record defines a lateral shift of the lane reference line(which is usually identical ...
int32_t LaneId
Definition RoadTypes.h:19
static std::pair< double, double > ComputeTotalLaneWidth(const T container, const double s, const LaneId lane_id)
Returns a pair containing first = width, second = tangent, for an specific Lane given an s and a iter...
Definition Lane.cpp:101
This file contains definitions of common data structures used in traffic manager.
Definition Carla.cpp:133
static auto MakeListView(Iterator begin, Iterator end)
void ApplyLateralOffset(float lateral_offset)
Definition Geometry.cpp:28