CARLA
 
载入中...
搜索中...
未找到
Geometry.cpp
浏览该文件的文档.
1// Copyright (c) 2019 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// 引入carla/road/element/Geometry.h头文件
9
10// 引入carla/Debug.h头文件
11#include "carla/Debug.h"
12// 引入carla/Exception.h头文件
13#include "carla/Exception.h"
14// 引入carla/geom/Location.h头文件
15#include "carla/geom/Location.h"
16// 引入carla/geom/Math.h头文件
17#include "carla/geom/Math.h"
18// 引入carla/geom/Vector2D.h头文件
19#include "carla/geom/Vector2D.h"
20
21// 引入boost/array.hpp头文件
22#include <boost/array.hpp>
23// 引入boost/math/tools/rational.hpp头文件
24#include <boost/math/tools/rational.hpp>
25
26// 引入odrSpiral/odrSpiral.h头文件
27#include <odrSpiral/odrSpiral.h>
28
29// 引入algorithm标准库头文件
30#include <algorithm>
31// 引入cmath标准库头文件,用于数学运算
32#include <cmath>
33// 引入stdexcept标准库头文件,用于处理异常
34#include <stdexcept>
35
36// 定义命名空间carla
37namespace carla {
38// 定义命名空间road,在carla命名空间内
39namespace road {
40// 定义命名空间element,在road命名空间内
41namespace element {
42
43// 函数:DirectedPoint类的成员函数,用于应用横向偏移量
44// lateral_offset: 横向偏移量
45void DirectedPoint::ApplyLateralOffset(float lateral_offset) {
46 /// @todo Z轴相关(这里可能是待处理的关于Z轴的内容)
47 // 计算法向量的x分量,将弧度制的tangent转换为sin值
48 auto normal_x = std::sin(static_cast<float>(tangent));
49 // 计算法向量的y分量,将弧度制的tangent转换为 -cos值
50 auto normal_y = -std::cos(static_cast<float>(tangent));
51 // 根据横向偏移量更新位置的x坐标
52 location.x += lateral_offset * normal_x;
53 // 根据横向偏移量更新位置的y坐标
54 location.y += lateral_offset * normal_y;
55}
56
57// 函数:GeometryLine类的成员函数,根据距离获取位置点
58// dist: 距离
60 // 调试断言,确保_length大于0.0
61 DEBUG_ASSERT(_length > 0.0);
62 // 将距离限制在0.0到_length之间
63 dist = geom::Math::Clamp(dist, 0.0, _length);
64 // 创建一个DirectedPoint对象,初始位置为_start_position,方向为_heading
66 // 根据距离和方向更新位置的x坐标
67 p.location.x += static_cast<float>(dist * std::cos(p.tangent));
68 // 根据距离和方向更新位置的y坐标
69 p.location.y += static_cast<float>(dist * std::sin(p.tangent));
70 // 返回计算后的DirectedPoint对象
71 return p;
72}
73
74// 函数:GeometryArc类的成员函数,根据距离获取位置点
75// dist: 距离
77 // 将距离限制在0.0到_length之间
78 dist = geom::Math::Clamp(dist, 0.0, _length);
79 // 调试断言,确保_length大于0.0
80 DEBUG_ASSERT(_length > 0.0);
81 // 调试断言,确保曲率的绝对值大于1e - 15
82 DEBUG_ASSERT(std::fabs(_curvature) > 1e-15);
83 // 根据曲率计算半径
84 const double radius = 1.0 / _curvature;
85 // 定义常量pi_half,即圆周率的一半
86 constexpr double pi_half = geom::Math::Pi<double>() / 2.0;
87 // 创建一个DirectedPoint对象,初始位置为_start_position,方向为_heading
89 // 根据半径和初始方向更新位置的x坐标
90 p.location.x += static_cast<float>(radius * std::cos(p.tangent + pi_half));
91 // 根据半径和初始方向更新位置的y坐标
92 p.location.y += static_cast<float>(radius * std::sin(p.tangent + pi_half));
93 // 根据距离和曲率更新tangent(方向相关的值)
94 p.tangent += dist * _curvature;
95 // 根据更新后的tangent和半径再次更新位置的x坐标
96 p.location.x -= static_cast<float>(radius * std::cos(p.tangent + pi_half));
97 // 根据更新后的tangent和半径再次更新位置的y坐标
98 p.location.y -= static_cast<float>(radius * std::sin(p.tangent + pi_half));
99 // 返回计算后的DirectedPoint对象
100 return p;
101}
102
103// 函数:用于将点绕某个角度旋转的辅助函数
104// angle: 旋转角度
105// x, y: 点的坐标
106geom::Vector2D RotatebyAngle(double angle, double x, double y) {
107 // 计算旋转角度的cos值
108 const double cos_a = std::cos(angle);
109 // 计算旋转角度的sin值
110 const double sin_a = std::sin(angle);
111 // 返回旋转后的向量
112 return geom::Vector2D(
113 static_cast<float>(x * cos_a - y * sin_a),
114 static_cast<float>(y * cos_a + x * sin_a));
115}
116
117// 函数:GeometrySpiral类的成员函数,根据距离获取位置点
118// dist: 距离
120 // 将距离限制在0.0到_length之间
121 dist = geom::Math::Clamp(dist, 0.0, _length);
122 // 调试断言,确保_length大于0.0
123 DEBUG_ASSERT(_length > 0.0);
124 // 创建一个DirectedPoint对象,初始位置为_start_position,方向为_heading
126
127 // 获取螺旋线终点的曲率
128 const double curve_end = (_curve_end);
129 // 获取螺旋线起点的曲率
130 const double curve_start = (_curve_start);
131 // 计算曲率的变化率
132 const double curve_dot = (curve_end - curve_start) / (_length);
133 // 计算起始参数s_o
134 const double s_o = curve_start / curve_dot;
135 // 计算当前参数s
136 double s = s_o + dist;
137
138 double x;
139 double y;
140 double t;
141 // 调用odrSpiral函数,可能是根据参数计算螺旋线上的点坐标和切线方向
142 odrSpiral(s, curve_dot, &x, &y, &t);
143
144 double x_o;
145 double y_o;
146 double t_o;
147 // 再次调用odrSpiral函数,计算起始参数对应的点坐标和切线方向
148 odrSpiral(s_o, curve_dot, &x_o, &y_o, &t_o);
149
150 // 计算相对坐标x
151 x = x - x_o;
152 // 计算相对坐标y
153 y = y - y_o;
154 // 计算相对切线方向t
155 t = t - t_o;
156
157 // 调用RotatebyAngle函数旋转点坐标
158 geom::Vector2D pos = RotatebyAngle(_heading - t_o, x, y);
159 // 更新位置的x坐标
160 p.location.x += pos.x;
161 // 更新位置的y坐标
162 p.location.y += pos.y;
163 // 更新tangent(方向相关的值)
164 p.tangent = _heading + t;
165
166 // 返回计算后的DirectedPoint对象
167 return p;
168}
169
170// 函数:GeometrySpiral类的成员函数,计算到给定位置的距离(未完全实现)
171// location: 给定的位置
172std::pair<float, float> GeometrySpiral::DistanceTo(const geom::Location &location) const {
173 // 注释表明不是解析解,采用离散化并找到最近点的方法(目前未实现)
174 // 直接返回一个简单的差值作为临时结果(可能不准确)
175 return {location.x - _start_position.x, location.y - _start_position.y};
176}
177
178// 函数:GeometryPoly3类的成员函数,根据距离获取位置点
179// dist: 距离
181 // 使用rtree获取最近邻元素
182 auto result = _rtree.GetNearestNeighbours(
183 Rtree::BPoint(static_cast<float>(dist))).front();
184
185 // 获取最近邻元素中的两个值的引用
186 auto &val1 = result.second.first;
187 auto &val2 = result.second.second;
188
189 // 计算插值比例
190 double rate = (val2.s - dist) / (val2.s - val1.s);
191 // 根据插值比例计算u值
192 double u = rate * val1.u + (1.0 - rate) * val2.u;
193 // 根据插值比例计算v值
194 double v = rate * val1.v + (1.0 - rate) * val2.v;
195 // 根据插值比例计算tangent(可能是方向相关的值,这里计算方式存疑)
196 double tangent = atan((rate * val1.t + (1.0 - rate) * val2.t)); //?
197
198 // 调用RotatebyAngle函数旋转点坐标
200 // 创建一个DirectedPoint对象,初始位置为_start_position,方向为_heading + tangent
202 // 更新位置的x坐标
203 p.location.x += pos.x;
204 // 更新位置的y坐标
205 p.location.y += pos.y;
206 // 返回计算后的DirectedPoint对象
207 return p;
208}
209
210// 函数:GeometryPoly3类的成员函数,计算到给定位置的距离(未完全实现)
211// p: 给定的位置(这里虽然有参数名,但未使用)
212std::pair<float, float> GeometryPoly3::DistanceTo(const geom::Location & /*p*/) const {
213 // 注释表明没有解析表达式(可能需要牛顿 - 拉夫逊法或者点搜索,未实现)
214 // 直接返回起始位置坐标作为临时结果(可能不准确)
216}
217
218// 函数:GeometryPoly3类的成员函数,预计算样条曲线
220 // 定义常量,大概是区间大小(单位:米)
221 constexpr double interval_size = 0.3;
222 // 定义变量,表示u值的区间间隔,初始化为interval_size
223 const double delta_u = interval_size; // interval between values of u
224 double current_s = 0;
225 double current_u = 0;
226 double last_u = 0;
227 // 计算初始的v值
228 double last_v = _poly.Evaluate(current_u);
229 double last_s = 0;
230 // 创建一个RtreeValue对象,存储上次的值
231 RtreeValue last_val{last_u, last_v, last_s, _poly.Tangent(current_u)};
232 // 循环,直到current_s大于_length加上delta_u
233 while (current_s < _length + delta_u) {
234 // 更新u值
235 current_u += delta_u;
236 // 计算当前的v值
237 double current_v = _poly.Evaluate(current_u);
238 // 计算u值的差值
239 double du = current_u - last_u;
240 // 计算v值的差值
241 double dv = current_v - last_v;
242 // 计算s值的变化量
243 double ds = sqrt(du * du + dv * dv);
244 // 更新s值
245 current_s += ds;
246 // 计算当前的切线值
247 double current_t = _poly.Tangent(current_u);
248 // 创建一个当前的RtreeValue对象
249 RtreeValue current_val{current_u, current_v, current_s, current_t};
250
251 // 创建两个Rtree的点对象
252 Rtree::BPoint p1(static_cast<float>(last_s));
253 Rtree::BPoint p2(static_cast<float>(current_s));
254 // 在rtree中插入元素
255 _rtree.InsertElement(Rtree::BSegment(p1, p2), last_val, current_val);
256
257 // 更新上次的值
258 last_u = current_u;
259 last_v = current_v;
260 last_s = current_s;
261 last_val = current_val;
262
263 }
264}
265
266// 函数:GeometryParamPoly3类的成员函数,根据距离获取位置点
267// dist: 距离
269 // 使用rtree获取最近邻元素
270 auto result = _rtree.GetNearestNeighbours(
271 Rtree::BPoint(static_cast<float>(dist))).front();
272
273 // 获取最近邻元素中的两个值的引用
274 auto &val1 = result.second.first;
275 auto &val2 = result.second.second;
276 // 计算插值比例
277 double rate = (val2.s - dist) / (val2.s - val1.s);
278 // 根据插值比例计算u值
279 double u = rate * val1.u + (1.0 - rate) * val2.u;
280 // 根据插值比例计算v值
281 double v = rate * val1.v + (1.0 - rate) * val2.v;
282 // 根据插值比例计算t_u值
283 double t_u = (rate * val1.t_u + (1.0 - rate) * val2.t_u);
284 // 根据插值比例计算t_v值
285 double t_v = (rate * val1.t_v + (1.0 - rate) * val2.t_v);
286 // 根据t_u和t_v计算tangent(可能是方向相关的值)
287 double tangent = atan2(t_v, t_u); //?
288
289 // 调用RotatebyAngle函数旋转点坐标
291 // 创建一个DirectedPoint对象,初始位置为_start_position,方向为_heading + tangent
293 // 更新位置的x坐标
294 p.location.x += pos.x;
295 // 更新位置的y坐标
296 p.location.y += pos.y;
297 // 返回计算后的DirectedPoint对象
298 return p;
299}
300
301// 函数:GeometryParamPoly3类的成员函数,计算到给定位置的距离(未完全实现)
302// (这里虽然有参数,但未使用)
303std::pair<float, float> GeometryParamPoly3::DistanceTo(const geom::Location &) const {
304 // 注释表明没有解析表达式(可能需要牛顿 - 拉夫逊法或者点搜索,未实现)
305 // 直接返回起始位置坐标作为临时结果(可能不准确)
307}
308
309// 函数:GeometryParamPoly3类的成员函数,预计算样条曲线
311 // 定义常量,大概是区间大小(单位:米)
312 constexpr double interval_size = 0.5;
313 // 根据_length和interval_size计算区间数量,至少为5
314 size_t number_intervals =
315 std::max(static_cast<size_t>(_length / interval_size), size_t(5));
316 double delta_p = 1.0 / number_intervals;
317 if (_arcLength) {
318 // 如果_arcLength为真,根据_length调整delta_p
319 delta_p *= _length;
320 }
321 double param_p = 0;
322 double current_s = 0;
323 double last_u = _polyU.Evaluate(param_p);
324 double last_v = _polyV.Evaluate(param_p);
325 double last_s = 0;
326 // 创建一个RtreeValue对象,存储上次的值
327 RtreeValue last_val{
328 last_u,
329 last_v,
330 last_s,
331 _polyU.Tangent(param_p),
332 _polyV.Tangent(param_p) };
333 // 循环number_intervals次
334 for(size_t i = 0; i < number_intervals; ++i) {
335 // 更新param_p
336 param_p += delta_p;
337 // 计算当前的u值
338 double current_u = _polyU.Evaluate(param_p);
339 // 计算当前的v值
340 double current_v = _polyV.Evaluate(param_p);
341 // 计算u值的差值
342 double du = current_u - last_u;
343 // 计算v值的差值
344 double dv = current_v - last_v;
345 // 计算s值的变化量
346 double ds = sqrt(du * du + dv * dv);
347 // 更新s值
348 current_s += ds;
349 // 计算当前的u方向切线值
350 double current_t_u = _polyU.Tangent(param_p);
351 // 计算当前的v方向切线值
352 double current_t_v = _polyV.Tangent(param_p);
353 // 创建一个当前的RtreeValue对象
354 RtreeValue current_val{
355 current_u,
356 current_v,
357 current_s,
358 current_t_u,
359 current_t_v };
360
361 // 创建一个Rtree中的BPoint类型对象p1,将last_s转换为float类型后作为构造函数的参数
362 // BPoint可能是Rtree中表示点的数据结构,这里是使用last_s的值来初始化这个点
363 Rtree::BPoint p1(static_cast<float>(last_s));
364 // 创建一个Rtree中的BPoint类型对象p2,将current_s转换为float类型后作为构造函数的参数
365 // 同样,这里是使用current_s的值来初始化这个点
366 Rtree::BPoint p2(static_cast<float>(current_s));
367 // 调用_rtree对象的InsertElement函数,将由p1和p2组成的线段(BSegment)以及相关的值last_val和current_val插入到_rtree中
368 // 这里的_rtree可能是某种数据结构(例如空间索引结构),用于存储和管理这些元素
369 _rtree.InsertElement(Rtree::BSegment(p1, p2), last_val, current_val);
370
371 // 将当前的u值赋给last_u,用于记录上一次的u值,可能是为了后续的计算或者数据更新
372 last_u = current_u;
373 // 将当前的v值赋给last_v,用于记录上一次的v值
374 last_v = current_v;
375 // 将当前的s值赋给last_s,用于记录上一次的s值
376 last_s = current_s;
377 // 将当前的val值赋给last_val,用于记录上一次的val值,这里的val可能是包含多个属性值的数据结构
378 last_val = current_val;
379
380 // 如果当前的s值大于_length(这里_length可能是预先定义的某个长度限制或者阈值)
381 if (current_s > _length) {
382 // 则跳出当前的循环
383 break;
384 }
385 }
386 }
387} // namespace element
388} // namespace road
389} // namespace carla
#define DEBUG_ASSERT(predicate)
Definition Debug.h:68
value_type Evaluate(const value_type &x) const
评估 f(x) = a + bx + cx^2 + dx^3
value_type Tangent(const value_type &x) const
使用 df/dx = b + 2cx + 3dx^2 计算正切值
static T Clamp(T a, T min=T(0), T max=T(1))
Definition Math.h:54
boost::geometry::model::point< float, Dimension, boost::geometry::cs::cartesian > BPoint
Definition Rtree.h:93
boost::geometry::model::segment< BPoint > BSegment
Definition Rtree.h:94
void InsertElement(const BSegment &segment, const T &element_start, const T &element_end)
Definition Rtree.h:97
std::vector< TreeElement > GetNearestNeighbours(const Geometry &geometry, size_t number_neighbours=1) const
Definition Rtree.h:128
定义两个嵌套的命名空间:carla和geom。
float x
定义一个名为Vector2D的公共类,用于表示二维向量。
DirectedPoint PosFromDist(double dist) const override
Definition Geometry.cpp:76
DirectedPoint PosFromDist(double dist) const override
Definition Geometry.cpp:59
DirectedPoint PosFromDist(double dist) const override
Definition Geometry.cpp:268
std::pair< float, float > DistanceTo(const geom::Location &) const override
Definition Geometry.cpp:303
geom::CubicPolynomial _poly
Definition Geometry.h:309
std::pair< float, float > DistanceTo(const geom::Location &) const override
Definition Geometry.cpp:212
DirectedPoint PosFromDist(double dist) const override
Definition Geometry.cpp:180
std::pair< float, float > DistanceTo(const geom::Location &) const override
Definition Geometry.cpp:172
DirectedPoint PosFromDist(double dist) const override
Definition Geometry.cpp:119
geom::Location _start_position
Definition Geometry.h:125
geom::Vector2D RotatebyAngle(double angle, double x, double y)
Definition Geometry.cpp:106
CARLA模拟器的主命名空间。
Definition Carla.cpp:139
void odrSpiral(double s, double cDot, double *x, double *y, double *t)
compute the actual "standard" spiral, starting with curvature 0
void ApplyLateralOffset(float lateral_offset)
Definition Geometry.cpp:45