frenet坐标与cartesian坐标相互转换与代码实现(第二部分)

由于csdn文章长度的限制,将本篇文章分成两篇发布,另一篇文章见frenet坐标与cartesian坐标相互转换与代码实现(第一部分)
也可以直接通过公众号iDoitnow的frenet坐标与cartesian坐标相互转换与代码实现直接阅读完整版

1 frenet转cartesian坐标系

frenet转cartesian坐标系是已知$ s$ 、$ \dot{s}$、 s ¨ \ddot{s} s¨ l l l l ′ l' l、$ l’’ $,求 r ⃗ \vec{r} r θ \theta θ v ⃗ \vec{v} v a ⃗ \vec{a} a k k k

1.1 求 r ⃗ \vec{r} r

由图中的几何关系可得
r ⃗ = r r ⃗ + l n r ⃗ (30) \vec{r}=\vec{r_r}+l\vec{n_r} \tag{30} r =rr +lnr (30)

1.2 求 v ⃗ \vec{v} v

由公式(18)和(17)可得
v ⃗ n r ⃗ = l ˙ v ⃗ τ r ⃗ = ( 1 − k r l ) s ˙ (31) \begin{align*} \vec{v}\vec{n_r}&=\dot{l} \\ \vec{v}\vec{\tau_r}&=(1-k_rl)\dot{s} \end{align*} \tag{31} v nr v τr =l˙=(1krl)s˙(31)
将上面两个式子展开可得
∣ v ⃗ ∣ ∣ n r ⃗ ∣ s i n ( θ − θ r ) = ∣ v ⃗ ∣ ⋅ 1 ⋅ s i n ( θ − θ r ) = l ˙ ∣ v ⃗ ∣ ∣ τ r ⃗ ∣ c o s ( θ − θ r ) = ∣ v ⃗ ∣ ⋅ 1 ⋅ c o s ( θ − θ r ) = ( 1 − k r l ) s ˙ (32) \begin{align*} |\vec{v}||\vec{n_r}|sin(\theta - \theta_r)&=|\vec{v}| \cdot 1 \cdot sin(\theta - \theta_r)=\dot{l} \\ |\vec{v}||\vec{\tau_r}| cos(\theta-\theta_r)&=|\vec{v}| \cdot 1 \cdot cos(\theta-\theta_r)=(1-k_rl)\dot{s} \end{align*}\tag{32} v ∣∣nr sin(θθr)v ∣∣τr cos(θθr)=v 1sin(θθr)=l˙=v 1cos(θθr)=(1krl)s˙(32)
将上面两个式子两侧分别平方并相加可得
∣ v ⃗ ∣ = ( l ˙ 2 + ( 1 − k r l ) 2 s ˙ 2 ) 1 2 (33) |\vec{v}|={(\dot{l}^2 + (1-k_rl)^2 \dot{s}^2)}^{\frac{1}{2}} \tag{33} v =(l˙2+(1krl)2s˙2)21(33)
将(32)两式相除可得
t a n ( θ − θ r ) = l ˙ ( 1 − k r l ) s ˙ (34) tan(\theta-\theta_r)=\frac{\dot{l}}{(1-k_rl)\dot{s}} \tag{34} tan(θθr)=(1krl)s˙l˙(34)
结合公式(22),可得
θ = θ r + a r c t a n l ˙ ( 1 − k r l ) s ˙ = θ r + a r c t a n l ′ 1 − k r l (35) \theta = \theta_r + arctan\frac{\dot{l}}{(1-k_rl)\dot{s}}=\theta_r + arctan\frac{l'}{1-k_rl} \tag{35} θ=θr+arctan(1krl)s˙l˙=θr+arctan1krll(35)

1.3 求 a ⃗ \vec{a} a a τ a_{\tau} aτ

由公式(23)和(25)可得
a ⃗ n r ⃗ = l ¨ + k r ( 1 − k r l ) s ˙ 2 a ⃗ τ r ⃗ = s ¨ ( 1 − k r l ) + k r s ˙ 2 l ′ + ( k r ′ l − k r l ′ ) s ˙ 2 (36) \begin{align*} \vec{a} \vec{n_r} &= \ddot{l} + k_r(1-k_rl) \dot{s}^2 \\ \vec{a} \vec{\tau_r} &= \ddot{s}(1-k_rl) + k_r \dot{s}^2l' + (k_r'l-k_rl') \dot{s}^2 \end{align*}\tag{36} a nr a τr =l¨+kr(1krl)s˙2=s¨(1krl)+krs˙2l+(krlkrl)s˙2(36)
与求解 v ⃗ \vec{v} v 类似,将上两式分别平方在相加可得
∣ a ⃗ ∣ = ( ( l ¨ + k r ( 1 − k r l ) s ˙ 2 ) 2 + ( s ¨ ( 1 − k r l ) + k r s ˙ 2 l ′ + ( k r ′ l − k r l ′ ) s ˙ 2 ) 2 ) 1 2 (37) |\vec{a}|=((\ddot{l} + k_r(1-k_rl) \dot{s}^2)^2 + (\ddot{s}(1-k_rl) + k_r \dot{s}^2l' + (k_r'l-k_rl') \dot{s}^2 )^2)^{\frac{1}{2}} \tag{37} a =((l¨+kr(1krl)s˙2)2+(s¨(1krl)+krs˙2l+(krlkrl)s˙2)2)21(37)
将(36)两式再相除可得
t a n ( θ a − θ r ) = l ¨ + k r ( 1 − k r l ) s ˙ 2 s ¨ ( 1 − k r l ) + k r s ˙ 2 l ′ + ( k r ′ l − k r l ′ ) s ˙ 2 (38) tan(\theta_a - \theta_r) = \frac{ \ddot{l} + k_r(1-k_rl) \dot{s}^2}{ \ddot{s}(1-k_rl) + k_r \dot{s}^2l' + (k_r'l-k_rl') \dot{s}^2} \tag{38} tan(θaθr)=s¨(1krl)+krs˙2l+(krlkrl)s˙2l¨+kr(1krl)s˙2(38)
其中, θ a \theta_a θa为向量 a ⃗ \vec{a} a 与笛卡尔坐标系 X X X轴的夹角。

由上式可得
θ a = θ r + a r c t a n l ¨ + k r ( 1 − k r l ) s ˙ 2 s ¨ ( 1 − k r l ) + k r s ˙ 2 l ′ + ( k r ′ l − k r l ′ ) s ˙ 2 (39) \theta_a = \theta_r + arctan\frac{ \ddot{l} + k_r(1-k_rl) \dot{s}^2}{ \ddot{s}(1-k_rl) + k_r \dot{s}^2l' + (k_r'l-k_rl') \dot{s}^2} \tag{39} θa=θr+arctans¨(1krl)+krs˙2l+(krlkrl)s˙2l¨+kr(1krl)s˙2(39)

对于切线加速度 a τ = ∣ v ˙ ⃗ ∣ a_{\tau}=|\vec{\dot{v}}| aτ=v˙ ,将公式 ( 10 ) (10) (10)两边同时点乘 τ ⃗ \vec{\tau} τ 可得
a τ = ∣ v ˙ ⃗ ∣ = a ⃗ τ ⃗ = ∣ a ⃗ ∣ c o s ( θ a − θ ) (40) a_{\tau}=|\vec{\dot{v}}|=\vec{a} \vec{\tau} = |\vec{a}|cos(\theta_a - \theta) \tag{40} aτ=v˙ =a τ =a cos(θaθ)(40)

1.4 求 k k k

将公式 ( 10 ) (10) (10)两边点乘 n ⃗ \vec{n} n 可得
a ⃗ n ⃗ = k ∣ v ⃗ ∣ 2 (41) \vec{a} \vec{n}=k |\vec{v}|^2 \tag{41} a n =kv 2(41)
由上式可得
k = a ⃗ n ⃗ ∣ v ⃗ ∣ 2 (42) k = \frac{\vec{a} \vec{n}}{|\vec{v}|^2} \tag{42} k=v 2a n (42)

1.5 小结

综上,可得
{ r ⃗ = r r ⃗ + l n r ⃗ ∣ v ⃗ ∣ = ( l ˙ 2 + ( 1 − k r l ) 2 s ˙ 2 ) 1 2 θ = θ r + a r c t a n l ˙ ( 1 − k r l ) s ˙ = θ r + a r c t a n l ′ 1 − k r l ∣ a ⃗ ∣ = ( ( l ¨ + k r ( 1 − k r l ) s ˙ 2 ) 2 + ( s ¨ ( 1 − k r l ) + k r s ˙ 2 l ′ + ( k r ′ l − k r l ′ ) s ˙ 2 ) 2 ) 1 2 θ a = θ r + a r c t a n l ¨ + k r ( 1 − k r l ) s ˙ 2 s ¨ ( 1 − k r l ) + k r s ˙ 2 l ′ + ( k r ′ l − k r l ′ ) s ˙ 2 a τ = ∣ a ⃗ ∣ c o s ( θ a − θ ) k = a ⃗ n ⃗ ∣ v ⃗ ∣ 2 (43) \begin{cases} \vec{r}&=\quad\vec{r_r}+l\vec{n_r} \\ |\vec{v}|&= \quad {(\dot{l}^2 + (1-k_rl)^2 \dot{s}^2)}^{\frac{1}{2}} \\ \theta &= \quad \theta_r + arctan\frac{\dot{l}}{(1-k_rl)\dot{s}}=\theta_r + arctan\frac{l'}{1-k_rl} \\ |\vec{a}|&=\quad ((\ddot{l} + k_r(1-k_rl) \dot{s}^2)^2 + (\ddot{s}(1-k_rl) + k_r \dot{s}^2l' + (k_r'l-k_rl') \dot{s}^2 )^2)^{\frac{1}{2}} \\ \theta_a &=\quad \theta_r + arctan\frac{ \ddot{l} + k_r(1-k_rl) \dot{s}^2}{ \ddot{s}(1-k_rl) + k_r \dot{s}^2l' + (k_r'l-k_rl') \dot{s}^2}\\ a_{\tau}&=\quad |\vec{a}|cos(\theta_a - \theta)\\ k &= \quad \frac{\vec{a} \vec{n}}{|\vec{v}|^2} \end{cases} \tag{43} r v θa θaaτk=rr +lnr =(l˙2+(1krl)2s˙2)21=θr+arctan(1krl)s˙l˙=θr+arctan1krll=((l¨+kr(1krl)s˙2)2+(s¨(1krl)+krs˙2l+(krlkrl)s˙2)2)21=θr+arctans¨(1krl)+krs˙2l+(krlkrl)s˙2l¨+kr(1krl)s˙2=a cos(θaθ)=v 2a n (43)

2. 代码实现(python)

cartesian到frenet坐标转换:

import numpy as np
from math import *

def cartesian_to_frenet(rs, rx, ry, rtheta, rkappa, rdkappa, x, y, v, a_v, theta, kappa):
    vec_r = np.array([x, y])
    vec_rr = np.array([rx, ry])
    vec_nr = np.array([cos(rtheta + np.pi / 2), sin(rtheta + np.pi / 2)])
    if np.cross(vec_r - vec_rr, vec_nr) >= 1.0e-6: # 投影点应与目标点组成的向量应与nr平行
        print("The reference point [rx, ry] and [x, y] don't match")

    vec_t = np.array([cos(theta), sin(theta)])
    vec_v = np.array([v * cos(theta), v * sin(theta)])
    vec_n = np.array([cos(theta + np.pi / 2), sin(theta + np.pi / 2)])
    vec_a = a_v * vec_t + v * v * kappa * vec_n

    vec_tr = np.array([cos(rtheta), sin(rtheta)])

    # 计算s、l
    l = np.dot(vec_r - vec_rr, vec_nr)
    s = rs
    # 计算dot_s
    dot_s = np.dot(vec_v, vec_tr) / (1 - rkappa * l)

    dot_l = np.dot(vec_v, vec_nr)
    ddot_l = np.dot(vec_a, vec_nr) - rkappa * (1 - rkappa * l) * dot_s * dot_s
    # 计算dl
    dl = dot_l / dot_s
    # 计算ddl、dot_s
    ddot_s = np.dot(vec_a, vec_tr) / (1 - rkappa * l) \
             + dot_s * dot_s * rkappa * dl / (1 - rkappa * l) \
             + dot_s * dot_s * (rdkappa * l + rkappa * dl) / (1 - rkappa * l)
    ddl = (ddot_l - dl * ddot_s) / (dot_s * dot_s)

    return np.array([s, dot_s, ddot_s]), np.array([l, dl, ddl])

frenet到cartesian坐标转换:

import numpy as np
from math import *

def normalize_angle(angle):
    a = fmod(angle+np.pi, 2*np.pi)
    if a < 0.0:
        a += (2.0*np.pi)
    return a - np.pi

def frenet_to_cartesian(rs, rx, ry, rtheta, rkappa, rdkappa, s_condition, d_condition):
    if fabs(rs - s_condition[0]) >= 1.0e-6:
        print("The reference point s and s_condition[0] don't match")

    vec_rr = np.array([rx, ry])
    vec_nr = np.array([cos(rtheta + np.pi / 2), sin(rtheta + np.pi / 2)])
    # 计算r,得到的就是目标点坐标(x, y)
    vec_r = vec_rr + d_condition[0] * vec_nr

    dot_l = d_condition[1] * s_condition[1]
    ddot_l = d_condition[2] * s_condition[1] * s_condition[1] + s_condition[2] * d_condition[1]
    # 计算速度v
    v = sqrt(dot_l**2 + (1  - rkappa * d_condition[0])**2 * s_condition[1]**2)
    # 计算theta
    theta = normalize_angle(rtheta + atan2(d_condition[1], (1 - rkappa * d_condition[0])))
    # 计算加速度a、theta_a和切线加速度a_v
    a_part1 = ddot_l + rkappa * (1 - rkappa * d_condition[0]) * (s_condition[1] * s_condition[1])
    a_part2 = (s_condition[2] * (1 - rkappa * d_condition[0])
               - rkappa * s_condition[1] * s_condition[1] * d_condition[1]
               - s_condition[1] * s_condition[1] *(rdkappa * d_condition[0] + rkappa * d_condition[1]))
    a = sqrt(a_part1 * a_part1 + a_part2 * a_part2)
    theta_a = normalize_angle(rtheta + atan2(a_part1, a_part2))
    a_v = a * cos(theta_a - theta)
    # 计算kappa
    vec_n = np.array([-sin(theta), cos(theta)])  # 切线单位向量n
    kappa = a * np.dot(np.array([cos(theta_a), sin(theta_a)]), vec_n) / (v*v)

    return  vec_r[0], vec_r[1], v, a_v, theta, kappa

2. 参考文献

B站up主忠厚老实的老王的自动驾驶决策规划视频


文章首发公众号:iDoitnow如果喜欢话,可以关注一下

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

打赏作者

艰默

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

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

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

打赏作者

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

抵扣说明:

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

余额充值