单车模型及其线性化

1 单车模型

  这里讨论的是以后轴为中心的单车运动学模型,由下式表达:

S ˙ = [ x ˙ y ˙ ψ ˙ ] = [ v c o s ( ψ ) v s i n ( ψ ) v t a n ( ψ ) L ] \dot S = \begin{bmatrix} \dot x\\ \dot y\\ \dot \psi \\ \end{bmatrix} = \begin{bmatrix} vcos(\psi)\\ vsin(\psi)\\ v\frac{tan(\psi)}{L} \\ \end{bmatrix} S˙= x˙y˙ψ˙ = vcos(ψ)vsin(ψ)vLtan(ψ)

其中 S S S代表系统状态, δ \delta δ为单车模型的前轮转角, x , y x,y x,y是车辆在世界坐标系下的位置, L L L为轴距, v v v为车辆速度, ψ \psi ψ代表航向角,单车模型中应该是假设了质心侧偏角为0,所以 ψ \psi ψ应该也等于横摆角,即车头朝向。

  如果把加速度和前轮转角的变化加上,则可以写成:
S ˙ = [ x ˙ y ˙ ψ ˙ v ˙ δ ˙ ] = [ v c o s ( ψ ) v s i n ( ψ ) v t a n ( ψ ) L a γ ] = [ f 1 f 2 f 3 f 4 f 5 ] = f ( S ) \dot S = \begin{bmatrix} \dot x\\ \dot y\\ \dot \psi \\ \dot v \\ \dot \delta \end{bmatrix} = \begin{bmatrix} vcos(\psi)\\ vsin(\psi)\\ v\frac{tan(\psi)}{L} \\ a \\ \gamma \end{bmatrix} = \begin{bmatrix} f_1\\ f_2\\ f_3 \\ f_4 \\ f_5 \end{bmatrix} =f(S) S˙= x˙y˙ψ˙v˙δ˙ = vcos(ψ)vsin(ψ)vLtan(ψ)aγ = f1f2f3f4f5 =f(S)
这里 γ \gamma γ是我自己取的名字,看别的博客把速度和前轮转角用额外的矩阵表示了,这里我放在一起推一推。

2 线性化

  将上述系统 S ˙ = f ( S ) \dot S = f(S) S˙=f(S) S = S r = [ x r y r ψ r v r δ r ] S = S_r = \begin{bmatrix}x_r\\y_r\\\psi_r\\v_r\\\delta_r\end{bmatrix} S=Sr= xryrψrvrδr 处泰勒展开,忽略高次项:

S ˙ ≈ f ( S r ) + d f d S ( S − S r ) \dot S \approx f(S_r) + \cfrac{df}{dS}(S - S_r) S˙f(Sr)+dSdf(SSr)

进而有:
S ˙ − S ˙ r = ( d f 1 d x d f 1 d y d f 1 d ψ d f 1 d v d f 1 d δ d f 2 d x d f 2 d y d f 2 d ψ d f 2 d v d f 2 d δ d f 3 d x d f 3 d y d f 3 d ψ d f 3 d v d f 3 d δ d f 4 d x d f 4 d y d f 4 d ψ d f 4 d v d f 4 d δ d f 5 d x d f 5 d y d f 5 d ψ d f 5 d v d f 5 d δ ) [ x − x r y − y r ψ − ψ r v − v r δ − δ r ] \dot S - \dot S_r = \begin{pmatrix} \frac{df_1}{dx} & \frac{df_1}{dy} & \frac{df_1}{d\psi} & \frac{df_1}{dv} & \frac{df_1}{d\delta} \\ \frac{df_2}{dx} & \frac{df_2}{dy} & \frac{df_2}{d\psi} & \frac{df_2}{dv} & \frac{df_2}{d\delta} \\ \frac{df_3}{dx} & \frac{df_3}{dy} & \frac{df_3}{d\psi} & \frac{df_3}{dv} & \frac{df_3}{d\delta} \\ \frac{df_4}{dx} & \frac{df_4}{dy} & \frac{df_4}{d\psi} & \frac{df_4}{dv} & \frac{df_4}{d\delta} \\ \frac{df_5}{dx} & \frac{df_5}{dy} & \frac{df_5}{d\psi} & \frac{df_5}{dv} & \frac{df_5}{d\delta} \\ \end{pmatrix} \begin{bmatrix}x - x_r\\y - y_r\\\psi - \psi_r\\v - v_r\\\delta - \delta_r\end{bmatrix} S˙S˙r= dxdf1dxdf2dxdf3dxdf4dxdf5dydf1dydf2dydf3dydf4dydf5dψdf1dψdf2dψdf3dψdf4dψdf5dvdf1dvdf2dvdf3dvdf4dvdf5dδdf1dδdf2dδdf3dδdf4dδdf5 xxryyrψψrvvrδδr

求导可得:
S ˙ − S ˙ r = ( 0 0 − v s i n ( ψ ) c o s ( ψ ) 0 0 0 v c o s ( ψ ) s i n ( ψ ) 0 0 0 0 t a n ( δ ) L v L c o s 2 ( δ ) 0 0 0 0 0 0 0 0 0 0 ) [ x − x r y − y r ψ − ψ r v − v r δ − δ r ] = J Δ S \dot S - \dot S_r = \begin{pmatrix} 0 & 0 & -vsin(\psi) & cos(\psi) & 0 \\ 0 & 0 & vcos(\psi) & sin(\psi) & 0 \\ 0 & 0 & 0 & \frac{tan(\delta)}{L} & \frac{v}{Lcos^2(\delta)} \\ 0 & 0 & 0 & 0 & 0 \\ 0 & 0 & 0 & 0 & 0 \\ \end{pmatrix}\begin{bmatrix}x - x_r\\y - y_r\\\psi - \psi_r\\v - v_r\\\delta - \delta_r\end{bmatrix} = J\Delta S S˙S˙r= 0000000000vsin(ψ)vcos(ψ)000cos(ψ)sin(ψ)Ltan(δ)0000Lcos2(δ)v00 xxryyrψψrvvrδδr =JΔS

最后可得线性化表示

Δ S ˙ = S ˙ − S ˙ r = J Δ S \Delta \dot S = \dot S - \dot S_r = J\Delta S ΔS˙=S˙S˙r=JΔS

在实际应用中需要把它写成差分的形式,假设采样时间间隔为 Δ t \Delta t Δt,则有:

Δ S k + 1 − Δ S k Δ t = J Δ S k \cfrac{\Delta S_{k+1} - \Delta S_{k}}{\Delta t} = J \Delta S_k ΔtΔSk+1ΔSk=JΔSk
最后得到车辆状态变化的差分方程形式
Δ S k + 1 = ( J Δ t + I ) Δ S k \Delta S_{k+1} = (J\Delta t + I)\Delta S_k ΔSk+1=(JΔt+I)ΔSk

3 实现效果

  现在假设采样时间为0.1秒,车辆初始状态在原点,车头朝向是45度,运行1.5秒,分别用单车模型和线性化方法实现两个单车模型,看看跑出来的误差是怎样的。这里给的加速度是 4 m / s 2 4m/s^2 4m/s2,前轮转角不变。效果如下红色是单车模型,绿色是线性化后的单车模型,这里的动画运行时间间隔是0.2s,方便看效果。可以看到在前1秒内这个线性化算出来的车辆状态和单车模型本身的误差还是可以的。
在这里插入图片描述

4 相关代码

  以车辆后轴为中心的单车模型

class KinematicModelBackCenter:
    """
    车辆后轴中心,单车模型
    x, y: 代表车辆中心的坐标
    psi: 代表车辆的航向角,也就是车辆的heading
    v: 代表车辆的速度
    L: 轴距,前轮到后轮中心的距离
    dt: 仿真的时间间隔
    """
    def __init__(self, x, y, psi, v, L, dt):
        self.x = x
        self.y = y
        self.psi = psi
        self.v = v
        self.L = L
        self.dt = dt

    def update_state(self, a, delta_f):
        self.x = self.x + self.v * math.cos(self.psi) * self.dt
        self.y = self.y + self.v * math.sin(self.psi) * self.dt
        self.psi = self.psi + self.v / self.L * math.tan(delta_f) * self.dt
        self.v = self.v + a * self.dt

  线性化的差分形式的伪代码,线性化在应用中不应该是模拟用,这里只是想看1秒内误差是怎样的

# 上面推出来的(J*dt + I)
J = np.matrix([[1, 0, -v * math.sin(psi) * dt, math.cos(psi) * dt, 0],
               [0, 1, v * math.cos(psi) * dt, math.sin(psi) * dt, 0],
               [0, 0, 1, math.tan(delta_f) * dt / L, v * dt / (L * math.cos(delta_f) ** 2)],
               [0, 0, 0, 1, 0],
               [0, 0, 0, 0, 1]])
# 加速度为4,delta_f的变化率为0,相邻时间步的变化量
ds = np.matrix([[v * math.cos(psi) * dt],
                  [v * math.sin(psi) * dt],
                  [v * math.tan(delta_f) / L * dt],
                  [a * dt],
                  [0.0]])
# 每一步更新ds
ds = J * ds

5 参考资料

  • 20
    点赞
  • 16
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值