古典力学:フィンガーディフューザー

最近、 Farseer Physics Engineの種類を調べました。 このエンジンに動的オブジェクトがどのように実装されるかがおもしろくなった。 予想通り、私は通常の微分方程式と、差分方程式または離散状態空間モデルの形でのそれらの離散実装を満たしていませんでした。 多くのゲーム物理エンジンで「誠実な」メカニクスを拒否するという主張された理由の主な言い訳は、微分方程式の操作の過度の複雑さと計算負荷の過剰です。



はじめに



この記事では、デジタル信号処理のトピックを続けます。 その中で、微分方程式に基づくアプローチを使用して、ゲームメカニクス(物理学)の概念について簡単な言語で話そうとします。 将来、このアプローチの実装が本当に計算負荷の急激な増加につながるかどうかを評価するつもりです。 この記事のフレームワーク内では、うまくいきません-ボリュームが大きすぎます。 ここでは、動的オブジェクトの数学的モデルに含まれる係数の目的を説明し、それらの物理的意味を説明します。 動的オブジェクトの動作への影響。

始めましょう...



物理的な意味



カルマンフィルターに関する記事では、入出力方程式、伝達関数、微分方程式を書く演算子形式について説明しました([2]の「基本概念」セクションを参照)。 次の式は、演算子形式の書き込みにおける動的オブジェクトの数学モデルの一部の例として役立ちます。

(1) 画像

これは、動的システムの一般的な単純化されたモデルです。 予想して、 Farseerエンジンのボディのモデルは、上に示したモデル(第2レベルのダイナミックリンク)の簡略化されたアナログを使用することを書きます。 以下に採用されている名称の説明を示します。



提示された方程式は、「1入力-1出力」(SISO)タイプの動的システムを記述しています。 自由度の1つに従ってオブジェクトのダイナミクスを記述するために使用できます。 ご存知かもしれませんが、フリーボディには6つの自由度があります。3つの並進(座標系(SC)の3つの軸に沿った直線運動)と3つの回転(SC軸の周りの回転)です。 したがって、肉体の完全なモデルは、6つのそのような方程式(または2Dの場合は4つ)によって記述されます。 すでにこれは、このアプローチの複雑さが高すぎることをすでに示していると言うことができます。 しかし、実際には、たとえば、Farseerでは、ボディクラス(Body)には、ボディの線形座標(実際には、OXとOYのα(s)のペア)とOXとOYの線形速度(s *α(s)のペア)の両方が含まれています)および方向と角速度のパラメーター。 これらのパラメーターは、各軸に対して個別に計算されます。 方程式の数は同じです-OX軸に沿った2つの方程式(直線および角運動)とOY軸に2つの方程式。 違いは、方程式の形式のみです。

Farseerエンジンのアルゴリズムは近似的かつ簡略化されていますが、可変タイムスライスを使用できます。 最後のパラメーター計算から経過した時間がモーションパラメーター計算関数に渡されます( Island.Solve(ref TimeStepステップ、ref Vector2重力) )。 これにより、コンピュータのパフォーマンスが不十分になり、ゲーム時間の速度をほぼ一定に保ち、ゲームオブジェクトの動きの滑らかさと現実感が損なわれます。

微分方程式に基づいて離散モデルを構築するとき、私たちは明らかに固定時間量子に結びついています。 方程式は、最初に指定されたサンプリングレートで統合され、何らかの理由で、最後のカウント(指定理由により、英語の文献では「時間サンプル」と呼ばれます)から指定された量を超えた場合、数回カウントする必要があります。そうしないと、速度が低下します。オブジェクトの動き。 後者は、弱いマシンのゲーム「 Command Cortex 」で観察したばかりです。 俳優の動きはスムーズでしたが、ゆっくりでした(人間主導の俳優が利用します)。 したがって、これらのアプローチの1つの優れた利点について話すことはできません。

さて、上記の方程式の係数が何に責任があるのか​​について。 この方程式は、α(s)= 0での平衡位置に対する身体の動きを表します。これは、ゲームメカニクスでこのようなモデルを使用することで不便に思われるもう1つの理由です。 外力がない場合、このモデルは遅かれ早かれ(モデルが安定している場合)身体を平衡位置に戻します。 常に原点に向かう傾向のあるボールで満たされたゲームの世界を想像してください(たとえば、画面の左上隅)。 剛性係数は、この動作につながります(上記のa2を参照)。 ボディがスプリングによって原点に接続されていると想像してください。 力が体に作用する間、バネは伸びますが、外部の影響を取り除く価値があり、体はゼロになります。 Farseerエンジンのボディには、この動作はありません。 係数a2をゼロに設定すると、この場合、ボディは原点に近づきません(上記を参照して、Farseerのモデルは本質的にこのモデルの切り捨てられたバージョンであると書きました)。 それでは、なぜこの係数が必要なのでしょうか。 方程式(1)の左側で、項の代わりに括弧を開くと

a2 *α(s)

書きます

a2 *(α(s)-α0)

次に、α0を介して、ゲームオブジェクトの傾向がある位置を設定できます。 係数a2の値は、身体が所定の平衡位置に移動する速さを左右します(値が高いほど、バネの剛性が高くなります)。 これがFarseerでどのように実装されているかはまだわかりませんが、影響力の追加ソースを作成する必要があると思います。

係数はa1です。 これが減衰係数です。 この係数の値が高いほど、速度はより速く消滅します(線形または角度)。 生命からの類推は、油、蜂蜜、エポキシなどの粘性流体です。 これらの液体は非常に粘性が高い(減衰係数が高い)。 それらの身体の動きの速度が速いほど、この動きに対する抵抗が大きくなります。 たとえば、スプーンをゆっくりと動かせば、抵抗に打ち勝つことは難しくありませんが、大規模に叩くと打撃は難しくなります。

係数a0の値は、オブジェクトの慣性を特徴づけます。 直線運動の説明では、質量が係数a0として使用されます。 その値が高いほど、外力が加えられたときの身体の速度が遅くなります。

次に、式(1)の右側の係数について説明します。 ここで、このモデルは、入力アクションが外力の値だけでなく、その変化によっても決定される場合に拡張されることに注意してください。 ゲームオブジェクトのダイナミクスを説明するには、これは冗長かもしれません。 ただし、産業用制御システムでは、このようなモデルも見つかります。 彼らの物理的な意味は何ですか? 係数b1は、本質的にオブジェクトへの外力の伝達係数です。 通常は1に等しい、つまり 電力はそのまま伝送されます。

係数b0は興味深いものです。 ブースティングファクターの役割を果たします。 力が加えられ、時間とともに徐々に増加する非常に慣性的な物体を想像してください。 スルーレートと力の最終的な大きさが小さい場合、オブジェクトは非常にゆっくりと速度を上げています。 しかし、力を大きくすると、外力が設定値に達した後、オブジェクトは特定の位置で停止せず、慣性の影響下で振動します。 強制は、外力の上昇率に比例する効果です。 大きな値を選択すると、外力の増加率が低い場合でも、オブジェクトは非常に迅速に速度を上げ、外力が指定された値に達すると強制がオフになります。 これがこの「b0」のcな例です。



写真のダイナミクス



差分係数の影響を明確に示すため。 動的オブジェクトの振る舞いの方程式は、ステップ( ステップ応答 )およびインパルス( インパルス応答 )入力アクションで遷移プロセスのグラフを作成することを決定しました。 合計で、6つのグループのグラフが表示されます(各係数に1つのグループ)。 グラフは、「Signal Processing」パッケージがインストールされたOctaveパッケージ(v。3.4)で作成されます。

したがって、ソースとして、次の形式のモデルを使用します。

==========================================

>>> w = tf([1 1]、[1 1 1])



入力 "u1"から出力への伝達関数 "w" ...



y1:(s + 1)/(s ^ 2 + s + 1)



連続時間モデル。

==========================================





記号形式のコード「w = tf([1 1]、[1 1 1])」の形式は次のとおりです。

>>> w = tf([b0 b1]、[a0 a1 a2])

下のスクリーンショットの右側には、おおよその安定化時間が示されています(指定された値の±5%を安定性コリドーと見なします)。



剛性係数a2で遊んでみましょう。

>>> w1 = 0.1 * tf([1 1]、[1 1 0.1])

y1:(s + 1)/(s ^ 2 + s + 0.1)



>>> w2 = 10 * tf([1 1]、[1 1 10])

y1:(s + 1)/(s ^ 2 + s + 10)

注:結果として得られるゲインが1になるように、ゲインを調整する必要がありました。





グラフに表示されるものは何ですか? w、w1、およびw2のグラフは、それぞれ左から右に表示されます。 w1グラフは、安定状態に達するまでより滑らかで遅くなります。 w2グラフは本質的に振動的ですが、すぐに定常値に達します。 結論:バネが硬いほど振動は大きくなりますが、移行プロセスは短くなります。



ダンピング(a1)を試してみましょう。

>>> w1 = tf([1 1]、[1 0.25 1])

y1:(s + 1)/(s ^ 2 + 0.25s + 1)



>>> w2 = tf([1 1]、[1 2 1])

y1:(s + 1)/(s ^ 2 + 2s + 1)





すぐに結論:より多くの粘度-より速い減衰振動。



慣性(a0)で遊んでみましょう。

>>> w1 = tf([1 1]、[0.1 1 1])

y1:(s + 1)/(0.1s ^ 2 + s + 1)



>>> w2 = tf([1 1]、[2 1 1])

y1:(s + 1)/(2s ^ 2 + s + 1)





結論:鋳鉄の質量が少ない-チャタリングが少なく、移行プロセスが短い。



右側に移動して、b1で遊んでみましょう。

>>> w1 = 10 * tf([1 0.1]、[1 1 1])

y1:(10秒+ 1)/(s ^ 2 + s + 1)



>>> w2 = 0.25 * tf([1 4]、[1 1 1])

y1:(0.25 s + 1)/(s ^ 2 + s + 1)





ステップ応答のグラフを見ると、その違いはほとんど目立たないようです。 しかし、インパルス応答のグラフでは、この係数の効果がはっきりと見えます。 ユニティに等しい場合、パルス遷移プロセスのグラフはユニティから始まります(実際、ゼロから始まりますが、問題ではありません-グラフの2番目の値はユニティです)。 グラフw1は値10(0.1からの逆数)で「始まり」、グラフw2は値0.25(4の逆数)で始まります。 したがって、係数b1は、制御効率の係数(入力インパクト)と「呼ぶ」ことができます。



そして最後に、おいしい-係数b0のゲーム。 比較は上記とは異なるため、これは注意が必要な要素です。 その効果を示すには、いくつかの要因を変える必要があります。

>>> w1 = tf([6 1]、[1 1 1])

y1:(6秒+ 1)/(s ^ 2 + s + 1)



>>> w2 = tf([6 1]、[1 3 1])

y1:(6秒+ 1)/(s ^ 2 + 3秒+ 1)





w1とw2の違いは何ですか? W2には3倍の減衰係数があります。 その結果、興味深い結論が得られます。 チャートw1とw2は、デフォルトのチャートよりも早く定常状態レベルを超えます。 ただし、グラフw1はその振動でデフォルトの形式を保持し、減衰の増加によるグラフw2はより滑らかです。 このように、強制と減衰で遊んで、蝶のようにリングを前後にちゅうちょせずに鋳鉄製の鉄を飛ばすことさえできます。



PSとして



この記事では、係数の正の値のみを考慮しました。 それらの陽性は、安定性に必要な条件です。 モデル。 ただし、負の値を試してみることができます。 不安定なシステムも制御できます。 第5世代の航空機(ゴールデンイーグルなど)を考えてください。 翼の逆掃引は不安定なグライダーですが、同時に高い機動性も備えています。 オートメーションはこの不安定性を修正すると同時に、必要に応じて急旋回します。

可能であれば、これらのすべての効果を明確に確認できるおもちゃを作成します。



ソース



  1. ゲーム物理エンジン「 Farseer
  2. カルマンフィルター-!複雑ですか?



All Articles