如何确定打开哪些推进器以旋转船舶?


47

船的配置会动态更改,因此当我想顺时针或逆时针旋转船时,必须确定要打开哪个推进器。推进器始终与船舶轴线对齐(永远不成角度),并且可以打开或关闭。这是可能的设置之一:

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

到目前为止,我已经尝试过将发射向量和方向向量可视化到船的质心:

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

不幸的是,我对此并不了解。


7
力矢量将使您朝正确的方向前进。请尝试查找角速度的公式,因为您试图使船绕质心旋转。
Amplify91 2012年

我忘了该怎么做,但基本上它只是作用在每个点上en.wikipedia.org/wiki/Center_of_mass特别是en.wikipedia.org/wiki/Parallel_axis_theorem
CobaltHex12年

1
我有完全相同的想法!一个可能使您更轻松的技巧是,您只需为每个推进器计算一次角加速度和线性加速度,因此计算可能会随所需而变。
Markus von Broady,2012年

@ Amplify91,您的评论巧妙地帮助了我,谢谢!
migimunz 2012年

1
@migimunz我本来是想计算每个推进器的加速度,而不是每个按键(推进器组)的加速度。同样,给玩家一个选择,应该激活哪个推进器,按下哪个键可能会很有趣(有些人会以更快的旋转速度
换成

Answers:


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;
}

根据Wikipedia的描述,扭矩的大小方程为T = rF sin(theta),其中:

  • r是推进器与COM之间的距离
  • F是施加的力的大小(我忽略了这个,假装它只是一个,因为我只关心符号)。
  • theta是两个向量之间的角度

当玩家向左按下时,我检查该推进器的扭矩符号-如果小于零,则发射推进器。顺时针旋转则相反。

可以通过使用点积计算向量之间的角度的余弦值来改善这一点,但这必须等到明天。

最后,这是一个现场演示


我想在那附近。它似乎不完全是重心。只需要使用向左/向右箭头,船就可以轻松离开屏幕。虽然非常接近。也许您要测量的点略有偏离。否则可能是一个时间问题,因为一段时间后它似乎稳定下来了。干得好。
MichaelHouse

我认为这与这种逻辑无关。这里没有任何东西可以确保车辆不会发射通过此机制选择的一组thurster产生的净平移力。如果不需要保持净平移力,则将需要能够调节单个推进器的力(并且可能会变得更加难以解决)
Trevor Powell

@TrevorPowell,完全是。为了简单起见(也很有趣,因为您的船的性能取决于您的设计水平),所以我决定打开或关闭推进器。我可能会添加一个阈值,以使那些不会引起太小扭矩(从而导致过多的横向运动)的阈值不会打开,但是“过多/过少”的确切大小可能取决于试错法。
migimunz 2012年

3
您想要避免角度计算的方法是使用垂直点积(如果使用z = 0的3D矢量,则取自扭矩T = r cross F 的叉积定义)。取垂直于r且幅度相同的向量(-ry,rx),然后计算该向量与F的点积。结果为T = rx * Fy-ry * Fx。然后,abs(T)是转矩的大小,其符号表示方向:T> 0为逆时针方向,T <0为顺时针方向。
Joren 2012年

1
它起作用的原因很容易直观地看出:rF = r F cosθ。如果将r逆时针旋转90度并求出点积,则得到r F sinθ,因为cos(θ-90˚)= sin(θ)。
Joren 2012年

14

对于扭矩的通用3D表达是位移和力的叉积:Ť = - [R˚F。在二维中,扭矩的标量值就足够了,并且仅给出推进器的四个正交方向,我们可以分段形式编写:

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

在此,F是推力器产生的力的大小,rx和ry是从枢轴点到推力器的向量的x和y分量。正扭矩倾向于使船逆时针旋转。使用上面的四个公式,推论每个推进器产生的扭矩的符号是很简单的。

对于适度准确的物理学表示,您不仅需要知道推力的符号,还需要知道其总大小和旋转惯量。而且,您可能不只是想激活所有正确对齐的推进器进行旋转。

太空飞船

如图所示,推进器B,D和E的全功率将使旋转最大化,但也将使船向右加速。关闭D可以防止这种情况。如果相反,是打算向右加速,而不是顺时针旋转,则最有效的方式是使C和F都以D的三分之二的全功率启用。

如果这不超出您要尝试的范围,则必须为运动方程编写某种求解器,显然这不是一件简单的任务。


7

一些不同的事情。首先,我们需要认识到这是一个约束不足的问题。就是说,推进器有许多不同的组合,它们可以发射而导致沿相同方向旋转。我假设在您的情况下,推进器只有两种状态:“打开”和“关闭”,并且所有推进器都输出相等的力。

其次,盯着模型,看起来您的“质心”实际上不是您的质心。幸运的是,这不会影响您的扭矩计算。但是,它将影响您对质心位移中心的计算。不过,我不确定您是否关心该级别的准确性,因为您的“质心”至少是最接近真实质心的正方形。

第三,尽管要使用某个效率低下的公式,但如果要计算某个推进器将如何影响旋转,就可以做到这一点。扭矩可以计算为r x F,具有大小r*F*sin(theta)。但是,在这种情况下,计算角度是一种无效的方法。相反,您应该直接使用扭矩的乘积定义,因为使用您的表示将更加简单。因为您所有的向量都不具有z分量,所以叉积的公式大大简化了。

完全不更改您的计算结果,我们只需更新您的代码

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

这样更好(更快)。

您在自己的答案中建议您的解决方案是向正确方向上的扭矩发射所有推进器。现在,这几乎可以解决您提出的问题。但是,我希望沿着这一点,如果用户按下“旋转”按钮,并且所有具有正扭矩的推进器都旋转,则可能会发现您的策略不太令人满意。旋转它们的角度(我不确定您的仿真的详细程度,如果您确实确实计算了推进器的作用力,或者只是直观地显示了它们的发射力,然后以恒定的加速度或其他方式旋转模型。这样,您就希望推进器至少能够精确地点火。

您无需考虑船上的净力。如果您有任意的推进器数量,那么这可能会变成一个非常复杂的问题。但是,由于我们的推进器只有两种状态,因此分析起来非常简单。我不确定我们的目标到底是什么,所以我可以想像两个不同的目标:首先,我们希望使总力最小化,同时仍将扭矩保持在所需的方向上。第二,我们要最大化扭矩与总力的比率。

顺便说一句,如果您可以想象一个同时影响所有推进器功率的“推进器容积”控制,那么您可以设置此控制,以便两个解决方案具有相同的转矩,并且您看到第二个解决方案只能具有一个比第一个位移。但是,我们需要记住,如果可以发射推进器,使您只旋转而根本不动,那么两种解决方案将是相同的。

因此,基于上一段的论点,我们将采用第二种解决方案。现在,当分析总力时,我们可以简单地注意到引擎只能指向四个方向。因此,x方向上的总力就是指向左的推进器数量减去指向右的数量,同样是y方向。

编写了到目前为止的内容后,我必须对优化算法进行更多的思考。我认为我的文章的其余部分照旧是有帮助的,因此我将其发布,但是当我找出优化此配置的最佳方法时我会进行更新(我想到了一些获得近似答案的方法,但是它们都不是精确的)。


感谢您的回答(以及更快速,更清洁的扭矩计算解决方案)。红色圆圈不是舰船的COM,而是动力核心。我正在使用物理引擎,而只是在船上施加局部脉冲。我对解决方案并不完美感到满意,因为它使使用不同的配置变得非常有趣,但是我很想知道您的想法。
migimunz 2012年

1
您可以从任意参考点计算扭矩。结果数将改变,但是只要您围绕该点旋转船(不必是质心),则物理行为就不会改变。实际上,在没有质量分布信息的情况下,质心本身是任意的,因此无法进行计算。
马克·托马斯
By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.