宇宙船の動的スラスタバランシング


14

私のゲームの宇宙船は、任意の量のスラスタを任意の回転で任意の場所に取り付けてプレイヤーが構築することを意図しています。現在、船を所定の角度に回転させる(加速と減速)ための汚いコードがあります。

これは、赤い線が指す場所に面し、左に回転するように指示された対称的な船の例です。

輸送する

しかし、ご想像のとおり、プレイヤーがスラスタをどこに置いたかによっては、望ましくない直線的な力が船に影響を与えることがあります。この場合、船は前進し始めます。

スラスタが線形速度を発生させないために適用できる最大推力を見つけることができるかどうかについて詳しく説明しています。(上記の場合、後部スラスタからの力に対抗するものが何もないため、それはありません。前部スラスタは互いに殺します)。

これまでに思いついたのは、「回転効率」を決定する式です。たとえば、直線運動に関連してどの程度の回転が発生するかです。

a-スラスタaへの位置ベクトルb-スラスタbへの位置ベクトルv1-スラスタaからの力v2-スラスタbからの力

EfficiencyDelta = a.cross(v1)/ | v1 | -(a.cross(v1)+ b.cross(v2))/ | v1 + v2 |

、基本的に「a.cross(v1 * t)/ | v1 |」ターン効率となるはずです。そして、新しいスラスタを発射する価値があるかどうかを確認するために、スラスタの回転効率を合わせて差し引きます。

スラスタがオン/オフになっているわけではないことを認識したときに問題が発生しますが、スラストを0から1に変えることができます。また、プレイヤーが船を前進させたい場合の対処方法 もちろん、回転/移動する量のバランスが必要です。

私はロケット科学者ではないので、各スラスタのスロットルをこのように計算し、正しい方向にプッシュすることが可能かどうかを教えてくれる人がいることを望んでいます。

お時間をいただきありがとうございます!/キム


3
私は同じ道から始めましたが、多くの構成では、回転と平行移動の両方を行うことは不可能です。だから、あなたは回転を奪いますか?または、翻訳を許可しますか?最終的に、それは船を設計するユーザー次第です。このデモのために、私はそれを偽造しました。関連:gamedev.stackexchange.com/questions/58216/…、gamedev.stackexchange.com / questions
MichaelHouse

私は同様の道を進み、このページでデモを書くことになりました。スラスタを動かしたり(船にドラッグして位置とパワーを設定したり)すると、3つの形状が描画されます。直観は、すべての可能な動きを3D空間(x、y、回転)の点と考えることができ、0-1に制限されることはその空間の制約です。そのため、すべての可能な動きを含む3Dシェイプになります。あなたは何の線速度を希望しない場合は、そのスペース内の(x = 0、Y = 0)の行(Q、W、E、私のデモのすべての0をS)を見ている
amitp

回答:


7

そうでなければ、この分析は成り立たないので、あなたはあなたの船に物理的に正しい動きがあると仮定します。この問題を適切に解決するには、効率よりも強力なものが必要です。

各スラスタは、船の動きに線形と角度の2つの効果をもたらします。これらは独立して考えることができます。スラスタがf方向dirに力を生成し、ベクトルによって重心からオフセットされる場合r(幾何学的な中心またはスプライトの中心ではない!)場合、線形コンポーネントへの影響は次のとおりです。

t = f * dir // f is a scalar, dir is unit length

角速度への影響はトルクによって与えられます:

tau = f * <dir.x, dir.y, 0> CROSS <r.x, r.y, 0> // cross product

t 力ベクトル(つまり、線形推力)です。 tauは、質量慣性モーメントで除算すると、角加速度を与える符号付きスカラーです。ことが重要であるdirとは、rローカル座標で、または両方のワールド座標の両方、すなわち、同じ座標空間の両方です。

船の全体的な線形加速度は、t各スラスタのの合計を船の質量で割った値で与えられます。同様に、角加速度は、トルクの合計を慣性質量モーメント(別のスカラー)で割ったものです。合計トルクがゼロの場合、船は回転しません。同様に、総推力がゼロの場合は移動しません。リコールトルクはスカラーですが、推力(の合計t)は2Dベクトルです。

この博覧会のポイントは、問題を線形プログラムとして書くことができるようになったことです。最初に、移動せずに船を回したい。各スラスタの変数$ x_1、x_2、... $があります。これは、スラスタが提供する推力の量です。制約の1つのセットは次のとおりです。

0 <= x_i < fmax_i  //for each i

fmaxそのスラスタの最大の力はどこにありますか(これにより、より強いまたはより弱いものが得られます)。次に、我々は両方の平等を言う:

0 = Sum_i  x_i * dir_i.x
0 = Sum_i  x_i * dir_i.y

これは、総推力がゼロである(推力はベクトルなので、各部分がゼロであるとだけ言う)ことで、線形加速度を適用しないという制約をエンコードします。

今、私たちは船に向きを変えてほしい。おそらく私たちはできるだけ早くそれをしたいので、次のことをしたいのです。

max (Sum_i  x_i * c_i)
where c_i = <dir_i.x, dir_i.y, 0> CROSS <r_i.x, r_i.y, 0>

の解決 x_i上記の不等式と等式を満たしながらを上記の合計が最大化され、目的の推力が得られます。ほとんどのプログラミング言語には、LPライブラリが用意されています。上記の問題を入力するだけで、答えが得られます。

同様の問題により、方向転換せずに移動できます。正のx方向に移動したい座標系で問題を書き直したとします。制約は次のとおりです。

0 <= x_i < fmax_i  //for each i
max Sum_i  x_i * dir_i.x
0 = Sum_i  x_i * dir_i.y
0 = (Sum_i  x_i * c_i)
where c_i = <dir_i.x, dir_i.y, 0> CROSS <r_i.x, r_i.y, 0> // as before

スラスタは単一方向の推力しか生成できないという制約により、達成できる回転と線速度の種類には制限があります。これは解決策として現れます0 = x_1 = x_2 = ... = x_nます。つまり、どこにも行けないということです。これを緩和するために、各プレイヤーが両側に45度のスラスタを配置するために、小さく弱い(たとえば5%、10%)スラスタを追加することをお勧めします。これにより、ソリューションの柔軟性が向上します。これらは、メインスラスタの弱い二次的な影響に対処するために使用できるためです。

最後に、最大100個のスラスターまで、LPの解決はフレームごとに実行できるほど高速です。ただし、ソリューションは場所や現在の状態に依存しないため、形状が変化するたびに、合理的なコントローラー入力の組み合わせごとにソリューションを事前計算できます(これには、慣性モーメントまたは船の質量を変更する非スラスタを追加すること、その理由は、スラスタが重心に対して異なる場所にあるからです!)。これは24の可能性です(つまり、8方向の時間{左回転、回転なし、右回転})。


非常によく説明されています!
キム14年

1
何をしないSum_i、この文脈で意味ですか?
S.タリクチェティン

1

私が最初に考えたのは、純粋に経験的なソリューションでした。つまり、サンドボックス環境でリグをシミュレートして、推力の程度を変えて動作を解明します。決定論的ソリューションの検索で多くの複雑な数学のバランスをとる代わりに、たとえばニュートンの方法を使用して数値的に達成できます。例:

推力の範囲は0〜1000で、1000はALOTです。

ステップ1

信頼(0 + 1000)/ 2 = 500でシミュレートします。結果:過度の信頼

ステップ2

範囲は0〜500になりました。信頼(0 + 500)/ 2 = 250でシミュレートします。結果:過度の信頼

ステップ#3

範囲は0〜250になりました信頼を使用してシミュレート(0 + 250)/ 2 = 125結果:信頼が少なすぎます

ステップ#4

範囲は125〜250になりました信頼を使用してシミュレート(125 + 250)/2=187.5結果が多すぎる

ステップ#5 範囲は125〜187.5になりました信頼を伴うシミュレーション(125 + 187.5)/2=156.25結果が小さすぎる信頼

ステップ6 範囲は156.25から187.5になりました範囲は35のしきい値を下回っています。つまり、十分な推定値であることを意味します

最終結果=(187.5 + 156.25)/ 2 = 171.875

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