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


目次へ戻る

■SCRIPT考察4 「気球を高度維持させたい」


◆考え方


静止している気球を一定高度に維持するには、気球に作用する重力と釣り合うだけの浮力を発生させれば良いことになります。
しかし、上昇/下降運動している気球を静止させるには、慣性の作用を打ち消すだけの力を発生させる必要があるため、上昇中は重力よりも小さい浮力、下降中は重力よりも大きい浮力を発生させて、気球にブレーキをかける必要があります。
気球が滑らかにブレーキをかけて、最終的に重力と釣り合った状態で空中静止させるための浮力調整は、上昇/下降速度を元に調整することになりますが、この調整を的確に行うために「PID制御」を活用します。
ここで制御したい物理量は「上昇/下降速度」ということになり、これを0になるように制御します。
なお、モデルにはデフォルトで付属している「Balloon.txt」を用います。


◆実装


//Balloon
Val{
	Hydrogen(default=8000,min=0,max=40000,step=0)
}
Key{
	0:Hydrogen(step=100)
	1:Hydrogen(step=-100)
}
Body{
	Core(){
		S:Chip(){
		}
		S:Frame(angle=-90,Spring=0.2,Damper=0.1){
			S:RudderF(Spring=0,Damper=0){
				S:TrimF(Spring=0,Damper=0){
					S:Frame(Spring=0,Damper=0){
						S:Jet(Option=1,Power=Hydrogen,Name=BAL){
						}
					}
				}
			}
		}
	}
}
Lua{ I=HYDROGEN -- 積分(I)項初期値 Y=_Y(BAL) -- 積分(I)項計算用 VY=0 -- 微分(D)項計算用 function main() local p,d if(_KEY(0)==0)and(_KEY(1)==0) then -- 各項係数 local kp=500 local ki=100 local kd=500 local vy=(_Y(BAL)-Y)*30 -- 上昇/下降速度[m/s] local ay=vy-VY -- 上昇/下降加速度[m/s/s] -- 比例項 p=-vy*kp -- 積分項 I=I-vy*ki I=math.min(16000,math.max(0,I)) -- リミッタ -- 微分項 d=-ay*kd -- 現在値保存 Y=_Y(BAL) VY=vy -- PID制御(リミッタ付き) local dh=p+I+d-HYDROGEN dh=math.min(1000,math.max(-1000,dh)) HYDROGEN=HYDROGEN+dh end out(0,"PID-Balloon") out(1,"Y=",Y," m") out(2,"VY=",VY," m/s") out(3,"Hydrogen=",HYDROGEN) out(4,"P=",p) out(5,"I=",I) out(6,"D=",d) out(7,"Weight=",_WEIGHT()," kg") out(8,"Hydrogen/Weight=",HYDROGEN/_WEIGHT()) out(9,"Hydrogen/Weight/6/g=",HYDROGEN/_WEIGHT()/6/9.80665," m/s/s") end }
PID制御の対象となる物理量は、気球の上昇/下降速度ですので、バルーン部分(JETチップ)に名前を付け、このチップのY座標を取得します。
このY座標を元に上昇/下降速度、及び上昇/下降加速度を計算で求めます。
		local vy=(_Y(BAL)-Y)*30	-- 上昇/下降速度[m/s]
		local ay=vy-VY	-- 上昇/下降加速度[m/s/s]
ここで上昇/下降速度を求めるのに_VY()を用いないのは、_VY()はチップのローカルY軸速度ベクトルであるため、チップが回転してしまうと上昇/下降速度を表さなくなってしまうためです。
チップが反転してしまうと、上昇と下降が逆になってしまいます。

PID制御では対象となる物理量を目標値に近づけるための、3つの制御値「比例項・積分項・微分項」を求めます。
比例項(P)は文字通り制御対象となる物理量に比例する成分ですので、上昇/下降速度vyに係数をかけて得ることができます。
		-- 比例項
		p=-vy*kp
積分項(I)は制御対象となる物理量を積分(足し算)することで得られる成分です。
なお、積分項は目標値からのズレが時間ごとに蓄積されて行くので、制御に破綻を生じないようリミッタを設けておくことをお勧めします。
		-- 積分項
		I=I-vy*ki
		I=math.min(16000,math.max(0,I))	-- リミッタ
微分項(D)は制御対象とする物理量を微分(単位時間あたりの変化量)することで得られる成分です。
		-- 微分項
		d=-ay*kd
3つの制御量P、I、Dを求めたら、これを加算したもの(P+I+D)を出力値とします。
但し、これだけだと、見た目にバルーンの大きさが激しく変化してしまうようになると思います。
そこで、時間あたりのバルーンの出力値変動を一定値以下に抑えるために、出力値の変動量dhを求め、これに上限/下限リミッタを施した上で、Hydrogenに加算するようにします。
		-- PID制御(リミッタ付き)
		local dh=p+I+d-HYDROGEN
		dh=math.min(1000,math.max(-1000,dh))
		HYDROGEN=HYDROGEN+dh
なお、PID制御全体の挙動は、各項の係数を変えることで変化します。
通常、係数を大きめにすると、状況変化に対して素早い対応をするようになりますが、反動が大きくなります。
係数を小さくすると、反動は小さくなりますが、ゆったりとした挙動を示すようになります。
		-- 各項係数
		local kp=500
		local ki=100
		local kd=500

目次へ戻る