Reeds-Shepp曲线公式推导及代码实现-第一部分(共三部分)

:由于优快云篇幅限制,文章只能拆分成三部分,完整的文章可见Reeds-Shepp曲线公式推导及代码实现

优快云剩余部分:
Reeds-Shepp曲线公式推导及代码实现-第一部分(共三部分)
Reeds-Shepp曲线公式推导及代码实现-第二部分(共三部分)
Reeds-Shepp曲线公式推导及代码实现-第三部分(共三部分)

1. 前言

Reeds-Shepp曲线是基于Dubins曲线进行改进的一种规划算法,其将后退也加入到了规划中,这样就使得在某些情况下可以得到比Dubins曲线更优的路径。

1.1 Dubins曲线

Dubins路径是一个简单汽车模型的解析路径规划(不考虑后退)算法。它可以生成具有最大曲率约束和切线(偏航角)约束的二维平面姿态之间的最短路径,其生成的路径由3段最大曲率或者一段直线组成,每段路段类型可以分为3种类型:

符号含义绕圆方向
L L L左转逆时针
R R R右转顺时针
S S S直行/

由于在路径规划的时候,起点和终点都是存在航向的,因此两点之间并不一定是直线最短,《On Curves of Minimal Length with a Constraint on Average Curvature, and with Prescribed Initial and Terminal Positions and Tangents》中证明了对于每种特定终点情况下的最佳路径集合中,最多只有6条可选曲线,其分别为: L R L LRL LRL L S L LSL LSL L S R LSR LSR R L R RLR RLR R S R RSR RSR R S L RSL RSL

其中 L S L LSL LSL R S R RSR RSR R S L RSL RSL L S R LSR LSR可以看作是一种情况,即一段圆弧、一段直线和一段圆弧,可以统一用 C S C CSC CSC来表示,这里 C C C代表圆弧、 S S S代表一条直线;则对于 L R L LRL LRL R L R RLR RLR是另外一种都是圆弧的情况,可以用 C C C CCC CCC来表示,综上可记为
C S C ⇒ { L S L 、 R S R 、 R S L 、 L S R } C C C ⇒ { L R L 、 R L R } \begin{align} CSC&\Rightarrow\{LSL、RSR、RSL、LSR\}\\ CCC&\Rightarrow\{LRL、RLR\} \end{align} CSCCCC{LSLRSRRSLLSR}{LRLRLR}

1.2 Reeds-Shepp曲线

在Reeds-Shepp曲线路径中,允许反方向运动,因此相当于在Dubins曲线上区分了运动方向,我们将字母上添加正负号来进行区分前进和后退,因此其有以下6种类型:

符号含义绕圆方向
L + L^+ L+向前左转逆时针
L − L^- L向后左转顺时针
R + R^+ R+向前右转顺时针
R − R^- R向后右转逆时针
L + L^+ L+向前直行/
L − L^- L向后直行/

同样的我们使用 C C C代表圆弧( L ± L^{\pm} L± S ± S^{\pm} S±)、 S S S代表一条直线( S ± S^{\pm} S±)。

Reeds-Shepp算法在论文 《optimal path for a car that goes both forward and backwards》中证明了从起点到终点的最短路径一定是以下组合中的一个: C ∣ C ∣ C C|C|C CCC C C ∣ C CC|C CCC C ∣ C C C|CC CCC C S C CSC CSC C C β ∣ C β C CC_{\beta}|C_{\beta}C CCβCβC C ∣ C β C β ∣ C C|C_{\beta}C_{\beta}|C CCβCβC C ∣ C π / 2 S C C|C_{\pi/2}SC CCπ/2SC C S C π / 2 ∣ C CSC_{\pi/2}|C CSCπ/2C C ∣ C π / 2 S C π / 2 ∣ C C|C_{\pi/2}SC_{\pi/2}|C CCπ/2SCπ/2C,这里 ∣ | 表示方向的反转。

其对应48的组合如下所示:

形式组合
C ∣ C ∣ C C|C|C CCC L + R − L + L^+R^-L^+ L+RL+ L − R + L − L^-R^+L^- LR+L R + L − R + R^+L^-R^+ R+LR+ R − L + R − R^-L^+R^- RL+R
C C ∣ C CC|C CCC L + R + L − L^+R^+L^- L+R+L L − R − L + L^-R^-L^+ LRL+ R + L + R − R^+L^+R^- R+L+R R − L − R + R^-L^-R^+ RLR+
C ∣ C C C|CC CCC L + R − L − L^+R^-L^- L+RL L − R + L + L^-R^+L^+ LR+L+ R + L − R − R^+L^-R^- R+LR R − L + R + R^-L^+R^+ RL+R+
C S C CSC CSC      L + S + L + L^+S^+L^+ L+S+L+ L − S − L − L^-S^-L^- LSL R + S + R + R^+S^+R^+ R+S+R+ R − S − R − R^-S^-R^- RSR
L + S + R + L^+S^+R^+ L+S+R+ L − S − R − L^-S^-R^- LSR R + S + L + R^+S^+L^+ R+S+L+ R − S − L − R^-S^-L^- RSL
C C β ∣ C β C CC_{\beta}|C_{\beta}C CCβCβC L + R β + L β − R − L^+R_{\beta}^+L_{\beta}^-R^- L+Rβ+LβR L − R β − L β + R + L^-R_{\beta}^-L_{\beta}^+R^+ LRβLβ+R+ R + L β + R β − L − R^+L_{\beta}^+R_{\beta}^-L^- R+Lβ+RβL R − L β − R β + L + R^-L_{\beta}^-R_{\beta}^+L^+ RLβRβ+L+
C ∣ C β C β ∣ C C|C_{\beta}C_{\beta}|C CCβCβC L + R β − L β − R + L^+R_{\beta}^-L_{\beta}^-R^+ L+RβLβR+ L − R β + L β + R − L^-R_{\beta}^+L_{\beta}^+R^- LRβ+Lβ+R R + L β − R β − L + R^+L_{\beta}^-R_{\beta}^-L^+ R+LβRβL+ R − L β + R β + L − R^-L_{\beta}^+R_{\beta}^+L^- RLβ+Rβ+L
C ∣ C π / 2 S C C|C_{{\pi}/{2}}SC CCπ/2SC        L + R π / 2 − S − L − L^+R^-_{{\pi}/{2}}S^-L^- L+Rπ/2SL L − R π / 2 + S + L + L^-R^+_{{\pi}/{2}}S^+L^+ LRπ/2+S+L+ R + L π / 2 − S − R − R^+L^-_{{\pi}/{2}}S^-R^- R+Lπ/2SR R − L π / 2 + S + R + R^-L^+_{{\pi}/{2}}S^+R^+ RLπ/2+S+R+
L + R π / 2 − S − R − L^+R^-_{{\pi}/{2}}S^-R^- L+Rπ/2SR L − R π / 2 + S + R + L^-R^+_{{\pi}/{2}}S^+R^+ LRπ/2+S+R+ R + L π / 2 − S − L − R^+L^-_{{\pi}/{2}}S^-L^- R+Lπ/2SL R − L π / 2 + S + L + R^-L^+_{{\pi}/{2}}S^+L^+ RLπ/2+S+L+
C S C π / 2 ∣ C CSC_{{\pi}/{2}}|C CSCπ/2C         L + S + R π / 2 + L − L^+S^+R^+_{{\pi}/{2}}L^- L+S+Rπ/2+L L − S − R π / 2 − L + L^-S^-R^-_{{\pi}/{2}}L^+ LSRπ/2L+ R + S + L π / 2 + R − R^+S^+L^+_{{\pi}/{2}}R^- R+S+Lπ/2+R R − S − L π / 2 − R + R^-S^-L^-_{{\pi}/{2}}R^+ RSLπ/2R+
L + S + L π / 2 + R − L^+S^+L^+_{{\pi}/{2}}R^- L+S+Lπ/2+R L − S − L π / 2 − R + L^-S^-L^-_{{\pi}/{2}}R^+ LSLπ/2R+ R + S + R π / 2 + L − R^+S^+R^+_{{\pi}/{2}}L^- R+S+Rπ/2+L R − S − R π / 2 − L + R^-S^-R^-_{{\pi}/{2}}L^+ RSRπ/2L+
C ∣ C π / 2 S C π / 2 ∣ C C|C_{{\pi}/{2}}SC_{{\pi}/{2}}|C CCπ/2SCπ/2C L + R π / 2 − S − L π / 2 − R + L^+R^-_{{\pi}/{2}}S^-L^-_{{\pi}/{2}}R^+ L+Rπ/2SLπ/2R+ L − R π / 2 + S + L π / 2 + R − L^-R^+_{{\pi}/{2}}S^+L^+_{{\pi}/{2}}R^- LRπ/2+S+Lπ/2+R R + L π / 2 − S − R π / 2 − L + R^+L^-_{{\pi}/{2}}S^-R^-_{{\pi}/{2}}L^+ R+Lπ/2SRπ/2L+ R − L π / 2 + S + R π / 2 + L − R^-L^+_{{\pi}/{2}}S^+R^+_{{\pi}/{2}}L^- RLπ/2+S+Rπ/2+L

其中角标 β \beta β代表 C C C的旋转弧度是 β \beta β,角标 π / 2 \pi/2 π/2代表 C C C的旋转弧度是 π / 2 \pi/2 π/2

Dubins曲线是从公式1中的6个曲线里选出最短的那条,而Reeds-Shepp曲线是从上面48个曲线中选出最短的那条。

注:最开始的论文认为最短的曲线一定在48条曲线中,后人研究发现有两条曲线不会是最短的,所以后来搜索范围减小到46条。

对于上述的48中组合,实际可以通过简单的变换,实现部分组合的转换,这种变换包括:

  • 时间翻转

    时间翻转就将车原行驶方向取反,即通过交换字母上的正负号,例如, L − R + L − L^-R^+L^- LR+L可以通过 L + R − L + L^+R^-L^+ L+RL+进行时间变换获得,即原始路径从 ( 0 , 0 , 0 ) (0,0,0) (0,0,0) ( x , y , φ ) (x,y,\varphi) (x,y,φ),当经过时间变换(符号取反),得到的新路径关于 Y Y Y轴对称,即得到新的目标点 ( − x , y , − φ ) (-x,y,-\varphi) (x,y,φ),因此对于 L − R + L − L^-R^+L^- LR+L可以通过 L + R − L + L^+R^-L^+ L+RL+的求解公式,将目标点变为 ( − x , y , − φ ) (-x,y,-\varphi) (x,y,φ)获得。

  • 反射变换

    反射变换就是通过交换字母 L L L R R R,即车辆通过左右反向转向,例如, R + L − R + R^+L^-R^+ R+LR+可以通过 L + R − L + L^+R^-L^+ L+RL+进行反射变换获得,即原始路径从 ( 0 , 0 , 0 ) (0,0,0) (0,0,0) ( x , y , φ ) (x,y,\varphi) (x,y,φ),当经过反射变换(交换字母 L L L R R R),得到的新路径关于 X X X轴对称,即得到新的目标点 ( x , − y , − φ ) (x,-y,-\varphi) (x,y,φ),因此对于 R + L − R + R^+L^-R^+ R+LR+可以通过 L + R − L + L^+R^-L^+ L+RL+的求解公式,将目标点变为 ( x , − y , − φ ) (x,-y,-\varphi) (x,y,φ)获得。

  • 逆向变换

    逆向变换就是将时间翻转和反射变换结合起来,即将先将原组合进行时间翻转,然后再对时间翻转后的结果进行反射变换,例如, R − L + R − R^-L^+R^- RL+R可以通过 L + R − L + L^+R^-L^+ L+RL+进行逆向变换获得,即原始路径从 ( 0 , 0 , 0 ) (0,0,0) (0,0,0) ( x , y , φ ) (x,y,\varphi) (x,y,φ),当经过时间翻转得到 ( − x , y , − φ ) (-x,y,-\varphi) (x,y,φ),再对其进行反射变换,即得到新的目标点 ( − x , − y , φ ) (-x,-y,\varphi) (x,y,φ),因此对于 R − L + R − R^-L^+R^- RL+R可以通过 L + R − L + L^+R^-L^+ L+RL+的求解公式,将目标点变为 ( − x , − y , φ ) (-x,-y,\varphi) (x,y,φ)获得。

通过上述变换,我们可以消除48种中的部分字段,最终保留以下12个字段:

形式组合
C ∣ C ∣ C C|C|C CCC L + R − L + L^+R^-L^+ L+RL+ L − R + L − \bcancel{L^-R^+L^-} LR+L R + L − R + \bcancel{R^+L^-R^+} R+LR+ R − L + R − \bcancel{R^-L^+R^-} RL+R
C C ∣ C CC|C CCC L + R + L − L^+R^+L^- L+R+L L − R − L + L\bcancel{^-R^-L^+} LRL+ R + L + R − \bcancel{R^+L^+R^-} R+L+R R − L − R + \bcancel{R^-L^-R^+} RLR+
C ∣ C C C|CC CCC L + R − L − L^+R^-L^- L+RL L − R + L + L\bcancel{^-R^+L^+} LR+L+ R + L − R − \bcancel{R^+L^-R^-} R+LR R − L + R + \bcancel{R^-L^+R^+} RL+R+
C S C CSC CSC      L + S + L + L^+S^+L^+ L+S+L+ L − S − L − L\bcancel{^-S^-L^-} LSL R + S + R + \bcancel{R^+S^+R^+} R+S+R+ R − S − R − \bcancel{R^-S^-R^-} RSR
L + S + R + {L^+S^+R^+} L+S+R+ L − S − R − \bcancel{L^-S^-R^-} LSR R + S + L + \bcancel{R^+S^+L^+} R+S+L+ R − S − L − \bcancel{R^-S^-L^-} RSL
C C β ∣ C β C CC_{\beta}|C_{\beta}C CCβCβC L + R β + L β − R − L^+R_{\beta}^+L_{\beta}^-R^- L+Rβ+LβR L − R β − L β + R + L\bcancel{^-R_{\beta}^-L_{\beta}^+R^+} LRβLβ+R+ R + L β + R β − L − \bcancel{R^+L_{\beta}^+R_{\beta}^-L^-} R+Lβ+RβL R − L β − R β + L + \bcancel{R^-L_{\beta}^-R_{\beta}^+L^+} RLβRβ+L+
C ∣ C β C β ∣ C C|C_{\beta}C_{\beta}|C CCβCβC L + R β − L β − R + L^+R_{\beta}^-L_{\beta}^-R^+ L+RβLβR+ L − R β + L β + R − L\bcancel{^-R_{\beta}^+L_{\beta}^+R^-} LRβ+Lβ+R R + L β − R β − L + \bcancel{R^+L_{\beta}^-R_{\beta}^-L^+} R+LβRβL+ R − L β + R β + L − \bcancel{R^-L_{\beta}^+R_{\beta}^+L^-} RLβ+Rβ+L
C ∣ C π / 2 S C C|C_{{\pi}/{2}}SC CCπ/2SC        L + R π / 2 − S − L − L^+R^-_{{\pi}/{2}}S^-L^- L+Rπ/2SL L − R π / 2 + S + L + L\bcancel{^-R^+_{{\pi}/{2}}S^+L^+} LRπ/2+S+L+ R + L π / 2 − S − R − \bcancel{R^+L^-_{{\pi}/{2}}S^-R^-} R+Lπ/2SR R − L π / 2 + S + R + \bcancel{R^-L^+_{{\pi}/{2}}S^+R^+} RLπ/2+S+R+
L + R π / 2 − S − R − L^+R^-_{{\pi}/{2}}S^-R^- L+Rπ/2SR L − R π / 2 + S + R + \bcancel{L^-R^+_{{\pi}/{2}}S^+R^+} LRπ/2+S+R+ R + L π / 2 − S − L − \bcancel{R^+L^-_{{\pi}/{2}}S^-L^-} R+Lπ/2SL R − L π / 2 + S + L + \bcancel{R^-L^+_{{\pi}/{2}}S^+L^+} RLπ/2+S+L+
C S C π / 2 ∣ C CSC_{{\pi}/{2}}|C CSCπ/2C         L + S + R π / 2 + L − L^+S^+R^+_{{\pi}/{2}}L^- L+S+Rπ/2+L L − S − R π / 2 − L + L\bcancel{^-S^-R^-_{{\pi}/{2}}L^+} LSRπ/2L+ R + S + L π / 2 + R − \bcancel{R^+S^+L^+_{{\pi}/{2}}R^-} R+S+Lπ/2+R R − S − L π / 2 − R + \bcancel{R^-S^-L^-_{{\pi}/{2}}R^+} RSLπ/2R+
L + S + L π / 2 + R − L^+S^+L^+_{{\pi}/{2}}R^- L+S+Lπ/2+R L − S − L π / 2 − R + \bcancel{L^-S^-L^-_{{\pi}/{2}}R^+} LSLπ/2R+ R + S + R π / 2 + L − \bcancel{R^+S^+R^+_{{\pi}/{2}}L^-} R+S+Rπ/2+L R − S − R π / 2 − L + \bcancel{R^-S^-R^-_{{\pi}/{2}}L^+} RSRπ/2L+
C ∣ C π / 2 S C π / 2 ∣ C C|C_{{\pi}/{2}}SC_{{\pi}/{2}}|C CCπ/2SCπ/2C L + R π / 2 − S − L π / 2 − R + L^+R^-_{{\pi}/{2}}S^-L^-_{{\pi}/{2}}R^+ L+Rπ/2SLπ/2R+ L − R π / 2 + S + L π / 2 + R − L\bcancel{^-R^+_{{\pi}/{2}}S^+L^+_{{\pi}/{2}}R^-} LRπ/2+S+Lπ/2+R R + L π / 2 − S − R π / 2 − L + \bcancel{R^+L^-_{{\pi}/{2}}S^-R^-_{{\pi}/{2}}L^+} R+Lπ/2SRπ/2L+ R − L π / 2 + S + R π / 2 + L − \bcancel{R^-L^+_{{\pi}/{2}}S^+R^+_{{\pi}/{2}}L^-} RLπ/2+S+Rπ/2+L

消除部分的字段均可以过上述12个字段运用上述三个变换性质得到,也就是说所有的48种轨迹均可以通过上述12种轨迹的求解公式直接或者间接的求解出来。

1.3 车辆模型

Reeds-Shepp曲线是基于一种简化的车辆运动学模型:
{ x ˙ = v cos ⁡ φ y ˙ = v sin ⁡ φ φ ˙ = v R R = L tan ⁡ δ f \begin{cases} \dot{x}=v\cos\varphi\\ \dot{y}=v\sin\varphi\\ \dot{\varphi}=\frac{v}{R}\\ R=\frac{L}{\tan\delta_f} \end{cases} x˙=vcosφy˙=vsinφφ˙=RvR=tanδfL
其中:

  • v v v:车辆的速度;
  • y y y:车辆后轴中心点的纵坐标;
  • x x x:车辆后轴中心点的横坐标;
  • R R R:车辆的转弯半径;
  • L L L:车辆的轴距;
  • φ \varphi φ:车辆的航向角;
  • δ f \delta_f δf:车辆前轮转角。

有了运动学方程,在给定时间间隔 T T T和速度 v v v,就可以得到一系列的点,对应的就是满足车辆运动学约束的路径,点的表达式可以表示为:
x = x p r e + v T cos ⁡ φ y = y p r e + v T sin ⁡ φ φ = φ p r e + v T R \begin{align} x&=x_{pre}+vT\cos\varphi\\ y&=y_{pre}+vT\sin\varphi\\ \varphi&=\varphi_{pre}+\frac{vT}{R} \end{align} xyφ=xpre+vTcosφ=ypre+vTsinφ=φpre+RvT

1.4 车辆位姿的归一化

车辆的起点和终点的位姿是不能完全穷举的,为了方便计算,我们会先将起点和终点的位姿归一化,假设起点位姿为 P s ( x s , y s , φ s ) P_s(x_s,y_s,\varphi_s) Ps(xs,ys,φs),终点位姿为 P e ( x e , y e , φ e ) P_e(x_e,y_e,\varphi_e) Pe(xe,ye,φe),车辆的最小转弯半径为 R m i n R_{min} Rmin

首先将车辆起点平移到原点,它后将车辆起点朝向转向到x轴的正方向,然后再按照最小转弯半径对向量 P s P e ⃗ \vec{P_sP_e} PsPe 进行缩放,这样就可以把最小转弯半径归一化为1,其变换过程如下:

原始向量 P s P e ⃗ \vec{P_sP_e} PsPe
P s P e ⃗ = [ x e − x s y e − y s ] = [ d x d y ] \vec{P_sP_e}= \begin{bmatrix} x_e-x_s\\ y_e-y_s \end{bmatrix}= \begin{bmatrix} dx\\ dy \end{bmatrix} PsPe =[xexsyeys]=[dxdy]
将起点朝向转到x轴正方向对应的旋转矩阵为
[ cos ⁡ ( − φ s ) − sin ⁡ ( − φ s ) sin ⁡ ( − φ s ) cos ⁡ ( − φ s ) ] = [ cos ⁡ φ s sin ⁡ φ s − sin ⁡ φ s cos ⁡ φ s ] \begin{bmatrix} \cos{(-\varphi_s)}& -\sin{(-\varphi_s)}\\ \sin{(-\varphi_s)}& \cos{(-\varphi_s)} \end{bmatrix}= \begin{bmatrix} \cos{\varphi_s}& \sin{\varphi_s}\\ -\sin{\varphi_s}& \cos{\varphi_s} \end{bmatrix} [cos(φs)sin(φs)sin(φs)cos(φs)]=[cosφssinφssinφscosφs]
旋转后的向量为
[ cos ⁡ φ s sin ⁡ φ s − sin ⁡ φ s cos ⁡ φ s ] [ d x d y ] = [ d x ∗ cos ⁡ φ s + d y ∗ sin ⁡ φ s − d x ∗ sin ⁡ φ s + d y ∗ cos ⁡ φ s ] \begin{bmatrix} \cos{\varphi_s}& \sin{\varphi_s}\\ -\sin{\varphi_s}& \cos{\varphi_s} \end{bmatrix} \begin{bmatrix} dx\\ dy \end{bmatrix}= \begin{bmatrix} dx*\cos{\varphi_s}+dy*\sin{\varphi_s}\\ -dx*\sin{\varphi_s}+dy*\cos{\varphi_s} \end{bmatrix} [cosφssinφssinφscosφs][dxdy]=[dxcosφs+dysinφsdxsinφs+dycosφs]
按照最小转弯半径 R m i n R_{min} Rmin归一化后起点位姿 q s q_s qs和终点位姿 q e q_e qe分别为
q s = [ 0 0 0 ] q e = [ ( d x ∗ cos ⁡ φ s + d y ∗ sin ⁡ φ s ) / R m i n ( − d x ∗ sin ⁡ φ s + d y ∗ cos ⁡ φ s ) / R m i n φ e − φ s ] q_s= \begin{bmatrix} 0\\0\\0 \end{bmatrix}\\ q_e= \begin{bmatrix} (dx*\cos{\varphi_s}+dy*\sin{\varphi_s})/R_{min}\\ (-dx*\sin{\varphi_s}+dy*\cos{\varphi_s})/R_{min}\\ \varphi_e-\varphi_s \end{bmatrix} qs= 000 qe= (dxcosφs+dysinφs)/Rmin(dxsinφs+dycosφs)/Rminφeφs
在归一化后,车辆圆弧的运动都是基于单位圆进行的,车辆形式的弧长和变化的角度一致,方便后面的计算。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

艰默

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值