みなさん、こんにちは。
今回はHibikino-Musashiのプログラムを支えるソフトウェアを紹介します。
私たちのプログラムは約10,000行ものコードで構成されています。この数字は他のプロジェクトと比較してそれほど多いものはありません。2009年の世界大会優勝チームは10万行あると言っていましたので、むしろ少ない方でしょう。
プログラムは全部フルスクラッチ、というわけではありません。コードの量を減らすために画像処理や通信といったものを全て外部ライブラリに任せています。
・OpenCV
Intelの画像処理ライブラリです。Intel製CPU環境で高速に動作します。
・CMU 1394 Digital Camera
カーネギーメロン大学が作った1394カメラのドライバ&ライブラリです。
・Open Dynamics Engine (ODE)
オープンソースの物理エンジンです。シミュレータに使われています。
・DrawStuff2(自作)
ODE付属の描画ライブラリを高機能化した上位互換ライブラリです。
・Musashi Framework(自作)
Hibikino-Musashiオリジナルライブラリです。基本的な数学関数や、タイマー、
シリアル通信、UDP、Wiiリモコン等プログラムの中核となるライブラリです。
Musashi Frameworkには、主にロボットを動かす際に必要となる関数が入っていますが、前回紹介したスプラッシュスクリーンや、Wiiリモコンなど、ロボカップとは関係ないものもたくさん実装されています。プログラマの遊び心がうかがえますね。
このように、私たちのプログラムは、いろいろなソフトウェアによって成り立っています。
1週間にわたってお送りしてきました「Hibikino-Musashiのプログラム」はいかがでしたか?
ロボットに興味がある、ロボカップをやってみたい、という方はいつでも大歓迎です。
一緒に世界を目指しましょう!
2009/12/07
2009/12/06
Hibikino-Musashiのプログラム(6)
こんにちは。
今回はプログラムの「デザイン」についてお話しします。
見た目の良さは重要ですね。
Hibikino-Musashiプログラムのソースコードも見やすさ、わかりやすさを重視した設計になっており、コメントも丁寧に書かれてあります。
アイコンの話は以前、出てきましたね。
実行ファイルにはバージョン情報や著作権情報がこっそり組み込まれてあります(メンバー内でもこれを知っている人は少数です)。
デバッグ中の画面もウィンドウを整列させるなどして、見やすさを向上させています。
こちらはプログラム起動時のスプラッシュ画面。
ロボカップらしくないオシャレなデザイン。
これがフェードしながら表示されます。
こうしたムダ機能もHibikino-Musashiプログラムの特徴の一つです。
今回はプログラムの「デザイン」についてお話しします。
見た目の良さは重要ですね。
Hibikino-Musashiプログラムのソースコードも見やすさ、わかりやすさを重視した設計になっており、コメントも丁寧に書かれてあります。
アイコンの話は以前、出てきましたね。
実行ファイルにはバージョン情報や著作権情報がこっそり組み込まれてあります(メンバー内でもこれを知っている人は少数です)。
デバッグ中の画面もウィンドウを整列させるなどして、見やすさを向上させています。
こちらはプログラム起動時のスプラッシュ画面。
ロボカップらしくないオシャレなデザイン。
これがフェードしながら表示されます。
こうしたムダ機能もHibikino-Musashiプログラムの特徴の一つです。
2009/12/05
Hibikino-Musashiのプログラム(5)
こんにちは。
今回は「シミュレータ」についてお話しします。
もともとシミュレータは実機プログラムとは別のプロジェクトとして進められていましたが、'09年の大阪大会から統合されました。
今では行動プログラムのデバッグに欠かせないツールとなっています。
シミュレータの動力学計算には、オープンソースの物理エンジンであるOpen Dynamics Engineを使っています。
ODEはきわめて高速に動作するので、多数の物体を動作させるのに向いています。
さらに、ODE付属の3D描画ライブラリを新しく書き直し、全画面表示や、サウンド再生、ジョイスティックのサポートなど、ムダに高機能化しています。詳細はこちら。
カメラの挙動も凝っており、ちょっとしたゲームの様な作りになっています。
いつか公開できれば、と思います。
今回は「シミュレータ」についてお話しします。
もともとシミュレータは実機プログラムとは別のプロジェクトとして進められていましたが、'09年の大阪大会から統合されました。
今では行動プログラムのデバッグに欠かせないツールとなっています。
シミュレータの動力学計算には、オープンソースの物理エンジンであるOpen Dynamics Engineを使っています。
ODEはきわめて高速に動作するので、多数の物体を動作させるのに向いています。
さらに、ODE付属の3D描画ライブラリを新しく書き直し、全画面表示や、サウンド再生、ジョイスティックのサポートなど、ムダに高機能化しています。詳細はこちら。
カメラの挙動も凝っており、ちょっとしたゲームの様な作りになっています。
いつか公開できれば、と思います。
2009/12/04
Hibikino-Musashiのプログラム(4)
こんにちは。
今回はロボットの「通信」についてお話しします。
ロボカップでは、無線LANによるロボット間通信を行うことが出来ます。
主にIEEE802.11aと11bが使われています。11nを使ってるチームはまだ見たことがありません。
Hibikino-Musashiは電波干渉の少ない11aを使っています。
Bluetoothも時々使いますね。Wiiリモコンで動かすデモを行う時とかに。試合中は使ってはいけないことになっていますので、エキシビションマッチの時にこっそりやっています(笑)
さて、ロボット間通信のプロトコルには、よく耳にするTCPではなく、UDP(User Datagram Protocol)を使っています。
TCPが通信の信頼性を重視しているのに対し、UDPは通信速度を重視しています。
ロボット達は、お互いに自己位置やボール情報を共有し、「誰が一番ボールに近いのか」や「誰がディフェンスに回るか」といった事を自分で考えます。
UDP通信の実装はWinSock2で行っていますが、コードを簡略化するために、一連の処理をまとめたオリジナルライブラリを今回新たに作成しました。
このライブラリについては、また今度紹介します。
次回は「シミュレータ」についてお送りします。
今回はロボットの「通信」についてお話しします。
ロボカップでは、無線LANによるロボット間通信を行うことが出来ます。
主にIEEE802.11aと11bが使われています。11nを使ってるチームはまだ見たことがありません。
Hibikino-Musashiは電波干渉の少ない11aを使っています。
Bluetoothも時々使いますね。Wiiリモコンで動かすデモを行う時とかに。試合中は使ってはいけないことになっていますので、エキシビションマッチの時にこっそりやっています(笑)
さて、ロボット間通信のプロトコルには、よく耳にするTCPではなく、UDP(User Datagram Protocol)を使っています。
TCPが通信の信頼性を重視しているのに対し、UDPは通信速度を重視しています。
ロボット達は、お互いに自己位置やボール情報を共有し、「誰が一番ボールに近いのか」や「誰がディフェンスに回るか」といった事を自分で考えます。
UDP通信の実装はWinSock2で行っていますが、コードを簡略化するために、一連の処理をまとめたオリジナルライブラリを今回新たに作成しました。
このライブラリについては、また今度紹介します。
次回は「シミュレータ」についてお送りします。
2009/12/03
Hibikino-Musashiのプログラム(3)
こんにちは。
今回は「画像処理」についてお話しします。
ロボットの頭には全方位カメラが取り付けられています。
カメラはSONY製のDFW-VL500です。
また、カメラの性能を最大限に引き出すため、ドライバはCMU 1394 Digital Camera Driverを使っています。
画像処理にはOpenCVというライブラリを使っています。
画像処理は「画像取得スレッド」と「画像処理スレッド」に分かれています。
最近流行のマルチスレッドで動いているんですね~。
画像取得スレッドでは、
・データの読み出し
・240×240にトリミング
・色変換(YUVとHSV)& 色抽出
画像処理スレッドでは、
・ボール検出
・自己位置推定
・障害物検出
といった処理を行っています。
中型リーグでは自己位置推定が大きな課題となっており、多くのチームが「パーティクルフィルタ」を用いた手法を採用しています。
OpenCVではパーティクルフィルタは「Condensation」という形で実装されています。パーティクルフィルタって何?という方はこちらをどうぞ(英語サイトです)。
検出した白線情報を元に、パーティクルフィルタによって自己位置を求めます。
↓こんな感じ
画像処理は行動に比べて専門性が高いです。
ですが、わかるようになれば、これほど面白いものはありません。「あれをやってみよう!」「こういうのはどうか?」など、考えを巡らせるのが楽しくなっていきます。
次回は「通信」についてお送りします。
今回は「画像処理」についてお話しします。
ロボットの頭には全方位カメラが取り付けられています。
カメラはSONY製のDFW-VL500です。
また、カメラの性能を最大限に引き出すため、ドライバはCMU 1394 Digital Camera Driverを使っています。
画像処理にはOpenCVというライブラリを使っています。
画像処理は「画像取得スレッド」と「画像処理スレッド」に分かれています。
最近流行のマルチスレッドで動いているんですね~。
画像取得スレッドでは、
・データの読み出し
・240×240にトリミング
・色変換(YUVとHSV)& 色抽出
画像処理スレッドでは、
・ボール検出
・自己位置推定
・障害物検出
といった処理を行っています。
中型リーグでは自己位置推定が大きな課題となっており、多くのチームが「パーティクルフィルタ」を用いた手法を採用しています。
OpenCVではパーティクルフィルタは「Condensation」という形で実装されています。パーティクルフィルタって何?という方はこちらをどうぞ(英語サイトです)。
検出した白線情報を元に、パーティクルフィルタによって自己位置を求めます。
↓こんな感じ
画像処理は行動に比べて専門性が高いです。
ですが、わかるようになれば、これほど面白いものはありません。「あれをやってみよう!」「こういうのはどうか?」など、考えを巡らせるのが楽しくなっていきます。
次回は「通信」についてお送りします。
2009/12/02
Hibikino-Musashiのプログラム(2)
こんにちは。
今回は行動プログラムについてお話しします。
ロボットの「行動」とは、ボールを取りに行ったり、シュートしたりすることを指します。
Hibikino-Musashiのプログラムでは、
1.行動選択
2.行動実行
3.下位制御
といった流れでロボットを動かしています。
1.行動選択では、「キックオフ」の信号が来たら何をする や、フォワードやディフェンダーといったロール(役割)を決める といった処理を行います。
2.行動実行では、具体的にどういう動きをすればよいかを計算して、目標速度や進行方向などを算出します。
3.下位制御では、モーターを回したり、方位センサやエンコーダからのデータを読み出します。
行動プログラムで重要なのが、「ボールを取る動作」と「ボールを運ぶ動作」です。これらに関しては、ポテンシャル関数を使って軌道生成をしたり、他チームの論文を参考にしてファジー制御を取り入れたりしています。
ちなみに、前回の動画ではポテンシャル法で動きを作っています。
ボールの相対距離・角度と、ゴールの相対角度を用いて、
↓このような式を作ります(aは正の定数、Vminはロボットの最低速度)。
Omegaが角速度、Angleが進行方向、Velocityが速度ですので、ロボットはゴールの方向を向きつつボールとゴールが一直線に並ぶような位置に緩やかに減速しながら移動します。
いかがでしたでしょうか?
行動プログラムでは、この他にも回転行列を使ったロボットのポジショニングなど、面白いコードを見ることが出来ます。
基本的に使われているのは高校レベルの数学ですので、そこまで難しくはありませんよ。
次回は「画像処理」についてお送りします。
今回は行動プログラムについてお話しします。
ロボットの「行動」とは、ボールを取りに行ったり、シュートしたりすることを指します。
Hibikino-Musashiのプログラムでは、
1.行動選択
2.行動実行
3.下位制御
といった流れでロボットを動かしています。
1.行動選択では、「キックオフ」の信号が来たら何をする や、フォワードやディフェンダーといったロール(役割)を決める といった処理を行います。
2.行動実行では、具体的にどういう動きをすればよいかを計算して、目標速度や進行方向などを算出します。
3.下位制御では、モーターを回したり、方位センサやエンコーダからのデータを読み出します。
行動プログラムで重要なのが、「ボールを取る動作」と「ボールを運ぶ動作」です。これらに関しては、ポテンシャル関数を使って軌道生成をしたり、他チームの論文を参考にしてファジー制御を取り入れたりしています。
ちなみに、前回の動画ではポテンシャル法で動きを作っています。
ボールの相対距離・角度と、ゴールの相対角度を用いて、
↓このような式を作ります(aは正の定数、Vminはロボットの最低速度)。
Omegaが角速度、Angleが進行方向、Velocityが速度ですので、ロボットはゴールの方向を向きつつボールとゴールが一直線に並ぶような位置に緩やかに減速しながら移動します。
いかがでしたでしょうか?
行動プログラムでは、この他にも回転行列を使ったロボットのポジショニングなど、面白いコードを見ることが出来ます。
基本的に使われているのは高校レベルの数学ですので、そこまで難しくはありませんよ。
次回は「画像処理」についてお送りします。
2009/12/01
Hibikino-Musashiのプログラム(1)
みなさん、こんにちは。
先月の「ひびきの祭」デモは大盛況のうちに終了しました。
ご来場いただいた皆さま、本当にありがとうございました。
さて、当ブログでは、これまでHibikino-Musashiのロボットの活躍やデモの様子などをお送りしてきましたが、
「ロボットって どうやって動いているの?」
「プログラムってなに?」
と、興味を持ってくださった方もきっと多いことと思います。
そこで今回はロボットのプログラムについてご紹介します。
まずはこちらの動画をご覧下さい。
ロボットの中心にはノートPCが入っています。
私たちは、このノートPCにプログラムを入れてロボットを動かしています。
プログラムは大体10,000行ぐらいですね。言語はC++です。
内容は大きく分けると、
・行動
・画像処理
・通信
・シミュレータ
の4つです。ソフト班メンバーが分担して作っています。
今日から1週間にわたって、Hibikino-Musashiのプログラムを紹介していきます。
次回は「行動」プログラムについてお送りします。
先月の「ひびきの祭」デモは大盛況のうちに終了しました。
ご来場いただいた皆さま、本当にありがとうございました。
さて、当ブログでは、これまでHibikino-Musashiのロボットの活躍やデモの様子などをお送りしてきましたが、
「ロボットって どうやって動いているの?」
「プログラムってなに?」
と、興味を持ってくださった方もきっと多いことと思います。
そこで今回はロボットのプログラムについてご紹介します。
まずはこちらの動画をご覧下さい。
ロボットの中心にはノートPCが入っています。
私たちは、このノートPCにプログラムを入れてロボットを動かしています。
プログラムは大体10,000行ぐらいですね。言語はC++です。
内容は大きく分けると、
・行動
・画像処理
・通信
・シミュレータ
の4つです。ソフト班メンバーが分担して作っています。
今日から1週間にわたって、Hibikino-Musashiのプログラムを紹介していきます。
次回は「行動」プログラムについてお送りします。
2009/11/08
ひびきの祭(2)
2009/11/07
ひびきの祭(1)
2009/10/04
2009/09/19
アイコン
2009/09/03
2009/08/09
Drawstuff開発報告(4)
2009/08/05
新Drawstuff β版できました
こんばんは、ソフト班Shinpukuです。
とりあえずベータ版ができました。
Windows7 RCでも動きます(笑)
更新
・GetKeyState()っぽい関数を実装
・テクスチャ(.ppm)実装
・球、円柱、カプセル、線の描画を実装
・ポリゴン(Trimesh、Convex)の描画を実装
・FPS表示
・マウスホイールの動きに対応
・ライブラリをDLL化
TODO
・文字描画関数の実装
・三角メッシュ(.x)読み込み関数の実装
・BMPテクスチャの実装
・ジョイスティック実装
・サウンド再生実装
2009/07/26
Drawstuff開発報告(3)
ソフト班Shinpukuです。
新Drawstuffの開発が早くもピンチになりました。
テクスチャです。
真っ白(笑)。
いや、Windows環境だから、
HBITMAP hBmp = (HBITMAP)LoadImage(NULL, filename, IMAGE_BITMAP, 0, 0, LR_LOADFROMFILE);
BITMAP bmp;
GetObject(hBmp, sizeof(BITMAP), &bmp);
こんな感じにWindowsのAPIでビットマップ読み込んで、後はテキトーにglTexImage2Dにデータ渡して終わりっ!・・・と思ってたんですよ。
どうも うまく動かないようです。
あっ、ちなみに以前の方法(ppm読み込むやつ)はうまくいきました。
う~ん、どうしよう・・・。
2009/07/25
2009/07/24
2009/07/22
シミュレータの話
こんにちは、ソフト班Shinpukuです。
現在HPで公開されているシミュレータは結構、昔のものです。
とりあえず、今週からHibikino-Musashiも互換ライブラリの開発をスタートします。
最新版は実機プログラムに統合されています。
これは統合される前の最後のバージョンです。
剛体の動力学計算にODE(Open Dynamics Engine)を、グラフィックの描画にSDL(Simple Direct-media Layer)を用いて作りました。
フルスクリーン切り替えやジョイスティック操作に対応しています。
ODE付属のdrawstuffは扱いやすいのですが、機能が少ないので少し不満です。Alt+F4や×押しても終了できない致命的なバグもあります。
出村先生も互換ライブラリを開発しているみたいですし、自分で書いてみるのもいいと思います。
とりあえず、今週からHibikino-Musashiも互換ライブラリの開発をスタートします。
2009/07/15
RoboCup 2009 GRAZ-AUSTRIA
2009/05/27
RoboCup JapanOpen 2009 Osaka
2009/04/02
春ですか?いいえ、それはペンです。
おはようございます!
ゴーリー担当 yamadaでございます。
今日、パスポートを申請しました。
(住民票こっちにないので、居所申請。めんどくさかったです。)
世界大会に向けて、準備ということですが、
「がんばった人だけ連れて行く」という今年の方針から、
まだまだ、オーストリアに行くにはがんばらないといけないところですね。
最近、めっきり春めいて、
着るものも、一枚また一枚と薄くなっていきますね。
うれしいところです。(なにが!?アレか?!)
さてゴーリーさんのご機嫌を伺いに、また作業に戻りましょうか。
ではまた、御機嫌よう。。。
ゴーリー担当 yamadaでございます。
今日、パスポートを申請しました。
(住民票こっちにないので、居所申請。めんどくさかったです。)
世界大会に向けて、準備ということですが、
「がんばった人だけ連れて行く」という今年の方針から、
まだまだ、オーストリアに行くにはがんばらないといけないところですね。
最近、めっきり春めいて、
着るものも、一枚また一枚と薄くなっていきますね。
うれしいところです。(なにが!?アレか?!)
さてゴーリーさんのご機嫌を伺いに、また作業に戻りましょうか。
ではまた、御機嫌よう。。。
2009/03/29
ロボティクスTOWN小倉(2)
こんにちは、ソフト班Shinpukuです。
今日は「ロボティクスTOWN小倉」の2日目です。
今日は昨日より多くの人が来場されました。
メンバーの皆さんも調整に慣れてきたみたいで、この日はロボットが前日以上に良い動きをしてくれました。
会場では僕たちのデモの他にもマサノヴァ・アートやロボスクエアの展示も行われていました。
これは「i-SOBOT」のデモの様子です。
デモ中によく転倒していましたが、あの大きさでヒューマノイドを実現できているのには驚きでした。
こちらは「プレオ」という恐竜型ロボットです。
パッと見、オモチャですが、中身はセンサの塊です。
さらに、学習機能を搭載しており、進化するロボットなのだそうです。凄いッ!
プレオの隣には「パロ」がいました。
カメラを向けたらこっちを見ました。
かわいい。
・・・おっと、そろそろ作業に戻らねば。
忙しくて大変でしたが、たくさんの人に喜んでもらい、とても楽しい2日間でした。
まぁ、デモ中のウラ話もあるのですが、長くなるので今回はこの辺で。
今日は「ロボティクスTOWN小倉」の2日目です。
今日は昨日より多くの人が来場されました。
メンバーの皆さんも調整に慣れてきたみたいで、この日はロボットが前日以上に良い動きをしてくれました。
会場では僕たちのデモの他にもマサノヴァ・アートやロボスクエアの展示も行われていました。
これは「i-SOBOT」のデモの様子です。
デモ中によく転倒していましたが、あの大きさでヒューマノイドを実現できているのには驚きでした。
こちらは「プレオ」という恐竜型ロボットです。
パッと見、オモチャですが、中身はセンサの塊です。
さらに、学習機能を搭載しており、進化するロボットなのだそうです。凄いッ!
プレオの隣には「パロ」がいました。
カメラを向けたらこっちを見ました。
かわいい。
・・・おっと、そろそろ作業に戻らねば。
忙しくて大変でしたが、たくさんの人に喜んでもらい、とても楽しい2日間でした。
まぁ、デモ中のウラ話もあるのですが、長くなるので今回はこの辺で。
2009/03/28
ロボティクスTOWN小倉(1)
こんにちは、ソフト班Shinpukuです。
3月28日・29日の2日間で、JR小倉駅、リバーウォーク北九州、小倉井筒屋、勝山公園の4会場で「ロボティクスTOWN小倉」と題して、全国から集まったロボットの体験イベントが開催されます。
僕たちHibikino-Musashiはリバーウォーク北九州でデモを行います。
で、今日はその1日目です。
野外です。ロボットには厳しい環境です。
まぁ、日照の変化にさえ気を付けていれば大丈夫でしょう。
さて、デモ開始です。
上の写真はPKデモの様子です。
寒い中、たくさんの人が来て下さいました。
明日も引き続きリバーウォーク北九州にてデモを行いますので、興味のある方は是非いらしてくださいね。
3月28日・29日の2日間で、JR小倉駅、リバーウォーク北九州、小倉井筒屋、勝山公園の4会場で「ロボティクスTOWN小倉」と題して、全国から集まったロボットの体験イベントが開催されます。
僕たちHibikino-Musashiはリバーウォーク北九州でデモを行います。
で、今日はその1日目です。
野外です。ロボットには厳しい環境です。
まぁ、日照の変化にさえ気を付けていれば大丈夫でしょう。
さて、デモ開始です。
上の写真はPKデモの様子です。
寒い中、たくさんの人が来て下さいました。
明日も引き続きリバーウォーク北九州にてデモを行いますので、興味のある方は是非いらしてくださいね。
2009/03/14
ZMP研修
こんにちは、ソフト班Shinpukuです。
先日、(株)ZMP の「nuvoソースコード公開プログラム」に行ってきました。
今回は研修レポートといった感じです。
オフィスに入ると早速PINOがお出迎え。
こちらは音楽ロボットの「miuro」
そして、こちらが今回の研修で使う「nuvo」です。
今回の研修では、nuvoの分解・組立や、歩行調整の他にも、nuvo上で動くプログラムの作成などを行いました。
社長の谷口さんは気さくな方で、研修の合間に差し入れをいただいたり、ロボカップの話で盛り上がったりしました。
ヒューマノイドの技術的なこともわかり、とても為になる研修でした。
先日、(株)ZMP の「nuvoソースコード公開プログラム」に行ってきました。
今回は研修レポートといった感じです。
オフィスに入ると早速PINOがお出迎え。
こちらは音楽ロボットの「miuro」
そして、こちらが今回の研修で使う「nuvo」です。
今回の研修では、nuvoの分解・組立や、歩行調整の他にも、nuvo上で動くプログラムの作成などを行いました。
社長の谷口さんは気さくな方で、研修の合間に差し入れをいただいたり、ロボカップの話で盛り上がったりしました。
ヒューマノイドの技術的なこともわかり、とても為になる研修でした。
2009/02/13
距離校正はつらいよ(8)
2009/02/12
距離校正はつらいよ(7)
こんにちは、ソフト班Shinpukuです。
まずは下のグラフを見てください。赤が指数近似、青が多項式近似です。
指数近似は距離が離れるにしたがって誤差が大きくなっていくのに対し、多項式近似では遠距離でも安定して近似できています。精度もなかなかのものです。
でも、ちょっと待ってください。
多項式近似の近距離部分、中心からのピクセル数で言うと25ピクセルより前の部分です。
ピクセル数が小さくなっているのにも関わらず、距離が大きくなっています。
ここなんですよ、多項式近似の怖いところは。
この改善についてはいろいろ考えました。
例えば「近・中距離は指数、遠距離は多項式」とか、「指数と多項式の平均」とか。
ですが、どれも理想的な形にならないんですよ。書くコードの量も無駄に増えてしまいうわけですし。
そこでですね、見えない部分にダミーデータを配置するようにしました。さらに、6次多項式にして精度を上げます。
最終的な結果はコチラ↓
す ば ら し い。
キレイな近似曲線が出ています。
コレいけんるんじゃないですか?
まずは下のグラフを見てください。赤が指数近似、青が多項式近似です。
指数近似は距離が離れるにしたがって誤差が大きくなっていくのに対し、多項式近似では遠距離でも安定して近似できています。精度もなかなかのものです。
でも、ちょっと待ってください。
多項式近似の近距離部分、中心からのピクセル数で言うと25ピクセルより前の部分です。
ピクセル数が小さくなっているのにも関わらず、距離が大きくなっています。
ここなんですよ、多項式近似の怖いところは。
この改善についてはいろいろ考えました。
例えば「近・中距離は指数、遠距離は多項式」とか、「指数と多項式の平均」とか。
ですが、どれも理想的な形にならないんですよ。書くコードの量も無駄に増えてしまいうわけですし。
そこでですね、見えない部分にダミーデータを配置するようにしました。さらに、6次多項式にして精度を上げます。
最終的な結果はコチラ↓
す ば ら し い。
キレイな近似曲線が出ています。
コレいけんるんじゃないですか?
2009/02/11
距離校正はつらいよ(6)
こんにちは、ソフト班Shinpukuです。
ここを参考にして作った「n次多項式近似のプログラム」です。
const int num = 16;
double distance[num] = {0.3, 0.4, 0.5, 0.6, 0.7, 0.8, 0.9, 1.0, 1.5, 2.0, 2.5, 3.0, 3.5, 4.0, 4.5, 5.0, 5.5};
double pixels[num] = { 21, 27, 31, 37, 42, 44, 46, 50, 62, 68, 74, 76, 80, 82, 84, 84, 86};
// n次多項式近似 ///////////////////////////////////////////////////////
const int N = 5; // N-1次の多項式近似
double x[N];
double a[N][N+1];
double b[1][N+1];
for (int i = 0; i < N; i++) {
for (int j = 0; j < N + 1; j++) {
a[i][j] = 0.0;
}
}
for (int i = 0; i < N; i++) {
for (int j = 0; j < N; j++) {
for (int k = 0; k < num; k++) {
a[i][j] += pow((double)pixels[k], (double)(i + j));
}
}
}
for (int i = 0; i < N; i++) {
for (int j = 0; j < num; j++) {
a[i][N] += pow((double)pixels[j], (double)i) * distance[j];
}
}
for (int i = 0; i < N; i++) {
double m = 0;
int pivot = i;
for (int j = i; j < N; j++) {
if (fabs(a[j][i]) > m) {
m = fabs(a[j][i]);
pivot = j;
}
}
if (pivot != i) {
for(int j = 0; j < N+1; j++) {
b[0][j] = a[i][j];
a[i][j] = a[pivot][j];
a[pivot][j] = b[0][j];
}
}
}
for (int k = 0; k < N; k++) {
double p = a[k][k];
a[k][k] = 1;
for (int j = k+1; j < N+1; j++) a[k][j] /= p;
for (int i = k+1; i < N; i++) {
double q = a[i][k];
for (int j = k+1; j < N+1; j++) a[i][j] -= q*a[k][j];
a[i][k] = 0;
}
}
for (int i = N-1; i >= 0; i--) {
x[i] = a[i][N];
for (int j = N-1; j > i; j--) x[i] -= a[i][j]*x[j];
}
//////////////////////////////////////////////////////////////////////
これで、
r = 中心からのピクセル数
y = x[4]*r*r*r*r+ x[3]*r*r*r+ x[2]*r*r+ x[1]*r+ x[0];
で距離yがでます。
ここを参考にして作った「n次多項式近似のプログラム」です。
const int num = 16;
double distance[num] = {0.3, 0.4, 0.5, 0.6, 0.7, 0.8, 0.9, 1.0, 1.5, 2.0, 2.5, 3.0, 3.5, 4.0, 4.5, 5.0, 5.5};
double pixels[num] = { 21, 27, 31, 37, 42, 44, 46, 50, 62, 68, 74, 76, 80, 82, 84, 84, 86};
// n次多項式近似 ///////////////////////////////////////////////////////
const int N = 5; // N-1次の多項式近似
double x[N];
double a[N][N+1];
double b[1][N+1];
for (int i = 0; i < N; i++) {
for (int j = 0; j < N + 1; j++) {
a[i][j] = 0.0;
}
}
for (int i = 0; i < N; i++) {
for (int j = 0; j < N; j++) {
for (int k = 0; k < num; k++) {
a[i][j] += pow((double)pixels[k], (double)(i + j));
}
}
}
for (int i = 0; i < N; i++) {
for (int j = 0; j < num; j++) {
a[i][N] += pow((double)pixels[j], (double)i) * distance[j];
}
}
for (int i = 0; i < N; i++) {
double m = 0;
int pivot = i;
for (int j = i; j < N; j++) {
if (fabs(a[j][i]) > m) {
m = fabs(a[j][i]);
pivot = j;
}
}
if (pivot != i) {
for(int j = 0; j < N+1; j++) {
b[0][j] = a[i][j];
a[i][j] = a[pivot][j];
a[pivot][j] = b[0][j];
}
}
}
for (int k = 0; k < N; k++) {
double p = a[k][k];
a[k][k] = 1;
for (int j = k+1; j < N+1; j++) a[k][j] /= p;
for (int i = k+1; i < N; i++) {
double q = a[i][k];
for (int j = k+1; j < N+1; j++) a[i][j] -= q*a[k][j];
a[i][k] = 0;
}
}
for (int i = N-1; i >= 0; i--) {
x[i] = a[i][N];
for (int j = N-1; j > i; j--) x[i] -= a[i][j]*x[j];
}
//////////////////////////////////////////////////////////////////////
これで、
r = 中心からのピクセル数
y = x[4]*r*r*r*r+ x[3]*r*r*r+ x[2]*r*r+ x[1]*r+ x[0];
で距離yがでます。
2009/02/10
距離校正はつらいよ(5)
こんにちは、ソフト班Shinpukuです。
まだ距離校正しています。
先日の実験の失敗は、
1. サンプル数が少なかった
2. サンプルを採る位置が悪かった
3. ロボットの位置が悪かった
4. そもそも指数近似の問題ではなかった
なのだと思います。
まずは1.と2.について。
サンプル数を78個。0.3m~8.0mを0.1m間隔で採って見ました。
あれ?サンプル少ない時とあまり変わりませんね。
やはり距離が離れるに従って、距離精度が落ちています。
これは仕方がないことなのでしょう。
次は3.についてです。
試行錯誤の結果、ロボットの前方(少し凹んでいる所)にメジャーの9cmを合わせて距離校正を行うと、自己位置がちゃんと出るようになりました。
「自己位置」っていきなり出てきましたけど、これはアレですよ。ロボットの座標です。
距離校正の最終的な目標というのは、ボールの距離がどうのというではなく、白線の距離を正確に求めることなのです。
そういう意味では指数近似では力不足といったところです。
そこで4.なのですよ。
これについては・・・禁断のn次多項式を使うしかありません。
できればこれは使いたくなかった・・・!
理由は後ほど。
まだ距離校正しています。
先日の実験の失敗は、
1. サンプル数が少なかった
2. サンプルを採る位置が悪かった
3. ロボットの位置が悪かった
4. そもそも指数近似の問題ではなかった
なのだと思います。
まずは1.と2.について。
サンプル数を78個。0.3m~8.0mを0.1m間隔で採って見ました。
あれ?サンプル少ない時とあまり変わりませんね。
やはり距離が離れるに従って、距離精度が落ちています。
これは仕方がないことなのでしょう。
次は3.についてです。
試行錯誤の結果、ロボットの前方(少し凹んでいる所)にメジャーの9cmを合わせて距離校正を行うと、自己位置がちゃんと出るようになりました。
「自己位置」っていきなり出てきましたけど、これはアレですよ。ロボットの座標です。
距離校正の最終的な目標というのは、ボールの距離がどうのというではなく、白線の距離を正確に求めることなのです。
そういう意味では指数近似では力不足といったところです。
そこで4.なのですよ。
これについては・・・禁断のn次多項式を使うしかありません。
できればこれは使いたくなかった・・・!
理由は後ほど。
2009/02/09
距離校正はつらいよ(4)
こんばんは、ソフト班Shinpukuです。
今日は指数近似を用いた距離校正プログラムの実験です。
でも、その前に・・・
ロボットのカメラが少し傾いていたので、機械班の人に直してもらいました。
さて、距離校正の実験です。
前回と同じく16サンプル採って、理論値と比較してみました。
図中のピンクが距離校正用サンプルで、これを元に近似式を作っています。
その上で、2回目の計測を行ったのが青の点です。
1.0m~3.5mはうまく出ています。
近距離と遠距離がイマイチです。
近距離の精度が悪いのは計測方法が間違っていたのでしょうか?
まぁ、これは何とかなるでしょう。
問題は遠距離です。
誤差0.8mって何ですか?
ていうか遠距離はムリですよ。
解像度240×240ですよ。
ムチャ言わないで下さいよ。
今日は指数近似を用いた距離校正プログラムの実験です。
でも、その前に・・・
ロボットのカメラが少し傾いていたので、機械班の人に直してもらいました。
さて、距離校正の実験です。
前回と同じく16サンプル採って、理論値と比較してみました。
図中のピンクが距離校正用サンプルで、これを元に近似式を作っています。
その上で、2回目の計測を行ったのが青の点です。
1.0m~3.5mはうまく出ています。
近距離と遠距離がイマイチです。
近距離の精度が悪いのは計測方法が間違っていたのでしょうか?
まぁ、これは何とかなるでしょう。
問題は遠距離です。
誤差0.8mって何ですか?
ていうか遠距離はムリですよ。
解像度240×240ですよ。
ムチャ言わないで下さいよ。
2009/02/08
距離校正はつらいよ(3)
こんにちは、ソフト班Shinpukuです。
指数近似のプログラム書きましたよ。
#include <stdio.h>
#include <math.h>
#define DATA_NUM 17
int main(void)
{
//距離
double distance[DATA_NUM] = {0.3, 0.4, 0.5, 0.6, 0.7, 0.8, 0.9, 1.0, 1.5,
2.0, 2.5, 3.0, 3.5, 4.0, 4.5, 5.0, 5.5};
// 中心からのピクセル数
double pixels[DATA_NUM] = {21, 27, 31, 37, 42, 44, 46, 50, 62, 68, 74,
76, 80, 82, 84, 84, 86};
double X[DATA_NUM], Y[DATA_NUM];
double sumX, sumX2;
double sumY, sumXY;
// XとY初期化
for (int i = 0; i < DATA_NUM; i++) {
X[i] = pixels[i];
Y[i] = log(distance[i]);
}
// Σたち
sumX = sumX2 = sumY = sumXY = 0;
for (int i = 0; i < DATA_NUM; i++) {
sumX += X[i];
sumX2 += X[i]*X[i];
sumY += Y[i];
sumXY += X[i]*Y[i];
}
// 最小2乗計算
double A1 = (sumX*sumY - DATA_NUM*sumXY)/
(sumX*sumX - DATA_NUM*sumX2);
double A0 = (-sumX2*sumY + sumX*sumXY)/
(sumX*sumX - DATA_NUM*sumX2);
double alpha = exp(A0);
double beta = A1;
printf("alpha = %f\n", alpha);
printf("beta = %f\n", beta);
return 0;
}
α=0.122702
β=0.042482
と出て、
x=中心からのピクセル数
y = α * exp(β * x)
で距離yが出ます。
指数近似のプログラム書きましたよ。
#include <stdio.h>
#include <math.h>
#define DATA_NUM 17
int main(void)
{
//距離
double distance[DATA_NUM] = {0.3, 0.4, 0.5, 0.6, 0.7, 0.8, 0.9, 1.0, 1.5,
2.0, 2.5, 3.0, 3.5, 4.0, 4.5, 5.0, 5.5};
// 中心からのピクセル数
double pixels[DATA_NUM] = {21, 27, 31, 37, 42, 44, 46, 50, 62, 68, 74,
76, 80, 82, 84, 84, 86};
double X[DATA_NUM], Y[DATA_NUM];
double sumX, sumX2;
double sumY, sumXY;
// XとY初期化
for (int i = 0; i < DATA_NUM; i++) {
X[i] = pixels[i];
Y[i] = log(distance[i]);
}
// Σたち
sumX = sumX2 = sumY = sumXY = 0;
for (int i = 0; i < DATA_NUM; i++) {
sumX += X[i];
sumX2 += X[i]*X[i];
sumY += Y[i];
sumXY += X[i]*Y[i];
}
// 最小2乗計算
double A1 = (sumX*sumY - DATA_NUM*sumXY)/
(sumX*sumX - DATA_NUM*sumX2);
double A0 = (-sumX2*sumY + sumX*sumXY)/
(sumX*sumX - DATA_NUM*sumX2);
double alpha = exp(A0);
double beta = A1;
printf("alpha = %f\n", alpha);
printf("beta = %f\n", beta);
return 0;
}
α=0.122702
β=0.042482
と出て、
x=中心からのピクセル数
y = α * exp(β * x)
で距離yが出ます。
2009/02/07
距離校正はつらいよ(2)
こんにちは、ソフト班Shinpukuです。
距離校正の話の続きです。
具体的にどうやって距離を算出するかといいますと、ボール等を用いて、「中心から○○ピクセルの位置は△△メートル」というデータを複数回をサンプリングして近似式を作り、それとカメラ画像を照らし合わせているのです。
こんな感じに↓
以前は職人の手によって調整されていたようです。
しかし、それでは試合に間に合わないので、距離校正の単純化が求められるようになりました。
「サンプル数が少なくても高精度」というやつですか。
夢のような距離校正プログラムですね。
試しにデータを採って見ましょう。
16サンプル採って、Excelに近似曲線を出してもらいました。
指数近似がイイ感じです。
やるじゃないか、Excel。
距離校正の話の続きです。
具体的にどうやって距離を算出するかといいますと、ボール等を用いて、「中心から○○ピクセルの位置は△△メートル」というデータを複数回をサンプリングして近似式を作り、それとカメラ画像を照らし合わせているのです。
こんな感じに↓
以前は職人の手によって調整されていたようです。
しかし、それでは試合に間に合わないので、距離校正の単純化が求められるようになりました。
「サンプル数が少なくても高精度」というやつですか。
夢のような距離校正プログラムですね。
試しにデータを採って見ましょう。
16サンプル採って、Excelに近似曲線を出してもらいました。
指数近似がイイ感じです。
やるじゃないか、Excel。
登録:
投稿 (Atom)