2024年11月7日
001-1.ロボットの基礎-第5回「持ち運びロボットを作る」
レゴマインドストームNXT(以下、NXTと呼びます)を使ったロボット作りの基本的なノウハウを紹介していきます。前回に紹介した「歩行ロボット」は前後に進むだけで芸がありませんでした。そこで今回は自由自在に動けて、さらに物がつかめるロボットを作ってみたいと思います。(文/松原拓也)

こちらがロボットの土台となる部分です。
2つのモーターとインテリジェントブロックをアームで接続しただけのシンプルな3輪車です。 タイヤの1つはキャスターになっています。
この3輪車は「グレーブック」という書籍にも登場しますので、興味のある人は読んでみてください(宣伝)。

そして、ロボットの目となる超音波センサーです。

それから、ロボットの手の部分です。 16歯ギヤを2つ使って、指が左右に開いたり閉じたりできるようにしています。

すべてを組み合わせた様子です。これでハードウェアは完成です。
ケーブルは次のように接続してください。
出力ポートA:右タイヤのモーター
出力ポートB:左タイヤのモーター
出力ポートC:手のモーター
入力ポート1:超音波センサー

このロボットは構造的にあまり重たいものはつかめませんので、紙コップを用意してみました。このコップをつかめるようにプログラムを作ってみます。
◆ 手の開閉
いきなり全部のプログラムを作るのは大変なので、簡単そうなところから順番に作っていきます。

こちらが手を開閉させるだけのプログラムです。プログラミングには「Robolab2.9」を使ってみました(どういうわけか、教育現場ではNXTソフトウェアよりもRobolabを使っている場合が多いようです)。
処理の手順は次のとおりです。
・(1)「開始」:プログラムを開始させます。
・(2)「モーターC順回転」:モーターCを正転させます。これで手が開きます。
・(3)「NXT回転を待つ」:ある目的の角度になるまでプログラムの処理を待ちます。ここでは、角度が45度になるまで待ちます。
・(4)「停止C」:モーターの回転を止めます。
・(5)「1秒待つ」:1秒間、処理を止めます。
・(6)「モーターC順回転」:モーターCを逆転させます。処理2の時と回転方向が逆です。これで手が閉じます。
・(7)「NXT回転を待つ」:ある目的の角度になるまでプログラムの処理を待ちます。ここでは、角度が45度になるまで待ちます。
・(8)「停止C」:モーターCの回転を止めます。
・(9)「終了」:プログラムを停止させます。
[DOWNLOAD]作成したプログラム(Robolab2.9用)

手が閉じた状態でプログラムを実行させます。

実行させると手が開きます。そして、 1秒後に手が閉じます。成功です。
◆ 方向転換

次に方向転換のプログラムを作ってみたいと思います。方向転換はモーターAとモーターBを互いに逆に回転させるだけです。その場で回転するため「真地回転」と言います。

では、モーターをどれくらいの角度で回したらいいのか。それを計算で求めてみたいと思います。ものさしで計ったところ、タイヤの直径は5.7cmでした。円周は「直径×π」なので、タイヤの円周は約17.9cm。つまり、モーターを一回転させると、約17.9cm進むということになります。

真地回転をした場合、タイヤの進路は赤い円の上になるはずです。ものさしでタイヤの間隔を計ると9.5cmでした。なので、円周は9.5×π= 約29.8cm。その距離をタイヤの円周で割ると、モーターに必要な回転角度が求まります。
360×29.8÷17.9=597.6…
…これがロボットが360度方向転換に必要なモーターの回転角度です。タイヤを約597度回せば、ロボットが360度方向転換できることになります。さらにこれを4で割ると、
597÷4=149.25
…90度の方向転換に必要な回転角度となります。

さっそく、プログラムを実行してみましたが…

…一周できずにプログラムが終わってしまいました。失敗です。
なぜ失敗したのでしょうか?

これが失敗してしまったプログラムです。「ループの開始」に4の数字が入っているのは、90度ずつの方向転換を4回(90×4=360度)行う予定だったためです。
うまくいかなかった原因はモーターAとモーターBの回転スピードが違ったためです。このプログラムではモーターAだけを監視していたため、モーターBの速度が遅いと途中で回転を終わらせてしまっていたのです。モーターの回転速度が違うのは、製品のバラつきでしょうか?
この問題を解決するためには、モーターAとモーターBの回転角度を同時に監視する必要があります。
[DOWNLOAD]作成したプログラム(Robolab2.9用)

そこで「タスク」という機能を使います。タスクというのは仕事のことです。
たとえばラーメンを作る時、めんをゆでることとスープを温めることを同時に行ったほうが能率がいいです。この場合「めんをゆでる」と「スープを温める」がタスクに相当します。
同じようにプログラムでは「モーターAを回す」というタスクと「モーターBを回す」というタスクを同時に行う必要があります。

再チャレンジです。

90度方向転換しました。

さらに90度方向転換しました。

さらに90度方向転換しました。

4回目の90度方向転換で終了です。合計で360度です。
なぜか5度くらい多く回りすぎてるように見えますが、ひとまず成功です。

プログラムです。
「タスク分岐」を使って、モーターAとモーターBを同時に監視しています。 2つのタスクはどちらが先に終わるか分かりません。そこで、A側のタスクがB側のタスクが終わるまで待つようにしました。
タスクの終了を伝える方法としてコンテナを使いました。コンテナというのは変化する値を格納することができる入れ物(変数)です。
[DOWNLOAD]作成したプログラム(Robolab2.9用)
◆ 直進

ロボットを10cm前進させてみたいと思います。モーターに必要な回転角度は次の式で計算できます。
360×10÷17.9=201.1…
…約201度。この角度で10cm進むはずです。
では、プログラムを実行させてみましょう。

モーターの回転が止まりました。一応それらしく動きましたが…。

モものさしで計ると10cmのはずが、12.5cm進んでました。この原因はなんでしょうか。
おそらく、モーターを停止してから実際に止まるまでに動いてしまったぶんではないでしょうか。ここでは対策をせず、そのまま使います。

こちらが10cm(実際は12cm)前進するプログラムです。タスクを使って2つのモーターを監視しています。
[DOWNLOAD]作成したプログラム(Robolab2.9用)
◆ つかんで移動
今までに作った3つのプログラム(手の開閉・方向転換・前進)をすべて組み合わせて、1つのプログラムにしてみました。

目標となる紙コップの10cm手前にロボットを配置します。そしてプログラムを実行します。

紙コップをつかんだら、90度の方向転換を2回行います。

進行方向が180度切り替わりました。

そして、10cmだけ前進します。プログラム終了です。

こちらが完成したプログラムです。やたらと長くなりました。
前進する処理は2回繰り返しますので、節約のため「サブルーチンをつくる」「サブルーチンを実行」を使っています。
[DOWNLOAD]作成したプログラム(Robolab2.9用)
[Movie]動いてるところのムービーです(音が入っていません。すみません)
当ブログの内容は、弊社製品の活用に関する参考情報として提供しております。
記載されている情報は、正確性や動作を保証するものではありません。皆さまの創意工夫やアイデアの一助となれば幸いです。