2025年1月10日
018-1.SPIKEプライムPython入門-第4回「カラーセンサーの使い方」
この連載では「レゴ エデュケーションSPIKEプライム(以下、SPIKE)」を使ったPython(SPIKEアプリ)によるプログラミングの方法を紹介します。 Python(パイソン)はプログラミング言語の一つです。Pythonは教育や人工知能の研究など様々な分野で使われていて、人気があります。 Pythonの主な特徴はオブジェクト指向を採用していることです。オブジェクト指向というのはプログラムの機能をオブジェクトという単位で切り分けて扱う手法のことです。オブジェクト指向は複雑なプログラムを作る場合に効果を発揮します。(文/松原拓也)
◆ ライントレースロボットを作る
前回はきょりセンサーを使いましたが、今回は「カラーセンサー」を使ってライントレースロボットを作ってみたいと思います。
写真は、SPIKEプライム入門の時に作ったライントレースロボットです。このときは、「ワードブロック」というブロック状のプログラムで動かしていましたが、今回はPythonで動かします。
前回、使用したロボットです。これをライントレースロボットに改造します。
ロボットからきょりセンサーとグリッパーを取り外します。
そして、カラーセンサーを取り付けます。カラーセンサーは「周辺光」「反射光」「色」「RGB」「色の強さ」を測定することができます。ワードブロックのときは周辺光を測定できなかったので、Pythonの方が機能が少し優れていることになります。今回は「反射光」だけを読み取ります。
カラーセンサーをポートFに取り付けてみました。これで、ライントレースロボットのハードウェアは完成です。
◆ 床面の反射光を測る
続いて、プログラムを作ります。
まずは、LEDマトリクスに反射光の値を表示するだけのプログラムを作ってみます。
カラーセンサーを使うには、まず「ColorSensor」というクラスを使ってオブジェクトを作ります。ここではオブジェクト名を「color」と名付けてみました。このオブジェクトを使って測定できる関数は次の4つがあります。
・周辺光(LED消灯時の光の強さ):get_ambient_light関数
・反射光(LED点灯時の光の強さ):get_reflected_light関数
・色(全8色または'None'):get_color関数
・赤、緑、青、色の強さ:get_rgb_intensity関数
今回は反射光を読み取りたいので、「color.get_reflected_light()」と記述します。この関数の戻り値の範囲は0~100です。明るいほど値は大きくなります。
ロボットをラインの上に置きます。
センサーが正常に機能しているかを確認したいので、ここではライトの光が、床面の白色と黒色に半分ずつ当たるようにします。
丸の部分はカラーセンサーとビームとのすき間です。写真の状態では、ペグを根本まで挿し込んでいるので、すき間がありません。すき間を作ることで、センサーを床面に近づけることができます。
プログラムを実行します。
LEDマトリクスに反射光の値が表示されます。本当は50くらいが理想だったのですが、筆者の場合だと、測定値は88~89でした。思ったよりも大きいです。床面とセンサーの距離が近すぎるのかもしれません。許容範囲内なので、このまま直さずに使うことにします。
◆ 比例制御のプログラム
ライントレースのプログラムです。比例制御を行って、ラインをトレースします。
工夫した点がいくつかあります。まず、「単体モーター」を使うと意図した方向と逆にモーターが回ってしまうことがありますので、「モーターペア」を使ってモーターを回します。
比例制御では、センサーの「測定値の差」に比例してモーターの「変化させるパワー」を決定しています。 これを数式で表すと、「変化させるパワー=(中心の値 - 現在の値)×ゲイン」となります。 「中心の値」というのはラインの中心にいる時のセンサーの値です(変数center)。「現在の値」は現在のセンサーの値です(変数value)。 ゲイン(変数gain)は0.4に設定しました。この値が大きいほど機敏にラインをトレースさせることができますが、逆にコースアウトしやすくなります。 変化させるパワーは右モーターに対しては減算、左モーターに対しては加算に割り振りました。これによって、ラインのどちら側にそって進むかが変わります。ロボットは前進する必要がありますので、左右両方のモーターにパワーを30上乗せしています(変数power)。
特に重要な点として、算出したパワー(変数right_powerとleft_power)は整数である必要があります。整数以外の値でパワーを設定しようとすると、エラーが出てプログラムが止まってしまいます。このため、「int」という関数を使って、値を整数に変換しています。
プログラムを実行する直前の様子です。 ロボットをラインの上に置きます。このとき、ライトの光が床面の白色と黒色に半分ずつ当たるようにします。この状態で実行します。
プログラムの実行結果です。
ラインをトレースしながら、ロボットが走ります。10秒後にロボットは自動的に停止します。
ラインの内側にロボットを置いた場合は時計回りで走ります。ラインの外側にロボットを置いた場合は反時計回りで走ります。
もし、ロボットがコースアウトしてしまう場合には、変数powerや変数gainの値を減らしてみましょう。
今回作成したプログラム(SPIKEアプリ用)
当ブログの内容は、弊社製品の活用に関する参考情報として提供しております。
記載されている情報は、正確性や動作を保証するものではありません。皆さまの創意工夫やアイデアの一助となれば幸いです。