2024年12月17日
013-1.EV3ライントレース入門-第5回「移動きょりの検出機能を追加する」
この連載では「教育版レゴ マインドストームEV3基本セット」を使ったライントレースロボットの作り方を紹介していきたいと思います。ライントレースロボットはその名のとおり「線(ライン)を追跡(トレース)」するロボットのことです。(文/松原拓也)
◆ 前回のプログラムを改良する

ライントレースロボットとしての機能は前回の時点でほぼ完成しました。しかし、ロボット競技でライントレースを行う場合には、「ライントレースをしながら物を動かす」とか「ライントレースをしながら色を検出する」など、さらに複雑な制御が必要となります。
今回はそうした複雑な制御を行う例として「移動きょりの検出機能」を紹介したいと思います。
ライントレースロボットとコースを用意します。前回に引き続きEV3カラーセンサーを2つ搭載したタイプのロボットを使用します。コースはアフレルの「楕円コース」を使用します。

まず、前回のプログラムを少し改良するところから始めます。以下の点を改良しました(linetrace1.ev3)。
●どこでどんな処理を行っているのか、パッと見ただけでは分かりにくい部分がありました。そこで、「変数」ブロックを最初に置いて設定値を分かりやすくしました。
変数「power」はモーターのパワーの設定値です。パワーが大きいほど速く走ります。
変数「gain」は比例制御をするためのゲインの設定値です。ゲインが大きいほど敏感に走行します。
●「ステアリング」ブロックを使うのをやめて、「未調整のモーター」ブロックを使いました。これによって、回転センサーからのフィードバックが一切なくなりますので、カラーセンサーの変化をダイレクトに反応させることができます。
●グラフの描画機能は確認する必要がなくなったので削除しました。

プログラムを実行すると、このようにロボットが8秒間だけラインをトレースします。この動きは前回の最後に作ったプログラムとほぼ同じです。
◆ コースを1周したら自動的に止まる

ここからが本題ですが、さらにプログラムを改良して、移動きょりの検出機能を追加します(linetrace2.ev3)。
赤いワクで囲んだ部分が追加したブロックです。「endflag」という変数を新しく作りました。この変数「endflag」はロジック型といって、「真(1)」または「偽(0)」という2種類の値だけを格納することができます。プログラムの実行時、最初は「偽(0)」が格納されていますが、ロボットがコースを1周すると「真(1)」となる仕組みです。

プログラムの追加部分を拡大してみました。
このループは移動したきょりを監視する処理を行います。移動きょりを求めるには「数学」ブロックを使って「((a+b)/2)*17.6/360」という数式を計算します。「a」と「b」には左右の回転センサーの角度を代入します。「((a+b)/2)」は左右の回転センサーの角度の平均値を求める式です。「17.6」はタイヤの円周です(直径5.6cm×円周率3.14)。「360」はモーター1回転ぶんの角度です。
この計算結果が167cm以上なるとループを終了します。「167cm」はコース1周ぶんの長さです。ループを抜けると変数「endflag」に「真(1)」を代入します。真となることでループを終了して、ロボットが停止します。

ここで使用する「楕円コース」の長さを調べます。実物のコースを定規で測るとこのような結果となりました。

コースの長さは次のように計算しています。最初にコースを想像の中でバラしてつなぎ直します。すると、4本の線と円だけになります。これで計算しやすくなります。計算式は次のとおりです。円周の長さは「円の直径×円周率3.14」で計算します。数式は次のとおりです。
(29×2)+(9×2)+(14.5×2×3.14)
この結果は「167.06」cmです。これがコース1周ぶんのきょりです。

移動したきょりは回転センサーを使って計算します。
しかし、ここで1つの疑問が生じます。曲がったラインを走っていると、タイヤは右側と左側で回転する量が違います。では、ラインの長さを計算するにはどうしたらいいでしょうか。
結論としては、左右の回転センサーの平均値から求めることができます。
例として、図のような半径14.5cmのカーブを走行した場合を計算してみましょう。両タイヤのきょりを10.5cmとします。このため、タイヤの経路は内側が半径9.25cm、外側が半径19.75cmとなります。きょりは次のとおりです。
・内側のタイヤの移動きょり:半径9.25cm×2×3.14÷4 = 14.5225 cm
・外側のタイヤの移動きょり:半径19.75cm×2×3.14÷4 = 31.0075 cm
・ラインの長さ:半径14.5×2×3.14÷4 = 22.765 cm
そして、内側と外側のタイヤの移動きょりを平均して確認します。(14.5225+31.0075)÷2 = 22.765 cmです。先ほど算出したラインの長さとぴったり同じです。つまり、左右の平均から求める方法が正しいということになります。

プログラムを実行した様子です。ロボットがラインをトレースして、コースを1周すると停止します。

インテリジェントブロックの画面に走行タイムが表示されます。「14.978秒」でした。連載1回目のタイムが「26.6秒」だったことを思えば、結構優秀な結果だと思います。
この連載の第1回目ではラップタイマーを自作して、走行タイムを測定していましたが、この方法を使えばロボットだけで走行タイムを測定できます。

ロボットが停止した状態の写真です。 ちょっと気になる点としては、スタート地点で止まるはずが4.5cmくらい通り過ぎて止まっています。計算方法は合ってるので間違いはないはすですが、このズレがどこから生じているのか分かりません。気になりますが、今回はそのままにして進みます。
仮説としては、停止時にモーターが惰性で回転してしまったか、ラインの内側を走ってしまいきょりが短くなってしまったことが考えられます。
◆ 直線走行時だけ速度を上げる

それでは、移動きょりの検出機能を応用してみましょう。
図のように直線を走行する時はモーターのパワーを上げるようにします。

改良したプログラムです(linetrace3.ev3)。赤いワクで囲んだ部分が追加した処理です。

追加部分を拡大しました。
「範囲」ブロックを使って、スタート地点からの移動きょりを判定して、「スイッチ」ブロックで分岐します。移動きょりが69.03~98.03cmの場合には、ロボットが直線を通過中ということなので、モーターのパワーを60に設定します。そうでない場合にはパワーを30とします。これで通常移動と高速移動を切り替えることができます。

プログラムを実行してみました。
写真では伝わりませんが、直線を走行する時だけは高速移動するようになりました。

走行タイムはこのとおりです。1.3秒ほど短縮できました。一応速くはなりましたが、思ったよりも効果はありませんでした。さらに速くするには全体のパワーを引き上げるか、高速移動する場所
を増やすといいでしょうか。まだまだ検討する必要があります。
この方法を使えば、コースの特定の場所で走り方を変えることができるようになります。
欠点としてはタイヤがスリップしてしまうと、移動きょりの誤差が生じてしまいます。あと、コースの形状が変わってしまうと正しく動作できません。コースごとにプログラムを書き替えないといけません。
ロボット競技にも応用してみましょう。
[DOWNLOAD]今回作成したプログラム(教育版EV3ソフトウェア用)
当ブログの内容は、弊社製品の活用に関する参考情報として提供しております。
記載されている情報は、正確性や動作を保証するものではありません。皆さまの創意工夫やアイデアの一助となれば幸いです。