独り言日記(2008/09)
独り言日記
NMEA-0183の緯度経度をGoogleMapにあわせる(2008/09/28)
GPS情報での追加事項です。GoogleMapでは
http://maps.google.co.jp/?ie=UTF8&ll=緯度,経度&z=19
のように「緯度」と「経度」の部分に緯度経度を指定して場所を特定できます。
便利なのとしては、以下のページより緯度経度を指定して地図位置を表示することができます。
http://google-earth-travel.net/maps/
GPSレシーバの「NMEA-0183」形式の場合は、「xx度xx.xx分」という表記ですのでこれを変換する必要があります。
n度m分の場合は「n + (m / 60)」がGoogleMapで言う緯度または経度になります。たとえば、35度44.033798分の場合は、「35 + (44.033798 / 60) = 35.7338966333」となります。
これで緯度経度を計算しなおしてGoogleMapで指定すると、、、おもいっきりどんぴしゃで位置が出てきました。精度すげ〜〜。更新の取得時間は、だいたい1秒間隔くらいですかね。スレッド内のSleep時間を短くしたりしてもあんまり変わらなかったので、たぶんそれくらいが限界なのかも。
GPSのプログラム(2008/09/28)
もうちょっと扱いやすくしました。プロジェクトとソースです。
http://ft-lab.ne.jp/files/program/gps/GPSTest_src_20080928.zip
main.cppにてアクセス方法を書いてます。受信した文字列を表示する部分と、(今のところ)GGAデータを取得する部分に分かれてます。メインスレッドではこの2つを利用して情報をゲットできます。たぶん、NMEA-0183のプロトコルを採用しているものですと、秋月電子のGPSでなくても使えるかもしれません。
使い方はコマンドラインにて、
gpstest.exe COMポート番号 転送速度
のように入力します。うまくいくと、GPSから取得できた文字列とGGA部分のみ抜き出した結果が表示されます。何かキーを押すと終了です。
で、場所を変えると見事に情報をゲットできました。どうも、少し時間を置いて情報を取得し続けると室外ではうまくいきますね(起動直後はうまく取れない)。室内ではやっぱり衛星数が0になってアウトでした。
測位時刻(UTC) : 08:56:10 緯度(北緯) : xx度xx.xxxx分 経度(東経) : xx度xx.xxxx分 GPSのクオリティ : 1 受信衛星数 : 5 平均海水面からのアンテナ高度 : 12.500000 m
みたいにゲットできました(緯度経度は場所が特定できてしまうといけませんので伏字で)。
この緯度経度が正しく取れているかどうかは、GoogleMapなどで確認してみるとよいかもしれません。今のところ、受信衛星数は8まで取得できてました。これは、実際の地図と照らし合わせてマッピングしたくなるなぁ。
ということで、GPSに関してはこのへんで。いずれにしても応用としていろいろ使えそうではあります。
秋月電子のGPS(2008/09/27)
ちょっと遊びたいことがあったので、USB-GPSを秋月電子で買ってきました。
http://akizukidenshi.com/catalog/items2.php?q=%22M-02556%22&p=1
アイオーデータ製なら2万円くらいするものが8400円です。しかし、相変わらず秋月電子は宝の山ですねぇ。ハードは分からないのですが、ほかにもほしいものがいろいろありました。ジャイロが気になってしまった・・・。
GPSは
http://www.thegpsstick.com/
のものです。通信プロトコルは「NMEA-0183」。38400bps。
GPSに付属しているソフトは日本では使えない、という一般人向けではない仕様ですので、プログラマがいじれるように試行錯誤してみました。以下、VC2005でビルドできるプロジェクトとソースです。コマンドラインにて垂れ流されてくる情報を表示します。
http://ft-lab.ne.jp/files/program/gps/GPSTest_src_20080927.zip
根っこにあるのはCOMとのやりとりですが、
http://futr.cocolog-nifty.com/blog/gpscontrol/index.html
のサイトのを参考にさせてもらいました。GPSアクセス部分は、どうも微妙に異なるので
http://bg66.soc.i.kyoto-u.ac.jp/forestgps/nmea.html
で書かれているNMEA-0183のプロトコルを参考にしつつ自前で解析したほうがよさげです(解析まではしてませんが、パースするだけなので簡単ですよね)。
コマンドラインにて実行するときに、引数にCOMポート番号と転送速度を指定します。COMポート番号は環境によって異なるのでデバイスマネージャにて調べてください。転送速度は、38400固定のようです。
ちと室内環境では当たり前ですが衛星からの受信はできませんので、
$GPGGA,120233.000,0000.0000,N,00000.0000,E,0,00,0.0,0.0,M,0.0,M,,0000*6C $GPGSA,A,1,,,,,,,,,,,,,0.0,0.0,0.0*30 $GPRMC,120233.000,V,0000.0000,N,00000.0000,E,000.0,000.0,280606,,,N*7D $GPVTG,000.0,T,,M,000.0,N,000.0,K,N*02
な感じでデータが取れてません(NMEA-0183の仕様と見比べると、失敗してるのが分かります)。ただ、文字列は流れてきている、かつ時刻情報などは取得できてるので、プログラムとしてはこれで正解かなと。また別の場所でチェックしてみよう。
GPSの場合は、衛星から垂れ流されるデータを「GPSレシーバ」が受信する動きですので、ずっと受信し続けることになります。3衛星以上から情報が得られると位置が推測できるのかな。緯度経度のほかに高さ、衛星情報なども受信できそうです。さてはて、どれくらいの精度があるのか、またレポートしてみることにします。
後、これは想像ではありますが、カーナビみたいに方向を知りたい場合は、緯度経度の差分を取ってそこから割り出すのかなぁと思ってます。でも、RMCに進行方向があるのでそれも使えるのかな?
wxWidgetsを使っているときによくあるdefineでのバッティング(2008/09/22)
wxWidgetsでは、ツリー操作時に「GetFirstChild / GetNextSibling / GetPrevSibling」なる関数があるのですが、WinAPIのヘッダ(windowsx.h)ではこれを#defineで置き換えている部分があります。
windowsx.hでは以下なことをしてます。
#define GetFirstChild(hwnd) GetTopWindow(hwnd)
それで場合によってはコンパイルエラーになるので、
#ifdef GetFirstChild #undef GetFirstChild #endif #ifdef GetNextSibling #undef GetNextSibling #endif #ifdef GetPrevSibling #undef GetPrevSibling #endif
のようにしてdefineを無効化。しかし、このへんはカオスになりやすい部分ですね。よく使う命名はヘタにdefineで置き換えないでほしいなぁと思ったりもします。
wxTreeListCtrl(2008/09/22)
wxWidgetsにて、ツリー(wxTreeCtrl)とリスト(wxListCtrl)をあわせたようなUIがほしいのですが、標準ではこれというのがありません。
で、「wxTreeListCtrl」というのを公開している方がいらっしゃいましたので使ってみることにしました。
http://wxcode.sourceforge.net/
のConponents - Controlをたどるとソースがあります。
日本語もOKですね。
wxTreeCtrlを使った上記の例のソースは以下な感じです。アイコンはリソースのBitmapを割り当ててるだけです。
// parentは親のwxWindow派生クラス、 // (x, y) は表示位置をあらわす wxTreeListCtrl *pTestList = new wxTreeListCtrl(parent, -1, wxPoint(x, y), wxSize(400, 200), wxTR_DEFAULT_STYLE | wxTR_FULL_ROW_HIGHLIGHT); // ツリーアイコンをリソースより読み込み (16x16 pixel) wxImageList *pImgList = new wxImageList(16, 16, true); // 緑色を透明としてビットマップをアイコンにする pImgList->Add(wxBitmap(wxT("ICON_MATERIAL")), wxColour(0, 255, 0)); pImgList->Add(wxBitmap(wxT("ICON_MATERIAL_GROUP")), wxColour(0, 255, 0)); pTestList->AssignImageList(pImgList); // トップのカラム部分の指定 pTestList->AddColumn(wxT("ツリー部")); pTestList->AddColumn(wxT("項目部")); // ツリーのルートノードを追加 wxTreeItemId rootItem = pTestList->AddRoot(wxT("root"), 1); wxTreeItemId item, item0; item = pTestList->AppendItem(rootItem, wxT("あいてむ00"), 0); pTestList->SetItemText(item, 1, wxT("data0")); item = pTestList->AppendItem(rootItem, wxT("あいてむ01"), 0); pTestList->SetItemText(item, 1, wxT("てすと")); item = pTestList->AppendItem(rootItem, wxT("あいてむ02"), 0); pTestList->SetItemText(item, 1, wxT("てすと02")); item0 = pTestList->AppendItem(rootItem, wxT("あいてむ03"), 1); pTestList->SetItemText(item0, 1, wxT("item03")); item = pTestList->AppendItem(item0, wxT("あいてむ10"), 0); pTestList->SetItemText(item, 1, wxT("item 10")); item = pTestList->AppendItem(item0, wxT("あいてむ11"), 0); pTestList->SetItemText(item, 1, wxT("item 11")); item = pTestList->AppendItem(item0, wxT("あいてむ12"), 0); pTestList->SetItemText(item, 1, wxT("item 12"));
ツリーアイテムを追加して(wxTreeItemIdでノードを識別)、そこに属性を追加するような感じですね。こりゃ便利です。これで目的のことが実装できそうですので、早速使わせてもらおう。もちろん、マウスイベントなどもGetできます。
mqoImporter for Shade9/10 64ビット版(2008/09/21)
http://ft-lab.ne.jp/cgi-bin/wiki.cgi?page=mqoImporter_shade
にて、64ビット版ShadeのためのmqoImporterを追加しました。64ビット環境の方は「mqoImporter_win_101_2.zip」を解凍後の「mqoImporter64.dll」をご使用くださいませ。
KLT(2008/09/20)
2次元画像の特徴点の検出アルゴリズムとして有名なものにKLT(Kanade-Lucas-Tomasi)があります。このアルゴリズム、OpenCVでも使用されてますね。以下から論文などダウンロードできます。サンプルソースもあるのでそのまま実装可能。
http://www.ces.clemson.edu/~stb/klt/index.html
で、実験してみました。どういった動きをするのかOpenCV抜きで確認したかったので、純粋に特徴点検出のみ。
特徴点の数を変えながら確認してみたのですが、基本的に増えても過去の検出された位置は変わってないですね。ですが、増えすぎるとあまり関係なさそうなのも検出するのかな。若い検出から重要度が高い感じかもしれない。
もっと分かりやすく、二値の画像でチェック。
たしかに特徴のある部分に集まってますね。これらの計算は、Celeron 1GHzのノートPCでも320 x 240 pixelの特徴点検出で90msくらいです。まだソース自身最適化できそうですので、もう少し速くできそう。
マルチスレッドのためのビュワー・モデラー最適化(2008/09/18)
私がツールを作る場合によく使うテクニックとして「遅延」というのがあります。マルチスレッドのプログラムをする場合は、よく使うのですが「時間のかかる命令は分離してしまえ」という方法です。
たとえば、3DCGツールでシーン情報を読み込んでビュー(OpenGLなりDirectXなり)領域でテクスチャも含めて表示する場合を考えましょう。テクスチャは、
- ファイルから読み込み
- 2の累乗になるようにテクスチャをリサイズ
- マルチレイヤの場合は複数のテクスチャを重ね合わせ
- ハード(OpenGL/DirectX)のテクスチャとして生成
のような結構負荷の高い処理が行われます。同様に、
- 頂点法線計算
- その他画像リソース読み込み(hdrとか)
などは負荷の対象です。
で、最近はせっかくのマルチコア環境が流行りですので、重い部分はメインスレッドではやらないようにします。分かりにくいですが概念図。
その代わり、上の図でいう「タスクスレッド」というのにQueue領域を設けてそこに命令を格納していきます(格納したらすぐ抜ける)。タスクスレッドでは、Queueより順番に命令を取り出して処理します。描画部とのタイミングがバッティングしないようにクリティカルセクションでの保護は忘れずに。
処理後の結果として画面の反映の必要があるものなら、メインスレッドに「終了したよ」というシグナルを送ります。こうすると、タスクスレッドのQueueに命令がたまったら順に消化する、といった「遅延」状態ができます。
このほうがストレスなく作業はできます(実は今のツールに実装してます)。シーンファイル読み込みも、遅延でテクスチャを読み込む(そしてビューのテクスチャとして画面に反映)、などすることで読み込み時間は短縮できますね。
ということで、リアルタイムにあれやこれやしたい場合は使えるテクかと思います。
ただし、注意点。Windows環境の場合は、サブスレッドからSendMessage系の処理(画面の更新(invalidate)とか)を呼ぶと不安定になるので、ワンクッションかませましょう。具体的には、シグナルをメインスレッドに送るか、メインスレッドのタイマーで感知できるフラグ立てのみをサブスレッドで行うか。
wxWidgetsを使ったアプリでのメモリリークのトレース(2008/09/16)
wxWidgetsを使ったアプリで、Debugモードにてメモリリークが発生している箇所がありまして格闘してました(問題は私の書いたソース内で、です。wxWidgetsは問題なし)。
VisualStudioの出力ウィンドウにて
Detected memory leaks!
が出た後、
{1234} normal block at 0x00AA4020, 20 bytes long.
みたいに番号が出るのですが、これは「_CrtSetBreakAlloc」の第一引数に{xxx}内の番号を入れるとそこでトレースを中断できます。が、実行のたびに番号が変わるので難航。明確な怪しいプログラムの行を確認したかったので
#ifdef _DEBUG #include <crtdbg.h> #define DEBUG_NEW new(_NORMAL_BLOCK ,__FILE__, __LINE__) #else #define DEBUG_NEW new #endif #ifdef _DEBUG #define new DEBUG_NEW #endif
を該当しそうなソースの先頭に入れてみました。
d:\user\vc program\xxxx\sources\scenehierarchy.cpp(94) : {18446} normal block at 0x01205DE0, 20 bytes long.
みたいな感じで特定でき、ようやくつぶせました。しかし、このメモリリークをチェックする機能、便利ですねぇ。
ノートPCをあけてみる(2008/09/14)
VAIOノートを開いてみました。なお、ノートの場合は勝手にあけてはサポート対象外になるのが多いのでやらないようにしましょう。案の定、マシン起動してもファンが回ってませんでした。ゴミを取ったりファンを手動でクルクルまわしたりで、なんとか動くように。
なお、下の写真のように
キーボードとはこの幅のある線でつながってます。これをはずすと、キーボードからの入力は受け付けなくなります(いったんはずすと、取り付けるのに微妙にコツがいる)。
ファンがきっちり回るようになると、なぜかOSが重くなったりFlash動画でexplorer.exeがCPUを使用して重くなったり、は解決したような。ということで、分かったことが1点。explorer.exeまたはtaskmgr.exeでやたらCPUを占有する、Flash動画が重い、それが突然起こった、デフラグしても解決しない、といった現象の原因は「ファンが回ってないから」といった物理要因が関係していることがあるみたいですね。少ないメモリで遅いマシンの方(当方512MB)は、一度疑ってみるのもいいかもしれません。ネット上で同様の現象の方もいらっしゃったのですが、おそらく解決策にあったメモリ増設などは無関係かなぁと思ってます。
PCが壊れる直前(2008/09/14)
どうもメインのノートPCがそろそろ壊れる予兆が。えらい筺体が熱くなってて、ファンがうまく機能してないっぽい状態のようです。exploere.exeとtaskmgr.exeがほぼ50%を超える状態でFlash動画のみならず常に重い状態になりました。ということで何もできない・・・(今は仕事場のPCから書き込み)。デフラグとchkdskなど一通り試したのですが、こりゃ寿命ですかねぇ。いつ発火するかも分からないので、そろそろ大事なデータだけ待避させて新マシンを考えなければ。その前にせっかくなんで分解するかな(ノートPCの場合は、分解した段階でサポートが効かなくなるという諸刃の剣ではあるので、最後の手段)。ということで、東京来てからの相棒として長い間お世話になったVAIOノートとおさらばです。
後、しばらくメールが使えませんので返答が遅くなりますがご了承くださいませ。仕事場のは常に使えますので、緊急の場合はそちらにお願いいただければ幸いです。
やっぱりモバイル環境のほうがよいので、ノートPCを買う予定です。前に日記に書いたとおり、Mac(iBook)を買おうかなと思ってます(ネットとプログラムしかしないですので)。ただ、e-taxのクライアントとカードリーダーがMac対応してたっけなぁ、確認しないと。
懐かしのパソコンサンデー(2008/09/07)
ふと思い出して、ニコニコでパソコンサンデーを検索。まさかあるとは・・・。
http://www.nicovideo.jp/watch/sm3596573
昔、親が見てる横でこの番組見てましたよ。いやはや懐かしい。実家にはもうないですが、FM-8(富士通マイクロ8)+テープで打ち込んで遊んでたもんです。BASICでもコマンドが機種によって微妙に違うので、若干移植作業がいるんですよね。当時小学生だったもんで自分の年代からみても、同年代では知ってる人はいなかったのですが、年上でたった一人この話が通じた方がいます(以前いた会社の親会社にて)。悲しいかな、おっさんホイホイタグがついてますな(^_^;;。
しかし、今後のデジタル放送時代、民放でもこういう番組が復活してほしいなぁ。といいつつ、もうテレビはあんまり見てないです。ぶっちゃけ、デジタル放送で何が変わるのか把握してなかったり。
透明と粗さ(2008/09/07)
レンダラにてちと難しい問題が。
最近、透明度のあるマテリアルに粗さを与えると視点から見てその後ろがぼやける、といった拡散的な効果を入れたのですが、その形状の後ろに「点光源」を置いたらどのような光の通し方をするのだろうか。上の画像を例にすると、青い半透明物体の真ん中に点光源を置くとか。
点なので視点からの逆光線追跡ではヒットしません。ということで、光源での直接照明の分離+シャドウレイを考えることになります。が、今まで点光源から見たときの粗さは不透明のような遮断によるシャドウ生成のみを与えてました。でも、「粗さ」で光は拡散するのでそうじゃない、ですね。さて、どう計算したものか・・・。これは屈折の場合もまじめに計算するとするなら発生する問題ではありますね。光源からたどらないとすると(面光源とか)、何も考えないでOKなんだけどなぁ。でも、この延長線上にSSSがある気がするので、そろそろこのあたりの実装にも踏み込んでいかなければ。
ブラウザ上のFlash(2008/09/02)
Celeron 1GHzのノートPCで、Flashの処理時にえらいもたつくようになりました。特に動画はガタガタです。調べて見ると、explorer.exeやtaskmgr.exeでCPUをかなり使用してます(これはFlash再生時の特徴らしい)。しばらく待つとCPUを100%消費して、あるタイミングでCPU使用率が下がります。これの繰り返し。その間Swapが発生しているというわけではないようです。最近FireFoxやFlashPlayerを最新版に変えたのも影響しているのかもしれないです。後、作業フォルダのあるHDDの容量が少なかったもの影響しているかも(残り600MBくらい。いらないのを削除して1GBくらい空きを作りましたが、Flash再生時の負荷軽減には影響せず)。
ハードディスクをデフラグするともたつきはかなり少なくなりましたが、やはりCPU100%使用は変わらないですねぇ。
ということで、そろそろマシンスペックが限界なんでしょうね。しかし、今までもたつき無く動作していたものがきびきび動かなくなる、というのは、、、ソフトとしてパフォーマンスチューンしてほしいなぁと思ったり(OSしかりAdobe製のアプリやサービスしかり)。
Future's Laboratory 技術格納庫 2004-2013 Yutaka Yoshisaka.