干渉検出

モデルを動かしていると、リンクが他のリンクと干渉(衝突)を起こすことがあります。Choreonoidはそのような干渉を検出する機能を備えており、ここではその利用法を説明します。

干渉検出とワールドアイテム

干渉検出を行うためには、まず「ワールドアイテム」型のアイテムを導入する必要があります。

ワールドアイテムはChoreonoid上でひとつの仮想世界を表すアイテムです。このアイテムによって、

  • ボディモデルをある仮想世界に結びつける
  • 仮想世界全体の設定を行う
  • 複数の仮想世界を同時に扱う

といったことが可能となります。

干渉検出においても、

  • どの物体とどの物体の干渉を検出するか
  • 干渉検出結果をどのように表示するか

といった設定が必要となりますが、これらはある仮想世界と結びつけることが合理的です。そこで干渉検出の設定もワールドアイテムを介して行うようになっています。

ワールドアイテムの作成

ワールドアイテムは、通常のアイテムの作成方法で作成することができます。具体的には、メインメニューの「ファイル」-「新規」-「ワールド」を実行すると現れる「新しいワールドアイテムの生成」ダイアログで「生成」ボタンを押して作成します。

ボディモデルの関連付け

ワールドアイテムは、それにボディモデルを関連付けることで初めて意味を成します。関連付けは、ボディアイテムをワールドアイテムの子アイテムとして配置することで行います。

ここでは、今まで扱ってきたPA10のモデルでこれを行ってみましょう。PA10モデルが読み込まれている状態で上記のワールドアイテムの作成を行うと、アイテムツリービューでは2つのアイテムが以下のように並んで表示されているかと思います。

../_images/pa10_and_world.png

ここで、 アイテムツリーの管理 - 移動 の説明に従って "PA10" を "World" の上にドラッグすると、PA10がWorldの子アイテムに移動して以下のようになります。

../_images/pa10_in_world.png

これでPA10モデルが仮想世界"World"と関連付けられたことになります。

注釈

"PA10"が選択状態の時にワールドアイテムの生成を行うと、生成されたワールドアイテムはPA10の子アイテムとして配置されてしまい、親子関係が上の例とは逆になってしまいます。この場合はいったんワールドアイテムをアイテムツリービュー下部の何も無い領域にドラッグします。するとワールドアイテムがPA10の子アイテムでは無くなりますので、その後上記の操作を行うようにしてください。

注釈

ワールドアイテムを作成し、それを選択した状態でボディモデルを読み込むと、モデルが最初からワールドアイテムの子アイテムとして読みこまれることになります。ワールドアイテムを導入したプロジェクトを一から作成する際には、そのようにすることで操作を効率化できます。

複数ボディモデルの関連付け

通常はひとつの仮想世界に複数のボディモデルを関連付けることになります。その場合、単純に複数のボディアイテムが同じワールドアイテムの子アイテムとなっていればOKです。

ここでは先ほどのPA10モデルに加えて、 サンプルモデル の中から床のモデルを追加してみましょう。share ディレクトリの "misc/floor.wrl" を読み込んで、同じワールドアイテムへの関連付けを行なってください。アイテムツリーが以下のようになればOKです。

../_images/pa10_floor_in_world.png

このようにFloorにもチェックを入れて、床のモデルもシーンビューに表示させてみましょう。PA10を標準姿勢にすれば、以下のようなシーンが表示されるかと思います。

../_images/pa10_floor_scene.png

以下では干渉検出の例としてこのPA10と床のモデルの間の干渉を検出・表示させてみたいと思います。

干渉検出の設定

干渉検出を行うかどうかは、ワールドアイテムとボディアイテムのプロパティで切り替えることができます。関連するプロパティは以下のとおりです。

アイテム プロパティ(true、false) 概要
ワールドアイテム 干渉検出 仮想世界全体としてそもそも干渉検出を行うかどうか
ボディアイテム 干渉検出 各ボディモデルに対して、他のボディモデルとの干渉検出を行うかどうか
ボディアイテム 自己干渉検出 各ボディモデルにおける自己干渉を検出するかどうか

まず干渉検出を行う根本的な設定として、ワールドアイテムの「干渉検出」をtrueにしておく必要があります。その上で、各モデルに対して個別に干渉検出を行うかどうかを切り替えるために、ボディアイテムの2つのプロパティを設定します。

ワールドアイテムの「干渉検出」はデフォルトではfalseとなっているので、まずはこれをtrueに切り替えてください(アイテムのプロパティ 参照)。ボディアイテムについては、「干渉検出」のプロパティはデフォルトでtrueとなっており、これはこのままでOKです。「自己干渉検出」については後ほど説明します。

注釈

干渉検出は一般的に比較的計算時間のかかる処理となります。特にモデルが複雑(ポリゴン数が多い等)になるとこの影響を大きくなり、場合によってはモデルの操作や表示が重くなる場合があります。このことを考えると、干渉検出が特に必要ではない作業を行う際には干渉検出の処理は省いた方が快適な場合もあります。これがワールドアイテムの「干渉検出」がデフォルトでfalseとなっている理由です。

上記の設定で内部の干渉検出計算は行われるようになりますが、さらにこれを表示するための設定が必要となります。干渉の表示の仕方は様々なものが考えらますし、それらを常に表示させたいとも限らないため、このようになっています。

干渉検出結果の表示

ここでは、干渉検出結果をシーンビュー上に表示する方法を紹介します。これを行うためには、まずアイテムツリービュー上でワールドアイテムのチェックをオンにします。

../_images/pa10_floor_in_world_checked.png

これはボディアイテムのチェック入れるとそのモデルがシーンビュー上に表示されるのと同様に、ワールドアイテムが有する仮想世界の情報をシーンビュー上に表示するという意味になります。

さらに、シーンビューの設定として、 シーンバー の「干渉線の表示」ボタン(以下の図で赤枠で囲った部分)もオンにします。

../_images/collision-toggle.png

これにより、干渉が生じている場合はシーンビュー上で対応する箇所に「干渉線」が表示されることになります。

以上で干渉の検出と表示に関わる設定は完了です。干渉計算やその表示が必要でなくなった場合は、上記のうちの対応する設定を再度オフにすればOKです。

干渉検出の例

ではPA10と床との間の干渉検出を行ってみましょう。逆運動学による姿勢の変更 を用いて、アームの先端を床に向かって動かしてみてください。アームが床にめり込む位置まで動かすと、衝突している部分に下図のように緑の線が何本か表示されるかと思います。これが干渉線です。

../_images/pa10_floor_collision.png

ここで干渉線の方向は干渉している面の法線を、長さは干渉の深さを表しています。このようにして、干渉検出の結果を確認することができます。

貫通ブロック機能

リンクを動かす最中に干渉を検出した場合に、それ以上干渉が深くならないように(貫通していかないように)ブロックすることもできます。これを行うには、運動学バーの「貫通ブロックモード」ボタン(以下に赤枠で示した部分)をオンにします。

../_images/PenetrationBlockButton.png

この状態で、先ほどと同様にアームを床の方まで動かしていきましょう。ドラッグしているリンクが床に接触すると、それ以上はそちらの方向へ動かせなくなります。例えば"J7"リンクを動かしていくと下図のような状態でブロックされます。

../_images/pa10_j7_blocked.png

ただしこの図でも分かるように、ブロックされるのはあくまでユーザが動かしているリンクです。それ以外のリンクに干渉が発生してもそちらはブロックされませんので、この点に注意する必要があります。この例で先端のグリッパの部分でブロックしてほしい場合は、運動学モードを逆運動学モードにして、先端のリンク("HAND_L" や "HAND_R")を動かすようにすればOKです。すると以下のような位置でブロックがかかります。

../_images/pa10_HAND_L_blocked.png

自己干渉の検出

上の例では異なるボディモデル間の干渉検出を行いましたが、ひとつのボディモデルの中で生じる自己干渉を検出することもできます。この機能はデフォルトではオフとなっていますが、ボディアイテムの「自己干渉検出」のプロパティをtrueとすることで利用可能となります。

PA10の例では、下図のようにアームの先端をベース部分に衝突させるなどすると、自己干渉が検出できていることが分かります。

../_images/pa10_selfcollision.png

なお、貫通ブロック機能は自己干渉では効かないようになっています。

ボディ/リンクビューの干渉表示

干渉検出の結果は、 ボディ/リンクビュー の「干渉」表示領域でも確認することができます。ここでは、対象となっているリンクに干渉がある場合、干渉相手のリンク名を表示します。「干渉」の領域には他モデルのリンクが、「自己干渉」の領域には自己干渉しているリンクが表示されます。

例えばPA10モデルでJ7リンクを対象として選択し、J7リンクが床モデルと自身の"Base"リンクに干渉している場合、表示は以下のようになります。

../_images/collision-panel-pa10.png

干渉検出器の切り替え

干渉検出を行うアルゴリズムは様々なものが開発されています。それらを用途によって使い分けたり、より高速なアルゴリズムを利用したいといった要望に応えるため、Choreonoidでは干渉検出アルゴリズムを実装した「干渉検出器(Collision Detector)」をプラグインによって新たに追加し、それらを切り替えて使えるようになっています。

干渉検出器の切り替えは、ワールドアイテムの「干渉検出器」プロパティを設定することによって行います。このプロパティは選択式になっており、利用可能な干渉検出器の一覧が表示されるので、そこから希望のものを選択します。Choreonoidが提供する標準の干渉検出器は "AISTCollisionDetector" で、デフォルトではこれが選択されています。"NullCollisionDetector" というのも有りますが、これは空の干渉検出器を表しており、これを選ぶと干渉検出が行われません。

プラグインを導入することで、これら以外の干渉検出器も利用可能となります。例えばChoreonoidのオプションのプラグインのひとつである「ODEプラグイン」は、Open Dynamics Engine (ODE) の干渉検出機能を用いた "ODECollisionDetector" という干渉検出器を提供しており、プラグインを導入すればこれが選択できるようになります。

シミュレーションにおける干渉検出について

本節で紹介した干渉検出機能は、 シミュレーション機能 とは基本的に独立して行われるものとなっています。現在の仕様では、ワールドアイテムやボディアイテムの「干渉検出」プロパティがtrueであってもfalseであっても、シミュレーションの挙動に変化はありません。シミュレーションにおける干渉検出は、シミュレータ内部の物理計算用モデルに対して行われるものであり、その処理内容は シミュレータアイテム によって決定されます。

本節の干渉検出機能を有効にしておくと、シミュレーション結果に対しても干渉状況が表示されますが、これについても注意が必要です。これはシミュレータ内部で実際に行われた干渉検出結果とは異なっている可能性があります。