2016-08-10 14 views
2

私はReynoldsの古典的なBoidsペーパー、より具体的にはnatureofcode.comのDan Shiffmanの実装に基づいて到着する動作を持つ自律エージェントを作成しようとしています。これらのアプローチは両方とも理解しやすく(また動作しやすい)、最後のフレーム更新以降の経過時間を照会し、オイラー統合ステップ中にこの時間デルタを適用するのではなく、固定名目更新ステップを前提としています。すなわち、それらは単に示唆:到着動作を時間デルタで実装する方法は?

//pseudocode 
acceleration.add(force); 
velocity.add(acceleration); 
location.add(velocity); 

を私は時間デルタを含めたい場合しかし、その後、様々な物理学の論文が、私はこれを書き換える必要がありますお勧め:私は、ステアリング動作を実装しようとするまで、これも動作します

//pseudocode 
delta = timeElpasedSinceLastFrameUpdate(); 
acceleration.add(force); 
deltaAcceleration = acceleration.mult(delta); 
velocity.add(deltaAcceleration); 
deltaVelocity = velocity.mult(delta); 
location.add(deltaVelocity); 

具体的には到着行動である。方法論を参照のためにここにリンク例6.2を参照してください(擬似コードで)

Nature of Code Steering Behaviours

問題のステップはsteeringForce =所望である - 速度。

時間デルタが適用されていないと、操舵力に「速度」が寄与すると、現在保持されている速度ベクトルに正しく反作用され、オブジェクトが到着先で減速停止します。

しかし、デルタが適用されているが、steeringForceは加速度をデルタで乗算すると分数時間デルタで効果的にモデレートされるため、オブジェクトを時間内に停止させるのに十分な減速度を蓄積速度に適用せず、振動する挙動。

累積された力(すなわち加速度)に時間デルタを掛けないでこれを修正することはできますが、これは正しくないようです。

だから、私の質問:到着行動のためのsteeringForceが可変のデルタ時間を考慮するために生成する必要がありますどのように

ありがとうございました。

答えて

1

編集:質問の主要部分を逃しました。あなたが望む結果を得るには多くの方法がありますが、それぞれ異なる方法で行います。私が思いつくのが最も簡単なのはおそらくsteeringForceをすべてスキップして速度を変更することです。

我々は

desired_velocity = velocity + correction 

これは、あなたが以前に書いたのと同じである(ただし、「steeringForce」の)というベクトルは、そのような希望:

correction = desired_velocity - velocity 

velocity + correctionを行うことにより、あなたはすぐに希望を取得しますそれは非常に不気味な動きにつながります。

len = length(correction) 
corr_length = len > max_correction ? max_correction : len 
correction = correction/len*corr_length 

そして今、あなたはこれが発振せず、多少の動的運動につながるはず

velocity += correction 

を行うことができます。代わりに、スムーズな運動につながるいくつかの値に補正をクランプできます。


明示的な時間ステップの統合(あなたのケースでは、前方オイラーは、例えば)通常

new_acceleration = old_acceleration + (delta_t/mass)*force 
               ^^ note 

と同様に、と書かれている

new_velocity = old_velocity + delta_t*acceleration 
new_position = old_position + delta_t*velocity 

だからあなたの質問に答えるために、あなたがする必要があります蓄積する前に時間ステップを掛けます:

acceleration.add(force.mult(delta_t/mass)); 
velocity.add(acceleration.mult(delta_t)); 
location.add(velocity.mult(delta_t)); 
+0

詳細な返信と返信の遅れにお詫び申し上げます。私は、ステアリングフォース変数の使用を避け、速度を直接操作することでどのように修正を提供することができるかを見ることができますが、ステアリングビヘイビア全体の原理を破るように見えます。 turnは位置を決定する速度に影響を与える。可変時間ステップデルタの文脈でこのパラダイム内で作業する方法はありませんか?すなわち、適切な操舵力を得ることができるか? –

+0

@MattGreenhalgh現実にはこれを達成できないので、この方法は「物理的に正しい」ものではないということは間違いありません。しかし、私は多くのアプリケーションでこの方法(およびそれの小さな変更)が十分であると言います。これは実際には速度を制御する小さなPIDコントローラ(参考文献を参照)です。代わりに 'steeringForce'のために同じことをすることができますが、もう少し複雑になります。私はあなたの学問レベルを知らなかったので、私は最もまっすぐな解決策を最初に提案したかったのです。 – pingul

+0

https://en.wikipedia.org/wiki/PID_controller – pingul

関連する問題