调整开普勒轨道以获得具有数值稳定性的推力

计算科学 算法 稳定 计算物理学
2021-11-27 15:53:03

我正在为模拟轨道物理(Kerbal Space Program,或 KSP)的游戏编写一个 mod。我试图在某些状态下模拟推力对航天器的影响,其中游戏仅将它们建模为开普勒轨道(这艘船“在轨道上”),并且我在数值稳定性方面遇到了一些困难——即使我没有没有施加任何推力,我最终会不断增加轨道的偏心率。

在“在轨”状态下,游戏中的航天器完全遵循开普勒轨道。轨道是在航天器上轨道时计算的,然后当它出轨时,游戏会计算当前时间的预期位置和速度,并设置航天器从那里做正常的牛顿事情。

目前,我的代码所做的只是计算航天器在当前时间的位置和速度(使用游戏自己的代码),然后调用游戏中已经存在的函数来计算具有该位置的物体的开普勒轨道和当前占主导地位的身体周围的速度 - 也就是说,它应该是无操作的。实际上,我看到轨道的偏心率在快速漂移,当然速度很快,这对于游戏目的来说是行不通的。这段代码在游戏中的每个物理时间步都被调用,这相当频繁 - 大约每秒 50 次 - 所以我怀疑我看到的是游戏中用于计算轨道位置和速度的代码,反之亦然不稳定。一世' 已经证实,在实际游戏过程中,将一艘船从轨道上取下然后放回轨道上会导致可观察到的轨道差异,并且我已经确认在我重新计算轨道后计算出的飞船位置/速度会发生变化。位置相对误差约为108,速度的相对误差约为102

我不确定这里最好的解决方案是什么,而且我在数值计算方面的经验非常有限。我想知道解决这个问题的好方法可能是什么样的。据我所知,基本上有三类解决方案:

  • 直接根据旧轨道参数和推力计算新轨道。不过,我不知道计算开普勒轨道上的增量有多么合理,而且我在网上找不到太多关于这样做的信息。
  • 编写具有更好精度或更好数值稳定性的代码以进行轨道 -> pos/vee -> 轨道转换。不过,我不知道当你每秒这样做五十次时,任何稳定性有多合理。我找到了一些用于计算的代码,但我不知道它在快速/稳定/良好的频谱上的位置。
  • 为飞船保留我自己的位置/速度值,不断更新它们,每隔一段时间重新计算轨道,以便玩家获得一些反馈。这将需要实施一个通用的二体问题解决方案,这听起来需要做很多工作。

这里有什么好的选择?

1个回答

对于应该是身份运算的相对误差绝对是可怕的。每个时间步的相对误差为,时间后以每秒 所以时间-误差累积的比例是对于,这是108102ϵt50

(1+ϵ)50te50ϵt,
0.02/ϵϵ=1022秒。从你的偏心漂移来看,相对误差不仅很大,而且偏向一个方向,而这种偏差就是导致漂移的原因。目前尚不完全清楚这是否是具体的数值稳定性,或者这是否只是一种不准确的计算方法。

0. 实现自己的函数来计算位置-速度轨道参数转换当然是可行的。一本好的轨道动力学教科书可以解释必要的公式;还有这个有用的网站Higham的《数值算法的准确性和稳定性》等书将解释什么是数值稳定性以及如何为这些计算设计稳定的算法。

主要困难是正确覆盖所有极端情况,因为倾斜轨道的方程稍微复杂一些。如果我没记错的话,这只是坐标变换,只有一个很容易求解的非线性开普勒方程。

另请注意,在每个时间步开始时添加少量加速度可能足够准确,也可能不够准确,这需要通过实验检查。这只是一阶准确的(如果推力在积分端点消失,则为二阶),所以如果这还不够,那么编写自己的积分器就是要走的路。

1.实现自己的 ODE 积分器非常可行,而且比听起来容易。积分器需要是辛的,所以像 Stormer-Verlet 方法是一个好的开始: 但是,您可能需要比游戏中每个时间步仅一个 Stormet-Verlet 步的精度更高,因此可能值得研究一种高阶方法。

x˙=v,v˙=f(x),
v12=v0+h2f(x0),x1=x0+hv12,v1=v12+h2f(x1).

相关参考文献是Hairer, Lubich, Wanner的Geometric Numerical Integration和 Hairer, Norsett, Wanner 的 Solveing Ordinary Differential Equations据此,隐式高斯方法(Butcher-Kuntzmann 方法)是辛的,因此,例如,如果您不介意求解 6 个非线性方程组,那么 6 阶 Butcher-Kuntzmann 方法可能值得尝试;是 Butcher Implicit Runge-Kutta Processes (1964)ν=3