2025年1月27日

021-2.SPIKEプライムヒント集-第11回「ロボットの位置から角度を求めるには?」

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

◆ アークタンジェントを使う

前回の続きです。 前回は「ロボットの位置情報を求める」というお題で、角度ときょりから位置情報を算出する方法を紹介しました。
今回はその逆で、位置情報から角度ときょりを算出してみたいと思います。 考えたお題はこちらです。 ロボットが(0cm,0cm)からスタートして、(20cm,10cm)にゴールしたい場合、ロボットは何度の方向に何cm移動すれば良いのでしょうか?

図にすると、こうなります。今までは90度単位にロボットを動かしていましたが、今回は最短きょりでななめに動かします。青色の矢印がロボットの進む方向です。 黄色のおうぎ型の部分が知りたい角度です。 パッと見て「30度くらい?」と思うかもしれませんが、残念ながらハズレです。正解は「約26.56度」です。

「Thonny(Pythonの開発環境)」を使って、角度ときょりを算出するプログラムを作ってみました(atan_test.py)。実行すると、画面に「degree(角度)=26.56…」「length(きょり)=223.6…」と表示されます。長さの単位はmmです。ロボットを26.56度に22.3cm移動させればゴール地点です。これでお題はクリアできます。 角度を算出するには「atan(アークタンジェント)」という関数を使います。atanは三角関数の一つで、「かたむきから角度を求める関数」です(Pythonの場合は「かたむきからラジアンを求める関数」ですが、話がややこしくなるので省略します)。 目標地点までのきょりを求めるには「三平方の定理(ピタゴラスの定理)」を使います。式は「sqrt((X方向移動量の二乗)+(Y方向移動量の二乗))」となります。「sqrt」は平方根を求める関数です。

◆ 演算ブロックのtanとatan

SPIKEアプリ(ワードブック)を使って角度を求めるには演算ブロックの「atan(アークタンジェント)」を使います。
しかし、その前に演算ブロックの「tan(タンジェント)」について説明します。このプログラム(tangent1.llsp3)では演算ブロックを使ってtanの計算を行います。「tan」は「角度からかたむきを求める関数」です。引数に「26.56度」を与えると、戻り値の「0.49989」が表示されます。これがかたむきです。26.56度というのはY方向に10cm、X方向の20cm移動した時の角度です。

「かたむき」というのは「Y方向の移動量」を「X方向の移動量」で割った値のことです。たとえば、「Y方向10cm」「X方向20cm」に移動するのであれば、かたむきは10÷20=「0.5」となります。
中学校の数学の授業で一次関数を習いますが、「y=ax+b」という式にある変数「a」がかたむきです。数学のグラフではY座標の値が大きいほど上に向かっていきますが、コンピュータの場合は下に向かっていきます。

かたむきから角度を算出するのが「atan(アークタンジェント)」です。「tan(タンジェント)」とは逆の機能になります。 このプログラム(tangent2.llsp3)では演算ブロックを使って、atanの計算を行います。atanの引数に「傾き0.5」という値を与えると、「26.56505度」という戻り値が表示されました。

「atan」はX方向が0以上であることが前提に計算を行いますので、-90度以下や+90度以上の角度には対応することができません。 他の角度も対応させる場合、この写真のプログラム(tangent2b.llsp3)のように対策します。分岐のブロックを使って、X方向の移動量がマイナスだった時の処理を追加します。
このプログラムの場合、「X方向移動量-20cm」「y方向移動量10cm」で計算して「153.435度」という角度が求まりました。90度以上の角度に対応できています。

◆ 座標から角度を自動で計算する

ロボットにもっと複雑な動きをさせてみましょう。 ロボットの現在地を(0,0)と考えて、(30cm,20cm)に移動させて、それから(-20cm,-10cm)に移動させてみたいとします。
この現在地を(0,0)と考える座標のことを「相対座標」と呼ぶことにします。

プログラムを作ってみました(tangent3.llsp3)。プログラムの量が多いので2つに分けて紹介します。こちらがマイブロック「move」です。引数に相対座標を与えると、ロボットがその座標に向かってせん回して移動します。
変数「target_deg」は目標地点の角度です。変数「degree」は今現在のロボットの角度です。単位は度です。 変数「length」には目標地点までのきょりです。単位はcmです。
なお、X方向の移動量が0だった場合、0の割り算が発生してエラーになってしまいます。そこで、0だった場合には0.001に置き換える処理を追加しています。

プログラムの続きです。プログラム開始直後にマイブロック「init(初期化)」を呼び出し、マイブロック「move」を呼び出します。
マイブロック「init(初期化)」「forward(前進)」「turn(せん回)」は前回の最後に作ったプログラムの内容と同じです。

実行してみましょう。 ロボットが最初に(30cm,20cm)の相対座標に移動します。続いて、(-20cm,-10cm)の相対座標に移動します。

最終的にロボットは(10cm,10cm)の位置で止まりました。
想定したとおりの場所に動かすことができました。 このように三角関数を使うと、角度を扱うプログラムが作れるようになります。
今回作成したプログラム(SPIKEアプリ3用)

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