物理モデルを備えた船のAIコントロール


19

2D空間でフォローを実装する方法のアイデアを探しています。残念ながら、AI /パスの検索/自律制御についてはまだあまり知りません。

この船は自由に移動できるが、質量と勢いがあるとしましょう。また、外力がそれに影響を及ぼす可能性があります(爆発など)。プレイヤーはいつでも船の目標を設定でき、その場所に到達して停止するはずです。

物理学がなければ、これは簡単で、ただ方向を指して進むだけです。しかし、既存の勢いに対処し、その場で停止する方法は?船の配置を直接変更したくありません。

編集:明確にするために、船自体の物理学関連の数学は問題ではありません。


これと似たような問題がすぐに発生することを期待しています。これに対する答えを楽しみにしています。
ビル

回答:


15

ステアリング動作を見てください。特にシーク到着はあなたのニーズにとって興味深いかもしれません。これらの動作は、爆発のような他の影響が船の位置を一時的に変更する場合にも機能します。


+1。2D空間ゲームでは、フレームワークとしてステアリング動作を使用し、フレームワーク内のコンポーネントとして私の回答の1つを使用することをお勧めします。
-tenpn

私が質問を読んだとき、同じ考えを提案するつもりでした。私は多くのステアリング動作を使用しました、それは簡単で、かなり素晴らしいAI /モーションを可能にします。
-dotminic

5

正確に取得するのは簡単な問題ではありません。各ソリューションの詳細は異なりますが、2つの選択肢があります。

数学的な解決策。物理システムが十分に単純な場合、モーションの閉じたフォームを作成し、ある時点で停止するためにブレーキ力の適用を開始する必要がある場合を計算できます。ブレーキ力が一定で、空気抵抗がない場合、これは2次に分解されます。

実証的なソリューション。手動で調整したPIDコントローラーを使用するか、物理システムで実際に船舶の制動距離を記録できます:テストベッドで、最大速度から停止まで船舶を制動し、移動時間と小さなタイムステップごとの速度を記録します。結果の距離/速度グラフをデータディレクトリに保存します。

実行時に、グラフを再構築し、現在の速度と目標速度を差し込んで距離を出します。ターゲットポイントからこの距離で、フルブレーキをかける必要があります。

このアプローチの利点は、あらゆる速度に正確にブレーキをかけることができることです。不利な点は、ブレーキをオンまたはオフにする必要がある場合、カーブに正確に乗ることができないことです。


1

前に述べたように、この状況はステアリングの動作に最適ですが、少しだけ拡張したいと思います。到着動作は、このシナリオに最適です。また、障害物も考慮する必要があります。ここでも障害回避動作を利用できます。

残念ながら、http://www.red3d.com/cwr/steer/は動作のソースコードを提供していません。ただし、Example by Programming Game AIは、動作をわかりやすくまとめて説明しています。この本を入手できない場合は、http//www.wordware.com/files/ai/からいつでもソースコードを入手できます。

さらに、パスファインディングを含むように動きを拡張したい場合は、パスを計算するパスファインダークラスを作成し(おそらく2Dベクトルのコレクションとして)、パスフォローステアリング動作を使用してそれをミックスに追加することもできます。

リンクしたソースコードには、これらのステアリング動作を組み合わせる3つの異なる方法も用意されています。

お役に立てば幸いです。


red3d.comのリンクはソースを直接提供しませんが、そのページには、ステアリング動作のオープンソース実装であるOpenSteer(opensteer.sourceforge.net)へのリンクがあります。
-bummzack

ああ、知らなかった、ありがとう。ただし、OpenSteerのソースを調べたところ、Bucklandの本に記載されているフェイスコードの方がわかりやすいことがわかりました。特に開始時。
レイデイ

1

ある位置に向かって操縦するのはそれほど難しくありませんが、私はしばらくの間、その位置に向かって操縦し、特定の速度で到達するか、速度に制約のある道を辿るという問題に苦労しました。

私はエルミート曲線を使用して問題を解決しました。p0とm0を船の位置と速度に設定し、p1とm1を目標の位置と速度に設定します。これは、船が目標の1秒後に追従することを前提としています。p(0)の2次導関数を計算します。これにより、船に適用する加速度が得られます。

2次導関数のコードは次のとおりです(F#では、選択した言語に適応できることを望みます。sq()は、引用符としてではなく文字として解釈される正方形の単一引用符を計算し、識別子の一部です)。

    let h'' t =
        let h00'' t = 12.0 * t - 6.0
        let h10'' t = 6.0 * t - 4.0
        let h01'' t = -12.0 * t + 6.0
        let h11'' t = 6.0 * t - 2.0

        let t = (t - t0) / diff_t

        (sq (1.0 / diff_t)) *
        ((h00'' t * p0) +
         (h10'' t * diff_t * v0) +
         (h01'' t * p1) +
         (h11'' t * diff_t * v1))

船が外力(惑星からの重力など)の影響を受ける場合、加速度から推力を計算する際にそれを考慮する必要があることに注意してください。



-3

船には、位置と速度のようなパラメータが必要だと思います。

速度は、すべての力(重力、爆発、ユーザー入力など)の各フレームの合計であり、何らかの湿気を含むこともあります。

位置は、最後の位置と速度* time_stepから計算されます。

ただし、これを使用すると、ターゲットで停止を実装するのが困難になる場合があります。


3
-1 Petteri Hietavirtaは基本的な物理システムの使用方法を知っているようです。この質問に対するあなたの答えは、ターゲットで停止するのは難しすぎるということですか?
AttackingHobo
弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.