线性化

线性化的方法

泰勒级数展开是一种将非线性微分方程在某个特定点(通常是平衡点或操作点)附近线性化的方法。这种方法基于在该点附近,非线性函数可以近似为线性函数加上高阶无穷小。以下是使用泰勒级数展开进行线性化的步骤:

  1. 选择平衡点
    选择系统的平衡点,即系统在没有外部扰动时的稳态工作点。在这个点上,系统的所有导数(或状态变量的变化率)都为零。

  2. 计算函数值和导数
    在平衡点处计算非线性函数的值以及所有一阶和高阶导数。这些导数将构成泰勒级数展开的系数。

  3. 泰勒级数展开
    将非线性函数在展开点附近展开为泰勒级数。通常只保留一阶项(线性项),因为高阶项在小扰动下的影响较小。泰勒级数展开的一般形式为:
    f ( x ) ≈ f ( a ) + f ′ ( a ) ( x − a ) (1) f(x) \approx f(a) + f'(a)(x - a) \tag{1} f(x)f(a)+f(a)(xa)(1)
    其中, f ( x ) f(x) f(x) 是非线性函数, a a a 是展开点, f ′ ( a ) f'(a) f(a) 是函数在点 a a a 的导数。

  4. 线性近似
    通过忽略高阶项,得到非线性函数在展开点附近的线性近似。这个近似可以用来分析系统的局部行为,例如稳定性分析。

  5. 应用线性化模型
    使用线性化后的模型来分析系统的行为,设计控制器,或者进行数值模拟。线性系统的理论工具可以直接应用于这个线性化模型。

举例说明,假设有一个非线性微分方程:
x ˙ = f ( x , u ) (2) \dot{x} = f(x, u) \tag{2} x˙=f(x,u)(2)
其中, x ˙ \dot{x} x˙ 表示 x x x 的导数, u u u 是控制输入。如果我们选择展开点 ( x 0 , u 0 ) (x_0, u_0) (x0,u0),那么在该点附近的泰勒级数展开的一般形式是:
f ( x , u ) = f ( x 0 , u 0 ) + ∂ f ∂ x ( x 0 , u 0 ) ( x − x 0 ) + ∂ f ∂ u ( x 0 , u 0 ) ( u − u 0 ) + ⋯ (3) f(x, u) = f(x_0, u_0) + \frac{\partial f}{\partial x}(x_0, u_0)(x - x_0) + \frac{\partial f}{\partial u}(x_0, u_0)(u - u_0) + \cdots \tag{3} f(x,u)=f(x0,u0)+xf(x0,u0)(xx0)+uf(x0,u0)(uu0)+(3)
如果我们只保留到一阶项,那么非线性方程就可以近似为线性方程:
f ( x , u ) ≈ f ( x 0 , u 0 ) + ∂ f ∂ x ( x 0 , u 0 ) ( x − x 0 ) + ∂ f ∂ u ( x 0 , u 0 ) ( u − u 0 ) (4) f(x, u) \approx f(x_0, u_0) + \frac{\partial f}{\partial x}(x_0, u_0)(x - x_0) + \frac{\partial f}{\partial u}(x_0, u_0)(u - u_0) \tag{4} f(x,u)f(x0,u0)+xf(x0,u0)(xx0)+uf(x0,u0)(uu0)(4)
这个线性化过程的关键在于选择一个合适的点 ( x 0 , u 0 ) (x_0, u_0) (x0,u0) 作为展开点,以及确定展开到哪个阶数。通常,我们会选择平衡点或某个特定的工作点作为展开点。需要注意的是,线性化是一种近似方法,只在一定条件下成立。当扰动或偏差较大时,线性化可能不再准确。因此,在应用线性化方法时,需要谨慎评估其适用性和误差范围。

车辆运动学线性化

{ x ˙ = v c o s φ y ˙ = v s i n φ φ ˙ = v t a n δ f L (5) \begin{cases} \dot{x} = vcos\varphi \\ \dot{y} = vsin\varphi \\ \dot{\varphi} = \frac{vtan\delta_f}{L} \end{cases} \tag{5} x˙=vcosφy˙=vsinφφ˙=Lvtanδf(5)
这里状态变化量和控制量分别为
X ˙ = [ x ˙ y ˙ φ ˙ ] = [ v c o s φ v s i n φ v t a n δ f L ] , u = [ v δ f ] \begin{align*} \dot{X}= \begin{bmatrix} \dot{x}\\ \dot{y}\\ \dot{\varphi} \end{bmatrix}= \begin{bmatrix} vcos\varphi\\ vsin\varphi\\ \frac{vtan\delta_f}{L} \end{bmatrix},& u= \begin{bmatrix} v \\ \delta_f\\ \end{bmatrix} \tag{6} \end{align*} X˙= x˙y˙φ˙ = vcosφvsinφLvtanδf ,u=[vδf](6)
则对应的非线性微分方程为
X ˙ = f ( X , u ) (7) \dot{X}=f(X,u) \tag{7} X˙=f(X,u)(7)
我们选取参考轨迹上的任意一点作为展开点,我们用 X r ˙ = f ( X r , u r ) \dot{X_r}=f(X_r,u_r) Xr˙=f(Xr,ur)表示,其中 X r = [ x r , y r , φ r ] T X_r=[x_r,y_r,\varphi_r]^T Xr=[xr,yr,φr]T u r = [ v r , δ f r ] T u_r=[v_r,\delta_{fr}]^T ur=[vr,δfr]T。对该点采用泰勒级数展开,并忽略高阶项,可得
X ˙ = f ( X r , u r ) + ∂ f ∂ x ( X r , u r ) ( X − X r ) + ∂ f ∂ u ( X r , u r ) ( u − u r ) X ˙ = X r ˙ + ∂ f ∂ x ( X r , u r ) ( X − X r ) + ∂ f ∂ u ( X r , u r ) ( u − u r ) (8) \begin{align*} \dot{X}&=f(X_r,u_r)+\frac{\partial f}{\partial x}(X_r,u_r)(X - X_r) + \frac{\partial f}{\partial u}(X_r,u_r)(u - u_r)\\ \dot{X}&=\dot{X_r}+\frac{\partial f}{\partial x}(X_r,u_r)(X - X_r) + \frac{\partial f}{\partial u}(X_r,u_r)(u - u_r) \end{align*} \tag{8} X˙X˙=f(Xr,ur)+xf(Xr,ur)(XXr)+uf(Xr,ur)(uur)=Xr˙+xf(Xr,ur)(XXr)+uf(Xr,ur)(uur)(8)
移项可得状态误差变化量
X e ˙ = X ˙ − X r ˙ = ∂ f ∂ x ( X r , u r ) ( X − X r ) + ∂ f ∂ u ( X r , u r ) ( u − u r ) (9) \dot{X_e}=\dot{X}-\dot{X_r}=\frac{\partial f}{\partial x}(X_r,u_r)(X - X_r) + \frac{\partial f}{\partial u}(X_r,u_r)(u - u_r) \tag{9} Xe˙=X˙Xr˙=xf(Xr,ur)(XXr)+uf(Xr,ur)(uur)(9)
其中
∂ f ∂ x ( X r , u r ) = [ ∂ v c o s φ ∂ x ∂ v c o s φ ∂ y ∂ v c o s φ ∂ φ ∂ v s i n φ ∂ x ∂ v s i n φ ∂ y ∂ v s i n φ ∂ φ ∂ v t a n δ f L ∂ x ∂ v t a n δ f L ∂ y ∂ v t a n δ f L ∂ φ ] ( X r , u r ) = [ 0 0 − v r s i n φ r 0 0 v r c o s φ r 0 0 0 ] ∂ f ∂ u ( X r , u r ) = [ ∂ v c o s φ ∂ v ∂ v c o s φ ∂ δ f ∂ v s i n φ ∂ v ∂ v s i n φ ∂ δ f ∂ v t a n δ f L ∂ v ∂ v t a n δ f L ∂ δ f ] ( X r , u r ) = [ c o s φ r 0 s i n φ r 0 t a n δ f r L v r L c o s 2 δ f r ] (10) \begin{align*} \frac{\partial f}{\partial x}(X_r,u_r)= \begin{bmatrix} \frac{\partial vcos\varphi }{\partial x} & \frac{\partial vcos\varphi }{\partial y} & \frac{\partial vcos\varphi }{\partial \varphi} \\ \frac{\partial vsin\varphi }{\partial x} & \frac{\partial vsin\varphi }{\partial y} & \frac{\partial vsin\varphi }{\partial \varphi} \\ \frac{\partial \frac{vtan\delta_f}{L} }{\partial x} & \frac{\partial \frac{vtan\delta_f}{L} }{\partial y} & \frac{\partial \frac{vtan\delta_f}{L} }{\partial \varphi} \\ \end{bmatrix}_{(X_r,u_r)}= \begin{bmatrix} 0 & 0 & -v_rsin\varphi_r\\ 0 & 0 & v_rcos\varphi_r\\ 0 & 0 & 0\\ \end{bmatrix}\\ \frac{\partial f}{\partial u}(X_r,u_r)= \begin{bmatrix} \frac{\partial vcos\varphi }{\partial v} & \frac{\partial vcos\varphi }{\partial \delta_f} \\ \frac{\partial vsin\varphi }{\partial v} & \frac{\partial vsin\varphi }{\partial \delta_f} \\ \frac{\partial \frac{vtan\delta_f}{L} }{\partial v} & \frac{\partial \frac{vtan\delta_f}{L} }{\partial \delta_f} \\ \end{bmatrix}_{(X_r,u_r)}= \begin{bmatrix} cos\varphi_r & 0 \\ sin\varphi_r & 0 \\ \frac{ tan\delta_{fr}}{L} & \frac{v_r}{Lcos^2\delta_{fr}} \\ \end{bmatrix} \end{align*} \tag{10} xf(Xr,ur)= xvcosφxvsinφxLvtanδfyvcosφyvsinφyLvtanδfφvcosφφvsinφφLvtanδf (Xr,ur)= 000000vrsinφrvrcosφr0 uf(Xr,ur)= vvcosφvvsinφvLvtanδfδfvcosφδfvsinφδfLvtanδf (Xr,ur)= cosφrsinφrLtanδfr00Lcos2δfrvr (10)
则状态误差变化量 X e ˙ \dot{X_e} Xe˙可表示为
X e ˙ = [ x ˙ − x r ˙ y ˙ − y r ˙ φ ˙ − φ r ˙ ] = [ 0 0 − v r s i n φ r 0 0 v r c o s φ r 0 0 0 ] [ x − x r y − y r φ − φ r ] + [ c o s φ r 0 s i n φ r 0 t a n δ f r L v r L c o s 2 δ f r ] [ v − v r δ − δ r ] = A X e + B u e (11) \begin{align*} \dot{X_e}&= \begin{bmatrix} \dot{x}-\dot{x_r}\\ \dot{y}-\dot{y_r}\\ \dot{\varphi}-\dot{\varphi_r}\\ \end{bmatrix} \\ &= \begin{bmatrix} 0 & 0 & -v_rsin\varphi_r\\ 0 & 0 & v_rcos\varphi_r\\ 0 & 0 & 0\\ \end{bmatrix} \begin{bmatrix} x-x_r\\ y-y_r\\ \varphi-\varphi_r\\ \end{bmatrix} + \begin{bmatrix} cos\varphi_r & 0 \\ sin\varphi_r & 0 \\ \frac{ tan\delta_{fr}}{L} & \frac{v_r}{Lcos^2\delta_{fr}} \\ \end{bmatrix} \begin{bmatrix} v-v_r\\ \delta-\delta_r\\ \end{bmatrix} \\ &= AX_e+Bu_e \end{align*} \tag{11} Xe˙= x˙xr˙y˙yr˙φ˙φr˙ = 000000vrsinφrvrcosφr0 xxryyrφφr + cosφrsinφrLtanδfr00Lcos2δfrvr [vvrδδr]=AXe+Bue(11)

离散化

离散化方法

欧拉法

对于线性微分方程
x ˙ = A x + B u (12) \dot{x}=Ax+Bu \tag{12} x˙=Ax+Bu(12)
其中 A A A B B B分别为状态矩阵和输入矩阵,对上式进行 t t t t + d t t+dt t+dt的积分可得
∫ t t + d t x ˙   d x = ∫ t t + d t ( A x + B u ) d t (13) \int_{t}^{t+dt} \dot{x}\,dx = \int_{t}^{t+dt}(Ax+Bu)dt \tag{13} tt+dtx˙dx=tt+dt(Ax+Bu)dt(13)
由微分中值定理可得
x ( t + d t ) − x ( t ) = A x ( ξ ) d t + B u ( ξ ) d t (14) \begin{align*} x(t+dt)-x(t)=Ax(\xi)dt+Bu(\xi)dt \end{align*} \tag{14} x(t+dt)x(t)=Ax(ξ)dt+Bu(ξ)dt(14)
其中 ξ ∈ ( t . d t ) \xi \in (t.dt) ξ(t.dt)

整理可得
x ( t + d t ) = x ( t ) + A x ( ξ ) d t + B u ( ξ ) d t (15) x(t+dt)=x(t)+ Ax(\xi)dt+Bu(\xi)dt \tag{15} x(t+dt)=x(t)+Ax(ξ)dt+Bu(ξ)dt(15)
根据 ξ \xi ξ的计算方式不同,欧拉法又分为前向欧拉法、后向欧拉法和中值欧拉法。其具体的形式如下

  • 前向欧拉法: x ( ξ ) = x ( t ) x(\xi)=x(t) x(ξ)=x(t)​;
  • 后向欧拉法: x ( ξ ) = x ( t + d t ) x(\xi)=x(t+dt) x(ξ)=x(t+dt)
  • 中值欧拉法: x ( ξ ) = x ( t ) + x ( t + d t ) 2 x(\xi)=\frac{x(t)+x(t+dt)}{2} x(ξ)=2x(t)+x(t+dt)

设离散间隔为 T T T,离散时间为 k k k,则(15)式子 t t t t + d t t+dt t+dt d t dt dt中分别对应的就是 k k k k + 1 k+1 k+1 T T T,结合(15)式,整理可得对应的微分方程如下

  • 前向欧拉法: x ( k + 1 ) = x ( k ) + T A x ( k ) + T B u ( k ) = ( I + T A ) x ( k ) + T B u ( k ) x(k+1)=x(k)+TAx(k)+TBu(k) =(I+TA)x(k)+TBu(k) x(k+1)=x(k)+TAx(k)+TBu(k)=(I+TA)x(k)+TBu(k)​​;
  • 后向欧拉法: x ( k + 1 ) = x ( k ) + T A x ( k + 1 ) + T B u ( k + 1 ) = ( I + T A ) x ( k + 1 ) + T B u ( t + 1 ) x(k+1)=x(k)+TAx(k+1)+TBu(k+1) =(I+TA)x(k+1)+TBu(t+1) x(k+1)=x(k)+TAx(k+1)+TBu(k+1)=(I+TA)x(k+1)+TBu(t+1)
  • 中值欧拉法: x ( k + 1 ) = x ( k ) + T A x ( k + 1 2 ) + T B u ( k + 1 2 ) = ( I + T A ) x ( k + 1 2 ) + T B u ( k + 1 2 ) x(k+1)=x(k)+TAx(\frac{k+1}{2})+TBu(\frac{k+1}{2}) =(I+TA)x(\frac{k+1}{2})+TBu(\frac{k+1}{2}) x(k+1)=x(k)+TAx(2k+1)+TBu(2k+1)=(I+TA)x(2k+1)+TBu(2k+1)
零阶保持法

对于(12)式的微分方程,设初始时间为 t 0 t_0 t0,则其任意时刻状态 x ( t ) x(t) x(t)
x ( t ) = x ( t 0 ) e A ( t − t 0 ) + ∫ t 0 t e A ( t − τ ) B u ( τ ) d τ (16) x(t)=x(t_0)e^{A(t-t_0)}+\int_{t_0}^t e^{A(t-\tau)} Bu(\tau)d{\tau} \tag{16} x(t)=x(t0)eA(tt0)+t0teA(tτ)Bu(τ)dτ(16)
式(16)的证明过程如下

证明

将状态方程(12)移项并左右同乘 e − A t e^{-At} eAt
e − A t ( x ˙ ( t ) − A x ( t ) ) = e − A t B u ( t ) (17) e^{-At}(\dot{x}(t)-Ax(t))=e^{-At}Bu(t) \tag{17} eAt(x˙(t)Ax(t))=eAtBu(t)(17)
上式整理可得
d ( e − A t x ( t ) ) d t = e − A t B u ( t ) (18) \frac{d(e^{-At}x(t))}{dt}=e^{-At}Bu(t) \tag{18} dtd(eAtx(t))=eAtBu(t)(18)
方程左右同时积分得
∫ t 0 t d ( e − A τ x ( τ ) ) d τ d τ = ∫ t 0 t e − A τ B u ( τ ) d τ (19) \int_{t_0}^t \frac{d(e^{-A\tau}x(\tau))}{d\tau} d\tau=\int_{t_0}^te^{-A\tau}Bu(\tau)d\tau \tag{19} t0tdτd(eAτx(τ))dτ=t0teAτBu(τ)dτ(19)
化简可得
e − A t x ( t ) − e − A t 0 x ( t 0 ) = ∫ t 0 t e − A τ B u ( τ ) d τ (20) e^{-At}x(t)-e^{-At_0}x(t_0) =\int_{t_0}^te^{-A\tau}Bu(\tau)d\tau \tag{20} eAtx(t)eAt0x(t0)=t0teAτBu(τ)dτ(20)
移项可得
x ( t ) = x ( t 0 ) e A ( t − t 0 ) + ∫ t 0 t e A ( t − τ ) B u ( τ ) d τ (21) x(t)=x(t_0)e^{A(t-t_0)} + \int_{t_0}^te^{A(t-\tau)}Bu(\tau)d\tau \tag{21} x(t)=x(t0)eA(tt0)+t0teA(tτ)Bu(τ)dτ(21)

设离散系统的采样时间间隔为 T T T,则离散时间 t k + 1 = t k + T t_{k+1}=t_k + T tk+1=tk+T,结合(12)式状态微分方程的解(16)可得
x ( t k + 1 ) = x ( t k ) e A ( t k + 1 − t k ) + ∫ t k t k + 1 e A ( t k + 1 − τ ) B u ( τ ) d τ (22) x(t_{k+1})=x(t_k)e^{A(t_{k+1}-t_k)} + \int_{t_k}^{t_{k+1}}e^{A(t_{k+1}-\tau)}Bu(\tau)d\tau \tag{22} x(tk+1)=x(tk)eA(tk+1tk)+tktk+1eA(tk+1τ)Bu(τ)dτ(22)
根据零阶保持器的特性(即动态系统的输入 u ( t ) u(t) u(t)在每一个采样时间内保持不变)。可得
u ( t ) = u ( t k )          t k ≤ t < t k + 1 (23) u(t)=u(t_k) \;\;\;\; t_k \leq t \lt t_{k+1} \tag{23} u(t)=u(tk)tkt<tk+1(23)
因此结合 t k + 1 − t k = T t_{k+1}-t_k = T tk+1tk=T,可将式(22)写为
x ( t k + 1 ) = x ( t k ) e A T + B u ( t k ) ∫ t k t k + T e A ( t k + T − τ ) d τ = e A T x ( t k ) + ( ∫ t k t k + T e A ( t k + T − τ ) d τ ) B u ( t k ) = e A T x ( t k ) + ( − A − 1 e A ( t k + T − τ ) ∣ t k t k + T ) B u ( t k ) = e A T x ( t k ) + ( − A − 1 ( e 0 − e A T ) ) B u ( t k ) = e A T x ( t k ) + A − 1 ( e A T − I ) B u ( t k ) (24) \begin{align*} x(t_{k+1})&=x(t_k)e^{AT} + Bu(t_k)\int_{t_k}^{t_k+T}e^{A(t_k+T-\tau)}d\tau \\ &=e^{AT}x(t_k) + (\int_{t_k}^{t_k+T}e^{A(t_k+T-\tau)}d\tau)Bu(t_k) \\ &=e^{AT}x(t_k) + (-A^{-1}e^{A(t_k+T-\tau)}\bigg|_{t_k}^{t_k+T})Bu(t_k) \\ &=e^{AT}x(t_k) + (-A^{-1}(e^0-e^{AT}))Bu(t_k) \\ &=e^{AT}x(t_k) + A^{-1}(e^{AT}-I)Bu(t_k) \\ \end{align*} \tag{24} x(tk+1)=x(tk)eAT+Bu(tk)tktk+TeA(tk+Tτ)dτ=eATx(tk)+(tktk+TeA(tk+Tτ)dτ)Bu(tk)=eATx(tk)+(A1eA(tk+Tτ) tktk+T)Bu(tk)=eATx(tk)+(A1(e0eAT))Bu(tk)=eATx(tk)+A1(eATI)Bu(tk)(24)
根据上式可得零阶保持法离散化后的微分方程:
{ x ( k + 1 ) = F x ( k ) + G u ( k ) F = e A T G = A − 1 ( e A T − I ) B = A − 1 ( F − I ) B (25) \begin{cases} x(k+1)=Fx(k)+Gu(k)\\ F=e^{AT}\\ G=A^{-1}(e^{AT}-I)B = A^{-1}(F-I)B \end{cases} \tag{25} x(k+1)=Fx(k)+Gu(k)F=eATG=A1(eATI)B=A1(FI)B(25)

车辆运动学离散化

对(11)式进行前向欧拉离散化,可得
X e ( k ) ˙ = X e ( k + 1 ) − X e ( k ) T = A X e ( k ) + B u e ( k ) (26) \dot{X_e(k)}= \frac{X_e(k+1)-X_e(k)}{T}= AX_e(k)+Bu_e(k) \tag{26} Xe(k)˙=TXe(k+1)Xe(k)=AXe(k)+Bue(k)(26)
整理后的矩阵形式如下所示
X e ( k + 1 ) = ( T A + I ) A X e ( k ) + T B u e ( k ) = [ 1 0 − T v r s i n φ r 0 1 T v r c o s φ r 0 0 1 ] [ x − x r y − y r φ − φ r ] + [ T c o s φ r 0 T s i n φ r 0 T v r t a n δ f r L T v r L c o s 2 δ f r ] [ v − v r δ − δ r ] (27) \begin{align*} X_e(k+1)&=(TA+I)AX_e(k)+TBu_e(k)\\ &= \begin{bmatrix} 1 & 0 & -Tv_rsin\varphi_r\\ 0 & 1 & Tv_rcos\varphi_r\\ 0 & 0 & 1\\ \end{bmatrix} \begin{bmatrix} x-x_r\\ y-y_r\\ \varphi-\varphi_r\\ \end{bmatrix} + \begin{bmatrix} Tcos\varphi_r & 0 \\ Tsin\varphi_r & 0 \\ \frac{Tv_r tan\delta_{fr}}{L} & \frac{Tv_r}{Lcos^2\delta_{fr}} \\ \end{bmatrix} \begin{bmatrix} v-v_r\\ \delta-\delta_r\\ \end{bmatrix} \\ \end{align*} \tag{27} Xe(k+1)=(TA+I)AXe(k)+TBue(k)= 100010TvrsinφrTvrcosφr1 xxryyrφφr + TcosφrTsinφrLTvrtanδfr00Lcos2δfrTvr [vvrδδr](27)
其中 T T T为采样步长, I I I为3x3的单位矩阵。

代码实现

python代码实现基于前面文章用到的车辆运动学模型,新增update_ABMatrix(vehicle, ref_delta, ref_yaw)方法实现,其中vehicleVehicle类实例,ref_deltaref_yaw分别为当前时刻参考线匹配点对应的角度变化 δ f r \delta_{fr} δfr和航向角 φ r \varphi_r φr,具体实现如下

import math
import numpy as np

class Vehicle:
    def __init__(self,
                 x=0.0,
                 y=0.0,
                 yaw=0.0,
                 v=0.0,
                 dt=0.1,
                 l=3.0):
        self.steer = 0
        self.x = x
        self.y = y
        self.yaw = yaw
        self.v = v
        self.dt = dt
        self.L = l  # 轴距
        self.x_front = x + l * math.cos(yaw)
        self.y_front = y + l * math.sin(yaw)

    def update(self, a, delta, max_steer=np.pi):
        delta = np.clip(delta, -max_steer, max_steer)
        self.steer = delta

        self.x = self.x + self.v * math.cos(self.yaw) * self.dt
        self.y = self.y + self.v * math.sin(self.yaw) * self.dt
        self.yaw = self.yaw + self.v / self.L * math.tan(delta) * self.dt

        self.v = self.v + a * self.dt
        self.x_front = self.x + self.L * math.cos(self.yaw)
        self.y_front = self.y + self.L * math.sin(self.yaw)


class VehicleInfo:
    # Vehicle parameter
    L = 3.0  # 轴距
    W = 2.0  # 宽度
    LF = 3.8  # 后轴中心到车头距离
    LB = 0.8  # 后轴中心到车尾距离
    MAX_STEER = 0.6  # 最大前轮转角
    TR = 0.5  # 轮子半径
    TW = 0.5  # 轮子宽度
    WD = W  # 轮距
    LENGTH = LB + LF  # 车辆长度

def draw_vehicle(x, y, yaw, steer, ax, vehicle_info=VehicleInfo, color='black'):
    vehicle_outline = np.array(
        [[-vehicle_info.LB, vehicle_info.LF, vehicle_info.LF, -vehicle_info.LB, -vehicle_info.LB],
         [vehicle_info.W / 2, vehicle_info.W / 2, -vehicle_info.W / 2, -vehicle_info.W / 2, vehicle_info.W / 2]])

    wheel = np.array([[-vehicle_info.TR, vehicle_info.TR, vehicle_info.TR, -vehicle_info.TR, -vehicle_info.TR],
                      [vehicle_info.TW / 2, vehicle_info.TW / 2, -vehicle_info.TW / 2, -vehicle_info.TW / 2,
                       vehicle_info.TW / 2]])

    rr_wheel = wheel.copy()  # 右后轮
    rl_wheel = wheel.copy()  # 左后轮
    fr_wheel = wheel.copy()  # 右前轮
    fl_wheel = wheel.copy()  # 左前轮
    rr_wheel[1, :] += vehicle_info.WD / 2
    rl_wheel[1, :] -= vehicle_info.WD / 2

    # 方向盘旋转
    rot1 = np.array([[np.cos(steer), -np.sin(steer)],
                     [np.sin(steer), np.cos(steer)]])
    # yaw旋转矩阵
    rot2 = np.array([[np.cos(yaw), -np.sin(yaw)],
                     [np.sin(yaw), np.cos(yaw)]])
    fr_wheel = np.dot(rot1, fr_wheel)
    fl_wheel = np.dot(rot1, fl_wheel)
    fr_wheel += np.array([[vehicle_info.L], [-vehicle_info.WD / 2]])
    fl_wheel += np.array([[vehicle_info.L], [vehicle_info.WD / 2]])

    fr_wheel = np.dot(rot2, fr_wheel)
    fr_wheel[0, :] += x
    fr_wheel[1, :] += y
    fl_wheel = np.dot(rot2, fl_wheel)
    fl_wheel[0, :] += x
    fl_wheel[1, :] += y
    rr_wheel = np.dot(rot2, rr_wheel)
    rr_wheel[0, :] += x
    rr_wheel[1, :] += y
    rl_wheel = np.dot(rot2, rl_wheel)
    rl_wheel[0, :] += x
    rl_wheel[1, :] += y
    vehicle_outline = np.dot(rot2, vehicle_outline)
    vehicle_outline[0, :] += x
    vehicle_outline[1, :] += y

    ax.plot(fr_wheel[0, :], fr_wheel[1, :], color)
    ax.plot(rr_wheel[0, :], rr_wheel[1, :], color)
    ax.plot(fl_wheel[0, :], fl_wheel[1, :], color)
    ax.plot(rl_wheel[0, :], rl_wheel[1, :], color)

    ax.plot(vehicle_outline[0, :], vehicle_outline[1, :], color)
    ax.axis('equal')


def update_ABMatrix(vehicle, ref_delta, ref_yaw):
    """
    计算离散线性车辆运动学模型状态矩阵A和输入矩阵B
    return: A, B
    """
    A = np.matrix([
        [1.0, 0.0, -vehicle.v * vehicle.dt * math.sin(ref_yaw)],
        [0.0, 1.0, vehicle.v * vehicle.dt * math.cos(ref_yaw)],
        [0.0, 0.0, 1.0]])

    B = np.matrix([
        [vehicle.dt * math.cos(ref_yaw), 0],
        [vehicle.dt * math.sin(ref_yaw), 0],
        [vehicle.dt * math.tan(ref_delta) / vehicle.L,
         vehicle.v * vehicle.dt / (vehicle.L * math.cos(ref_delta) * math.cos(ref_delta))]])
    return A, B

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

Logo

有“AI”的1024 = 2048,欢迎大家加入2048 AI社区

更多推荐