ホーミングミサイルがターゲットを周回するのをどのように防ぐのですか?


78

私は摩擦のない2D宇宙ゲームを開発しており、ホーミングミサイルをそのターゲットに向けることが非常に簡単だと感じています。私は反軌道戦略について興味があります。

簡単な例は、ターゲットに向かって直接加速するホーミングミサイルです。そのターゲットがミサイルの軌道に垂直に移動して停止した場合、ターゲットへのミサイルの加速はそれ自体の速度に打ち勝つには十分ではなく、ミサイルはターゲットの周りの軌道に打ち込まれる可能性があります:

周回問題

  • フレーム1では、ミサイルは目標に向かってまっすぐに向かっていますが、問題はありません。
  • フレーム2では、示されているようにターゲットが新しい位置に移動しました。ミサイルはターゲットに向かって直接(赤で)加速し続けますが、既存の速度により、ターゲットがかつてあった場所(黒で)に向かって移動し続けます。
  • フレーム3では、ミサイルの速度がミサイルをターゲット(黒)の周りに運び続け、加速ベクトルがミサイルをターゲットに向かって必死に引っ張ろうとします。
  • フレーム4以降では、ミサイルはターゲットの周りの安定した軌道に落ち、目標に到達しません。黒い矢印は速度ベクトルを示し、赤い線は同じ瞬間の加速度ベクトルを示します。

空間に摩擦がないことを考えると、ミサイルの速度を遅くして軌道を崩壊させるものは何もありません。可能な解決策は、ターゲットの「背後」に照準を合わせることであり、これにより軌道が閉じられますが、これはプログラミングの観点からどのように行われますか?

ホーミングミサイルを目標に到達させるにはどうすればよいですか?


9
これは、実際にスタッフの軌道を作る非常にクールな方法です。
デレク

これは、オイラー統合を思い出させます。あなたがしなければならないのは、タイムステップを限りなく小さくし、問題を解決することです!
ジェフ

ゲームにこの効果を実装したい!:D
ゾロモン


6
@Dezaこれはまさに軌道の定義です。軌道を回っている物体は、求心力で他の物体の中心に向かって加速しています。
ボボボボ

回答:


49

まず、ミサイルの基準フレームに適用する加速度(ミサイルが静止し、他のすべてがゲームエンジンで「オブジェクト座標」または「ローカル座標」とも呼ばれる)ただし、この場合、速度も正確にゼロにする必要があります)。

その場合のアイデアは、ターゲットを狙うのではなく、ターゲットが予想される影響時間になる場所を狙うことです。したがって、一般的なアルゴリズムは次のようになります。

  1. ミサイルが目標に到達するまでにかかる時間を見積もります。ターゲットがその場所に直接飛んでいる場合(ミサイルが静止していることを思い出してください)、距離 / 速度を計算するのと同じくらい簡単な場合もあれば、より複雑になる場合もあります。ターゲットが試行および回避できる場合、とにかく完全な推定を行うことはできませんので、あまり正確ではないことは問題ありません。

  2. ターゲットの一定速度(1次推定値)または一定加速度(2次推定値)を想定して、上記の推定時間での位置を計算します。

  3. ミサイルがほぼ同じ地点に同時に到達するようになる加速度を計算します。

  4. ミサイルの参照フレームからグローバルなものに加速度を再投影し、それを使用します。

ここで重要なことは、大まかな球場で時間の見積もりを取得し、その際にミサイルの加速能力を忘れないことです。たとえば、「ターゲットが私たちの真正面にあり、私たちの方向に飛んでいる」ためのより良い推定は、方程式を解くことです。

距離 = 速度 x 時間 + 1/2 x 加速度 x 時間2

...のための時間(ストレート飛行物体のための負の速度を使用して離れたミサイルから)、あなたが標準使用して探している溶液を用いた二次式であることを...

時間 =(√(速度2 + 2 x 加速度 x 距離)- 速度)/ 加速度

追加のパラメーター(ドラッグなど)を追加すると、代数的解法のない微分方程式にすぐに変わります。これがロケット科学が非常に難しい理由です。


これはまさに私が必要とするものだと思います。今までローカル座標で考えたことはありませんでした。
ジョンマクドナルド

5
素晴らしい答え。追記として、多くの追跡ミサイルは、これらの条件で自動的に爆発するように設計されています。1)トラックから一定の距離内に到達し、2)トラックまでの距離が増加しています。それは少しの費用で少しいい動作を追加するかもしれません。
パトリックヒューズ

1
これは素晴らしい答えです。武器に一定の加速を使用することになり(これが最も現実的だと思いました)、到着にかかる時間を推定しました(d = v t + 1/2 * a t * tを再配置してtを解きます)。秘密のソースは、ターゲットが現在の速度と影響を受ける推定時間を与えられるプロジェクトに推定時間をフィードバックすることにありました。うまくいく。
ボボボボ

1
私は、これはのタイプだと思いデッドレコニングアルゴリズム
bobobobo

42

@Martin Sojkaはすでに何をすべきかを教えてくれました。彼の応答を改善する代わりに、別のより簡単なアプローチを提案したい:DELOCK

車両の予想軌道で述べたように、ステアリング機能が制限されているオブジェクトは、いくつかのシャドウサークルを「投影」します。直接ステアリングでは到達できない2つの領域(トーラスと高次元のハイパートーラス)。

ターゲットがそのようなステアリングシャドウの1つに入ることを確認したら、ターゲットのホーミングを停止して、限られた時間だけ別の方向を維持することができます。

ロック解除トリガーは、トーラスを(ダブル)コーンで近似することで簡単に計算できます*:

ロック解除トリガー

(正規化された)方向ベクトルとターゲットの変位ベクトル(Target - Object / | Target - Object |)の間のスカラー積を単純に計算する必要があります。

スカラー積がゼロになると、ターゲットの方向が方向に垂直になり、円形の軌道になります**。ターゲットがシアンの領域に落ちたら、ステアリングの方向を逆にして、到達不可能な領域の外側に置いて、リホームすることができます。

*正直なところ、これは円錐ではありません...交差点を通り、二等分線に垂直な軸の周りの2つの平行でない線の(半)回転によって生成される別の種類の罫線面です。2D平面への投影はダブルコーンと同じですが、回転軸はコーンを生成するものに垂直です。

**その軌道は、円形でも楕円形でも、閉じられている可能性もありません。可能性は、軌道が2Dのパス(ハイトロトロコイド)のようなスピログラフまたは3次元以上のその他のモンスターに続くことです。とにかくそのような曲線の中心に到達することはできず、それらは円のように見えるので「円形」の軌跡です。


+1ミサイルの加速ベクトルが移動方向に垂直になるように制限されている場合の素晴らしいアイデア。しかし、これはこの質問には当てはまらないと思います。
マーティンソーカ

@Martin Sojka加速度ベクトルは、放射状と方向の接線方向の2つのコンポーネントに分割することもできます。最初のものはあなたがどれだけ回すことができるかを告げ、2番目のものはあなたがどれだけ加速/減速することができるかを告げます。
FxIII

1
はい、相対強度を互いに独立して自由に選択できる場合(つまり、加速度ベクトルの方向と強度が運動ベクトルから独立している場合)、「除外サークル」は消えます。
マーティンソーカ

@Martin Sojka加速強度に制約はありませんか?
FxIII

1
+1それはかなりクールです。私はそれについて前に考えたことがありません。私はおそらくこれを@Matinの答えと一緒に使用しようとするでしょう
ジョン・マクドナルド

8

誘導システムは、ターゲットに向かって直接加速すると最終的にオブジェクトが衝突するという前提に基づいて構築されています。この仮定は間違っているため、その仮定に基づいたガイダンスAIも同様に失敗します。

そのため、ターゲットに向かって直接加速するのを止めてください。ターゲットの位置がミサイルの動きの方向に対して多少垂直であるかどうかを検出するためのロジックを追加します。その場合、ミサイルはターゲットに向かって加速する必要がありますが、前方への動きも遅くなります。そのため、ターゲットに直接向かうのではなく、モーションの方向の現在の速度が遅くなるように、加速の方向をバイアスします。

また、遅くなりすぎないようにするためにトリガーが必要になります。そのため、しきい値の速度を追加して、そのしきい値を下回った場合にバイアスを停止します。

最後に、完璧なガイダンスシステムはありません。ミサイルが実生活でターゲットを迎撃できる理由は、ターゲットがミサイル自体よりもはるかに遅く動き、ターゲットが特に機敏ではないということです(相対的に言えば)。ミサイルが追跡するターゲットよりも何倍も速くならない場合、ミサイルは多くを見逃します。


2
「ターゲットは特に軽快ではありません
ボボボボ

5

ゲーム(および実際)でこれに使用する最も簡単で高度な方法は、比例ナビゲーションです。

二つのオブジェクト(ミサイルとターゲット)が互いの間に視線を変えずに同じ方向に走行している範囲(CBDR)ロジックを減少定数ベアリング下で、彼らはだろう衝突します。

視線、または視線(LOS)は、ミサイルとターゲットの間の架空の線です-ミサイルの位置とターゲットの位置の間のベクトルです。このLOSの角度変化率は、LOS回転率です。

LOS Rotation Rateがゼロになると、視線は変更されなくなります。2つのオブジェクトは衝突コース上にあります。自分をフットボール/サッカーをしながら誰かを追いかけていると考えてください。あなたの視界で彼の体が「凍った」ように彼を導く場合(あなたと彼の間の視線はもはや変わらない)、彼の体が凍って見えるように走る加速を維持している限り、彼と衝突します。あなたの見解。

比例航法(PN)では、ミサイルはLOS回転速度の「N」倍速く加速します。これにより、ミサイルはLOS回転率がゼロになるまでターゲットを強制的に動かします。つまり、ミサイルとターゲットは、視線が変化しなくなった状態でフリーズしているように見えます。変数「N」は、ナビゲーション定数(定数乗数)として知られています。

ミサイルの誘導コマンドは次のように指定する必要があります。

加速=終速度* N * LOSレート

LOSレートは、LOSベクトル(ターゲット位置-ミサイル位置)を測定し、その変数を保存することで簡単に導き出すことができます。新しいフレーム(LOS1)のLOSベクトルから古いフレーム(LOS0)のLOSベクトルを減算して、LOSのデルタを生成します。これで、プリミティブなLOS回転速度が得られます。

Closing Velocityを単純化するには、代わりに現在のLOSベクトルを使用するだけです。

加速度=(target_pos-missile_pos)* LOS_delta * N

Nはナビゲーション定数です。実際には、通常3〜5に設定されますが、ゲームで実際に実行可能な数値は、LOSレート/デルタを導出するサンプリングレートにある程度依存します。ランダムな数値(3から開始)を試して、ゲーム内で望ましい主な効果が見られるまで1500、2000などに増やします。ナビゲーション定数が高いほど、ミサイルが飛行の早い段階でLOSレートの変化に反応する速度が速くなることに注意してください。ホーミングロケットシミュレーションモデルが多少現実的である場合、過度の航法定数がミサイルの空力能力をオーバーロードする可能性があるため、試行錯誤に基づいてバランスの取れた数値を使用する必要があります。


4

マーティンとニコルによる他の回答が指摘しているように、おそらくターゲットに直接ではなく、後でターゲットと衝突するようにミサイルを誘導したいでしょう。ただし、Martinが説明する方法は複雑で、Nicolが説明する方法は非効率的です。

ミサイルを誘導するより簡単な方法ですが、それでもかなり効率的です。ミサイルとターゲットの間の角度の変化に応じて角度を調整します。すべてのティックで、ミサイルからターゲットまでの角度を計算し、前のティックからの角度と比較します。違いは、ミサイルの角度で作りたい正確な違いです。したがって、あるティックで角度が0.77で、次のティックで角度が0.75である場合、ミサイルの角度を-0.02だけ調整する必要があります。この方法は簡単で、ターゲットがミサイルの「前」にある限り、選択されたルートに関して非常に効率的です。また、2Dだけでなく、あらゆる次元に適用されます。

ただし、次のことに注意してください。

  • この方法は、ミサイルとターゲットの速度がまったく同じで、並行して移動する場合に機能しません。まだ理論的にはミサイルの衝突経路をプロットしていますが、無限の時間しかかかりません:)実際にはミサイルは常にターゲットよりも高速でなければなりませんが、同じ速度の場合はコーナーケースを追加して平行かどうかを識別する必要があります。

  • ターゲットとミサイルがまったく同じラインを反対方向に飛んでいる場合、この方法は失敗します。それは現実の世界では実際には起こりえませんが、個別のゲームでは珍しくありません。これをテストするには、上記のアルゴリズムにコーナーケースチェックを追加する必要があります。

  • ミサイルの回転能力が制限されている場合は、それ以上回す必要があるたびに最大回転させるようにします。ミサイルが十分である限り、それはまだ機能します。近すぎる場合は、最後の箇条書きを参照してください。

  • 衝突をチェックするときは、寛大であることを忘れないでください。現実の世界では、多くのミサイルは弾頭に依存して「キルゾーン」を生成するため、ターゲットに実際に衝突するのではなく、ターゲットに近づくだけで済みます。

  • 最後に、実際にはミサイルはまだ見逃している可能性があり、元の質問に戻ります。確かに、いくつかのティックでホーミングを無効にし、ある程度の距離を置いてから再度ホーミングするのが良い方法だと思います。デッドゾーンを識別するためにfxiiiによって提案された方法は、ホーミングをオフにする必要がある場合に検出するのに最適な方法だと思います。


1

過去に取り組んだゲームに「十分」であることがわかっているいくつかの簡単なオプション:

1)見ているシーンの解像度が許せば、オブジェクトはターゲットの近くで爆​​発する可能性があります(どのような場合でも、最も一般的なデイホーミングミサイルが実際に機能すると信じています)。軌道範囲がオブジェクトのサイズの約2倍離れている場合は、見た目が悪くなるため、これはおそらく機能しません。

ソリューションの最終目標が、ミサイルが目標に到達することを確認することだけである場合、目標を達成するだけで十分です。繰り返しますが、これはソリューションの外観に依存します。

2)ミサイルがターゲットに対して直角になっている場合、これはロックが「壊れる」ポイントになる可能性があり、ターゲットがミサイルの「正面」に再び入らない限り、ミサイルはまっすぐに移動します。

可能な限り、常にシンプルなソリューションを好みます。ホーミングミサイルが使用される武器の1つに過ぎないゲームを作成している場合、プレイヤーは一斉射撃を行い、できるだけ早く一定のエンゲージメント武器に交換する可能性が高いため、これらを回避できます。ただし、ミサイルのシミュレーションを行う場合は、明らかに他の答えの1つがより良い選択です。

お役に立てれば。


0

すでに述べたように、ターゲットが現在ある場所ではなく、ターゲットがそこに到着すると予想される場所にミサイルを向けるべきです。これにより、MOSTミサイルの軌道への進入が阻止されますが、ターゲットが適切に回避された場合でも、軌道は可能です。これは航空機のパイロットが入ってくるミサイルをかわすために使用する合法的な戦術です。なぜなら、ミサイルはあなたよりもはるかに速く進んでおり、回転半径が大きくなり、正しい瞬間に鋭い揺れが続くためです。(ただし、近接爆発の危険にさらされる可能性があります。)

FxIIIのポストが話しているゾーンの1つにターゲットが逃げた場合、まだ追跡でき、まだ突き刺さっているミサイルを扱っているため、軌道上の状況が発生します。

しかし、私は彼が問題を解決することに同意しません。代わりに、ミサイルを次のようにプログラムします。

ミサイルが90度で動いている場合、360度の動きで軌道に乗っています。推力を動線から120度に調整します。ミサイルの軌道はそれほど激しく回転していないので広がりますが、ミサイルも遅くなり、機動性が向上します。ターゲット範囲がデッドゾーンの直径の1.25倍に開くと(この直径はミサイルの速度のみに基づいており、実行時に複雑な計算は不要であることに注意してください)、ミサイルは通常の追跡動作に戻ります。

代わりに、ターゲットに設定する範囲がカウントダウンしなくなったときに、ダンバーシーカーヘッドを使用します。


0

これは古い質問であることがわかりますが、これまでの回答では見逃されていたものがあると思います。元の質問では、ミサイル(または何でも)はターゲットの位置に向かって加速するように言われました。これは間違っているといくつかの回答が指摘しているので、後ほどターゲットが置かれると思われる場所に向かって加速すべきです。これは良いですが、まだ間違っています。

あなたが本当にやりたいことは、目標に向かって加速するのではなく、目標に向かって移動することです。これについて考える方法は、目標に向けられた希望の速度を設定し(または目標の位置の投影)、最適な加速を見つけ出すことです(制限がある場合、つまりミサイルはおそらく加速できません)直接逆に)目的の速度を達成する(速度はベクトルであることを思い出してください)。

以下は、今朝実装した実際の例です。私の場合、スポーツシミュレーションゲームのプレーヤーAIで、プレーヤーが相手を追いかけようとしています。動きは、速度を更新するためにタイムステップの開始時に加速度が適用される標準の「キックドリフト」モデルによって管理され、その後、オブジェクトはタイムステップの持続時間にわたってその速度でドリフトします。

この派生物を投稿しますが、このサイトでは数学のマークアップはサポートされていません。ブー!これは最適なソリューションであると信頼する必要がありますが、加速方向には制限がありませんが、ミサイルタイプのオブジェクトには当てはまらないため、追加の制約が必要になります。

コードはpythonで記述されていますが、あらゆる言語の背景で読めるはずです。簡単にするために、各タイムステップの長さは1であると仮定し、それを反映する適切な単位で速度と加速度を表します。

self.x = # current x co-ordinate
self.y = # current y co-ordinate
self.angle = # current angle of motion
self.current_speed = # current magnitude of the velocity
self.acc # Maximum acceleration player can exert on themselves
target_x = # x co-ordinate of target position or projection of it
target_y = # y co-ordinate of target position or projection of it
vx = self.current_speed * math.cos(self.angle) # current velocity x component
vy = self.current_speed * math.sin(self.angle) # current velocity y component
# Find best direction to accelerate
acc_angle = math.atan2(self.x + vx - target_x,self.y + vy - target_y)

atan2(a、b)関数はa / bの逆タンを計算しますが、角度が円の正しい象限に収まるようにするため、aとbの両方の符号を知る必要があることに注意してください。

私の場合、加速度を取得したら、それを適用して速度を更新します

vx_new = vx + self.acc * math.cos(acc_angle)
vy_new = vy + self.acc * math.sin(acc_angle)
self.current_speed = math.sqrt( vx_new**2 + vy_new**2)
self.angle = math.atan2(vy_new,vx_new)

また、プレーヤーに依存する最大速度に対して新しい速度を確認し、その上限を設定します。ミサイル、車、または最大回転率(1ティックあたりの度数)のあるものの場合、計算された理想に対する現在の動きの角度を単純に見ることができ、この変化が許容よりも大きい場合は、角度を理想に向かって可能な限り。

これの派生に興味がある人のために、私はティムステップ後のプレイヤーとターゲットの間の距離を、初期位置、速度、加速率、および加速角に関して書き留め、その後、加速角に関する微分を取りました。これをゼロに設定すると、加速角の関数としてタイムステップ後のプレーヤーとターゲットの距離の最小値が見つかります。これはまさに知りたいことです。興味深いことに、加速率は元々方程式に含まれていましたが、実際にどれだけ加速できるかに関係なく、最適な方向を打ち消します。


いくつかのシナリオでは、速度を直接設定することをほぼお勧めしますが、ほとんど力に依存する物理システムと統合するのは難しいかもしれません。これがミサイルが定期的に発射されるゲームであり、「回避」が顕著なゲームメカニックではない場合、物理学が邪魔になるという小さなリスクを回避し、プレイヤーが期待するとおりにこのメカニックが機能することを保証することができます毎回。これは、たとえば、宇宙アクションゲームよりもRTSの方が意味があります。
Katana314

0

一定の回転率を使用しています。それがまさに完全な円軌道を作り出しているのです。

ガイダンスシステムのより現実的なアプローチは、ターゲット距離を逆にしてターンレートを変化させることです(距離が短い->ターンレートが高い)。これにより、軌道ではなくらせんが与えられ、より遅いターゲットとの衝突が保証されます。

また、はるかに現実的な飛行経路を提供します。一定の回転率は不自然に完璧です。乱流をシミュレートするために、回転速度にランダムな変動を追加することもできます。繰り返しますが、はるかに現実的であり、実際には定常状態の軌道シナリオを回避できます。

部分方程式は不要です。

弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.