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


目次へ戻る

■SCRIPT考察3-3 「飛行機の製作:水平飛行アシスト制御」


◆考え方


ここでは、機体を水平状態に維持するためのアシスト機能について紹介します。
機体の状態をコントロールするためには、対象となる機体の状態を数値化する必要があります。
機体の水平状態を維持するためには、まず「機体が水平」ということを数値で表現する必要があります。
機体が水平=機体のZ回転が0、かつ機体のX回転が0
即ち、_AX()と_EZ()が0でない場合、0に近づける方向にエルロンやエレベータを操作してやります。
例えば、機体が左にロールして傾いている場合は、エルロンを右ロールする方向に動かしてやれば良いわけです。
なお、ここでベースに用いる機体は、自動ギアアップ/ダウン制御搭載版としています。


◆実装


//plane
val{
	pitch(default=0,min=-10,max=10,step=1,disp=1)
	roll(default=0,min=-10,max=10,step=1,disp=1)
	yaw(default=0,min=-10,max=10,step=1,disp=1)
	jet(default=0,min=0,max=50000,step=0,disp=1)
	gear_angle(default=80,min=80,max=170,step=0,disp=1)
	gear_brake(default=0,min=0,max=200,step=0,disp=1)
}

key{
	0:pitch(step=-1)
	1:pitch(step= 1)
	2:roll(step= 0.5)
	3:roll(step=-0.5)
	4:yaw(step=-1)
	6:yaw(step= 1)
	5:jet(step= 50000)
	8:jet(step=-50000)
}

body{
	core(){
		n:frame(angle=-20){
			n:jet(angle=110,power=jet,effect=1){}
		}
		w:chip(){
			w:trim(angle=roll){
				w:chip(){}
			}
		}
		e:chip(){
			e:trim(angle=roll){
				e:chip(){}
			}
		}
		s:chip(){
			s:chip(){
				s:chip(){
					w:chip(angle=-90){
						s:chip(angle=-yaw){}
					}
					e:chip(angle=-90){
						s:chip(angle=yaw){}
					}
					s:chip(){
						w:trim(angle=pitch){}
						e:trim(angle=-pitch){}
					}
				}
			}
		}
		w:frame(angle=10){
			w:wheel(angle=gear_angle,brake=gear_brake){}
		}
		e:frame(angle=10){
			e:wheel(angle=gear_angle,brake=gear_brake){}
		}
	}
}

Lua{

function balancer() if(_EZ(0)<0) then -- 左ロールしている場合 ROLL= 5 -- 右ロール elseif(_EZ(0)>0) then -- 右ロールしている場合 ROLL=-5 -- 左ロール end if(_AX(0)<0) then -- ピッチダウンしている場合 PITCH= 5 -- ピッチアップ elseif(_AX(0)>0) then -- ピッチアップしている場合 PITCH=-5 -- ピッチダウン end end
function gear_updown() if(_H(0)>=0) then GEAR_ANGLE=GEAR_ANGLE-5 -- ギアダウン GEAR_BRAKE=0 else GEAR_ANGLE=GEAR_ANGLE+5 -- ギアアップ GEAR_BRAKE=GEAR_BRAKE+10 end end function main()
if(_KEY(7)>0) then -- Aキーを押しているとき水平維持制御 balancer() end
gear_updown() -- 表示 out(0,"Up/Down:Pitch, Left/Right:Roll, Z/C:Yaw, X:Jet-On, D:Jet-Off") out(1,"x=",_X(0),", y=",_Y(0),", z=",_Z(0)) out(2,"ax=",math.deg(_AX(0)),", ay=",math.deg(_AY(0)),", ez=",math.deg(_EZ(0))) out(3,"vx=",_VX(0),", vy=",_VY(0),", vz=",_VZ(0)) out(4,"wx=",_WX(0),", wy=",_WY(0),", wz=",_WZ(0)) end }
上記では、Aキーを押している間、機体を水平状態に戻すようにエルロンとエレベータに制御がかかります。
しかし、実際に動かしてみると、制御が行き過ぎてしまって、上下左右に振動してしまうと思います。
これは、機体の傾きに対して、エルロンやエレベータの制御量(動かす角度)が一定である所に問題があります。
大きく傾いている場合は大きく動かし、少しだけ傾いているときは少しだけ動かすようにすることで改善すると思われるので、そのように改造してみます。
function balancer()
	if(_EZ(0)<0) then		-- 左ロールしている場合
		ROLL=_EZ(0)*10	-- 右ロール
	elseif(_EZ(0)>0) then		-- 右ロールしている場合
		ROLL=_EZ(0)*10	-- 左ロール
	end
	if(_AX(0)<0) then		-- ピッチダウンしている場合
		PITCH=-_AX(0)*20	-- ピッチアップ
	elseif(_AX(0)>0) then		-- ピッチアップしている場合
		PITCH=-_AX(0)*20	-- ピッチダウン
	end
end
関数balancerを上記のように修正すると、機体がスムーズに水平状態に近づいて安定するようになったと思います。
但し、上記の記述方法には無駄があるので、以下のようにすっきりした記述方法に書き換えます。
function balancer()
	ROLL=_EZ(0)*10
	PITCH=-_AX(0)*20
end
「*10」や「*20」といった係数を増減することで、制御の効き(強さ)が変わるので、お好みに応じて調整してください。
この状態でとりあえず水平維持ができるようになったと思いますが、水平状態に戻るときに制御が行き過ぎて、水平状態で安定するまでに機体が振動してしまう場合があると思います。
これは機体の回転による慣性の作用が考慮されていないためです。
慣性の作用を考慮する一方法として、回転速度が速い場合には、その分だけ制御量を差し引く方法があります。
例えば、機体が左ロールしている状態から右ロールさせて水平に戻すとき、徐々に右ロールする回転速度が上がっていくに従ってエルロンの制御量を減らして行きます。
機体の回転速度は、_WX()などの角速度取得関数によって得ることができるので、上記の制御量算出式の中に角速度の項を追加します。
function balancer()
	ROLL=_EZ(0)*10+_WZ(0)
	PITCH=-_AX(0)*20-_WX(0)
end
上記のように改造することで、水平状態に戻る際の「行き過ぎ」が緩和されると思います。

ここまで改造してきて、実際に動作確認をしてみると気が付くと思いますが、水平状態を維持すると、徐々に飛行高度が下がってきてしまうと思います。
これは、(通常の)飛行機モデルが飛行するための揚力を生み出すには、進行方向に対して若干ピッチアップさせた状態にする必要があるためです。
そこで、飛行高度が落ちてきにくくするために、ピッチに関する制御量を補正します。
function balancer()
	ROLL=_EZ(0)*10+_WZ(0)
	PITCH=-_AX(0)*20-_WX(0)+0.8
end
ピッチ制御量算出式に補正項「+0.8」を追加します。
こうすることで、若干ピッチアップした状態で機体が安定するので、高度の変動を緩和できるようになります。
完全な高度維持を行うには、補正値を可変値にする必要があります。
これは、機体に生じる揚力の大きさが、飛行速度等に応じて変化するためです。
補正値を計算によって求めて高度維持を実現する方法については、別ページで紹介します。

目次へ戻る