Steamで配信している早期アクセスゲーム「From The Depths」の情報サイトです。日本語非対応のゲームなのでみんなで情報を載せあってプレイが捗るようにしましょう!

このページで解説すること


水中に潜って設定した深度を維持しつつ、姿勢を自動で安定化してくれる乗り物の作り方を説明します。
前進/後退と左右旋回、浮上/潜水の動きをする潜水艦を作ってみます。

前編ではACB(オートコントロールブロック)を使った水中翼の制御、
後編では最近追加されたPIDブロックのチュートリアルも兼ねて、PID制御を使って姿勢制御を行います。

応用編ではLuaを使った地形追随潜行など、より複雑な解説をしていく予定です。

共通部分

箱を作る




メタル等の重い素材でエンジン入りの箱を適当に作り、エアポンプを取り付けます。斜めブロックをうまく使い前面を流線型にすると速度が上がるようです。
いつものように椅子やビークルコントローラなども設置します。
SSは説明のために天井が開いていますが、浮かび上がれなくなってしまうので隙間なく密閉しておきましょう。

スラスターや舵を付ける




推進したり曲がったりするためにスクリューや舵を付けます。
曲がるために側面スラスターを設置するときは重心より前方ならばThruster、後方ならばThruster reverseに設定します。


前編(ACBを使った水中翼の制御)

ハイドロフォイルを付ける




艦首付近の左右にハイドロフォイルを付けます。

ACBを付けて設定する




Control→Automated Control Block(ACB)を2つ付けます。



1つ目のACBには左端の「Activate when altitude greater than [input]」をチェックします。
ここにチェックを入れると設定高度より高い場合にACBが起動します。
真ん中の効果対象に「Hydrofoils」をチェックします。
右端の実行処理は「Set hydrofoil angle to [affect var]」をチェックして、
下のControl panelから「Input」に潜行したい深度、「Affect」に負の値で水中翼の角度を入れます。-10度くらいが適当でしょう。

ここまで設定すると、潜行したい深度より高い場合に水中翼が-10度にセットされ、スクリューで前進することで艦首が下を向いて潜ることができます。
このままだと海底にぶつかるまで潜り続けるので、設定深度に達したら水中翼を10度にするように設定して深度を維持します。

2つ目のACBは左端の「Activate when altitude less than [input]」
真ん中の効果対象に「Hydrofoils」
右端の実行処理は「Set hydrofoil angle to [affect var]」をチェックして、
下のControl panelから「Input」に潜行したい深度、「Affect」に正の値で水中翼の角度を入れます。10度くらいが適当でしょう。

姿勢を安定化する




潜水艦は割りと簡単にひっくり返ってしまうので、Air→Jet Stabilizerを付けて水平を保つようにします。
Jet Stabilizerはエンジン不要、水中でも動く謎機関で水平を保つように推力を発生します。



Jet Stabilizerは向きにより動作が変わります。SSのように機体側面に側面を向けて付けるとロール方向を安定化し、
機体の前後に前後を向けて付けるとピッチ方向を安定化します。
これ以外の向きで付けるとうまく動作しないので注意しましょう。

完成!




ポンプの設定を開いて浮力を下げるか、ポンプをオフにして水中に沈み、スクリューで進みます。
前に進んでいる限りは水中翼により設定深度を保ってくれるはずです。ビクビクするときはACBの設定で水中翼の角度を小さくします。
AI制御にするときはNaval AIを付ければヨー軸で旋回して攻撃してくれます。



後編(PIDブロックを使った制御の実例)


後編では潜水艦が静止している時でも深度を保ちつつ、高度な姿勢安定化ができるようにするためのPIDブロックの使い方について解説します。

深度を設定して維持する




エアポンプでどれくらい空気を抜くかを自動制御して深度を維持するために、Control→PID(General Purpose)ブロックを使います。
このブロックを使うとPID制御と呼ばれる(詳細は割愛)方法で適切なポンプの設定を計算し船に付けた全てのポンプを自動で調節してくれます。



設置場所はどこでも良いですが、設定深度をいじりやすいように椅子の近くに設置しておきましょう。



設定画面は一番下にモードの設定があります。AirPump Altモードを設定するとエアポンプの制御モードになります。

左上でPID制御のパラメータを調整できます。
エアポンプの場合は適当で問題ないので、kP.Gainを0.2くらい、Ti.Integral Timeを右端のNo limit、Td.Derivative Timeをほぼ0にすればよいです。

パラメータの下は設定深度を入力するところです。Test Stim #1と#2があるのでどちらかに潜りたい深度を入力して下のチェックボックスで#1か2かを選びます。
ここまで入力すれば設定した深度に潜って維持してくれるはずです。

ピッチとロールを安定化する




無事に潜ることはできましたが、バランスによく気をつけて作っていないかぎり潜水艦はひっくり返ってしまうはずです。
水上に浮いている船の場合なら、傾いた場合に水没する体積が増えるので勝手に傾きが戻りますが潜水艦は全体が水没しているのでこの効果がなく、傾きが止まりにくいです。

前編ではJet stabilizerを使って安定化しましたが、この部品は取り付けるだけでいいので簡単な代わりに性能が悪いです。

そこでピッチとロールを担当するスラスターを取り付けてアクティブに姿勢を制御します。
スラスターの配置や推力によってはアドバンスキャノンを横向けて連射してもほとんど動揺しないような姿勢安定化が可能です。
ピッチスラスター



SSのように潜水艦の前か後ろの端(両方でもいいです)の上下にスクリューを取り付けます。
Qキーで設定画面を開き、重心よりまえのスクリューをThrusterに、後ろのスクリューをThruster reverseにします。
ロールスラスター






ロールを担当するスラスターでピッチまで変わらないように、重心の近くの左右端の上下にスクリューを取り付けます。
Qキーで設定画面を開き、潜水艦の左側のスラスターは上下ともにroll(LHS)、右側はroll reverse(RHS)に設定します。

PIDの設定


どこでもいいのでPID(General Purpose)ブロックをロール用とピッチ用の2つ取り付けます。


設定画面の一番下から、ロール用はRoll、ピッチ用はPitchを選択します。

ポンプの時と違い、左上のパラメータが不適切だとSSのように激しく振動してしまい酔います。
細かい理屈はPID制御でググった方がわかりやすいので検索してください。ここでは簡単にグラフやパラメータの見かたと調節の方針について解説します。
グラフの見かた

右のグラフは赤が指令値、緑が現在値、青がスラスターや水中翼等の出力を示しています。ピッチやロールの場合は現在値が時間経過とともに指令値の0度に収束していけばいいことになります。
白線は赤と緑の差(誤差)を時間ごとに足していったものです。(積分)
また、グラフに線は出ませんが誤差の時間変化率(微分)も計算されています。

青線で表される出力は
  kP * (誤差 + 積分/Ti + Td * 微分)
で計算されます。
スラスターも無限に推力が出るわけではないので、青線がグラフの上下を振り切ってしまうと頭打ちになり「Output saturated!」とグラフの上に表示されます。
パラメータの調整

パラメータの調整は海に浮かべたり、横向きにアドバンスキャノンを乱射するなど外乱が加わる状態で行います。

kPを大きくするとスラスターの推力が単純に大きくなるので、傾きに対して早く反応して戻してくれます。
その一方で大きくし過ぎると傾きが0度に戻った後に行き過ぎてしまい、いつまでたっても収束しなかったり、段々振幅が大きくなったりします。
まずはTiをno limit、Tdを0にして振動が収まるようなkPの上限を探し、うっかり振動しないように上限から数10%下げた値に設定します。

グラフをしばらく観察していると、特にピッチ軸は0度から微妙にずれたところで安定することが多いです。
Tiをno limitから下げていき、微妙なズレを時間経過とともに足して補正すれば、0度に合わせることができます。
下げ過ぎるとkPを上げすぎた時と同様、傾き0度を行き過ぎてしまい収束しなくなります。

Tdは発砲の反動など、鋭い外乱に対して素早く反応するために使います。変化に過敏になるので、Tdを大きくし過ぎると簡単に振動が発散していってしまいます。
様子を見ながら少しずつ上げて、小さい値を使いましょう。

完成!


これで姿勢制御しつつ設定深度に潜って水中を進める潜水艦が完成しました。
AI制御させる場合はNaval AIを使えば設定した深度を維持したまま普通の船と同じようにヨー軸で旋回して攻撃してくれます。
AIブロックにAIタブの方のPIDを接続してnaval yawモードを使うと、左右にフラフラしながら進む挙動も修正できます。


応用編


応用編ではLuaボックスを使いもっと便利に自動制御する方法を紹介していきます。
プログラミングがわからなくてもLuaボックスにコピペしてPID等の設定数値を適宜調整するだけで使えます。

地形追随潜行


このコードではマウスホイールを回して船の武装スロット(※)のどれかを選択した状態にすることで自動潜行が起動します。
エアポンプを自動制御して海底から一定間隔を空けて潜行し深度を維持します。
Lua側でPI制御を行っているので、これまでエアポンプを制御するのに使ってきたPIDブロックは撤去しておいてください。

※うまく動かないときは武装スロット2〜5を使ってみてください

maxaltoverterrain = 30 --海底から何m上に潜行するか指定
Kp = 0.2 --比例ゲイン
Ki = 0.001 --積分ゲイン

Ialt = 0
function SetairPump(I,pumpvar)
  for i=0, I:Component_GetCount(2)-1 do
    I:Component_SetFloatLogic(2,i,pumpvar)
  end
end
function IsControlling(I)
  for i=0,I:GetWeaponCount()-1 do
    if I:GetWeaponInfo(i).PlayerCurrentlyControllingIt == true then
      return true
    end
  end
  return false
end
function Update(I)
  altitude = I:GetConstructPosition().y
  terrainalt=I:GetTerrainAltitudeForPosition(I:GetConstructPosition())
  if IsControlling(I)== true then
    alterror = terrainalt + maxaltoverterrain - altitude
    if alterror > -10 and alterror < 10 then Ialt = Ialt + alterror end
    pumpvar = Kp * alterror + Ki * Ialt
    SetairPump(I,pumpvar)
  else  -- auftauchen
    SetairPump(I,1)
  end
end

追記予定
姿勢制御スラスターを使った急速潜航/浮上

このページへのコメント

推進も姿勢制御も全部イオンスラスターに任せてエアリアルAIの高度をマイナスに設定した航空機仕様の潜水艦も面白いぞ!

Posted by a 2016年01月12日(火) 15:48:12

訂正、スラスターで深度調整するだけでした。
重い船には、ポンプは必要ですよね。

Posted by 名前のない怪物 2015年12月30日(水) 13:23:30

詳しい解説、ありがとう。
PIDでの深度設定なんだけど、Altitude選べばポンプやらスクリューやら使って潜ってくれるっポイ。

Posted by 名前のない怪物 2015年12月30日(水) 01:50:34

コメントを参考に編集しました。潜水艦のチュートリアルと言いつつほとんどがPIDブロックを使った姿勢制御ネタなのでタイトルを変えたほうがいいかもしれませんね。
バグかもしれませんがPIDブロックが付いていると水中翼モードにしなくても勝手に水中翼が動いてしまうようなので水中翼関係はスルーしています。

Posted by 筆者 2015年12月22日(火) 01:14:42

追記、復元力に関しても、重心が低ければ重量だけである程度は復帰できる。スラスターとラダーが重心を貫いていればほとんどバランスは崩れなくなるので、適切に構成できていれば自重だけで多少アドキャ撃っても問題ないぐらいバランスが取れるようになる。

Posted by 名前有り 2015年12月22日(火) 00:42:18

コメントをかく


ユーザーIDでかく場合はこちら

画像に記載されている文字を下のフォームに入力してください。

「http://」を含む投稿は禁止されています。

利用規約をご確認のうえご記入下さい

どなたでも編集できます