カテゴリー「Processing」の1件の記事

2016年12月22日 (木)

ジャイロセンサーMPU6050とProcessingで飛行機の3D姿勢表示

 前から少しづつ進めていたプロジェクト、6軸の加速度・ジャイロセンサーMPU6050をESP8266のArduinoで動かして、PCの画面に3Dの画像(飛行機)を表示する開発がやっと一段落した。MPU6050の基板を手で動かすと、PCの飛行機がそれに合わせて動く。Dsc00804

 当研究所の大きな縛り「実用品を開発する」ことなら、MPU6050は本来ならドローンや2足歩行のロボット(まあ、これも実用品ではないが)に使って始めて開発と言えるのだが、そこまでの足慣らしということで始めた。ところがこれが思ったより難航したのである。Ws000011

Processingの3Dライブラリーが動かない(12/3/2016)
 Processingそのものは、すでに前回、単独で動くことを確認している。これからやりたいことは、MPU6050で検索すると必ず出てくる3Dの飛行機やティーポットをPCのProcessingの画面上で動かすことである。

 ところが3Dに必要なProcessingのリソースをダウンロードしようとすると、殆どの日本語サイトが紹介しているダウンロード先のAndrocityというサイトが変わってしまっていて、先に進めない。

 片っ端からウェブサイトを探し回って何とかファイルを見つけ、インストールには成功した。toxiclibというライブラリーも見つかった。しかし、動かしてみるとProcessingの3D出力のドライバーOpenGLでエラーが出る。平面図形は至極順調に動くのだが、OpenGLが以下のメッセージを出してエラーとなる。

Framebuffer error (framebuffer unsupported), rendering will probably not work as expected

 調べてみると、PCのグラフィックドライバーが古いと動かないようだ。このライブラリ(OpenGL)だけでなく他の3Dライブラリでもトラブっているようで、エラーメッセージをキーにすると海外のサイトが多数ヒットする。

Ws000009

 回避する方法は、残念ながら紹介されていない。基本的には新しいビデオカードに替えるか、メーカーがビデオドライバーを更新してくれるのを待つしかないようだ。しかし後者はこちらの場合望み薄である。

 現用のPCのビデオインターフェースが古すぎる。マザーに内蔵のビデオインターフェースはIntelのG33で、恐らく7年は経っている。最新のIntel汎用ドライバーに更新しようとしても、メッセージは「これが最新です」と出て、状況は変わらない。

 うーむ、買ってくるしかないか。前のPCで使っていた古いRADEONのボードは部品庫に残っているが、これとてかなり古く、動く保証はない。変なところで頓挫してしまった。余り意地になるのはやめようと思うが、どうも気になって他のことに移る気分にならない。

 本来の工作の方向ではない(単なるMPU6050の動作テスト)ので、潔く他のことをすれば良いと思うのだが、へそ曲がりなもので、出来ないとなると余計悔しくて気持ちが納まらない。因果な性分である。

ビデオボードを買ってきて解決(12/6/2016)
 色々迷ったが、次にやることが見つからないので、くだらない話だけれどビデオカードを更新することに決めた。ということで、買うことは決めたのだが、いざ具体的には何を買えばよいのか見当がつかない。PC自作から遠ざかって15年は経っている。

 ネットで久しぶりに「ビデオカード」をキーワードに検索をかけてみた。おお、出てくるわ出てくるわ。この世界はまだまだ活況のようだ。そのうち全体を俯瞰できる親切なサイトを見つけた。なにー、10万円を超すビデオカードが沢山市販されている。中には30万を越すボードもある。これ業務用ではないよね。ハイエンドPCゲーマー御用達のボードのようだ。

 こんな高いボードにはもとより縁はない。お値段は¥5000以下(さっきのサイトのランクでは5段階の下から2番目)、冷却ファンのない静かなボードが条件である。仕事の帰り、秋葉原に寄り、この前PC電源を買い替えたお馴染みのTwoTopで、適当なボードを物色する。ASUSのGeforce GT710を選んだ。¥4200余り。

 家に帰って久しぶりのPC拡張ボードの工作である。ビデオインターフェースのコネクター規格PCI Expressがえらく複雑になっていて悩ましい。バージョンが1から3まである上、2には枝番としてx1だのx16だのに分かれている。買ったきたビデオカード(2.0 x8)が現用のマザーに入るか心配だ。

 スロットに差してみると、何か接続されないピンの空きが多い。不安がよぎったが、とりあえずはきっちり入ったので試しに動かしてみた。BIOSは今のところ何もいじらない。新しいカードの方にビデオケーブルのコネクターをつけて電源を入れてみる。

 良かった。BIOS画面が映った。ビデオカードを自動認識してこちらを使うようだ。ドライバーを入れていないので、MicroSoftの汎用ドライバーで画像は荒いが、Win10までちゃんと動く。付属のDVDからビデオドライバーをインストールすると、正規の1920ドットの画面になった。やれやれ。

 さあ、目的のOpenGLのProcessingはどうだ。おおう、あっさり飛行機が出た。Arduinoとつないでいないので、飛行機はまだ正面を向いたまま動かないが、3Dの部分は問題なく動いているようだ。

 ビデオカードの効果は他にもあった。これまでMicroSoftの無料ゲームの中に、画像の乱れがあったり、やけに動きが遅かったりしたゲームがあったのだが、これらの不具合がすべて解消された。まあ、お金をかけたことは無駄ではなかった。

Processingで画像がグリグリ動く(12/7/2016)
 3Dが出たので、また暫くProcessingで遊ぶ。それこそティーポットやヨット、シリンダーなどの3D図形がマウスの操作で自由に動く。素晴らしい。

 すごく親切なProcessingのガイドがウェブで見つかった。それを夢中になって試す。いやいや、昔に比べると、良くインタプリターだけでこれだけ滑らかな動きが出来るものだと感心する。

 このサイトにも例の3D飛行機(MPUTeapot)の丁寧なインストール方法の紹介がある。この通り忠実に手順を踏めば簡単に動きそうだが、どうもこの前のスマホの無線操縦のように動いた後、何も出来なくなるような気がしてきた。

 もう少し基本からProcessingとArduinoを勉強した方が、のちのち良いような気がする。少し回り道でも、ひとつづつ段階を経て動作を確認していくことにした。ArduinoでMPU6050をドライブし、そのシリアル出力をPCのProcessingで受けて、画像ルーチンの入力にする過程を確認していこう。

 だいたい、MPU6050の6軸のセンサー値の意味も完全に理解しているわけではない。加速度センサーだけで測れるのは、飛行機で言えば、縦揺れ(ピッチング)と横揺れ(ローリング)だけで、縦軸(Z軸)の回転(ヨーイング)は、角速度センサー(ジャイロセンサー)で値を積分しないと測れないはずなのだが確証はない。ちょっとソースを覗いてみたけれど、全く手も足もでなかった。

 独自開発しようと意気込んでいたが簡単に白旗をあげた。このJeff Rowberg氏の開発したMPU6050関係のライブラリーは膨大で、MPU6050.cppなどは3000ステップを超える。I2Cのドライバーだけでも1000ステップ以上で、これを無償で公開されているのには頭が下がる。

ProcessingとArduinoの連携に目鼻がついた(12/10/2016)
 それでも、単にソースをコピーしてきて動かすことだけは避けたい。理由は、コピペだけでは身につかないProcessingとArduinoの技術を少しでも習得しておきたいからである。センサー、MPU6050のI2Cはライブラリを拝借するが、3Dの画像を出す部分は、せめて少しでも理屈を知っておきたい。

 作業を以下のように細かく分割して、ひとつづつ確認していくことにした。

(1)    Processingの学習  例のこのサイトがとても親切に教えてくれる。
(2)    Arduino スケッチとライブラリ構築の復習 これは上記のサイトのここが詳しい。 
(3)    Processingシリアル入出力のテスト
(4)    ProcessingとArduinoのシリアル連携 ここを参考にさせてもらった     
(5)    ArduinoとMPU6050の接続テスト
(6)    ProcessingとArduinoのハンドシェイクプロトコルの決定
(7)    ProcessingとArduinoの接続テスト
(8)    Processingの画像出力のスケッチ作成
(9)    MPU6050とProcessingのテスト

 現在は、(4)まで済んでいる。(5)が課題だ。ArduinoのシリアルコンソールにMPU6050の数値を出すスケッチはたくさんのサイトで紹介されている。これを試すことにする。

ステップ(5)MPU6050の接続テストまですんだ(12/12/2016)
 簡単に通過するはずだったのだが、意外に手間取った。原因はESP8266のI2Cの接続ピンの勘違いである。以前使ったピンアサインのメモに基づいて配線したのだが、MPU6050を認めないメッセージが出る。 

コピペさせてもらったソースに間違いはない(はずだ)。動かないとなると、途端に何も出来なくなるのがArduinoである。ピンの接触不良や、AD0ピンのプルダウンなどを疑うが問題はない。オシロなどを出して波形を見るまでもなく、何か基本的な間違いだと思うが、最初は以前自分で書いたメモを信じていたので途方に暮れた。

 気を取り直してESP8266の正式なピンアサインをネットで確かめる。あっあっあー、SDAピンが違うぞ。なぜだ。どうして間違ったところにメモしたのだ。正しい方にピンを差しなおしテストする。よーし、いいぞ。それらしい値が出てきた。

ステップ(6)(7)は既製のスケッチを流用(12/14/2016)
 次はArduinoのMPU6050のメッセージがProcessingのテキスト画面に出ることを確認する。これは問題なく動いた。ただし、Processingのテキスト画面はスクロールしないので単に、忙しく数字が変化するだけで、見映えはしない。

Procesingserial  Processingのテキスト画面をスクロールするように直したい気持ちが激しく盛り上がったのだが、やっとのことで自制する。ここで脱線するとまた戻れなくなる。我慢、我慢である。

 とりあえず、これでESP8266につないだMPU6050のデータは正しく、Processingに到着した。残るは最後の関門、画像表示である。既成のスケッチのソースを見て調べるが、そう難しいハンドシェイクはしていない。単にメッセージの頭に特定のキャラクター($)を入れて、それをトリガーに後続データを配分しているだけのようだ。

 難しいのはやはりセンサー値の加工である。色々ネットで調べる。クオータニオン(四元数、しげんすうと読む)という3Dでは常識らしい用語を発見して珍しく興奮し、暫く勉強する。いやあ、奥が深い。 

 これからMPU6050から出てきた数値を気安く加工しようと思っていたが、一筋縄で触れるものではなさそうだ。ここは素直に、既成のスケッチを使わせて貰うことにしよう。まずは動かすことが先決だ。

ステップ(8)(9)はMPUTeapot2のプロジェクトをそのまま使う(12/15/2016)
 人さまの動いたソースを借用するのだから、すんなり動くのかと思っていたが、そうは問屋が卸さなかった。参考にしたサイトは、すでに紹介したここである。

 このサイトは、以前、懸命に探し回ったリソースがちゃんとダウンロードできるようになっており、ここだけですべてが動く(実は大きな落とし穴があったのだが)。順調にMPUTeapot2のライブラリを入れてArduinoとProcessingを動かした。しかし、エラーメッセージが出るだけで機体は動かない。

 例のArduinoの弊害である。 スケッチソースは長大で、ちょっと目検したくらいでは何がおかしいのか見当はつかない。手も足も出ない状態だ。まあ、救いは、散々連携テストをしてきたので、ハードなどの問題はなく、動かない原因は現在入れたアプリケーションソフト(のはずだ)だ。

 ただ、エラーメッセージが奇妙である。つながったことを示すステートメントは出るが、何か(割り込み)を待つというステートメントのあと、タイムアウトが起きてリセットされ、これが延々と続く。

Initializing I2C devices...
Testing device connections...
MPU6050 connection successful

 

Send any character to begin DMP programming and demo:
Initializing DMP...
Enabling DMP...
Enabling interrupt detection (Arduino external interrupt 0)...
DMP ready! Waiting for first interrupt...

 

Soft WDT reset  (以下繰り返し)

 何らかの外部割込みをArduinoが待っているような感じだ。しかし、参考にしたサイトの結線図にはMPU6050の割り込みピンの接続はない。他のサイトを見るとMPU6050のINTピンが結線されている配線図や、動画が見受けられる。

 うーむ、どっちなんだろう。Arduino UNOでは割り込みピン#0に繋ぐという説明があるが、ESP8266には外部割込みピン#0はない(GPIO#0はあるが、これは制御用に使っている)。つまり繋ぐところが見当たらない。 Dsc00802

 こうなったら本当にMPU6050が割り込み付きで動いているのか(ソフトで設定できるようだ)、確かめるのが先決だ。もし、割り込みモードで動いているのなら、先の配線図が誤りということになる。

 オシロを持ち出して、MPU6050のINTピンを観測した。ピンポーン!当たりだった。I2Cのメッセージが出される前後に派手に割り込み信号が上がっているのを確認した。そうか、やはり必要なのだ。しかし、割り込み入力はESP8266のどこに入れたら良いのだ?

 恐る恐るArduinoのスケッチソースを調べ始める。良かった。見つかった。setup()ルーチンの中に、割り込みピンの定義をしているらしい以下のステートメントを発見した。

attachInterrupt(0, dmpDataReady, RISING);
mpuIntStatus = mpu.getIntStatus();

ふーむ、ここが0になっている。ESP8266のピン0は、ファーム書き込みの制御ピンのためプルアップされたままで入力には使えない。

やっとのことで飛行機が動いた(12/16/2016)

 ここを適当なピンに定義し直せば良いのはないか。希望の光が見えてきた。こいつをESP8266の適当なピンにアサインする。とりあえず2にしてみる。あせる手でジャンパーをMPU6050のINTピンの間に飛ばし、再ビルドする。

Ws000010_2  動く予感がする。まず、Processingを動かす。Arduinoはまだ電源を入れない。続いてArduino(ESP8266)の電源を入れる。これまではタイムアウトのメッセージが出るだけだったがどうだ。おおー、コンソールに字化けしたメッセージが出始めた。しかし依然として飛行機は動かない。

 割り込みジャンパーコードを抜き差ししているうち、突然メッセージが規則的なデータ列になった。同時に飛行機がズルッと動いた。何かのタイミングでMPU6050が暴走するようだ。ESP8266を立ち上げてから割り込みを有効にすると暴走しないことが多い。

Dsc00807  やった、やった。MPU6050を載せたミニブレッドボードを動かすと飛行機が姿勢を変える。反応はとても早い。やれやれビデオボードまで新調してやっとのことで、画像を動かすことに成功した。何度も電源を入れ直し動作を確認する。ささやかな達成感で胸が膨らむ。

 最後が少し手間取ったが(サイトの記述を信用しすぎた)、動いてしまえば何の問題もない。冷静になって考えれば、実にくだらない作業なのだが、仮説をたてて、ひとつづつ問題を解消し、それが思い通りになったときは、どんな小さなことでも嬉しい。これが電子工作の醍醐味である。

| | コメント (2) | トラックバック (0)