船を回転させるためにオンにするスラスタを決定する方法は?


47

船の構成は動的に変化するため、船を時計回りまたは反時計回りに回転させたいときに、どのスラスタをオンにするかを決定する必要があります。スラスタは常に船と軸が揃っており(角度を付けない)、オンまたはオフです。可能なセットアップの1つを次に示します。

http://i.stack.imgur.com/GSBSH.png

これまでに試したことは、発砲ベクトルと船の重心への方向ベクトルを視覚化することです。

http://i.stack.imgur.com/ZzNzi.png

残念ながら、私はそれでそれほど遠くに行きませんでした。


7
力ベクトルで正しい方向に向かっています。船を重心の周りで回転させようとしているので、角速度の公式を調べてみてください。
Amplify91

私は、各ポイントでそれを行う方法を正確に忘れますが、基本的にはそのわずかな力en.wikipedia.org/wiki/Center_of_mass特にen.wikipedia.org/wiki/Parallel_axis_theorem
CobaltHex

1
私はまったく同じ考えを持っていました!簡単にできるヒントの1つは、スラスタごとに角加速度と直線加速度を1回計算するだけでよいため、計算は必要に応じて複雑になる場合があります。
マーカスフォンブロードー

@ Amplify91、あなたのコメントのレリーは私がそれを理解するのを助けてくれました、ありがとう!
-migimunz

1
@migimunzキーを押すごと(スラスタのグループ)ではなく、スラスタごとに加速度を計算することを考えていました。また、(一部の人が所定の位置に回転させる回転速い貿易う)プレイヤーにスラスタは面白いかもしれ押されたキーに起動すべき選択肢を与える
マルクス・フォン・Broady

回答:


22

成功!ここにあり、必要に応じて回転しています: ここに画像の説明を入力してください

私がやったことは次のとおりです。各スラスタについて、重心に関連してトルクの大きさを計算します。

private function thrustTorque():Float
{
    // distToCom is the distance vector between the thruster and center of mass
    // fire angle is a unit vector representing the direction of the thruster
    var distAngle = Math.atan2(distToCOM.y, distToCOM.x);
    var fireAngle = Math.atan2(dir.y, dir.x);
    var theta = fireAngle - distAngle;
    var torque = distToCOM.length * Math.sin(theta);
    return torque;
}

ウィキペディアによると、トルクの大きさの式はT = rF sin(theta)であり、ここで:

  • rはスラスタとCOMの間の距離です
  • Fは、適用される力の大きさです(記号は気にするだけなので、1つだけのふりをして省略します)。
  • thetaは2つのベクトル間の角度です

プレイヤーが左を押すと、そのスラスタのトルクの兆候を確認します。ゼロよりも小さい場合は、スラスタを発射します。時計回りに回すのは逆です。

これはおそらく、ドット積を使用してベクトル間の角度のコサインを計算することで改善できますが、明日まで待たなければなりません。

最後に、ライブデモがあります。


ほぼそこにあると思います。正確には重心ではないようです。左/右矢印のみを使用すると、船は簡単に画面から消えます。しかし非常に近い。おそらく、あなたが測定しているポイントはわずかにずれています。または、しばらくすると安定して良好なスピンになるように見えるため、タイミングの問題になる可能性があります。いい仕事だ。
マイケルハウス

私はそれがこの論理と関係があるとは思わない。このメカニズムによって選択された一連のサースターを発射することから車両が正味の並進力を受けないことを保証するものはここにはありません。正味の並進力を維持しないことが要件である場合、個々のスラスタの力を調整できる必要があります(おそらく解決するのがはるかに困難な問題になります)
トレバーパウエル

@TrevorPowell、正確に。簡単にするために(そして、楽しく、船の性能は設計の程度に依存するので)、スラスタのオンとオフのどちらかを決定しました。おそらく、トルクが小さすぎる(したがって横方向の動きが大きすぎる)ものがオンにならないようにしきい値を含めますが、「大きすぎる/小さすぎる」の正確な量は、おそらく試行錯誤によって決定されます。
migimunz

3
角度の計算を回避するために行うことは、垂直ドット積を使用することです(z = 0の3Dベクトルを使用する場合、トルクT = r cross Fの外積定義から導出されます)。同じ大きさでrに垂直なベクトル(-ry、rx)を取得し、そのベクトルとFの内積を計算します。結果はT = rx * Fy-ry * Fxです。次に、abs(T)はトルクの大きさであり、その符号は方向を示します。T> 0は反時計回り、T <0は時計回りです。
ジョレン

1
動作する理由は直感的にわかりやすく、r dot F = r F cosθです。rを反時計回りに90度回転してドット積を取ると、cos(θ-90˚)= sin(θ)なのでr F sinθが得られます。
ジョレン

14

トルクのための一般的な3D表現は、変位と力の外積である:T = RF。2次元では、トルクのスカラー値で十分であり、スラスタの直交方向が4つしかない場合、区分形式で記述できます。

  • + x方向の力:T = F *(-ry)
  • -x方向の力:T = F *(ry)
  • + y方向の力:T = F *(rx)
  • -y方向の力:T = F *(-rx)

ここで、Fはスラスタによって生成される力の大きさ、rxとryはピボットポイントからスラスタまでのベクトルのxおよびy成分です。正のトルクは、船を反時計回りに回転させる傾向があります。上記の4つの式を使用すると、各スラスタが生成するトルクの符号を推測するのは簡単です。

物理学を適度に正確に表現するには、推力の符号だけでなく、その合計の大きさと回転慣性も知る必要があります。さらに、回転を行うために適切に配置されたすべてのスラスタを単にアクティブにしたくない場合があります。

宇宙船

描かれているように、スラスタB、D、およびEへのフルパワーは回転を最大化しますが、船を右に加速します。Dをシャットダウンすると、これを防ぎます。代わりに、右への加速が意図されているが、時計回りの回転が意図されていない場合、最も効率的な方法は、CとFの両方をDとともにフルパワーの3分の2で有効にすることです。

これがあなたがやろうとしていることの範囲を超えていなければ、明らかに単純なタスクではなく、運動方程式用のある種のソルバーを書く必要があります。


7

いくつかの異なるもの。まず、これが制約の少ない問題であることを認識する必要があります。すなわち、同じ方向に回転するために発火できるスラスタの多くの異なる組み合わせがあります。あなたの状況では、スラスタには「オン」と「オフ」の2つの状態しかなく、すべてのスラスタが等しい力を出力すると仮定しています。

第二に、モデルを目で見てみると、「重心」は実際には重心ではないように見えます。幸いなことに、これはトルクの計算には影響しません。ただし、重心変位の計算には影響します。あなたの「重心」は、少なくとも真の重心に最も近い正方形であるため、そのレベルの精度を気にするかどうかはわかりません。

第三に、特定のスラスタが回転にどのように影響するかを計算する場合、非効率的な式を使用しているにもかかわらず、それは正しいことです。トルクは、のように計算することができるr x F大きさを有しています、r*F*sin(theta)。ただし、この場合の角度の計算は非効率的な方法です。代わりに、トルクのクロス積定義を直接使用する必要があります。これは、使用している表現を使用するとはるかに簡単になるためです。すべてのベクトルにはzコンポーネントがないため、外積の式は大幅に簡素化されます。

計算結果をまったく変更せずに、コードを更新するだけです

private function thrustTorque():Float
{
    var torque = distToCOM.x*dir.y-distToCOM.y*dir.x;
    return torque;
}

それははるかに優れています(そしてより高速です)。

あなた自身の答えで、あなたの解決策はすべてのスラスタを正しい方向のトルクで発射することだと提案しています。さて、それはあなたが尋ねた質問をほぼ解決します。ただし、ユーザーが「回転」ボタンを押したまま、正のトルクを持つすべてのスラスタが回転し、潜在的にそれらを上に移動すると、線に沿ったある点で、戦略がそれほど満足できないことがわかります。スラスタからの力を実際に計算する場合や、発射を視覚的に表示してから一定の加速度などでモデルを回転させる場合、シミュレーションの詳細レベルがわかりません。方法として、スラスタを少なくともほぼ正確に発火させる必要があります)。

船にかかる正味の力は考慮しません。任意のスラスター量がある場合、これはかなり複雑な問題になる可能性があります。ただし、スラスタの状態は2つしかないため、分析は非常に簡単です。ここでの目標が正確に定かではないので、2つの異なる目標を想像できます。まず、必要な方向のトルクを維持しながら、総力を最小限に抑えたい。第二に、総力に対するトルクの比率を最大化します。

余談ですが、すべてのスラスタの出力に同時に影響する追加の「スラスタボリューム」コントロールを想像できる場合は、2つのソリューションのトルクが等しくなるようにこのコントロールを設定できます。最初よりも小さい変位。ただし、回転するだけでまったく動かないようにスラスタを発射できる場合は、両方のソリューションが同じであることを覚えておく必要があります。

したがって、前の段落の引数に基づいて、2番目のソリューションを使用します。さて、総力を分析するとき、エンジンが指すことができる方向は4つしかないことに簡単に注意できます。したがって、x方向の合計力は、左を指しているスラスタの数から右を指している数を差し引いただけで、y方向についても同様です。

ここまで書いた後、私はそれを最適化するアルゴリズムについてもう少し考えなければなりません。投稿の残りの部分はそのまま役立つと思うので、投稿していますが、この構成を最適化する最適な方法を見つけたときに更新します(おおよその答えを得るためのいくつかの方法を考えましたが、それらのどれも正確ではありません)。


答え(およびトルクを計算するためのより高速でクリーンなソリューション)をありがとう。赤い丸は船のCOMではなく、パワーコアです。私は物理エンジンを使用しており、船にローカルインパルスを適用しているだけです。さまざまな構成で遊ぶのが非常に楽しくなるので、ソリューションが完璧ではないことは大丈夫ですが、あなたが何を思いついたか知りたいです。
migimunz

1
任意の基準点からトルクを計算できます。結果の数は変わりますが、重心である必要のないこの点を中心に船を回転させる限り、物理的挙動は変わりません。実際、質量分布に関する情報がなければ、重心自体は任意であり、そのように計算することはできません。
マルクストーマス
弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.