简体   繁体   English

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

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

I'm currently building a simplified Reaction Control System for a Satellite game, and need a way to use the system to align the satellite to a given unit direction in world-space coordinates. 我目前正在为卫星游戏构建简化的反应控制系统,并且需要一种方法来使用该系统将卫星与世界空间坐标中的给定单位方向对齐。 Because this is a game simulation, I am faking the system and just applying a torque force around the objects epicenter. 因为这是一个游戏模拟,我伪造系统,只是在物体震中周围施加扭矩力。

This is difficult because in my case, the Torque cannot be varied in strength, it is either on or off. 这很难,因为在我的情况下,扭矩的强度不能改变,它可以打开或关闭。 It's either full force or no force. 这是完全的力量或没有力量。 Calculating the direction that the torque needs to be applied in is relatively easy, but I'm having trouble getting it to align perfectly without spinning out of control and getting stuck in a logical loop. 计算扭矩需要施加的方向相对容易,但是我无法使其完全对齐而不会失去控制并陷入逻辑循环。 it needs to apply the opposing force at precisely the right 'time' to land on the target orientation with zero angular velocity. 它需要在恰当的“时间”施加相反的力,以零角速度着陆在目标方向上。

What I've determined so far is that I need to calculate the 'time' it will take to reach zero velocity based on my current angular velocity and the angle between the two vectors. 到目前为止我所确定的是,我需要根据当前的角速度和两个矢量之间的角度计算达到零速度所需的“时间”。 If that exceeds the time until I reach angle zero, then it needs to apply the opposing torque. 如果超过我达到零角度的时间,则需要施加相反的扭矩。 In theory this will also prevent it from 'bouncing' around the axis too much. 从理论上讲,这也可以防止它在轴周围“弹跳”太多。 I almost have it working, but in some cases it seems to get stuck applying force in one direction, so I'm hoping somebody can check the logic. 我几乎让它工作,但在某些情况下似乎卡在一个方向施加力,所以我希望有人可以检查逻辑。 My simulation does NOT take mass into account at the moment, so you can ignore the Inertia Tensor (unless it makes the calculation easier!) 我的模拟目前不考虑质量,因此您可以忽略惯性张量(除非它使计算更容易!)

For one axis , I'm currently doing it this way, but I figure someone will have a far more elegant solution that can actually compute both Yaw and Pitch axes at once (Roll is invalid). 对于一个轴 ,我目前正在这样做,但我认为有人会有一个更优雅的解决方案,实际上可以同时计算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. 

This is far from elegant and there are definitely some sign issues. 这远非优雅,肯定有一些标志问题。 Do you folks know a better way to achieve this? 你们有没有人知道更好的方法来达到这个目的?

EDIT: If anybody understands Unreal Engine's Blueprint system, this is how I'm currently prototyping it before I move it to C++ 编辑:如果有人理解虚幻引擎的蓝图系统,这就是我在将它移动到C ++之前的原型。

在此输入图像描述

Beginning from the "Calculate Direction" line, you could instead directly compute the correction torque vector in 3D, then modify its sign if you know that the previous correction is about to overshoot: 从“计算方向”线开始,您可以直接计算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
}

But you should handle the problematic cases: 但你应该处理有问题的案件:

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

Okay well what i take from the pseudocode above is that you want to start braking when the time needed to break exceeds the time left till angle 0 is reached. 好吧,我从上面的伪代码中得到的是,当需要断开的时间超过剩余时间直到达到角度0时,你想要开始制动。 Have you tried to slowly start breaking (in short steps because of the constant torque) BEFORE the time to break exceeds the time till angle 0? 您是否尝试在断开时间之前慢慢开始断开(在短步骤中因为恒定的扭矩)超过角度0的时间?

When you do so and your satellite is near angle 0 and the velocity very low, you can just set velocity and angle to 0 so it doesn't wobble around anymore. 当你这样做并且你的卫星接近角度0并且速度非常低时,你可以将速度和角度设置为0,这样它就不会再摇晃了。

Did you ever figure this out? 你有没有想过这个? I'm working on a similar problem in UE4. 我正在研究UE4中的类似问题。 I also have a constant force. 我也有不变的力量。 I'm rotating to a new forward vector. 我正在转向一个新的前向矢量。 I've realized time can't be predicted. 我已经意识到时间无法预测。 Take for example you're rotating on Z axis at 100 degrees/second and a reverse force in exactly .015 seconds will nail your desired rotation and velocity but the next frame takes .016 seconds to render and you've just overshot it since you aren't changing your force. 例如,你在Z轴上以100度/秒的速度旋转,反向力精确地在.015秒内完成所需的旋转和速度,但下一帧需要.016秒才能渲染,你刚刚超过它不会改变你的力量。 I think the solution is something like cheating by manually setting the forward vector once velocity is zeroed out. 我认为解决方案类似于通过在速度归零时手动设置前向矢量来作弊。

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

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