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
25 // 获取当前车道所在的车道段
26 const LaneSection *Lane::GetLaneSection() const {
27 return _lane_section; // 返回车道段指针
28 }
29
30 // 获取当前车道所属的道路
31 Road *Lane::GetRoad() const {
32 DEBUG_ASSERT(_lane_section != nullptr); // 确保车道段不为空
33 return _lane_section->GetRoad(); // 返回车道段对应的道路
34 }
35
36 // 获取当前车道的ID
37 LaneId Lane::GetId() const {
38 return _id; // 返回车道ID
39 }
40
41 // 获取当前车道的类型
43 return _type; // 返回车道类型
44 }
45
46 // 获取当前车道的等级
47 bool Lane::GetLevel() const {
48 return _level; // 返回车道等级
49 }
50
51 // 获取当前车道在道路上的距离
52 double Lane::GetDistance() const {
53 DEBUG_ASSERT(_lane_section != nullptr); // 确保车道段不为空
54 return _lane_section->GetDistance(); // 返回距离
55 }
56
57 // 获取当前车道的长度
58 double Lane::GetLength() const {
59 const auto *road = GetRoad(); // 获取所属道路
60 DEBUG_ASSERT(road != nullptr); // 确保道路不为空
61 const auto s = GetDistance(); // 获取车道的距离
62 return road->UpperBound(s) - s; // 计算并返回车道长度
63 }
64
65 // 获取指定位置s处的车道宽度
66 double Lane::GetWidth(const double s) const {
67 RELEASE_ASSERT(s <= GetRoad()->GetLength()); // 确保s不超过道路的长度
68 const auto width_info = GetInfo<element::RoadInfoLaneWidth>(s); // 获取宽度信息
69 if(width_info != nullptr){
70 return width_info->GetPolynomial().Evaluate(s); // 根据多项式计算并返回宽度
71 }
72 return 0.0f; // 如果没有宽度信息,返回0
73 }
74
75 // 检查当前车道是否为直线
76 bool Lane::IsStraight() const {
77 Road *road = GetRoad(); // 获取所属道路
78 RELEASE_ASSERT(road != nullptr); // 确保道路不为空
79 auto *geometry = road->GetInfo<element::RoadInfoGeometry>(GetDistance()); // 获取几何信息
80 DEBUG_ASSERT(geometry != nullptr); // 确保几何信息不为空
81 auto geometry_type = geometry->GetGeometry().GetType(); // 获取几何类型
82 if (geometry_type != element::GeometryType::LINE) {
83 return false; // 如果不是直线,返回false
84 }
85 // 检查距离是否在几何范围内
86 if(GetDistance() < geometry->GetDistance() ||
87 // 检查当前对象的起点是否在几何对象的起点之前
89 // 检查当前对象的终点是否在几何对象的终点之后
90 geometry->GetDistance() + geometry->GetGeometry().GetLength()) {
91 return false; // 如果不在范围内,返回false
92 }
93 // 检查车道偏移信息
94 // 车道偏移信息通过多项式表示,其中C和D是多项式的系数。
95 // 如果C或D不为0,表示车道有偏移(不是直线)。
96 auto lane_offsets = GetInfos<element::RoadInfoLaneOffset>();// 获取车道偏移信息
97 for (auto *lane_offset : lane_offsets) {// 遍历每个车道偏移信息
98 if (std::abs(lane_offset->GetPolynomial().GetC()) > 0 ||
99 std::abs(lane_offset->GetPolynomial().GetD()) > 0) {
100 return false; // 如果偏移量不为0,返回false
101 }
102 }
103 // 检查道路高程信息
104 // 道路高程信息也通过多项式表示,其中C和D是多项式的系数。
105 // 如果C或D不为0,表示道路有高程变化(不是平面)。
106 auto elevations = road->GetInfos<element::RoadInfoElevation>(); // 获取道路高程信息
107 for (auto *elevation : elevations) { // 遍历每个道路高程信息
108 if (std::abs(elevation->GetPolynomial().GetC()) > 0 ||
109 std::abs(elevation->GetPolynomial().GetD()) > 0) {
110 return false; // 如果高程不为0,返回false
111 }
112 }
113 return true; // 如果所有检查通过,返回true
114 }
115
116 /// 返回一对包含特定车道在给定s和车道迭代器下的宽度和切线
117// 这个模板函数计算并返回一个包含车道宽度和切线的pair。
118// 它接受一个容器(可能是道路、路径等),一个s值(沿路径的距离),以及一个车道ID。
119 template <typename T>
120 static std::pair<double, double> ComputeTotalLaneWidth(
121 const T container,// 容器,可能代表道路或路径的抽象
122 const double s, // s值,表示沿路径的特定位置
123 const LaneId lane_id) {// 车道ID,用于标识特定的车道
124
125 // lane_id不能为0
126 RELEASE_ASSERT(lane_id != 0); // 断言 lane_id 不为 0
127
128const bool negative_lane_id = lane_id < 0; // 判断 lane_id 是否为负
129double dist = 0.0; // 初始化距离
130double tangent = 0.0; // 初始化切线
131
132for (const auto &lane : container) { // 遍历所有车道
133 auto info = lane.second.template GetInfo<element::RoadInfoLaneWidth>(s); // 获取当前车道宽度信息
134 RELEASE_ASSERT(info != nullptr); // 断言信息不为空
135 const auto current_polynomial = info->GetPolynomial(); // 获取当前多项式
136 auto current_dist = current_polynomial.Evaluate(s); // 计算当前距离
137 auto current_tang = current_polynomial.Tangent(s); // 计算当前切线
138
139 if (lane.first != lane_id) { // 如果当前车道 ID 不等于给定的 lane_id
140 dist += negative_lane_id ? current_dist : -current_dist; // 根据 lane_id 的正负更新距离
141 tangent += negative_lane_id ? current_tang : -current_tang; // 根据 lane_id 的正负更新切线
142 } else { // 如果当前车道 ID 等于给定的 lane_id
143 current_dist *= 0.5; // 将当前距离乘以 0.5
144 dist += negative_lane_id ? current_dist : -current_dist; // 更新距离
145 tangent += (negative_lane_id ? current_tang : -current_tang) * 0.5; // 更新切线
146 break; // 跳出循环
147 }
148}
149return std::make_pair(dist, tangent); // 返回距离和切线的对
150
151geom::Transform Lane::ComputeTransform(const double s) const { // 计算车道变换
152 const Road* road = GetRoad(); // 获取道路对象
153 DEBUG_ASSERT(road != nullptr); // 断言道路对象不为空
154
155 // 确保 s 小于等于道路长度且大于等于 0
156 RELEASE_ASSERT(s <= road->GetLength());
157 RELEASE_ASSERT(s >= 0.0);
158
159 const auto* lane_section = GetLaneSection(); // 获取车道段
160 DEBUG_ASSERT(lane_section != nullptr); // 断言车道段不为空
161 const std::map<LaneId, Lane>& lanes = lane_section->GetLanes(); // 获取车道映射
162
163 // 检查当前 s 上是否存在 lane_id
164 RELEASE_ASSERT(!lanes.empty());
165 RELEASE_ASSERT(GetId() >= lanes.begin()->first); // 断言 lane_id 在有效范围内
166 RELEASE_ASSERT(GetId() <= lanes.rbegin()->first); // 断言 lane_id 在有效范围内
167
168 // 累积当前车道与车道 0 之间的横向偏移 (t) 和车道方向
169 float lane_t_offset = 0.0f; // 初始化车道横向偏移
170 float lane_tangent = 0.0f; // 初始化车道方向
171
172 if (GetId() < 0) { // 如果是右侧车道
173 const auto side_lanes = MakeListView(
174 std::make_reverse_iterator(lanes.lower_bound(0)), lanes.rend()); // 获取从 0 到当前车道的车道列表
175 const auto computed_width =
176 ComputeTotalLaneWidth(side_lanes, s, GetId()); // 计算总车道宽度
177 lane_t_offset = static_cast<float>(computed_width.first); // 设置车道横向偏移
178 lane_tangent = static_cast<float>(computed_width.second); // 设置车道方向
179 }
180 else if (GetId() > 0) { // 如果是左侧车道
181 const auto side_lanes = MakeListView(lanes.lower_bound(1), lanes.end()); // 获取从 1 到当前车道的车道列表
182 const auto computed_width =
183 ComputeTotalLaneWidth(side_lanes, s, GetId()); // 计算总车道宽度
184 lane_t_offset = static_cast<float>(computed_width.first); // 设置车道横向偏移
185 lane_tangent = static_cast<float>(computed_width.second); // 设置车道方向
186 }
187
188 // 计算当前 s 的道路(车道 0)的“laneOffset”切线
189 const auto lane_offset_info = road->GetInfo<element::RoadInfoLaneOffset>(s); // 获取车道偏移信息
190 const auto lane_offset_tangent =
191 static_cast<float>(lane_offset_info->GetPolynomial().Tangent(s)); // 获取车道偏移切线
192
193 // 用当前 s 更新道路切线,减去“laneOffset”信息
194 lane_tangent -= lane_offset_tangent;
195
196 // 获取在当前 s 的车道中心的有向点
197 element::DirectedPoint dp = road->GetDirectedPointIn(s);
198
199 // 从道路中心转换到车道中心
200 dp.ApplyLateralOffset(lane_t_offset);
201
202 // 用当前 s 更新车道切线,减去道路的“laneOffset”
203 dp.tangent -= lane_tangent;
204
205 // Unreal 的 Y 轴转换
206 dp.location.y *= -1; // 反转 Y 轴
207 dp.tangent *= -1; // 反转切线
208
209 geom::Rotation rot(
210 geom::Math::ToDegrees(static_cast<float>(dp.pitch)), // 将俯仰角转换为度
211 geom::Math::ToDegrees(static_cast<float>(dp.tangent)), // 将切线角转换为度
212 0.0f); // Z 轴角度设为 0 // Fix the direction of the possitive lanes
213 if (GetId() > 0) { // 如果车道 ID 大于 0
214 rot.yaw += 180.0f; // 将偏航角加上 180 度
215 rot.pitch = 360.0f - rot.pitch; // 将俯仰角调整为 360 度减去当前俯仰角
216 }
217
218 return geom::Transform(dp.location, rot); // 返回位置和旋转变换
219}
220
221std::pair<geom::Vector3D, geom::Vector3D> Lane::GetCornerPositions( // 定义获取车道角落位置的方法
222 const double s, const float extra_width) const { // 接受参数 s 和额外的宽度
223 const Road *road = GetRoad(); // 获取道路对象
224 DEBUG_ASSERT(road != nullptr); // 断言道路对象不为空
225
226 const auto *lane_section = GetLaneSection(); // 获取车道段
227 DEBUG_ASSERT(lane_section != nullptr); // 断言车道段不为空
228 const std::map<LaneId, Lane> &lanes = lane_section->GetLanes(); // 获取车道映射
229
230 // 检查当前 s 上是否存在 lane_id
231 RELEASE_ASSERT(!lanes.empty()); // 断言车道不为空
232 RELEASE_ASSERT(GetId() >= lanes.begin()->first); // 断言 lane_id 不小于最小值
233 RELEASE_ASSERT(GetId() <= lanes.rbegin()->first); // 断言 lane_id 不大于最大值
234
235 float lane_t_offset = 0.0f; // 初始化车道横向偏移
236
237 if (GetId() < 0) { // 如果是右侧车道
238 // 获取从 0 到当前车道的车道列表
239 const auto side_lanes = MakeListView(
240 std::make_reverse_iterator(lanes.lower_bound(0)), lanes.rend());
241 const auto computed_width =
242 ComputeTotalLaneWidth(side_lanes, s, GetId()); // 计算总车道宽度
243 lane_t_offset = static_cast<float>(computed_width.first); // 设置车道横向偏移
244 } else if (GetId() > 0) { // 如果是左侧车道
245 // 获取从 1 到当前车道的车道列表
246 const auto side_lanes = MakeListView(lanes.lower_bound(1), lanes.end());
247 const auto computed_width =
248 ComputeTotalLaneWidth(side_lanes, s, GetId()); // 计算总车道宽度
249 lane_t_offset = static_cast<float>(computed_width.first); // 设置车道横向偏移
250 }
251
252 float lane_width = static_cast<float>(GetWidth(s)) / 2.0f; // 获取当前车道宽度的一半
253 if (extra_width != 0.f && road->IsJunction() && GetType() == Lane::LaneType::Driving) { // 如果有额外宽度且是交叉口且车道类型为驾驶
254 lane_width += extra_width; // 增加额外宽度
255 }
256
257 // 获取在给定 s 上道路中心的两个点
258 element::DirectedPoint dp_r, dp_l; // 初始化右侧和左侧的有向点
259 dp_r = dp_l = road->GetDirectedPointIn(s); // 获取道路中心的有向点
260
261 // 从道路中心转换到每个车道角落
262 dp_r.ApplyLateralOffset(lane_t_offset + lane_width); // 右侧车道角落
263 dp_l.ApplyLateralOffset(lane_t_offset - lane_width); // 左侧车道角落
264
265 // Unreal 的 Y 轴处理
266 dp_r.location.y *= -1; // 反转右侧点的 Y 坐标
267 dp_l.location.y *= -1; // 反转左侧点的 Y 坐标
268
269 // 对人行道应用偏移
270 if (GetType() == LaneType::Sidewalk) { // 如果车道类型为人行道
271 // RoadRunner 当前不导出该信息,作为临时解决方案,15.24 cm 是大多数 RoadRunner 人行道匹配的高度
272 dp_r.location.z += 0.1524f; // 右侧点的 Z 坐标增加 0.1524 米
273 dp_l.location.z += 0.1524f; // 左侧点的 Z 坐标增加 0.1524 米
274 /// @TODO: 使用 OpenDRIVE 5.3.7.2.1.1.9 车道高度记录
275 }
276
277 return std::make_pair(dp_r.location, dp_l.location); // 返回右侧和左侧点的位置
278}
#define DEBUG_ASSERT(predicate)
Definition Debug.h:68
#define RELEASE_ASSERT(pred)
Definition Debug.h:94
static constexpr T ToDegrees(T rad)
Definition Math.h:40
double GetDistance() const
bool IsStraight() const
检查几何形状是否是直线
Road * GetRoad() const
double GetWidth(const double s) const
返回给定位置s的车道总宽度
geom::Transform ComputeTransform(const double s) const
const LaneSection * GetLaneSection() const
LaneType
可以作为标志使用
Definition Lane.h:29
bool GetLevel() const
LaneType GetType() const
LaneSection * _lane_section
Definition Lane.h:126
double GetDistance() const
std::pair< geom::Vector3D, geom::Vector3D > GetCornerPositions(const double s, const float extra_width=0.f) const
计算给定位置s的车道边缘位置
LaneId GetId() const
double GetLength() const
LaneType _type
Definition Lane.h:132
int32_t LaneId
Definition RoadTypes.h:26
CARLA模拟器的主命名空间。
Definition Carla.cpp:139
static auto MakeListView(Iterator begin, Iterator end)