繁体   English   中英

计算两个3D矢量与恒定加速度对齐所需的扭矩?

[英]Calculate Torque Required To Align Two 3D Vectors with Constant Acceleration?

我目前正在为卫星游戏构建简化的反应控制系统,并且需要一种方法来使用该系统将卫星与世界空间坐标中的给定单位方向对齐。 因为这是一个游戏模拟,我伪造系统,只是在物体震中周围施加扭矩力。

这很难,因为在我的情况下,扭矩的强度不能改变,它可以打开或关闭。 这是完全的力量或没有力量。 计算扭矩需要施加的方向相对容易,但是我无法使其完全对齐而不会失去控制并陷入逻辑循环。 它需要在恰当的“时间”施加相反的力,以零角速度着陆在目标方向上。

到目前为止我所确定的是,我需要根据当前的角速度和两个矢量之间的角度计算达到零速度所需的“时间”。 如果超过我达到零角度的时间,则需要施加相反的扭矩。 从理论上讲,这也可以防止它在轴周围“弹跳”太多。 我几乎让它工作,但在某些情况下似乎卡在一个方向施加力,所以我希望有人可以检查逻辑。 我的模拟目前不考虑质量,因此您可以忽略惯性张量(除非它使计算更容易!)

对于一个轴 ,我目前正在这样做,但我认为有人会有一个更优雅的解决方案,实际上可以同时计算Yaw和Pitch轴(Roll无效)。

Omega = Angular Velocity in Local-Space (Degrees Per Second)
Force = Strength of the Thrusters

// Calculate Time Variables
float Angle = AcosD(DotProduct(ForwardVector, DirectionVector));
float Time1 = Abs(Angle / Omega.Z); // Time taken to reach angle 0 at current velocity
float Time2 = Abs(DeltaTime * (Omega.Z / Force); // Time it will take to reach Zero velocity based on force strength.

// Calculate Direction we need to apply the force to rotate toward the target direction. Note that if we are at perfect opposites, this will be zero!
float AngleSign = Sign(DotProduct(RightVector, DirectionVector));

float Torque.Z = 0;
if (Time1 < Time2)
{
   Torque.Z = AngleSign * Force;
}
else
{
   Torque.Z = AngleSign * Force * -1.0f
}

// Torque is applied to object as a change in acceleration (no mass) and modified by DeltaSeconds for frame-rate independent force. 

这远非优雅,肯定有一些标志问题。 你们有没有人知道更好的方法来达到这个目的?

编辑:如果有人理解虚幻引擎的蓝图系统,这就是我在将它移动到C ++之前的原型。

在此输入图像描述

从“计算方向”线开始,您可以直接计算3D中的校正扭矩矢量,如果您知道之前的校正即将超调,则修改其符号:

// Calculate Direction we need to apply the force to rotate toward the target direction
Torque = CrossProduct(DirectionVector, ForwardVector)
Torque = Normalize(Torque) * Force
if (Time2 < Time1)
{
  Torque = -Torque
}

但你应该处理有问题的案件:

// Calculate Direction we need to apply the force to rotate toward the target direction
Torque = CrossProduct(DirectionVector, ForwardVector)

if (Angle < 0.1 degrees)
{
  // Avoid divide by zero in Normalize
  Torque = {0, 0, 0}
}
else
{
  // Handle case of exactly opposite direction (where CrossProduct is zero)
  if (Angle > 179.9 degrees)
  {
    Torque = {0, 0, 1}
  }

  Torque = Normalize(Torque) * Force
  if (Time2 < Time1)
  {
    Torque = -Torque
  }
}

好吧,我从上面的伪代码中得到的是,当需要断开的时间超过剩余时间直到达到角度0时,你想要开始制动。 您是否尝试在断开时间之前慢慢开始断开(在短步骤中因为恒定的扭矩)超过角度0的时间?

当你这样做并且你的卫星接近角度0并且速度非常低时,你可以将速度和角度设置为0,这样它就不会再摇晃了。

你有没有想过这个? 我正在研究UE4中的类似问题。 我也有不变的力量。 我正在转向一个新的前向矢量。 我已经意识到时间无法预测。 例如,你在Z轴上以100度/秒的速度旋转,反向力精确地在.015秒内完成所需的旋转和速度,但下一帧需要.016秒才能渲染,你刚刚超过它不会改变你的力量。 我认为解决方案类似于通过在速度归零时手动设置前向矢量来作弊。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM