2012年10月8日月曜日

OpenNIを利用したアプリ:跳ねるボール2

in English

はじめに

以前こんなアプリを作りました。このアプリのシミュレーション部分をOpen Dynamics Engine(ODE)に置き換えてみたので紹介します。

動画

こんな感じ(アップロードしたら画質が悪くなった)。
video

開発環境

  1. Mac OS X 10.8.2
  2. プロセッサ:3.06 GHz Intel Core 2 Duo
  3. メモリ:4GB
  4. Xcode4.5.1

主要ライブラリ

  1. boost-1.51.0
  2. pcl-1.6.0
  3. OpenNI-Bin-Dev-MacOSX-v1.5.4.0
  4. ode-0.12

ソース

こちらです。自分のマシーンでしか動作確認していません。

コンパイルオプション

Header Search Path:
パス 目的
/usr/include/ni/ OpenNIヘッダー
/opt/local/include/ boost/odeヘッダー
/usr/local/include/pcl-1.6/ PCLヘッダー
/opt/local/include/eigen3/ eigenヘッダー(PCLがこれに依存している)
/opt/local/include/vtk-5.10/ vtkヘッダー(PCLがこれに依存している)

Library Search Path:
パス 目的
/opt/local/lib boostライブラリ
/usr/local/lib PCLライブラリ

Other Linker Flags:
-lboost_thread-mt -lboost_filesystem-mt -lboost_unit_test_framework-mt -lboost_chrono-mt -lboost_program_options-mt -lboost_system-mt /usr/lib/libOpenNI.dylib -framework OpenGL -framework GLUT -lpcl_filters -lpcl_kdtree -lpcl_segmentation -lpcl_surface -lpcl_search -lpcl_features -lpcl_common -lode -lpcl_io


使い方

実行ファイ名は、BouncingBallWithOdeです。引数--helpをつけて実行すると以下を出力します。 引数なしで実行すると、Viewerが起動しXtion Pro Liveの映像が映し出されます。 窓にフォーカスがある状態で、キーボードから「m」を打つと、その瞬間のポイントクラウドから三角メッシュを導出する計算が始まります。 19、20行目に警告が出ていますが大丈夫です。【追記:下記に示した関数gp.setMaximumNearestNeighborsの引数を10から100にしたところ、警告はなくなりました。】続いて「b」を打つと、環境内にボールが投入されます。ボールと背景との相互作用がリアルタイムで描画されます。ボールの投入は何度でもできます。 33行目にエラーが出ていますが大丈夫です。「q」を打つと終了します。

ソースの概要

OpenGLの視点

以下のように設定しています。本アプリの長さの単位は全てmmです。 6行目の引数は使用する環境に合わせる必要があります。

ポイントクラウドへの変換

Device::create_cloudで行います。カラー画像描画のためのポイントクラウド(cloud_)と三角メッシュ算出用のポイントクラウド(cloud_xyz_)の2種類を生成しています。 25,26行目でRGB値を設定しています。29,30行目でデプスから3次元座標への変換を行っています。33行目で三角メッシュ用のポイントクラウドを取得しています。

カラー画像の描画

カラー画像用のポイントクラウド(cloud_)は、OpenGLのglInterleavedArraysに以下(5行目)のように渡されます。bufcloud_の先頭ポインタ、sizecloud_のサイズです。

三角メッシュの計算

三角メッシュ用のポイントクラウド(cloud_xyz_)はDevice::convert_to_polyton_meshで処理されます。 PCLライブラリを使用しています。27から36行目にかけてのパラメータは環境に合わせる必要があるかもしれません。 【追記:上記に示した関数gp.setMaximumNearestNeighborsの引数を10から100にしたところ、警告はなくなりました。】

ボールの投入

ボールはODEのオブジェクトです。これは、剛体力学の計算に関与するdBodyと衝突計算に関与するdGeomから構成されます。 dSpheredGeomの子クラスです。 そして、ボールはPhysicalSimulator::create_balls()で環境内に投入されます。 20行目のworld_dWorldのオブジェクトです。41行目のspace_dSpaceのオブジェクトです。ODEでは、剛体力学の計算を必要とするオブジェクトはdWorldに、衝突計算を行うオブジェクトはdSpaceに登録しなければなりません。

三角メッシュの登録

先に計算した三角メッシュは、PhysicalSimulator::register_triangular_mesh内でODEに登録されます。 triangular_mesh_dGeomIDのオブジェクトです。

衝突の検出

毎フレーブごとに、ODEにより衝突検出が行われます。 3行目のdCollideが衝突を検出するODEの関数です。ループ内では衝突点の属性を設定します。14行目のbounceは反発係数に相当します。

0 件のコメント:

コメントを投稿