2025年1月10日
018-1.SPIKEプライムPython入門-第3回「きょりセンサーを読み取る」
この連載では「レゴ エデュケーションSPIKEプライム(以下、SPIKE)」を使ったPython(SPIKEアプリ)によるプログラミングの方法を紹介します。 Python(パイソン)はプログラミング言語の一つです。Pythonは教育や人工知能の研究など様々な分野で使われていて、人気があります。 Pythonの主な特徴はオブジェクト指向を採用していることです。オブジェクト指向というのはプログラムの機能をオブジェクトという単位で切り分けて扱う手法のことです。オブジェクト指向は複雑なプログラムを作る場合に効果を発揮します。(文/松原拓也)
◆ whileを使った繰り返し処理

前回に引き続き、「グリッパー搭載ロボット」を動かすプログラムを作ります。
今回は「きょりセンサー」を使ってみましょう。きょりセンサーは超音波を使ってきょりを測るセンサーです。

きょりを測るプログラムがこちらです。
きょりセンサーを使うには一番最初に「DistanceSensor」というクラスを使って、オブジェクトを作成します。関数にはセンサーを接続しているポートを引数として記述します。ここではポート「F」に接続しています。オブジェクトの名前を「wall_detector」にしました。
きょりを測るには「get_distance_cm」関数を呼び出します。戻り値の単位はセンチメートルです。
、、、しかし、これではセンサーを1回測定しただけでプログラムが終わってしまいます。何度もセンサーを測定するには処理を繰り返す必要があります。

処理を繰り返すには「while」文を使います。これは「ホワイル」と読みます。 whileの書式は次の通りです。
while (条件):
( 字下げ )処理
( 字下げ )処理
( 字下げ )処理
、、、「条件」と書かれた部分が「True」や「0以外」の場合、処理が繰り返されます。今回の場合は「1」と記述していますので、無限に繰り返されます。繰り返したい処理は字下げして記述します。

プログラムを実行すると、ライトマトリクスにセンサーの値が表示されます。
成功、、、のようですが、実はこれは失敗です。
グリッパーがセンサーをふさいでしまっています。センサーを測定するにはグリッパーを開かないといけません。
◆ ループから脱出
グリッパーを開閉できるように改良します。
前回に作成した「gripper」関数をコピー&ペーストしてプログラムに組み込みます。次のように処理を行います。
(1)グリッパーを開く。
(2)きょりセンサーの値が10cm以下になるまで繰り返す。
(3)グリッパーを閉じる。
、、、処理を繰り返すには「while 1」と記述します。このままだと無限に処理を繰り返してしまいますので、「break」という命令を使って、ループを抜け出します。きょりの比較にはif文を使います。 赤い線の部分が特に工夫したところです。赤い線の部分はきょりセンサーが測定結果が遠すぎた場合、戻り値が「None」となります。そして、if文で「None」を比較しようとするとエラーでプログラムが終わってしまいます。このため、Noneのときは比較をしないことでエラーを回避しています。

グリッパーが閉じた状態で、プログラムを実行します。
なお、この写真ではターゲットを少し大きくしています。きょりセンサーにうまく反応しない場合には、ターゲットを大きくしてみましょう。

グリッパーが開きました。きょりセンサーの値が1秒おきに表示されます。
もし、ターゲットが10cm以下にまで近づいたら、グリッパーが閉じます。
◆ きょりを測りながらロボットを前進させる

プログラムの実行結果です。
実行すると、グリッパーが開いて、ロボットが前進します。それから、ターゲットを検出すると、グリッパーが閉じて、180度向きを変えます。
プログラムはここで終わりです。では、この先の動きを作ってみましょう。
◆ 安全装置を組み込む

先ほどのプログラムには少し問題が残っていました。 たまにセンサーが反応せず、ターゲットを押したまま前進してしまうことがあります。
このまま前進を続けると、ロボットがテーブルから落ちてしまい、非常に危険です。

そこで、プログラムに安全装置を組み込みます。ロボットが40cm以上移動した場合には自動的に引き返して、テーブルから落下するのを防ぎます。ターゲットを正常につかんだ場合も引き返します。

改良したプログラムがこちらです。
モータの回転量を監視するために、新しく「motor_a」というオブジェクトを作りました。これはモータペアだと回転量が検出できないためです。本当は2つのモータの平均値から移動きょりを求めたいのですが、前進するだけなので、モータの片方だけを監視します。
回転量を求めるには「get_degrees_counted」関数を使います。戻り値は角度です。「17.6×回転角度÷360」と計算すれば移動したきょりを算出することができます。「17.6cm」はタイヤの円周です(タイヤの直径5.6cm×円周率)。 ここでは、40cm前進したらループを脱出するようにしました。 変数amountには移動きょりが入っていますので、そのきょりだけ移動すればスタート地点に帰ることができます。

プログラムを実行した様子です。
ここでは、わざとターゲットを置かずに実行してみました。テーブルの終端にさしかかると180度向きを変えて、スタート地点まで戻りました。安全装置が正しく機能しています。成功です。Pythonなら、複雑な処理も比較的短いプログラムで記述することができます。
今回作成したプログラム(SPIKEアプリ用)
当ブログの内容は、弊社製品の活用に関する参考情報として提供しております。
記載されている情報は、正確性や動作を保証するものではありません。皆さまの創意工夫やアイデアの一助となれば幸いです。