inventorでライントレース(PID制御 ざっくり全体解説)

コース上の黒い線に沿って進む技術をライントレースと言います。LEGOのロボットキットにはカラーセンサーが付いていて、センサーから出た光が何%反射して返ってくるか(反射光)を調べることができます。この反射光を使って黒い線に沿って進めるようにプログラムを作ってロボットを制御していきます。

PID制御とは、P制御(比例制御:Proportional)と、I制御(積分制御:Integral)、D制御(微分制御:Derivative)を組み合わせた制御です。ここでは、PID制御を使ったライントレースをYoutubeにアップした動画をベースに解説をします。

On-Off制御と比例制御

別の記事ですが、このカラーセンサーを使って、暗いところと明るいところを区別して、二択で左右に動かすOn-Off制御、反射光の強さに応じて曲がる強さを変える比例制御でライントレースを実装できることを説明しました。

関連記事

inventorはLEGO社のロボットキットです。反射光(センサーから当てた光の反射量)の強さを読み取れるカラーセンサーがありますし、モーターもかなり細かく制御できる上、ロボット本体が軽く、何よりLEGOなので形を自由に作り放題ということ[…]

まだ、Youtubeでも説明をしています。

On-Off制御は作るのも動きの原理もわかりやすいのですが、細かな調整が難しく、揺れが大きくなりやすいことで移動に無駄が多い上に、ロボットの姿勢が安定しません。比例制御は調整次第ではかなり綺麗にライントレースできる上、(OnーOff制御よりは難しいのですが)少し勉強すれば理解できるくらいプログラム自体はそれほど難しくありません。

基本的な動作で問題がなければ比例制御だけでも十分だと思いますが、ライントレースを綺麗に速く実現するために「PID制御」という制御が使われることがあります。

今回はこのPID制御について説明します。

PID制御の解説動画

PID制御の説明は、Youtubeで倒立振子(倒れないロボット)を題材にしてPID制御の説明をしていました。

動画でしか解説がないので、今回はここのブログでもPID制御について説明してみようと思います。

また、現時点でPID制御を使ったライントレースの解説動画をアップしています。ここのブログでもこの動画の流れと同じような解説になります。お好きな方で確認いただければ幸いです。

このブログでは、ライントレースに特化した説明になりますが、積分制御、微分制御の原理や考え方を大切にして、それに基づいたプログラミングの作り方を説明します。

比例制御(P制御)のまとめ

比例制御はP(Proportional)制御と呼ばれます。PID制御のPです。

つまりPID制御を理解するためには、まず比例制御を正しく理解しておくことがとても大切です。

比例制御の考え方

比例制御は、目標の値に対してどれだけずれているかを計算して、そのズレ具合を制御の強さにする制御です。

ライントレースの場合、白と黒の境目を閾値(しきい値)として、そのしきい値から離れるほど強く曲がり、近いほど緩く曲がることで、目標にスムーズに近づいていき、近づいたらそこから大きく外れないように動かすことができます。

うまく調整すればほぼ線にくっつくような動きにできます。

inventorでの比例制御のプログラム

色々な作り方がありますが、シンプルな作りにすると、以下のようなプログラムになります。

比例制御のプログラム

仮の条件で赤で止まるようにしてますが、条件は好きなように設定できます。

ただし、EV3など色を調べる時と反射光を調べるときで、光の当て方が変わってしまうセンサーは、ライントレースの精度が落ちます。

ループの中で比例制御の動きを作っています。サンプルのプログラムではわざと変数にして、要素がわかるようにしています。変数ではなく直接数値を打ち込んでも構いません。

しきい値はおおよそ50くらい、Pゲインは比例係数と呼ばれ、比例制御の倍率(制御の強さ)を調整する値になります。ライントレースの場合、比例制御の計算結果はパワーの変化より大きな値になるので、1未満の小数をかけて小さくすることが一般的です。

(パワーを遅くして、係数を1以上にして線に吸い付くような動きも作れます)

「パワーで動かす」というプログラムブロックなので「パワー」にしていますが、パワーはロボットのスピードと同じようなイメージで構いません。

比例制御の問題

比例制御も万能ではありません。(どんなものにも万能はありませんが・・・)

Pゲインを大きくする

Pゲインを大きくすると、曲がりが強くなりより線に近づけますが、線に近づいた後でも曲がる力が強いままになるので線を行きすぎたり、大きく黒い範囲に入り込んで、その反動でまた大きく曲がってしまい、大きく蛇行するような動きになります。

Pゲインを小さくする

反対にPゲインを小さくすると、曲がりが弱くなり、変化がほとんどなくなってしまい、線に近づけなくなってしまうことがあります。また、コースに急カーブがあると、その曲がりに対応できないこともあります。

解決策

単純な方法としてはパワーを落としてゆっくり動くようにするだけで、多くの問題は解決します。

しかし、ロボット競技においては速く正確な動きを求められるので、速度を落として移動するのは最終手段と考えておいた方が良いです。

ここだけは失敗できない、という時の最終手段のような感じです。

積分制御

積分とは・・・、と説明するには色々な論があるようですね。迂闊な断言はできませんが、ここでの使い方を簡単に説明すると、積分制御はそれまでの制御に使った値を「合計した値」を元にして制御するというイメージで使っていきます。

高校数学においては、グラフを細切れにしてそれぞれの値を合計すると・・・など出てきますが、グラフも関数も使わないので、高校生で習うような積分の計算そのものは行わず、手動で計算していくプログラムになります。

改めて、ライントレースでの積分制御は、目標値(しきい値)と今の値(反射光の値)のずれの合計を使って、合計が大きいほど強い制御になるようにして、ずれを修正する制御になります。

積分制御のイメージ

積分制御が無いとき

急なカーブがあり、ロボットが曲がりきれない場合、光が当たっている場所が黒い線の中に突入してしまいます。この時、反対側まで突き抜けてしまうとコースアウトしてしまいます。

ギリギリで耐えているとしても、その後、黒い線が直線に戻った後には、反動で白い床の方に大きくはみ出します。その結果、蛇行が始まります。(専門用語的にはハンチングと呼ばれます)

積分制御を取り入れることで、ずれている状態が続くと、そのずれの合計が積み重なり制御が強くなり、徐々に理想の位置に戻すことができます。

積分制御があるとき

図のように、しばらくずれ続けると、積分制御の力が強くなって、理想の位置に近づけます。適切に調整できていれば、理想の位置を走っている時には積分制御が(ほとんど)働かないので、比例制御だけできれいに進むことができます。

積分制御のプログラムのイメージ

前節で説明した通り、積分制御では、ずれの合計をライントレースの制御に活かします。

ループのたびに比例制御にも使った「反射光の値としきい値の差」を足していけば、その合計を求めることができます。

あとは、積分係数であるIゲインをかけて制御の強さを調整することになります。この時の注意点として、比例制御の時の元の値が「反射光の値としきい値の差」という同じものを使っており、積分制御はその合計を使います。つまり、その合計値は比例制御の計算結果よりとても大きな値になります。(プログラムを実行中のループは高速で回転しているので)

そのため、IゲインはPゲインに比べたらとても小さな数にしなければ、過剰に強い制御が働いてしまいます。

積分制御を追加したプログラム

比例制御に積分制御を追加したプログラムを実際に作ってみました。

PI制御のプログラム

見た目は色々と複雑になっていそうですが、計算量を増やさないために変数を増やした点と、実際に積分制御をして、それを比例制御と合算した部分が増えただけです。

実際に積分制御で計算しているのは、赤く囲った二行だけです。イメージで説明した通り、合計を計算して、その合計にIゲインをかけるようにしています。

ループの中身をもう少し細かく説明すると、1行目は反射光としきい値との差を計算しています。比例制御だけであれば、これに直接Pゲインをかければ良かったのですが、積分制御でも使う値なので、一旦別の変数に保存しておきます。

2行目で、比例制御の計算を行っています。

3行目は積分制御のための合計の計算。

4行目が、その合計とIゲインをかけて調整をします。

5行目でそれぞれの値を足して、6行目で実際にモーターを制御値に合わせて動かします。

ループの外に合計値を0にするブロックがありますが、これは何度もライントレースをしていると、前の積分制御の結果が残ってしまうために初期化しています。

ループの条件は、サンプルでは時間で動くようにしているだけで、なんでも構いません。

このプログラムは比例制御と積分制御を組み合わせているので、PI制御とも呼ばれます。

積分制御のまとめ

積分制御は、ずれている状態が続いたら、元に戻す力を強くできます。ですので先ほどのPI制御のプログラムでは、一瞬黒い線の内側に入った後、ぐっと加速して元に戻るような動きが追加されます。積分制御はズレが溜まってから制御が効くようになるので、タイミングが遅れると言われますが、プログラムが高速に回っていたり、少しの変化で調整できる場合は、遅れは気にならないと思います。

(動きに関しては、文章よりも動画で確認いただいた方がわかりやすいと思います。)

微分制御

微分は積分の反対とよく言われますが、細かく分けてその瞬間の変化を調べる計算というイメージで良いと思います。

一般的な微分制御は、目標との今の値のずれの変化量を調べて、その変化量に応じて制御の強さを変える制御になります。

ライントレースにおける微分制御は、コース(黒い線)が変わった直後に、「反射光としきい値の差」が大きく変化するので、その瞬間に制御を強くして変化にすぐに対応できる制御です。

微分制御のイメージ

同じような図になっていますが、ずれに対して反応するタイミングが速くなっています。

微分制御は変化した瞬間積分制御はずれ続けた途中から反応が始まります。

変化した瞬間に働く方が良さそうなイメージがあるかもしれませんが、変化しなくなったら微分制御は働かなくなるため、一定の間隔でずれ続ける場面では微分制御は効果がありません。

反動によってロボットが揺れて反射光が激しく変化してしまっている最中や、ちょっとしたノイズ(センサーの読み間違いや地面の汚れなどの影響による数値のずれ)にも微分制御が働いてしまうので、調整を間違えると、より強く蛇行してしまうことがあります。

積分制御はある程度遅れて反応するので、ノイズや細かな揺れにはあまり影響がありません。

微分制御のプログラムのイメージ

微分制御は直前の「反射光としきい値の差」と今の「反射光としきい値の差」を比較して変化量を調べます。

ループごとに計算できるように、すべての計算が終わってループが終わるところで直前の値を今の値に置き換えることで、次のループで一つ前の値を使えるようになります。

計算結果に微分制御の係数であるDゲインをかけるのは他の制御と同じです。このDゲインは、瞬間の変化量に対しての調整ですので、その時の値より変化量が小さくなることが多いので、Pゲインよりは大きくした方が良い場面が多いようです。

微分制御のプログラム

微分制御と比例制御を組み合わせたプログラムのサンプルです。

PD制御のプログラム

計算は、今の目標値(反射光としきい値の差)との差と直前の目標値との差を比較しています。特に分ける意味がないので、同じところでDゲインもかけて一気に計算しています。

ループの最後でしきい値との差を置き換えることで、次のループで今の値を使えるようにしています。微分制御では、直前の値が別のライントレースの分を使わないように初期化しています。

他の部分は積分制御と同じ考え方で理解できるはずなので、省略します。

微分制御のまとめ

微分制御は変化した瞬間に制御の力を強くできます。サンプルのPD制御のプログラムでは、コースが変化した瞬間により強く変化する動きが追加され、制御値が強すぎると小刻みに揺れるような動きが確認できると思います。

こちらも動きに関しては、動画を見ていただくのが一番わかりやすいと思います。

PID制御

比例制御、積分制御、微分制御を組み合わせたものがPID制御です。それぞれの制御のイメージはここまでで説明しているので、ここではその組み合わせに関して説明していきます。

PD制御とPI制御

ここまでに説明した全ての制御を組み合わせたらPID制御になりますが、サンプルのプログラムで示した通り、PI制御やPD制御もあります。積分制御でも微分制御でも、ライントレースの性能を向上させることはでき、ある程度の対応であればどの制御でも可能です。

イメージをより強くするために、もう一度それぞれの特徴を説明します。

PI制御

比例制御と積分制御を組み合わせた制御です。普段は比例制御で走行を続け、コースが変化した後、対応しきれなくなると積分制御が強くなって修正が入る制御です。コースの変化に対して、即時に対応することはできませんが、緩やかに対応できることで、反動を抑えやすく、制御が甘くても綺麗に走っているように見えるので、調整が楽です。

PD制御

比例制御と微分制御を組み合わせた制御です。これも普段は比例制御で走行を続け、コースが変化した瞬間に微分制御が働く制御になります。コースの変化に応じた調整ができれば、以後はまた比例制御だけの走行になります。

変化した瞬間に合わせることができない場合、さらに微分制御が働き、不自然な加速が続いたり、細かな蛇行が増えることになります。この揺れは比例制御の強さにも影響するため、微分制御の調整は、PI制御より難しい感じがします。

理論上は、変化にピッタリ制御できれば、無駄のない走行を実現できます。

PI制御とPD制御で調整の練習をする

PID制御の前にPI制御とPD制御で調整の練習をしておくと、それぞれの調整で何が変わるのかわかりやすいと思います。また、そのためにもP制御の調整を、意図がわかってできるようになっていて、その調整による変化をロボットのどこをみて感じとるかができるようになっておくことが大切だと思います。

動画では光の位置で解説している部分がりますが、ロボット全体を見るよりも、光がどこにあたっているか(どこを読み取っているか)を確認することで、どういう挙動になっているかを目で確認できると思います。

きれいに曲がっているように見えて、実は黒い線の中を走っている場合、ずれを修正できていないことになります。

綺麗に曲がっているように見えて、実は外れている走行の例

上の画像では、(比例制御だけですが)光の位置が黒い線の中に入っています。見た感じは揺れもなくきれいに走れているように見えますが、その後に直線に戻る時に反動が生まれ、揺れが収まらないうちに次のカーブに差し掛かると、ロボットの姿勢次第ではコースアウトにつながります。

この時、ロボットの揺れしか見ていないと、解決の判断を間違ってしまうかもしれません。

PI制御でのI制御は何を修正してくれるのか、PD制御でのDは何を修正してくれるのかが分かれば、本番のPID制御に入っても大丈夫でしょう。

PID制御のプログラム

大きな流れは変わらないので、PI制御もPD制御も作れるようになっていれば、PID制御も変わらずに作ることができると思います。

プログラムの各行は特に大きな違いはありません。

それぞれのゲインの調整の仕方ですが、変数で作っておいても良いと思いますし、今回のサンプルのプログラムではマイブロックのパラメーターとして入力できるようにしています。

マイブロックを使っているプログラム

こんな感じで、直接値を入力して実行することができます。(マイブロックなどの作り方は使う状況によって変わりますので、今回は特に説明はしません。)

調整は何度も行うことになるので、できれば同じ場所にまとめて修正できるようにしておいが方が事故を防げると思います。

サンプルのプログラムでは、コースの形状によって変わりますが、それぞれの係数はあかなり甘い調整になっているので、まだまだパワーを上げることができると思います。

PID制御の調整

これに関しては復習になります。

比例制御は全体的な動きに影響をします。

積分制御は目標からずれた時に、ずれを修正する制御です。ずれが続いてから反応するので調整が少し遅いです。

微分制御は変化が起こった時に、変化量に応じて制御を強くする制御です。変化した瞬間しか制御できません。

勘がいい方はこの時点で、何をどう調整すれば良いかというパターンが存在しないことがわかるかもしれません。

カーブが曲がりきれない時

カーブの内側をライントレースしていて、黒い線を突き抜けてコースアウトしてしまう場合、曲がる制御が不足していると判断できます。直前まで綺麗に進めていて、カーブには自然な姿勢で突入できたとします。曲がる制御を強くすること自体は、どの制御を強くしても解決できます。解決はできますが、制御を強くしすぎると別の問題が発生します。

比例制御を強くしすぎると、全体的に走行中の揺れが大きくなります。これによって、カーブに綺麗な姿勢で突入できなくなったり、次の行動に切り替える時の姿勢が不規則になります。

積分制御を強くしすぎると、突然内側に曲がってコースアウトします。一度強くなった積分制御は他の制御では対応できません。これを回避するために、一定期間や特定の条件で合計値を初期化する積分制御もあります。

微分制御を強くすると、カーブに差し掛かった時に小刻みに揺れてその影響で、それ以降もおかしくなります。

おおよそ考えられるイメージですが、実際にこの通りになるよりも、複数の要因が重なってよくわからない挙動になる方が多いと思います。

まずはパワーを落として一つ一つ改善していくことが重要です。意図を持って調整して、問題がなくなったらパワーを少しずつ上げて、またおかしな挙動が現れたら改善していく、という形で調整していくのが良いと思います。

急がば回れ、ですね。

PID制御を他でも使っていく

積分制御が効いているか、微分制御が効いているかを確認しながらの調整ができるようになれば、PID制御の基本はマスターできたと思って良いと思います。

あくまで基本であって、色々と改善の余地は残っていますし、そもそもPID制御はライントレースだけの技術ではないので、他でも使えるようになって初めて意味があると言えるでしょう。

例えば、PI制御だけで有効な制御もあります。まだ私は挑戦したことがないのですが、ジャイロセンサーを使った特定の角度までのターンはD制御が意味なさそうなので、PI制御で速く正確なターンが作れそうです。そして、この技術の方がロボット競技を始め、色々なロボット制御に有効な気がします。

倒立振子に関しても、もっと静止するまでの時間が短く、また静止した後のブレも少なく、などの調整はできると思います。

これらの動作に対して、どのような調整をしていけば良いかが根拠を持って判断できることが大切で、PID制御を勉強する時にはぜひここを目指してほしいと思います。

枚方ロボットプログラミング学習塾では、このような内容も取り扱っていく予定で授業を組み立てています。スタンダードコースで比例制御を学び、それをたくさん使って色々なコースにチャレンジして、しっかりと理解した上で、ハイレベルコースやエキスパートコースで積分制御と微分制御の違いを理解して、高度な制御にチャレンジしてもらうカリキュラムです。

難しそうなイメージを持たれるかもしれませんが、当教室では個別のペースに合わせて授業内容を調整して進めていきます。年齢的な成長を待って進めていくことも、数学的な考え方を先に指導するなど色々な試みが可能ですのでご安心ください。

PID制御は決して全員ができる必要はないと思っていますが、ロボット制御とは?というのを体験するだけでも、ここを卒業してからの学びの目的を見つけやすくなると思います。

体験授業を実施中です

枚方ロボットプログラミング学習塾では無料で体験授業を実施しております。

興味を持たれた方はお気軽にお申し込みください。事前の問い合わせも可能です。

メール(info@hrktrpg.com)への問合せもお待ちしております。