【发布时间】:2018-02-20 11:48:52
【问题描述】:
地图格式OpenDrive,提供(除其他外)道路的几何形状。道路的每一段都可以有不同的几何形状(例如线、弧线、螺旋线、多项式)。提供的道路几何“螺旋”信息如下:
- s - relative position of the road segment in respect to the beginning
of the road (not used in here)
- x - the "x" position of the starting point of the road segment
- y - the "y" position of the starting point of the road segment
- hdg - the heading of the starting point of the road segment
- length - the length of the road segment
- curvStart - the curvature at the start of the road segment
- curvEnd - the curvature at the end of the road segment
我的目标是在给定“分辨率”参数的情况下沿螺旋线插入点(例如,分辨率 = 1,每米沿螺旋线插入一个点)。 螺旋几何是这样的,它引入了一个恒定的曲率变化(1/半径),因此它产生了从直线到圆弧的平滑和稳定的过渡,因此车辆上的横向加速度力小于从直线直接转为圆弧(直线曲率 = 0,圆弧曲率 = 常数)。
螺旋总是有一个曲率为 0 的端点(它连接到道路的线段),另一个为常数(例如,0.05 连接到弧线)。根据连接顺序,curvStart 可以等于 0 或常数,curvEnd 也可以等于 0 或常数。它们不能同时等于 0 或常数。
下面的代码是一个函数,它将前面讨论的参数(由格式给出)和分辨率作为参数。
目前,我遇到以下问题:
- 插入相距 1 米的等距点(检查图 1)
- 获取点的正确航向(检查图 2)
- 找到最后 2 个案例的解决方案
从我对如何完成任务的研究中,我找到了一些有用的资源,但没有一个能帮助我获得最终的解决方案:
- OpenDrive Specification
- Open source road generation and editing software - 第 40(31) 页
- Euler Spiral Wiki
- Cephes library,scipy.special.fresnel 函数由此派生
- Klothoide - “Clothoid” Wiki 页面的德语版有更多公式
- Parameterized function for clothoid
-
SciPy: What are the arguments in
scipy.special.fresnel(x\[, out1, out2\])? - 指出“函数的 scipy 实现将参数缩放 pi/2”
import numpy as np
from math import cos, sin, pi, radians
from scipy.special import fresnel
import matplotlib.pyplot as plt
%matplotlib inline
def spiralInterpolation(resolution, s, x, y, hdg, length, curvStart, curvEnd):
points = np.zeros((int(length/resolution), 1))
points = [i*resolution for i in range(len(points))]
xx = np.zeros_like(points)
yy = np.zeros_like(points)
hh = np.zeros_like(points)
if curvStart == 0 and curvEnd > 0:
print("Case 1: curvStart == 0 and curvEnd > 0")
radius = np.abs(1/curvEnd)
A_sq = radius*length
ss, cc = fresnel(np.square(points)/(2*A_sq*np.sqrt(np.pi/2)))
xx = points*cc
yy = points*ss
hh = np.square(points)*2*radius*length
xx, yy, hh = rotate(xx, yy, hh, hdg)
xx, yy = translate(xx, yy, x, y)
xx = np.insert(xx, 0, x, axis=0)
yy = np.insert(yy, 0, y, axis=0)
hh = np.insert(hh, 0, hdg, axis=0)
elif curvStart == 0 and curvEnd < 0:
print("Case 2: curvStart == 0 and curvEnd < 0")
radius = np.abs(1/curvEnd)
A_sq = radius*length
ss, cc = fresnel(np.square(points)/(2*A_sq*np.sqrt(np.pi/2)))
xx = points*cc
yy = points*ss*-1
hh = np.square(points)*2*radius*length
xx, yy, hh = rotate(xx, yy, hh, hdg)
xx, yy = translate(xx, yy, x, y)
xx = np.insert(xx, 0, x, axis=0)
yy = np.insert(yy, 0, y, axis=0)
hh = np.insert(hh, 0, hdg, axis=0)
elif curvEnd == 0 and curvStart > 0:
print("Case 3: curvEnd == 0 and curvStart > 0")
elif curvEnd == 0 and curvStart < 0:
print("Case 4: curvEnd == 0 and curvStart < 0")
else:
print("The curvature parameters differ from the 4 predefined cases. "
"Change curvStart and/or curvEnd")
n_stations = int(length/resolution) + 1
stations = np.zeros((n_stations, 3))
for i in range(len(xx)):
stations[i][0] = xx[i]
stations[i][1] = yy[i]
stations[i][2] = hh[i]
return stations
def rotate(x, y, h, angle):
# This function rotates the x and y vectors around zero
xx = np.zeros_like(x)
yy = np.zeros_like(y)
hh = np.zeros_like(h)
for i in range(len(x)):
xx[i] = x[i]*cos(angle) - y[i]*sin(angle)
yy[i] = x[i]*sin(angle) + y[i]*cos(angle)
hh[i] = h[i] + angle
return xx, yy, hh
def translate(x, y, x_delta, y_delta):
# This function translates the x and y vectors with the delta values
xx = np.zeros_like(x)
yy = np.zeros_like(y)
for i in range(len(x)):
xx[i] = x[i] + x_delta
yy[i] = y[i] + y_delta
return xx, yy
stations = spiralInterpolation(1, 77, 50, 100, radians(56), 40, 0, 1/20)
x = []
y = []
h = []
for station in stations:
x.append(station[0])
y.append(station[1])
h.append(station[2])
plt.figure(figsize=(20,13))
plt.plot(x, y, '.')
plt.grid(True)
plt.axis('equal')
plt.show()
def get_heading_components(x, y, h, length=1):
xa = np.zeros_like(x)
ya = np.zeros_like(y)
for i in range(len(x)):
xa[i] = length*cos(h[i])
ya[i] = length*sin(h[i])
return xa, ya
xa, ya = get_heading_components(x, y, h)
plt.figure(figsize=(20,13))
plt.quiver(x, y, xa, ya, width=0.005)
plt.grid(True)
plt.axis('equal')
plt.show()
【问题讨论】:
-
由于 StackOverflow 的格式规则,我无法正确缩进我的代码。请记住,“def rotate()”下面的所有内容都应该没有任何标识
标签: python scipy spiral fresnel