「確実に動くようにする」という観点からは作り込みの余地が大いにあるのですが、実用に供するという わけでもないのでひとまずこのテーマはココまでとして、次のテーマに移ろうかと思います。
次のテーマとしては、パターン認識機能の強化、視覚を利用したロボット周囲の3Dモデル作成機能(空間認識機能の強化)、 「道」の認識、オプティカルフローを応用した 動体認識に関する機能の実装・・・あたりを考えています。
RCサーボのキャリブレーション
センサーヘッドを動かしつつ、ステレオマッチングによる測定を行う場合、センサーヘッドの
指向の正確さが誘導の正確さに利いてくるので、プログラム中から角度指定でセンサーヘッドを
動かしたときにその角度となる様、角度とPWMパルス幅の関係をとる係数を調整しました。
(ついでに調整作業の効率アップのためGUIも整備しました。)
視覚関連クラスの整備
w7b2側で、視覚フォームのボタンのコードに含まれている機能を、GPS誘導のフォームからも
利用できるよう、ボタンから切り離したコードにしつつ、変数のスコープを変えたりしました。
GPS誘導機能への視覚誘導機能埋め込み
GPSを利用して、ウェイポイントを辿るコードの途中、目的地に着いたか判断する部分に、
先日試した、「赤コーンにタッチする」機能を埋め込みました。具体的には、目的地到着したと
判断する、現在位置と目標座標の差を緩くし、GPSで到着判定が出た後で視覚誘導の機能に切り替わるようにしました。
前回までは、直径約2mで旋回するようにステアリングし、1周は車輪のエンコーダで 65カウント程度でした。よって精度としては360度÷65=5.53度で±5.53度の 誤差があり、コーンの3m手前で画像計測すると3m×tan5.53度≒0.3mでほぼ 車幅分の誤差が出ていました。
今回は、直径約4mで旋回するようにステアリングし、1周は車輪のエンコーダで 130カウント程度でした。よって精度としては360度÷130=2.77度で±2.77度の 誤差となり、触覚が触れる範囲になりました。
−−>
−−>
アプローチの過程の認識結果画像
その他、少しずつ、動かしてテストしながら大きくしてきたプログラムなので、いきあたり ばったりな感じで、変数に関して、フォーム間に変な依存関係などが出来てしまっていたりする あたりも、別途グローバル変数的に利用するクラスを作って整理しました。
視覚関係の機能追加に併せて、GPSの入力をベースとして移動する機能の動作確認をせずに、 だいぶ移動関係のコードをいじったので、GPS関係の機能が死んでいないか確認するため 、久しぶりにGPSベースの野外走行テストをしました。予想に反して特に問題ありませんでした。
画像で誘導する機能が安定して動くようになったら、GPSを利用して移動する機能と統合する 予定です。
視差ピクセル数−測定距離グラフ(画像サイズ320×240、カメラ間距離140mm)
最大測定距離のときは、視差が1ピクセルの時の測定値が44m、2ピクセルの時が22mだった ので、分解能は 22mです。そう考えてグラフを解釈すると、カメラの光軸のずれだけでも数ピクセル以上 あるので、今のアースローバーの装置構成では、測定結果を信じていいのは3m程度まで なのか〜と思い、先日の屋外テストの結果に納得しました。
Webで資料をいろいろ読んでみると、「カメラ間距離の10倍程度まで」が一般的に 精度良く測定できる実用的な測定範囲・・・らしいです。
スクリーンハードコピーの下側にあるグラフ中で赤い丸が測定できた点で、縦軸の 目盛りは500mmです。1スキャンに40秒近くかかりました。並列計算に適した アプリケーションの様に思えると共に、高速化したいと思ったので、CUDAを使って 、どれくらい早くできるか試してみたいと思いました。
下の動画では、イメージの中で水色の四角で囲んである部分が面積相関の計算を行っている
場所です。結果はウインドー左下の白いグラフエリアの赤丸と、隣のテキストボックスに
X,Y,Zの座標(ロボットの2台のカメラの中間が座標原点)で表示されます。
はじめは実行速度よりも、プログラムの動きの分かり易すさを重視して、vbで書いてみました。 機能としては、左の画像をクリックすると、右の画像から同じ場所を面積相関の計算で探し、 マッチングできた場所を三角測量で位置を割り出すというものです。
シーンによってマッチングがうまくいったり、いかなかったり・・・基本的には ロボットの周囲の障害物検知に使えそうですが、チューニングが難しそうだと思いました。 でもまあ、レーザーレンジファインダと比べると、ハードが安価なので、これはこれで いいかもしれないとも思いました。
チューニングといえば、左右のカメラの光軸のずれが気になります。 手作りのプラ板の箱にマウントしているので、あまりどうこう出来るとも思えませんが、 出来るだけ調整してみるつもりです。
今週も野外テストをしましたが、先週よりはだいぶ良くなりました。コーンがフレームから はみ出るほど近づいた時の考慮が無いことに気がついたので、こういう類をトラップするコードも 加えました。
今日もとても暑く、ロボットの中はすぐに40度弱まで上がり、手に持って歩いていた ネットブックの黒いキーボードも太陽熱で「あちっ」な感じでしたが、特に問題なく テストは出来ました。
テスト中の画面
いちおう動作したので、仕組み的には使えそうだと思いました。しかし、測定距離が
長くなるに従い誤差がとても大きくなってくる(実際2mのものが3mと出る程度)ことが分かった
ので、要因を一つづつ確認して改善しようと思いました。
テスト中のスナップ
部屋が狭いので、アースローバーを床に置くとけっこう邪魔です。
テスト中の画面
約600mm離れた場所にポテトチップの円筒形の赤いパッケージを置いてテストしました。
dos窓の一番下の行に測定結果が出ています。622mmの距離で、パッケージの幅(筒の太さ)
は57.7mmとでています。(実際は約66mm)W6と比べて、意外と良い数字が出たなーと思いました。
カメラ特性計測用画像
視野の広さと像のレンズの歪みを見るため、約30cmの距離からカッターマットを撮影しました。
「歪みはそれほどでもないか?」
と感じたので、とりあえずOpenCVのレンズゆがみ補正はかけずにおくこととしました。下記の機能を
作ってひととおりデータを取った後で、どれくらい改善するのか、補正をかけて同じ事を
してみようと思います。
このあとは移動制御のプログラムとの統合を行います。具体的には、GPSを利用して指定の経路を 走行する途中でコーンを探し、見つけたらコーンの緯度経度を記録する機能と、予め緯度経度を 登録しておいた場所にコーンを置き、コーンにタッチするまでの精密アプローチを画像利用で行う 機能を作ろうと思っています。
東に2m程度ずれているように見えます。予想よりずっと良かったです。11個の衛星を捉えていました。
現状のセンサーヘッドはカメラのケースを付けた状態で付ける設計なので、新しく カメラを基板の状態で付けるセンサーヘッドを設計中です。
データの桁数が大きい(16bit)なので、精度も高いのかと思っていましたが、測定結果は 以下のようなグラフになりました。読取ルーチンをGPSのスレッドに混ぜた 都合、通信間隔は2秒おきですが同じデータが続く部分が多いためグラフがカクカクしています。
X軸、Y軸を独立してプロット
X軸、Y軸を合成してプロット
データシートを改めて読み直してみると、磁気センサの方位精度は±10度でした。してみると チップの性能どおりのデータを受け取れているとも思えました。・・・がっかりorz
それらしい数値が入ってくるようになったので、同様のコードをGPSからのデータを 読み取るスレッドに組み込みました。近々にいつもの公園で、測地データと磁気ベクトルデータ を同時に記録し、どの程度地磁気以外の磁気があるのか見てみようと思います。
マイコン増設にあたり、この先センサ増設時の柔軟性やロボット運用のし易さなどの面から考えて、 USB−シリアル変換チップ経由で、直にPCと通信するのが良いか、既に搭載しているH8マイコン からI2Cバスを伸ばして通信するのが良いか検討中です。
2008年に今メインで使っているVistaのPCでも使えるように、Programmerなど関連ソフトを インストールすると共に、ライターのファームもアップデートしておいたのですが、最新版のソフトが 使えるようだったので、新しい物をインストールしました。
アナログブロックの使い方がピンと来ていないのですが、Webで公開されている情報や、メーカーの サンプル類を適当に真似ているうちに、CdsからのデータをPCまで持ってくることは出来ました。 以前の簡単なテストでは、GPSレシーバーへの 干渉も少なかったので、このマイコン(CY8C29466-24PXI)を使う方向で進めようと思いました。
すぐに壊れてしまったのと同系統のカメラを買うのはあまり気が進みませんでしたが、ロボット側のマウントを 作り変えなくとも使えそうなロジクールC500を、スペアも含めて3個購入しました。 (値段は1個約3000円でした)
ピントを手動で合わせる必用が無くなる等、光学系の仕様が若干違いましたが、マウントやアプリケーション ソフト等を変えずに使用できました。また、少し使ってみた感じでは、画角やダイナミックレンジも 大体同じくらいに感じました。
ちなみに不調になったQCAM7500Sの症状ですが、使い始めて数分たつとカメラからの画像更新に 非常に時間がかかるようになり、画面の中央付近から、途中の何ラインかがスキップされるような感じで 上下の画像が若干ずれます。表示ルーチンでアドレス 計算を間違えて時の表示みたいでした。なので初めはソフトを疑ったのですが、他のハードでは 問題ないので、故障と結論しました。
そこで、簡単にできる機能追加として、色の特徴でフィルタをかけたイメージの中から対象を切り出し、 検出窓の大きさにイメージを拡大縮小してからCogniMemにかける方針に変更しました。
下の動画では次のようなステップで各フレームの画像を処理しています。
実際やってみると、光源(木の間から見える空)の周りにWebカメラのレンズの色収差のためか、 青や赤の色が出て、実際にはコーンに似た色がそのシーンに無いのに上記ステップ1を通り抜けてくる ピクセルが大量にあったり、サンプルで使ったコーンに光沢があるため、周囲の映り込みから、「赤」 の幅がけっこう広かったりすることが分かりました。
こんな感じで1枚の画像だけでは情報を取れない場合が多かったですが、自機の絶対位置の誤差が 蓄積しない性質があるGPSを装備した移動ロボットから、移動しつつ別の方向から撮影したイメージ で補うと、画像認識の難しさを減らせる方向に持っていけそうな気がしました。
「コーン」として、イメージの中で学習させる部分を工夫しつつ、見失った時に今までイメージの中で
コーンが移動した方向から計算して、そちらの方向へ検出窓を移動させてみたところ、このサンプル
ではそれらしく追跡するようになりました。
ちなみに学習させた場所は、コーンの日向と日陰の境界辺りで、学習対象枠に背景が入らないように気をつけました。
また、640×400、30pfsで撮影した動画を5フレーム毎にbmpファイルに変換して使用しました
サンプル画像ではコーンに近づいてゆくため、初めのフレームで学習した対象がだんだん大きく なります。現状では特にターゲットサイズ変化の考慮をしていないので、すぐにロックオン が外れることを確認できました。
つぎは簡単な対策として、学習結果の更新動作を入れてみようと思いました。
サンプル画像
今使っているPCのマザーボード上のCOM1は、SerialPortコントロールにRS232規格の系列以外の 通信速度をセットするとエラーになりました。マイコン側で誤差少なく設定できる通信速度 の57600bpsが限度のようだったので57600bpsを使うことにしました。 マニュアルによるとこのエラーはPCのCOMポート用ドライバの制限による とのことだったので、アースローバーに載せてあるUSB−シリアル変換基板 (FT2232D USB−シリアル2ch変換モジュール)経由も試してみることとしました。
こちらは例えばマイコン側の上限である500000bps等を設定してもエラーにはなりませんでした。 でも比較のため57600bpsで認識処理をさせてみたところCOM1に比べて非常に時間がかかることが 分かりました。どうも、このモジュールのデフォルト状態では、各転送バイト間で長時間待たされてしまう 設定のようでした。
アルゴリズム的には有効に動いているっぽいです。これを1秒間に何回くらいできれば アースローバーに載せて使えるようになるのか?処理の効率を上げるにはどうすればいいか? など考えてみようと思いました。
2/21の所で触れたように、1秒間に処理できる回数が低いので、机の上のカタツムリくらいしか 追跡できませんが、仕組みとしては使えそうな感じがしました。
次は対象の向きや、照明条件が途中で変わるケースなどに対応するため、随時学習処理を入れ、試してみようと思います。
N−Bodyみたいなシミュレーションは、プログラミングの勉強を始めた頃(学生の頃)に 凝っていたことがあります。その頃はNEC PC−100のベーシックで、5個くらいの 質点を2Dで画面に描いて遊んでいました。8400GSはCUDAが使える一番性能の低い GPUですが、計算結果を見て、あの頃と比べて「えらい処理能力だな〜」と感心しました。
今週も、どんなパターンを学習させるのがアースローバーに良いのかな〜?などと考えながら Reference Guideを読み直したり、イメージを認識させてみたりしていじっていました。
工学社の「はじめてのCUDAプログラミング」という本を見かけて買ったのをきっかけに、サンプル プログラムをコンパイルして動作させるところまでセッティングを進めました。
チップが認識処理するスピードはとても速いので、要領がわかったらチップのパラレルインターフェイス を利用する方式に移行してもよいかな〜と考えています。(これが本来の使い方みたいですが・・・)
リファレンスマニュアルの内容について、よく分からない部分が残っていますが、これで だいたい使えるようになったので、いろいろなイメージを認識させてしばらく遊んでみようと 思いました。
SSDの書き込みに時間がかかるせいか、Atomの処理能力不足か良く分かりませんが、320×240/ 30fpsのセッティングでかなりコマ落ちしていました。
平行して、チップに学習させる前段階の画像処理の参考に「顔認識」でヒットする文献に目を通しました。 あとは、アースローバーにどういう機能を付与するかを考えています。「見えている物に向かってまっすぐ走る機能」 (こういった機能をvisual servoingと言うようですね)や先日のコンテストで使った 「コーンを視野の中から探す機能」、そしてそれらの機能を統合して「GPSで決めたルートを辿りながら、途中で 見つけた空き缶を集めてゆく」みたいなのはどうかな?などと考えています。
測定例
周囲6m以内に物が無い場所にロボットを置いてスキャンした結果です。右半分はうまく測定できていません。
この機会に、アースローバーが外を走っている時も同じソフトが使えるように、mini9の方もOpwnCV、 videoInput.lib、そしてQcamの最新のドライバをインストールしました。
通信が出来るようになったみたいなので、正月休みにロボソートさんのところに遊びに行って 教えてもらった情報を参考に、H8とPC用のソフトを書き始めました。
現在既にI/Oのポートが不足しているので、次はI/O点数が多く、 内蔵RAMも3664に比べれば多いH8/3052に換装してもいいかと思いました。
アクセルコントロール機能は当初マイコン側に実装しようと検討しましたが、うまく まとまらなかったのでPC側に実装しました。制御が荒いのですが、無い状態よりも ずっと良くなったのでまあ良しとしました。