2025年1月27日

021-2.SPIKEプライムヒント集-第1回「ロボットの移動速度は毎秒何cmか?」

この連載ではロボットコンテスト(ロボコン)で役立つロボット作りのヒントを紹介していきたいと思います。ヒントを実感しやすいように、ここでは競技風の「お題」を出します。お題をクリアするロボットを作ってみましょう。自分の手を動かすことが大切です。この記事では「レゴ エデュケーションSPIKEプライム(以下、SPIKE)」とSPIKEアプリ3を使用しています。(文/松原拓也)

◆ 秒速5cmで走らせる

まず、最初にロボットとフィールドを作ります。
ロボットに最低限必要なパーツはラージハブとモーター2つです。モーターはラージハブのポートEとFに接続します。

フィールドの図(field1_a4.odg)です。 OpenOfficeの「Draw」というフリーソフトで25cmの目盛りを描いています。出来上がったら、プリンタでA4の紙に印刷します。

一つ目のお題は「25cm走」です。普通のコンテストはロボットの早さを重視すると思いますが、ここでは正確さを重視します。ルールは以下のとおりです。
・ロボットがスタート地点から出発して、ゴール地点で止めます。ぴったり25cmで止まれば成功。25cmから何cmかズレて止まったら失敗とします。
走行タイムがぴったり「5秒」なら成功です。走行タイムが5秒より早かったり、遅かったら失敗です。

◆ 移動スピードを調節する

プログラムはSPIKEアプリ3(ワードブロック)で作ることにします。ここで必要となるのは、ロボットで秒速5cmで5秒、走る(25cm走る)という処理です。どうすればそれを実現できるのでしょうか?
このプログラム(speed_control 1.llsp3)では「移動スピードを~%にする」ブロックを使っています。移動スピードの単位は「%」なので、速度との関係がわかりません。まず「20%(思い付きの値)」に設定して、試走してみます。

プログラムの実行結果です。ぴったり25cmの場所で止まりました。走行タイムは「2.887秒」でした。
「5秒」ではないので、これは失敗です。
ですが、この情報を活用すれば、「5秒」で走らせることができます。

SPIKEアプリには指定した移動スピードに合わせて、モーターのパワーを自動で調節するという機能があります。 たとえば、坂道では平地よりもモーターへの負荷が大きいですが、そのぶんパワーを増やして、同じ速度で走らせることができます。坂道でも25cmの走行タイムは「2.887秒」に近くなるはずです。本当にそうなるかは各自で確認してください。

移動スピードを何%にすれば、秒速5cmで走るのでしょうか?
たとえば、少しずつ%値をちょっとずつ減らしながら試走を繰り返せば、いつかは移動時間が5秒になると思います。ただし、そういうやり方はオススメしません。ムダに時間がかかりすぎます。頭を使っていません。
このプログラムの例(speed_control 2.llsp3)では、移動スピード1%あたりの移動速度を「speed_rate」という変数に格納します。あとは比を使って計算すれば、最適な移動スピードを求めることができます。

実行結果がこちらです。走行タイムは「4.916秒」です。0.1秒ほどズレていますが、許容範囲だと思います。これで「25cm走」のお題はクリアできました。
ロボコンは試走に時間を食われてしまうのが命取りです。頭を使って問題を解決しましょう。

◆ モーターのスピードを読む

二つ目のお題は「ロボットの移動速度の測定」です。ロボットを秒速5cmで走らせて、「本当に移動速度が秒速5cmだ」と測定できたら成功とします。
このプログラム(speed_control 3.llsp3)ではモーターのスピードを読み取るブロックを使ってグラフを作成します。

プログラムを実行するとロボットが秒速5cmで前進します。走り終わるとグラフが表示されます。
(プログラムに問題があり、ロボットが25cmより長く走ってしまいます。これはあとで直したいと思います。)

グラフを拡大します。グラフの横軸が時間(単位は秒)、縦軸はモーターのスピード(単位は不明)です。
一見すると、うまくグラフができていて、お題をクリアしているように思えますが、おかしな点がいくつかあります。気が付くでしょうか?
まず、モーターのスピードが「0」から始まるべきですが、なぜか「-16」から始まっています。 あと、スピードの値がだいたい「9」を示しているのですが、その意味がわかりません。移動スピードだとすると、秒速5cm÷0.446なので、計算上は11.2くらいであるはずです。 もしかして「移動スピード」と「モーターのスピード」では、単位が違うのでしょうか? ちょっと使いにくいです。

スピードのブロックを使わずに移動速度を測定するプログラム(speed_control 4.llsp3)を作りました。ちょっと規模が大きくなってしまったので、測定の処理をマイブロックにしました。
プログラムを細かく説明すると終わらないので、大まかに説明します。速度を測るには、モーターの回転角度をこまめに検出しないといけません。このプログラムでは0.1秒に1回のペースで速度を求めることにしました。

出来上がったグラフです。グラフの横軸が時間(単位は秒)、縦軸はロボットの速度(単位はcm/秒)です。秒速5cmだと、モーターの回転角度は0.1秒に10度くらいなので、グラフの線が荒いです。このグラフを見ると、「だいたい毎秒5cmで走っている」ことがわかると思います。これでお題をクリアできました。
これで終わって良いのですが、実は1つおかしなところがあります。
グラフの最後が「秒速0cm」で終わるべきなのに、「秒速5cm」で終わっています。これはロボットが25cm前進したあと、正しく止まっていないためです。

◆ 並列処理を行う

先のプログラムの改良版です(speed_control 5.llsp3)。
今度は「25cm前進する処理」と「グラフを描く処理」を同時に実行します。これを並列処理といいます。並列処理を行うため、「メッセージ~を送る」ブロックを使います。メッセージとはブロックが出す合図のようなものです。この場合、ロボットが走り始めた瞬間にメッセージを1回だけ送っています。

実行結果です。ロボットが25cmで止まるようになりました。
何かを作るには改良を繰り返すことが重要です。 改良点を見つける「目」が必要です。

移動の加速度を「低速」「中」「高速」に変えて、実行してみました。3種類のグラフが出来上がりました。
グラフを見ると、5秒後に秒速0cmになっています。改良することができた証拠です。
あと、「低速」は最初に速度が上がりすぎているように見えますが、これはどういうことでしょうか? 理由を考えてみましょう。

今回作成したプログラム(SPIKEアプリ3用)

当ブログの内容は、弊社製品の活用に関する参考情報として提供しております。
記載されている情報は、正確性や動作を保証するものではありません。皆さまの創意工夫やアイデアの一助となれば幸いです。