2026年3月31日

024-2.SPIKE-RT入門 第3回目 「ジャイロセンサーを検出する」

この記事では「レゴ エデュケーションSPIKEプライム(以下、SPIKE)」で動作する「SPIKE-RT」の使い方を紹介します。
ここではアフレルが販売している教材「レゴ エデュケーションSPIKEプライム C言語プログラミングブック」で配布しているSPIKE-RTの開発環境を使っています。同製品の紹介ページは次の通りです。
https://afrel.co.jp/product/spike/c-language/
(文/松原拓也)

◆ ジャイロセンサーとは

今回はSPIKE-RTでジャイロセンサーを使う方法を紹介します。ジャイロセンサーとは角速度を検出するセンサーのことです。
ラージハブに内蔵しているジャイロセンサーは加速度センサーの機能を含んでいて、回転方向の他に直線方向の速度も検出することができます。レゴ エデュケーションの公式ページでは「6-axis gyro」と呼んでいますが、これは角速度3軸+加速度3軸=6軸という意味です。
SPIKE-RTの場合、ジャイロセンサーと呼ばず、IMU(Inertial Measurement Unit:慣性計測ユニット)と呼んでいます。
角速度を検出するにはhub_imu_init関数を呼び出してセンサーを初期化します。それから、hub_imu_get_angular_velocity関数を呼び出すと、ラージハブの角速度を検出することができます。関数の引数はfloat型配列(要素数3)のポインタです。関数を呼び出すと、配列にピッチ軸、ロール軸、ヨー軸の順に角速度が格納されます。角速度の単位は角度/秒です。 SPIKE-RTにはジャイロセンサーで絶対的な角度を検出する関数は存在しません。そこで、自前のプログラムで絶対角度を算出する必要があります。

ジャイロセンサーで絶対的な角度を表示するプログラムを作ってみました(gyro)。hub_imu_get_angular_velocity関数を呼び出して、ジャイロセンサーの角速度を検出して、ヨー軸だけを加算して絶対的な角度を算出します。角速度は1秒あたりに回転する角度という意味なので、1秒ごとに関数を呼び出して値を加算すればジャイロの絶対的な角度が求まるはずです。しかし、それだと1秒未満の素早い回転に対応できないので、もっと早いペースで呼び出さないといけません。ここでは関数を100ミリ秒おきに呼び出して、角速度を1/10にしてから加算してみました。

プログラムを実行すると、ライトマトリクスに点が表示されます。
ラージハブのヨー軸を時計方向に回転させると、点が反時計方向に移動するので、点が留まっているように見えます。センサーの検出がうまく機能しています。
ラージハブを時計方向に回転させると、角速度はマイナスの値になります。角速度の符合が想定してものと逆になってしまいましたが、そのまま使うことにします。

◆ ジャイロセンサーにロボットを連動させる

ジャイロセンサーで絶対的な角度を検出することに成功したので、それに連動してロボットがその場旋回を繰り返すプログラムを作ります。
ここでマルチタスクの機能が必要となります。ジャイロセンサーの角速度を加算する処理(タスク1)とライトマトリクスの表示とその場旋回をする処理(タスク2)、この2つを並列的に行わないといけません。マルチタスクはリアルタイムOSであるSPIKE-RTの得意分野です。
、、、ですが、SPIKE-RTでマルチタスクを実現するのは技術的に大変です(具体的にはcfgファイルを書き換える。タスクを実装する。act_tsk関数でタスクを起動する。sta_cyc関数で周期通知を開始する。等々)。そこで、「簡易マルチタスク」と名付けたオリジナルの方法を使うことにします。簡易マルチタスクの仕組みは単純で、システム時刻を監視して予定した時刻になったら処理を実行するだけです。2つのタスクが重なった場合にはどちらか一方のタスクを先に実行します。

出来上がったプログラムがこちらです(gyro2)。長いので3つに分割して紹介します。
まずは最初の1/3です。
システム時刻を取得する関数とモーターペアの関数を定義しています。

続いて2/3です。
センサーやモーター等の初期化とタスク1の処理です。モーターはポートAを左モーター、ポートBを右モーターに割り振ります。
タスク1ではジャイロセンサーの絶対的な角度を算出しています。できるだけ細かくジャイロセンサーを検出したほうが良いと思ったので、タスクの実行周期は10ミリ秒に設定しています。

最後の3/3です。 タスク2の処理です。ここではライトマトリクスの表示とその場旋回の処理を行っています。あまりシビアなタイミングを要求していないので、タスクの実行周期は100ミリ秒に設定しています。 その場旋回の処理は「時計方向に180度旋回」→「3秒待つ」→「反時計方向に180度旋回」→「3秒待つ」の繰り返しです。3秒待つ場合は処理を止めてしまうと他のタスクが実行できなくなってしまうので、処理を止めずに変数を使って時間を測定します。

プログラムを実行すると、ロボットがその場旋回を繰り返します。きちんとジャイロセンサーに連動しています。成功です。 このプログラムは無限にその場旋回を繰り返します。終了したい場合にはロボットを持ち上げた状態で中央ボタンを長押ししましょう。

この簡易マルチタスクの機能は他の場面に応用することができると思います。処理が増えると、プログラムの見た目が悪くなってしまうので、タスクごとに切り分けると良いかもしれません。

プログラムを実行中の様子

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