2024年12月17日
013-1.EV3ライントレース入門-第3回「三角関数を使ったライントレース」
この連載では「教育版レゴ マインドストームEV3基本セット」を使ったライントレースロボットの作り方を紹介していきたいと思います。ライントレースロボットはその名のとおり「線(ライン)を追跡(トレース)」するロボットのことです。(文/松原拓也)
◆ 三角関数の使い方
前回は比例制御を使ってライントレースロボットを作ることに成功しました。しかし、問題が1つだけありました。
この図を見てみましょう。ロボットがラインを横切って、カラーセンサー(反射光モード)で測定しています。表示されたグラフの線が丸みを帯びています。ラインの位置に対して、センサーの測定値が比例していないということです。今回はこの問題点を正して、完全な比例制御を実現したいと思います。
原因はカラーセンサーの特性にあります。カラーセンサーは赤い光の中心から外れるほど感度が弱くなります。
そこで、カラーセンサーがきちんと比例するように改善します。ハードウェア的には修正できませんので、ソフトウェア的に修正します。これを「正規化」と呼ぶことにします。
具体的には三角関数を使います。三角関数は高校あたりの数学の授業で習います。そのため、小学生~中学生の方々には理解しにくいかもしれません。難しいと思う場合は「そういう関数がある」ということだけ覚えておきましょう。
まず最初にコサイン(cos)という関数を使ってみましょう。
こちらがコサイン関数を使ったテスト用のプログラムです(cos.ev3)。 EV3ソフトウェアで三角関数を使うには「数学」ブロックの「拡張機能」を使います。
コサイン関数の書式は「cos(引数)」です。「引数」の部分には角度を入れます。ここではループブロックを使って、0~359度の値を入力しています。
プログラムを実行すると、画面にグラフが描かれます。
これがコサイン関数のグラフです。X軸は関数の引数(0~359度)です。Y軸は関数の戻り値です。
コサイン関数を使って描いたグラフをカラーセンサーで実際に測定したグラフと見比べてみましょう。
両者は形が良く似ています。この「似ている」という点を活かしてカラーセンサーを正規化します。
◆ カラーセンサーの正規化
こちらがカラーセンサーを正規化するための実験用のプログラムです(acos.ev3)。ロボットが移動して測定するだけで、ライントレース機能は搭載されていません。
次の変数を使っています。
・変数「max」。床面が「完全に白色」の時のカラーセンサーの値。
・変数「min」。床面が「完全に黒色」の時のカラーセンサーの値。
・変数「ave」。「白と黒の中間」のカラーセンサーの値。この場合、(22+1)÷2=11.5が入ります。
・変数「dif」。maxとaveとの差。この場合、22-11.5=10.5が入ります。
筆者の場合、変数maxには「22」を代入して、変数minには「1」を代入しました。この値はロボットの形状や、センサーの特性、照明の明るさによって違います。
このプログラムで初登場するのがアークコサイン(acos)関数です。アークコサイン関数はコサイン関数の逆の働きをします。コサイン関数は角度からコサイン値を算出しますが、アークコサイン関数はコサイン値から角度を算出することができます。 アークコサイン関数の引数の有効範囲は-1~1です。引数が1より大きかったり、-1より小さかったりしてはいけません。
プログラムの仕組みを図にしてみました。カラーセンサーの値の範囲はmin~maxです。これを比を使って、-1~1の値に変換します。その値をアークコサイン関数の引数として与えます。すると、関数は角度(0~180度)を返します。この角度を元にしてカラーセンサーがラインのどの位置にいるのかを知ることができます。
プログラムを実行すると、ロボットが10cmだけ前進します。
画面にはこのようなグラフが描かれました。 グラフのX軸は時間(単位は秒)。Y軸はカラーセンサー(反射光モード)の値です。
グラフを見ると、カラーセンサーがラインを通過している様子が分かります。Y軸は画面の中心に中心の値がくるように描いています。グラフは部分的に線がつながっていませんが、これはセンサーの分解能が低すぎるためです。
対策前と対策後のグラフを見比べてみましょう。
対策前のグラフは丸みがあります。 対策後のグラフは尖っていて、傾きがほぼ一定です。つまり、ラインの位置に対して、センサーの変化がほぼ比例しているということになります。
これでカラーセンサーの正規化に成功しました。
◆ 完全な比例制御
カラーセンサーの正規化の技術をライントレースに取り入れてみました(linetrace.ev3)。
プログラムの基本的な仕組みは前回の最後に作ったプログラムと同じです。違うのはマイブロックを2つ追加していることです。
初期化処理用マイブロック「init」の中身です。
ここでは変数の初期化を行っています。 変数「max」や「min」などの役割は先に作ったプログラムと同じです。
パワー算出用マイブロック「getpower」の中身です。
ここではカラーセンサー(反射光モード)の値を入力すると、戻り値としてモーターのパワーを返すという処理を行います。
最初に「範囲」ブロックを使って入力値の範囲をチェックします。範囲から外れている場合には中心の値を入れて無効にします。
パワーの計算には先ほどと同じくアークコサイン関数を使っています。 この場合、アークコサイン関数の戻り値は0~180度です。カラーセンサーがラインの白黒の中間に居る場合、90度を返します。右下にある数学ブロックでは角度から90を引くことでラインの中心に位置する場合には「0」を示すようにしています。数式内にある「0.4」は角度からパワーを算出するための倍率です。この倍率を「ゲイン」を呼びます。ゲインが大きいと、モーターが敏感に反応するようになりますが、蛇行しやすくなります。ゲインが小さいと蛇行しにくくなりますが、ラインに追従しきれなくなり、コースアウトしやすくなります。
プログラムを実行すると、ロボットがラインをトレースします。
なめらかにロボットを走らせることができました。 特に問題ないのですが、これで走りが改善できたかどうかが分かりにくいです。
プログラムの実行結果がこちらです。ライントレースのカラーセンサーの値がグラフとして描かれます。
前回の最後に作ったプログラムとグラフを見比べてみましょう。上が前回(linetrace5.ev3)のグラフで、下が今回のグラフです。
新しい方のグラフは以前と比べて変化が荒っぽくなっているように見えます。予想ですが、計算処理に時間がかかりすぎてループの周期が遅くなってしまい、反応がにぶくなっているのかもしれません。ゲインの値を増やせば改善する可能性があります。今回の改良ではコースアウトしにくくなっているはずなのですが、このようなコースではうまく確認することができませんでした。
なので、プログラムが改善できたかどうかはっきりしないという結果になりました。今回のプログラムは複雑すぎるわりに効果が薄いので、前回のプログラムの方が使いやすいと思います。しかし、待望の「完全な比例制御」が実現できたので、筆者としては満足しています。
次回はカラーセンサーを2個使ってラインをトレースする方法を紹介します。
[DOWNLOAD]今回作成したプログラム(教育版EV3ソフトウェア用)
当ブログの内容は、弊社製品の活用に関する参考情報として提供しております。
記載されている情報は、正確性や動作を保証するものではありません。皆さまの創意工夫やアイデアの一助となれば幸いです。