PIDバランス制御

Last-modified: 2023-06-17 (土) 19:18:08

dsa作量。PIDコントローラによって計算され、制御対象を操作する値。
操作量がプラスのときに、制御量がプラスに変化するように制御対象を接続する。|
制御対象: PIDに操作されて制御量を目標値に近づける装置。速度が目標の時のエンジン~プロペラや、方位が目標の時のラダーなど。

プロパティ設定内容
Proportional Gain比例制御のゲイン。Kp。
Integral Gain積分制御のゲイン。Ki。
Derivative Gain微分制御のゲイン。Kd。

ゲイン: どのくらい各制御を強くするか決める値。コントローラ内部では制御量から算出される値に掛ける倍率なのでGainと呼ばれます。
Derivative Gain: PIDパーツやロジックゲートにはDerivative Gainと記載されていますが、工学では一般的にDifferentialの語を使います。
語義は差分で、工学およびその元になった数学分野での定訳は微分です。

PIDの調整

機体の出力や重量といったスペックは千差万別なので、機体ごとに制御の強さを調整する必要があります。
そのためにはPID制御の3つのゲインすなわちKp、Ki、Kdの3つのパラメータを設定します。*1

wiki_PID_graph.png
  • P動作(比例制御)

    制御量を目標値に近づける効果があります。制御量が目標値から遠いほど、近づける方向へ大きな操作量を出力します。Kp値を大きくすることでより素早く目標値に近づくようになります。しかし、目標値に向かって進むだけなので、P動作だけでは目標値を通り越してしまいます。この現象をオーバーシュートといいます。
    オーバーシュートは制御したい事象によっては致命的になる場合があります。例えば任意の高度でホバリングしているヘリの高度制御に介入して、ボタンを押したら自動的に地表に着陸する機能です。目標値は地上との距離=0mですから、オーバーシュートすると地表に激突することになります。
    目標値を通り越した後はどうなるでしょう。P動作だけだと、操作量は目標値から遠ざかるほどマイナスになります。制御量の増加は遅くなり、ついには減少に転じます。そしてまた目標値を通り過ぎて操作量がプラスに……と上下に発振が起きます。こちらはハンチングといいます。
    収束する前に何回か振れる程度の揺れも除去できるように調整したいものです。

  • I動作(積分制御)

    基本的にはP動作とD動作だけでも数値を安定させることはできますが、例えばヘリの高度を制御する場合、機体の重量の分だけ目標よりも低い数値で安定してしまいます。
    これをオフセット(定常偏差)といいます。I動作はこのように目標に達しない状態が続いた時に出力にテコ入れをする効果があります。
    しかし、目標に達しない状態が続けば続くほど効果が増してしまうため、大きな負担が掛かって数値が上げられない(重い荷物を持ち上げようとする時など)とテコ入れの強さが増し、負担がなくなった瞬間に暴走してしまう恐れがあります。また、制御対象の電源が入っていないのにPIDが起動していると、やはり目標に達しない状態が続くことになり制御対象の電源が入った瞬間に暴走します。PIDの出力が正しく制御対象を操作できているかを考えてPID自体のON/OFFをしましょう。例えば機体の方向を制御するためにラダーを制御対象にしている場合は、速度が出ていないと方向が変わらないので、速度が出ていない時もPIDはOFFにすべきです。

    Kiは0.0001といった小さい数値にするか、多少の誤差が気にならなければ0にしてしまうのも手です。大きすぎる値を設定するとKpほどではないにしても発振傾向に(ハンチングしやすく)なります。

  • D動作(微分制御)

    目標値に近づくにつれてP動作の効果をゆるやかにし、行き過ぎる前に上昇を止めるブレーキの役割があります。
    オーバーシュートやハンチングを能動的に止める動作です。
    Kd値を大きくすることでブレーキの効果が高まりますが、高すぎると目標値に到達するのに時間がかかってしまうようになります。

基本的にはトライアンドエラーを繰り返して感覚で調整する必要がありますが、StormworksのPID制御でも利用できる、実際の制御工学で利用されているジーグラ・ニコルスの限界感度法(以下ZN法)という、ある程度最適値に近いK値を得られる方法もあります。*2

StormworksでのZN法の使用例->【Stormworks】 PIDの調整がちょっと楽に出来る(かもしれない)方法 [沿岸警備ゆかりさん番外編]
https://www.nicovideo.jp/watch/sm36286214

StormworksでしかPIDに触れたことがない素人によるStormworksのPIDに限定した経験則

ZN法を使うのが不適切なPID制御があるらしいです。どういうものがそれに当たるのか知りませんし、ZN法以外にKを決める手がかりがなさすぎるので何があろうと全部ZN法でまず出発点を決めます。*3

そのZN法で無難なKd値の設定をした上でも、まだ発振が起きる場合(振動し続ける以外にも、段差入力後に減衰する振動がある時も含む)はまずKp値を小さくしてみます。P制御は振動の主原因です。ZN法で数値を決めたなら、Kp1(ZN法の、KiとKdを0にして発振させた時の最小のKp)の値自体を小さくして3つのKを計算しなおします。その後で、先に述べた通りD制御は振動を抑える働きがありますからKd値を大きくしてみます。Kp値を小さくし、Kd値を大きくしても振幅が小さい振動が収まらない時は、Ki値を小さくしてみます。これらの調整をする時、複数のKを同時に変えてテストしてはいけません。どの値の変更がどの程度効果があったのか分からなくなります。必ずひとつだけ変更してテストして結果を比較しましょう。

「小さくします」、「大きくしてみます」、と述べましたが、どのくらい上げ下げするかは個人の感覚に依存します。でも目安が要りますから、まずは10%変えてみます。結果が大きく変わったら5%戻します。変わらなかったらもう一度10%変えます。さらにもう3回変えても結果が変わらなかったら、次の変更項目を試す価値がありそうです。どんな時もKに負の値を代入することはありません。操作量がプラスのときに、制御量がプラスに変化するように制御対象を接続しているはずですが、もし逆相の出力値が必要ならPIDのKではなく制御対象側で符号を反転させてください。

PIDの操作量が-1~1を遥かに超える(Stormworksの大抵の装置はそれより広い範囲の操作を受け付けません)振幅で振動する時は、Kpが大きすぎるか、別の振動を発生させる機構が制御対象にあります。
ヘリのローター(特にヘビーローター)のコレクティブをGyroのUp/Downで制御していると、過剰なブレードピッチ変動に伴う1秒以下の周期の上下振動を生むようです。Up/DownをGyroの前段に介入してPID制御していれば直接的にこれが原因で振動が収まらなくなりますし、Up/DownをPID制御していなくても、ロールやピッチ、エンジンスロットルをPID制御していれば大きく影響を受けます。これを解決するにはPIDではなく、GyroのプロパティでMax Throttleを小さくし、Stabilized Up/Downの出力制限をしてください。ただし、小さくしすぎると離昇できなくなります。Stabilized Up/Downに出力されている値を調べて、適切な値を考えましょう。
また、ディーゼルエンジンによって駆動されているプロペラは、エンジンがレブリミットに達した時のエンジン回転数の振動を速度に変換してしまいます。これがプロペラではなくヘリのローターなら、上下振動を引き起こすでしょう。エンジンがレブリミットに達しないように運転してください。

Tilt Sensorの出力を制御量にして傾斜を制御しようとしてもPIDがほとんど能動的な出力をせず制御できない時があります。Tilt Sensorの出力は90度の傾斜で0.25ですから、例えば波による船の揺れ程度だと±0.02がいいところだったりします。この場合はPIDに入力する制御量に20や100を乗算するとよい結果が得られます。Tilt Sensorに限らず変動幅が最大でも0.25より少なかったり、波や風などの小さい外乱による動揺幅が0.05より狭いような制御量は10、20、100を乗算するのは一考に値します。ただし、乗算値が大きすぎると振動の原因になります。振動がKの調整でなくならない時は乗算値を半分~1/5にしてみてください。乗算値を変更した場合は、ZN法によるK値算出からやりなおしです。制御量に定数を乗算した場合、目標値が0でない制御では目標値にも同じ値を乗算することを忘れずに。

ヘリのヨーやロールをPID制御しているのに、傾きや斜行が収まらないことがあります。強風が原因である場合があるので、風速を計ってみてください。現実では20m/sの強風ならヘリの飛行中止が検討され、30m/sなら着陸禁止のヘリポートがあります。もちろん、制御対象の向きを誤って左右逆に付けてしまっていたりもありえます。(←ここが経験則)

PIDの例

  • ヘリコプターの高度維持
    目標値: 任意の高度を入力できる装置で与える。メモリレジスタを使って上下機動をやめた瞬間の制御量を目標値にするのも使いやすいだろう。
    制御量: 高度計
    制御対象: メインローターのコレクティブ ← ジャイロのUp/Down

    ジャイロを全く使わないヘリも作れるが、高度に限らず4軸とも操縦席からジャイロへの入力に介入するほうが簡単。
    介入する場合は、操縦席が操作している時はその操作値をそのままジャイロに送り、操縦席の上下操作がされていない時にPIDを起動して高度を維持するように作るとよい。
    水平機動中に高度が維持されるように作ると、現実のドローン(4つのローターを駆動するモーター4個の回転数を制御して飛行するラジコンヘリ)のように操作できる非常に使いやすいヘリになる。
    上下機動をやめた瞬間の高度を目標値にするとオーバーシュート戻しが1回は必ず起こる(上下機動をやめた瞬間は上下方向の速度が0ではない)ので、制御量をリニアスピードセンサの垂直速度にすると垂直方向へ高度のオーバーシュートはあるものの、スムースに停止する動作になる。

  • 固定翼機のロール安定装置
    目標値: 0
    制御量: 傾斜計を左舷向きにつける(この向きに設置すると右ロールで正の値を出力するようになる)
    制御対象: エルロンを正の操作値で右ロールするようにつける

    操縦席のロール操作がされていない時にのみPID制御するとよい。
    速度や高度は上下正負が分かりやすいが、左右は混乱しやすい。気をつけ…間違ってたら直せばいいので、これが間違っている可能性を忘れないようにしよう。
    制御量を傾斜計ではなく角速度計から得る方法もある。
    これなら固定翼機の背面飛行をPID制御で維持することもできるが、傾いていない状態に向かって安定するのではなく、操作をやめた瞬間に傾きが変わらないように動作する。

  • エンジンのアイドリング
    目標値: 例えば2.5などのアイドリングが維持される固定数値。バッテリーの残量によって目標値を高くする回路を足すと自動アイドルアップができる。
    制御量: エンジンのRPS
    制御対象: エンジンのスロットル

    エンジンを停止させている時にPIDも止めないとI制御が暴走するので、エンジン停止状態を作るスイッチが必要。
    ヘリの垂直制御をスロットルではなくローターのコレクティブでしている時に、十分な出力が出る回転数を維持するようにPID制御してもよいだろう。

  • オートラダー
    目標値: 目標地点(マップのウェイポイントの座標をキーパッド大で入力できる)と現在地(GPSから座標が得られる)の二つの座標から目標方位を計算する。
    制御量: コンパスセンサー
    制御対象: ラダー

    コンパスセンサーから得られる方位は真南で0.5と-0.5が交差する。
    例えば南の僅かに東-0.47が目標値で、現在の制御量が南のちょっと西+0.43の場合に、右にぐるーっと回るのではなく正しく左にちょろっと向きを変えるように作ろう。
    ラダーは速度が出ていないと作用しない。船なら停船時、微速時にはPIDをオフにしてI制御の暴走を防ぐ必要もあるだろう。
    この機能をONにしている時に後進することはないと思われるが、「堅牢なシステム」(SEに予算外で求められる仕事)にするなら後進時に制御をやめる機能があってもよいかもしれない。


  • タイトルがPIDバランス制御となってるけど検索してもそういう用語の使い方をしてるページはないみたいだし普通にPID制御じゃダメなんだろうか? -- 2020-11-27 (金) 18:49:53
  • オートラダーの項目にある、『左にちょろっと向きを変えるように』するにはどうすればいいのでしょうか。 -- 2021-09-23 (木) 23:28:03
  • 右にぐるーっとの値と左にちょろっとの値の絶対値を比較して、絶対値が小さい方の符号付の値を採用するだけだよ -- 2021-09-24 (金) 17:14:07
  • ありがとうございます。 -- 2021-09-24 (金) 20:43:36
  • 固定翼機の自動速度制御を作っているのですがPIDを起動した瞬間に入力が下振れて一時的に速度が下がります。過剰に下がらないようにはどのようにしたらいいでしょうか -- 2021-09-30 (木) 11:35:45
  • PIDを常時起動しておいて、PIDを使わない時は制御量と同じ値を目標値に入力しておく切り替え回路おすすめ。もちろん使わない時はPIDからの操作量もカットしておくようにしてね -- 2022-02-03 (木) 10:06:25
  • 「オートラダー」の作り方がどうにもわからないのでWorkshopで検索したのですが、それらしいものがどうしても見つけられませんでした。オートラダーというのはこのWiki独自の用語なのかと思うのですが、英語だとなんという名前になるんでしょうか…? -- 2022-05-06 (金) 20:47:31
  • auto navigation,auto pilot(どちらも日本語で自動航行)でどうでしょうか? -- 2022-06-03 (金) 19:15:05
  • 古いから返事あるか分からないけど、航空機としてジェット推進で前進して揚力を得られるものでPIDで高度をジャイロ越しにピッチをコントロールするパーツへ伝えようとしたけど、高度が規定値を超えても下がることなくずっと上に上がり続けるんだけど何が原因か分かんないです -- 2023-04-26 (水) 16:01:00
  • 機体やロジック見てみないとなんとも言えないけど、症状だけ聞くとI値が大きすぎるとか目標値と設定値が離れている時間が長すぎる事によるワインドアップに思える。試しにI値を0にしてみて解決するようならそれが原因 -- 2023-04-26 (水) 20:18:29

*1 工学的にはp、i、dは小さい大文字をKの後ろの下の方に添えて表記します。Iの誤読を避けるため小文字で書く場合もありますが、やはりKの後ろの下の方に小さい文字で添えます。
*2 本ページではジーグラ・ニコルスの限界感度法を指してZN法と略していますが、限界感度法の他にジーグラ・ニコルスのステップ応答法というのもあります。
*3 ZN法を知る前はKp=1 Ki=0.0001 Kd=10固定でスタートしていつも挫折していました…