Rigid Chips リファレンスマニュアル モデルデータ SCRIPT考察1



目次へ戻る

■SCRIPT考察1 「トラクション制御(WHEELのスリップ防止)を実現したい」


◆考え方


WHEELをタイヤとして使用しているときに、地面との間でスリップが発生すると、急激にWHEELの回転数が上がります。
WHEELの回転数は、モデル全体の速度に比例して大きくなりますが、WHEELの直径は一定なので、WHEELがスリップしていなければ、WHEELが1回転する間にモデルが進む距離は一定のはずです。
これは言い換えれば、WHEELの回転数とモデルの速度の比率は、スリップしていなければ一定になっているということです。
そこで、WHEELの回転数が上昇した、またはモデルの速度が低下したことで、「WHEELの回転数÷モデルの速度」が上昇した場合には、WHEELでスリップが発生しているものと捉え、WHEELのPOWER属性を下げて、回転数を下げてやるように制御します。


◆実装


対象となるWHEELのPOWER属性指定に用いている変数を「TRQ」、NAME属性を「TIRE」と仮定します。
WHEELの回転数は、関数「_WY」を用いることで調べることが出来ます。
これは、WHEELが自身のローカルY回転軸(上下軸)を中心として回転するためです。
また、モデルの前進方向の速度は、関数「_VZ」を用いることで調べることが出来ます。
_VZ()はチップの南北方向のローカル速度ベクトルを返すため、WHEELに角度が付いた状態になっていると、_VZ()ではWHEELの並進速度が求められない場合があります。
そこで、WHEELの並進速度=コアの並進速度という前提で、_VZ(0)を参照することとします。
SCRIPTブロック内に以下のように記述します。
ratio=_WY(TIRE)/_VZ(0)
if ratio>3.4 {
	TRQ=TRQ*0.95	// 順方向にスリップしたらTRQを5%減
}
if ratio<0 {
	TRQ=0	// 逆方向にスリップしたらTRQ=0
}
if(ratio<=3.4)&(ratio>=0){
	TRQ=(TRQ+1000)*1.05	// スリップしていなければTRQ回復
}
「3.4」という数値(このような条件分岐に用いる数値を「しきい値」と呼ぶ)は、実際にモデルを稼動させてみて、WHEELがスリップしていない状態での「ratio」の計測値を元に決めています。
ratioは、大体3.3〜3.4の間の数値になります。
これは理論値とも整合しています。
(なお、WHEELのつなぎ方によっては、_WYと_VZの符号の関係が逆になるので、その場合は「-_WY(TIRE)」などとしてください。)

【理論値】
WHEELの半径:r[m]、角速度:w[rad/sec]、並進速度:v[m/sec]としたとき、時間t[sec]でWHEELが移動する距離L[m]は、 vを使って計算するとL=vtとなり、wを使って計算するとL=wt×2πr/(2π)=rwtとなります。
スリップが発生していなければ両者のLは同じ値となるので、vt=rwtとなり、ratio=w/v=1/r=3.33・・・となります。

if文によって、ratioが3.4を上回るようなスリップが発生した場合は、TRQを5%減らしています。
また、ratioがマイナスの場合は、モデルの進行方向に対してWHEELが逆回転しているため、TRQを0にしています。
ratioが0以上3.4以下になっているときは、スリップが治まったものと考えて、TRQに1000を足してから5%回復させています。
(1000を足しているのは、TRQ=0となったときに、0に何を掛けても0のままであるため、TRQ=0で固まってしまうのを防ぐためです。)
減衰率・回復率については、モデルの特性に合わせて、適切な値を選択してください。
プログラムの大枠は以上で完成ですが、このプログラムには幾つか問題点があるため、それらを解決します。

●問題点1 _VZ(0)が丁度0のとき、演算エラー(0除算)が発生する。

除算"/"を用いる場合は、0除算には、常に注意を払う必要があります。
これを回避するには、いかなるときも分母が0にならないように、全体の計算値には殆ど影響が出ない程度に、細工をします。
ratio=_WY(TIRE)/(_ABS(_VZ(0))+0.01)*_SGN(_VZ(0))
この細工の発想としては、_VZ(0)に小さな数値を足してやって分母が0になるのを防ごうというものです。
しかし、_VZ(0)はプラスの値だけでなくマイナスの値も取るので、単に「_VZ(0)+0.01」としただけだと、_VZ(0)=-0.01のときに、やはり分母が0になってしまいます。
そこで_VZ(0)の絶対値を取って、それに0.01を足すということをしています。
こうすると、_VZ(0)がマイナスの値であったとき、ratioの符号が逆になってしまうため、符号を補正するために最後に「_SGN(_VZ(0))」を掛けています。
なお、細工の仕方はこれだけではありません。例えば以下のような方法もあります。
ratio=_WY(TIRE)*_WY(TIRE)/(_VZ(0)*_VZ(0)+0.01)*_SGN(_WY(TIRE)*_VZ(0))

●問題点2 モデルが低速のときに、ratioの値が異常に大きな値になり、TRQがスムーズに上がらない。

これは、RigidChipsに限らずコンピュータシミュレーションでは常に付きまとう問題の「離散化誤差」が増幅されていることが原因です。
詳しい説明は割愛しますが、要は「低速時は、振動の影響が強くなる所為で、ratioの計算値が安定しない」ものと割り切って、低速時とそれ以外とで制御の仕方を変えることで解決します。
vz=_VZ(0)
if(vz<0)&(vz>-10){
	vz=-10	// -10<vz<0の場合vz=-10
}
if(vz>=0)&(vz<10){
	vz=10	// 0<vz<10の場合vz=10
}
ratio=_WY(TIRE)/vz
if ratio>3.4 {
	TRQ=TRQ*0.95	// 順方向にスリップしたらTRQを5%減
}
if ratio<0 {
	TRQ=0	// 逆方向にスリップしたらTRQ=0
}
if(ratio<=3.4)&(ratio>=0){
	TRQ=(TRQ+1000)*1.05	// スリップしていなければTRQ回復
}
ratioの計算に用いる分母の絶対値が10以下にならないように、_VZ(0)の値を補正します。
こうすることで、_VZ(0)の絶対値が10以下の場合は、絶対値を10と見なして計算するため、ratioの値は実際より小さめに求められ、その結果、速度が小さいときはトラクション制御がかからないようになります。
また、ratioの計算の分母は絶対値が10以上になることが保証されているので、問題点1の0除算の発生についても、同時に解決できています。

目次へ戻る