ターゲット追跡:回転タレットを加速および減速するタイミングは?


24

target次のように定義された移動円形があるとします。

Vector2 position;
Vector2 velocity;
float radius;

そして、turret次のように定義された回転(何らかの移動車両に搭載)

Vector2 position;
Vector2 velocity;
float angle; // radians
float angularVelocity; // radians per second
const float maxAngularVelocity; // radians per second
const float maxAngularAcceleration; // radians per second per second

(またはそれらの線に沿った何か。両方の位置と速度は他の場所で制御されることに注意してください-速度は一定であり、速度に基づいて位置が変化すると仮定します。)

特定のフレームで、次の2つのAI関数を作成して決定しようとしています。

  • 砲塔をターゲットに向け続けるために、砲塔の角度にどの角加速度(およびどの方向)を適用しますか?

  • ターゲットが現在視界にある場合、その半径内の任意の部分をx数秒間視界に保つことができxますか?(あるいは、ターゲットが実際に「ロックオン」され、単にサイトを横切って飛行するのではないことを保証する別の戦略がありますか?)

そして、私はいくつかの助けを使うことができます...


1
回転の加速と減速の値が異なる場合があります-実際には、1つはおそらくモーターであり、もう1つはブレーキです。
e100

回答:


19

まず、砲塔に面する方向とターゲットの方向の角度の差を決定する必要があります。

Vector2 turretToTarget = target.position - turret.position;
float desiredAngle = atan2(turretToTarget.y, turretToTarget.x);
float angleDiff = desiredAngle - turret.angle;

// Normalize angle to [-PI,PI] range. This ensures that the turret
// turns the shortest way.
while (angleDiff < -PI) angleDiff += 2*PI;
while (angleDiff >= PI) angleDiff -= 2*PI;

これらの数量を取得したら、タレット角度の2次式を設定できます。更新のたびにこれを計算して、常に位置と速度の最新データを使用するようにする必要があります。

// Compute angular acceleration.
const float C0 = // Must be determined.
const float C1 = // Must be determined.
float angularAcc = C0 * angleDiff - C1 * turret.angularVelocity;

ここでは、加速式の最初の項(ゼロ度)により、砲塔が目標に向かって回転し始めます。ただし、時間内に停止するのではなく、前後に振動します。停止させるには、高い回転速度に高い加速度が逆行する原因となる減衰第2項(1次)が必要です。

システムが適切に動作するように、正の定数(必ずしもプログラム定数である必要はありません)を決定し、バランスを取る必要があります。C0システムの速度の主要な制御です。の値を大きくするC0と回転速度が速くなり、値を小さくすると回転速度が遅くなります。実際の値は多くの要因に依存するため、ここで試行錯誤を行う必要があります。C1減衰の大きさを制御します。二次方程式の判別式は、C1*C1 - 4*C0 >= 0振動しないシステムがある場合にそれを伝えます。

// New definition.
const float C1 = 2*sqrt(C0); // Stabilizes the system.

C1数値的な理由からおそらくこれよりも少し大きい値を選択する必要がありますが、過度に減衰し、応答が遅くなる可能性があるため、大きすぎないようにしてください。繰り返しますが、微調整する必要があります。

また、このコードは角加速度のみを計算することに注意することが重要です。角度と角速度は、何らかの別の積分器を使用して、これからどこかで更新する必要があります。質問から、これはカバーされていると思います。

最後に、高速ターゲットを追跡する場合、砲塔はおそらく常に後ろにあるため、遅れについて言うことがあります。これに取り組む簡単な方法は、ターゲットの位置に線形予測を追加することです。つまり、常にターゲットの前方にわずかに前方を向けます。

// Improvement of the first lines above.
const float predictionTime = 1; // One second prediction, you need to experiment.
Vector2 turretToTarget = target.position + predictionTime * target.velocity - turret.position;
/// ...

ターレットをターゲットの半径内でしばらくの間照準を保つことに関して、これはこの種のシステムに直接課すことは難しい要件かもしれません。このコントローラーは、常に砲塔をターゲット(または予測された位置)に向けるよう努力することを確信できます。結果は満足できるものではないが判明した場合、あなたはパラメータを変更する必要がありpredictionTimeC0かつC1(安定した境界内)。


これが正しいかどうかを言う資格はありませんが、巧妙なもののように聞こえます!私は過去に加速の効果を前もって予測し、いつ加速し、いつ「ブレークを適用する」かを解決することで、この種の問題を解決しました。それは私が間違っていたことを意味しますか?
イアン

atan2のxおよびyパラメーターはtに依存するため、atan2ではこの方法を予測システムに適合させることが困難になります。
スキズ

これはまさに、以下の回答で示唆した解決策です。優れたディテールとプレゼンテーション!
drxzcl

@Iain:いいえ、ここには善悪はありません。私の方法には加速/減速の2つの離散状態があると思いますが、この方法は制御理論からのレギュレーターに触発され、加速をスケーリングしてオーバーシュートと振動を減らしながら高速応答を行います。
スタファンE

1
他のコメントと同様に、これは静止したターゲットでは機能しますが、移動するターゲットでは受け入れられない可能性があります。C0とC1の用語は、従来の減衰スプリングのk要素です。C0はスプリングの強度(通常)と、C1は減衰係数(通常「B」または「c」)を表します。そうです、あなたは減衰を上げることにより、振動を最小限に抑えることができますが、問題は、これはターゲットがどこ先取りしようとしないということであるだろうので、所望の目的を遅らせるために運命づけられている、こと。
ダッシュトムバン

3

ここにあるのは基本的な制御問題です。タレットはシステムであり、加速度は制御であり、センサーは位置/速度を測定します。これらの問題に取り組むには多くの方法がありますが、それはエンジニアリングにおいて非常によく研究されている問題だからです。

キーは最終的に安定したシステム、つまり振動を生成しないシステムになります。これは通常、減衰を追加することによって行われます。ウィキペディアのページから始めてください。


2

まず、砲塔からターゲットまでのベクトルを計算します。次に、これを砲塔の現在のベクトルと比較します。次に、2つの差を使用して、所定の時間内にタレットが正しい方向を向くようにするために必要な角加速度と角速度を計算します。

OK、それは簡単に思えた。ただし、ターゲットは砲塔を回した時点までに移動するため、ターゲットの位置を予想する必要があります。これをする:-

Pd' = Pd + t.Vd
Ps' = Ps + t.Vs

ここで、Pは位置、Vは速度、下付き文字は目的地(ターゲット)のd、ソース(タレット)のsです。これにより、方向ベクトルが得られます。

Dsd' = Pd' - Ps' = Pd + t.Vd - (Ps + t.Vs) = Pd - Ps + (Vd - Vs).t

ここで、Dは方向ベクトルであり、Dsd 'は時刻tに必要な方向です。次に、現在の位置と、指定された時間tの最大速度と加速度に基づいて、砲塔の方向を決定します。

Ds' = t.Ds.Rs -> this is a vector rotation

DsとDs 'はソース方向で、Rsは回転速度です。以上のことから、Dsd '== Ds'であり、したがってRs(必要な回転速度)のtを見つける必要があります。すべてのP、D、およびVがxおよびyコンポーネントを持っていることを忘れないでください。

ここでは加速を考慮していません。これにより、複雑さがさらに増します。Rsとtが得られたら、おそらく放物線Rsを近似(加速と減速)して同じ結果を得ることができます。


これはインターセプト計算の良い答えのように見えますが、残念なことに、そのような数学表記を読んでプログラムコードに変換できる人と、その答えをまだ知らないほとんどの人との間には大きなギャップがあります質問。言い換えれば、その数学表記を読むことができるゲーム開発者は、おそらく発射ソリューションのプログラミング方法をすでに理解していると思います。あなたの用語が何を意味するのかを説明してくれれば、あなたの式を理解するのに役立ちます。
ドロンツ


0

最初に行うことは、急流と追跡対象の間の角度を計算することです。
次に、現在のトレント速度を使用し、最大加速度を逆方向に適用する(トレントを停止する)ことで、追跡対象の前後でトレントが停止するかどうかを確認します。
答えが、追跡対象のオブジェクトの前にトレントが停止するというものである場合、前方に最大加速度を適用します(速度を上げます)。
答えが、追跡されたオブジェクトの後にトレントが停止することである場合、最大加速を逆方向に適用します(トレントを停止します)。
このようにして、トレントは常に最速で到着し、適切なポイント(またはその一部)で停止します。

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