🚲

二輪車の運動特性(1) ベンチマーク自転車モデルの固有値解析

に公開

システム行列の固有値・固有ベクトルと挙動との関係がわかったので、次はいよいよ二輪車の安定性解析モデルについて固有値・固有ベクトルを求めて、どのような挙動を示すのかを見ていきたいと思います。

二輪車安定性解析モデルのシステム行列

二輪車の運動方程式は次のように表されることを紹介しました。

\bold{M}\ddot{\bm{q}} + v\bold{C_1}\dot{\bm{q}} + (g\bold{K_0} + v^2\bold{K_2})\bm{q} = \bm{f} \\

これも倒立振子の場合と同様の手法で二階常微分方程式の一階化を行います。質量行列\bold{M}は通常逆行列を持つので、二輪車の運動方程式は次のような状態方程式に変換することができます。

\begin{bmatrix} \bm{\dot{q}} \\ \bm{\ddot{q}} \end{bmatrix} = \begin{bmatrix} \bold{O} & \bold{E} \\ -(g\bold{M^{-1}K_0}+v^2\bold{M^{-1}K_2}) & -v\bold{M^{-1}C_1} \end{bmatrix} \begin{bmatrix} \bm{q} \\ \bm{\dot{q}} \end{bmatrix} + \begin{bmatrix} \bold{O} \\ \bold{M^{-1}} \end{bmatrix} \bm{f}

このシステム行列を\bold{A}として、

\bold{A} = \begin{bmatrix} \bold{O} & \bold{E} \\ -(g\bold{M^{-1}K_0}+v^2\bold{M^{-1}K_2}) & -v\bold{M^{-1}C_1} \end{bmatrix}

について固有値・固有ベクトルを求めれば二輪車の運動特性がわかるのですが、これを数式的に表すことは非現実的であり、通常は数値を代入して数値計算で求めることになります。

ベンチマーク自転車の固有値

ここでは、Meijaardらの論文[1]に記載されているベンチマーク自転車の諸元を使用し、Scilabによって車速v=0-10\,\mathrm{m/s}についての固有値を計算しました。また車速ごとに得られた固有値をプロットすると、次のように論文と同様の結果が得られています。固有値計算とグラフを描くScilabスクリプトを末尾に示します。

固有値の実部を実線、虚部を破線で表し、複素数のペアを同じ色で表しています。車速v_d以下の領域では複素数の固有値はありませんが、解の連続性から同じ色で表しました。

グレーに塗った車速v_w < v < v_cの領域では全ての固有値の実部が負となっており、システム全体が安定であることがわかります。つまりこの速度領域では、手放し運転などライダーが何もしなくても二輪車は直立して直進走行を保つことができる自己安定な領域となっており、二輪車が倒れずに走ることができることを表しています。

一方、v < v_wの領域では赤線で描いたweaveの固有値実部が正となり、またv_c < vの領域では緑線のcapsize固有値が正となって、不安定になってしまいます。これらのモードはどのような挙動を示すのか、固有ベクトルで確認していきたいと思います。

ベンチマーク自転車の固有モード

まず、車速v=5\,\mathrm{m/s}での固有値・固有ベクトルの計算結果を例にとって、二自由度系の固有ベクトルを見ていきましょう。末尾のScilabスクリプトを実行後、Scilabコンソール上で

sl=BicycleSys(5,9.81,M,K0,K2,C1);
[V D]=spec(sl.A);

を実行すると車速v=5\,\mathrm{m/s}での固有値・固有ベクトルが得られます。

車速v=5\,\mathrm{m/s}での固有値は、\lambda = [-14.078,\: -0.32287,\: -0.77534 \pm 4.4649i]で、それぞれに対応する固有ベクトルは以下のように計算されました。

\begin{bmatrix} \phi \\ \delta \\ \dot{\phi} \\ \dot{\delta} \end{bmatrix} = \begin{bmatrix} -0.00016187 \\ -0.070852 \\ 0.0022788 \\ 0.99748 \end{bmatrix},\; \begin{bmatrix} -0.87481 \\ -0.37457 \\ 0.28245 \\ 0.12094 \end{bmatrix},\; \begin{bmatrix} 0.00034845 \mp 0.13152i \\ -0.029204 \mp 0.16818i \\ 0.58694 \pm 0.10353i \\ 0.77353 \end{bmatrix}

Scilabで計算された固有ベクトルは、ベクトルの大きさが1になるように正規化されていますが、固有ベクトルは方向だけを表していて大きさは不定なので、見やすくするためにここでは\delta=1として\phiとの比を表すことにします。また、固有ベクトルの速度の成分\dot{\phi},\:\dot{\delta}は、指数関数の微分の性質により\phi,\:\delta\lambda倍となり、以下のように変位成分と固有値の積で表せます。つまり固有ベクトルの変位成分を見ればそのモードの振幅比がわかります。

\begin{bmatrix} \phi \\ \delta \\ \dot{\phi} \\ \dot{\delta} \end{bmatrix} = \begin{bmatrix} 0.0022846 \\ 1 \\ 0.0022846*(-14.078) \\ 1*(-14.078) \end{bmatrix},\; \begin{bmatrix} 2.3355 \\ 1 \\ 2.3355*(-0.32287) \\ 1*(-0.32287) \end{bmatrix},\; \begin{bmatrix} 0.75879 \pm 0.13384i \\ 1 \\ (0.75879 \pm 0.13384i)*(-0.77534 \pm 4.4649i) \\ 1*(-0.77534 \pm 4.4649i) \end{bmatrix}

キャスタリングモード

一つ目のモードの固有値は\lambda=-14.078で非常に安定であり、固有値のグラフ上では青の実線で表されいます。このモードは常に安定で速度が増すほど安定になっています。また、固有ベクトルはほぼ\deltaのみの成分からなり、操舵系がほぼ単独で動くモードであることがわかります。これはステアリングが直進状態に維持されるモードであることを表しており、ショッピングカートなどの車輪(caster)が自動的に進行方向を向くことになぞらえて、キャスタリングモードと呼ばれます。

速度ごとに固有ベクトルの振幅比を算出すると以下のようなグラフとなり、ほぼ速度によらず常に舵角\deltaが卓越していることがわかります。

キャプサイズモード

二つ目のモードの固有値は\lambda=-0.32287であり、固有値のグラフ上では緑の実線に対応します。このモードは低速域では安定ですが、速度が大きくなってv_cを超えるとわずかに正となり、不安定になることがわかります。

固有ベクトルはロール角\phiが優位であり、速度ごとの振幅比をCasteringとは逆に\phiを分母にとって算出すると以下のようなグラフとなります。速度が上昇して不安定になる領域でロール角\phiが卓越し、ロール角\phiが支配的になっていくことがわかります。このモードによる挙動は、低速では車体が直立状態に維持される一方、高速ではわずかに不安定になってゆっくり倒れていくことを表しています。この不安定なときの挙動は船が転覆する(capsize)ときと似ていることから、キャプサイズモードと呼ばれています。

ウィーブモード

三つ目のモードの固有値は\lambda=-0.77534 \pm 4.4649iであり、共役複素数となっていて振動するモードであることがわかります。固有値のグラフ上では実部が赤の実線、虚部が赤の破線で表されています。このモードはキャプサイズとは逆に高速では安定ですが、v < v_wの低速域では不安定になることがわかります。

複素固有値の場合、固有ベクトルも複素数となり、複素平面上での極形式表現により絶対値と偏角の情報が得られます。ここから\phi\deltaの振幅比に加えて位相差の情報も得られます。そこで舵角\deltaを基準としたロール角\phiの振幅比と位相差を速度ごとにプロットする以下のようなグラフとなります。

振幅比はおおむね0.6から0.8でロール角のほうがやや小さいですが、舵角もロール角も左右に振動するモードであり、タイヤの拘束によって舵角に比例してヨーレートが生じるため、車体全体が左右に傾きながら蛇行する挙動を示すモードです。このようにうねうねと蛇行する挙動(weave)からウィーブモードと呼ばれています。

位相をみると、ウィーブモードが安定なv_w < vの領域では舵角とロール角がおおむね同位相であるのに対し、v < v_wになるとロール角の位相が進む(舵角の位相が遅れる)ことによって、ロール角を立て直すための操舵(旋回)が遅れるようになって不安定になることがわかります。


車速がv < v_dになると、固有値が2つの実数根に分かれて操舵とロールの連成が無くなります。舵角が切れない場合は車体全体が倒立振子とみなせることを紹介しましたが、舵角が切れる場合には操舵系も重心が操舵軸より上にあることで倒立振子とみなすことができ、極低速では二重倒立振子と同等の挙動を示すことがわかります。

まとめ

二輪車の挙動には、キャスタリング、キャプサイズ、ウィーブの3つの特徴的なモードがあり、ある程度速度が出ると自己安定性を示して倒れずに走るできることが固有値解析の結果からいえることがわかりました。また、高速ではキャプサイズモードが、低速ではウィーブモードが不安定になることが理論的に示されました。

ウィーブモードの安定・不安定の境界となる速度v_wはウィーブ速度、キャプサイズモードの安定・不安定の境界となる速度v_cはキャプサイズ速度と呼ばれていますが、これらの速度は設計諸元から直接算出することが可能であり、安定性の検討要素の一つになっていることから、次の記事ではこれらの速度について解説したいと思います。

benchmark_bicycle.sce
//================================================
// Eigenvalue Analysis for the benchmark bicycle
//================================================
clear;
// Define Bicycle Specifications
function bicycle=DefBicycleSpec()
    bicycle.w = 1.02; // Wheel base
    bicycle.c = 0.08; // Trail
    bicycle.lambda = %pi/10; // Steer axis tilt
    bicycle.g = 9.81; // Gravity
    //// Rear WHeel R
    bicycle.rR = 0.3; // Radius
    bicycle.mR = 2; // Mass
    bicycle.IRxx = 0.0603; // Mass moment of inertia xx
    bicycle.IRyy = 0.12; // Mass moment of inertia yy
    //// Rear Body and frame assembly B
    bicycle.xB = 0.3; // Position centre of mass x
    bicycle.zB = -0.9; //Position centre of mass z
    bicycle.mB = 85; // Mass
    bicycle.IBxx = 9.2; // Mass moment of inertia xx
    bicycle.IByy = 11; // Mass moemnt of inertia yy
    bicycle.IBzz = 2.8; // Mass moement of inertia zz
    bicycle.IBxz = 2.4; // Mass product of inertia xz
    //// Front Handlebar and fork assembly H
    bicycle.xH = 0.9; // Position centre of mass x
    bicycle.zH = -0.7; // Position centre of mass z
    bicycle.mH = 4; // Mass
    bicycle.IHxx = 0.05892; // Mass moment of inertia xx
    bicycle.IHyy = 0.06; // Mass moment of inertia yy
    bicycle.IHzz = 0.00708; // Mass moment of inertia zz
    bicycle.IHxz = -0.00756; // Mass product of inertia xz
    //// Front wheel F
    bicycle.rF = 0.35; //Radius
    bicycle.mF = 3; // Mass
    bicycle.IFxx = 0.1405; // Mass moment of inertia xx
    bicycle.IFyy = 0.28; // Mass moemnt of inertia yy
endfunction
//
// Create Bicycle Matrices
function[M, K0, K2, C1]=BicycleMatrices(b)
    // Total system T properties
    mT = b.mR + b.mB + b.mH + b.mF; // Mass
    xT = (b.xB*b.mB + b.xH*b.mH + b.w*b.mF)/mT; // Position centre of mass x
    zT = (-b.rR*b.mR + b.zB*b.mB + b.zH*b.mH - b.rF*b.mF)/mT; // Position centre of mass z
    ITxx = b.IRxx + b.IBxx + b.IHxx + b.IFxx + b.mR*b.rR^2 + b.mB*b.zB^2 + b.mH*b.zH^2 + b.mF*b.rF^2;
    ITxz = b.IBxz + b.IHxz - b.mB*b.xB*b.zB - b.mH*b.xH*b.zH + b.mF*b.w*b.rF;
    ITzz = b.IRxx + b.IBzz + b.IHzz + b.IFxx + b.mB*b.xB^2 + b.mH*b.xH^2 + b.mF*b.w^2;
    // front assembly A properties
    mA = b.mH + b.mF; // Mass
    xA = (b.xH*b.mH + b.w*b.mF)/mA; // Position centre of mass x
    zA = (b.zH*b.mH - b.rF*b.mF)/mA; // Position centre of mass z
    IAxx = b.IHxx + b.IFxx + b.mH*(b.zH - zA)^2 + b.mF*(b.rF + zA)^2;
    IAxz = b.IHxz - b.mH*(b.xH - xA)*(b.zH - zA) + b.mF*(b.w - xA)*(b.rF + zA);
    IAzz = b.IHzz + b.IFxx + b.mH*(b.xH - xA)^2 + b.mF*(b.w - xA)^2;
    uA = (xA - b.w - b.c)*cos(b.lambda) - zA*sin(b.lambda);
    IAll = mA*uA^2 + IAxx*sin(b.lambda)^2 + 2*IAxz*sin(b.lambda)*cos(b.lambda) + IAzz*cos(b.lambda)^2;
     IAlx = -mA*uA*zA + IAxx*sin(b.lambda) + IAxz*cos(b.lambda);
     IAlz = mA*uA*xA + IAxz*sin(b.lambda) + IAzz*cos(b.lambda);
     // Other parameters
     mu = (b.c/b.w)*cos(b.lambda);
     SR = b.IRyy/b.rR;
     SF = b.IFyy/b.rF;
     ST = SR + SF;
     SA = mA*uA + mu*mT*xT;
     // Coefficient Matrices
     M = [ITxx IAlx+mu*ITxz; IAlx+mu*ITxz IAll+2*mu*IAlz+mu^2*ITzz];
     K0 = [mT*zT -SA; -SA -SA*sin(b.lambda)];
     K2 = [0 (ST-mT*zT)*cos(b.lambda)/b.w; 0 (SA+SF*sin(b.lambda))*cos(b.lambda)/b.w];
     C1 = [0 mu*ST+SF*cos(b.lambda)+ITxz*cos(b.lambda)/b.w-mu*mT*zT; -(mu*ST+SF*cos(b.lambda)) IAlz*cos(b.lambda)/b.w+mu*(SA+ITzz*cos(b.lambda)/b.w)];
endfunction
//
// Create Bicycle System
function sl=BicycleSys(v,g,M,K0,K2,C1)
    MI = inv(M);
    gMIK0 = g*MI*K0;
    MIK2 = MI*K2;
    MIC1 = MI*C1;
    A = [zeros(2,2) eye(2,2); -(gMIK0 + v^2*MIK2) -v*MIC1];
    B = [zeros(2,2); MI];
    C = [eye(2,2) zeros(2,2)];
    D = zeros(2,2);
    sl = syslin('c', A,B,C,D);
endfunction
//
// Main routine
// Eigenvalue Calculation
bicycle = DefBicycleSpec();
[M K0 K2 C1]=BicycleMatrices(bicycle);
v=[0:0.1:0.68428307889246,0.7:0.1:10];
i=0;
for vi=v
    i=i+1;
    sl=BicycleSys(vi,bicycle.g,M,K0,K2,C1);
    [V D]=spec(sl.A);
    D=diag(D).';
    sort_key=[abs(imag(D)); real(D)];
    [dmy idx]=gsort(sort_key,"lc","i");
    E(i,:)=D(idx);
end
//
// Draw Eigenvalue Plots
f=scf();
f.axes_size=[600 600];
// add origin axis
xpoly([v(1),v($)],[0,0],'lines');
e = gce();
e.thickness = 2;
e.line_style = 1;
e.foreground = color("black");
// plot eigenvalues
plot(v,[E(:,1),E(:,2),real(E(:,3)),imag(E(:,3))]);
xlabel("v [m/s]"),xgrid(),ylabel("Eigenvalue");
// adjust the imaginary line style and the color to the real one
h1 = gce().children;
h1(1).foreground=h1(2).foreground;
h1(1).line_style=3;
// add the plot for the conjugate complex data
plot(v,[real(E(:,4)),imag(E(:,4))]);
h2 = gce().children;
h2(1).line_style=3;
h2.foreground=h1(2).foreground;
// ajust the y scale
replot([0 -10 10 10]);
// add legend
l=legend(h1(4:-1:1),['castering','capsize','weave(Re)','weave(Im)']);
脚注
  1. J. P. Meijaard, et al., "Linearized dynamics equations for the balance and steer of a bicycle: a benchmark and review", Proc. R. Soc. A 463:1955-1982, 2007 ↩︎

Discussion