对于如何操纵可以在3D中平移和旋转的太空船来进行太空游戏,这是一个非常困难的问题。
宇宙飞船有n
个喷气式飞机放置在不同的位置和方向。
相对于宇宙飞船的CM,i
- 喷射的变换是常数= Ti
。
换句话说,所有喷射器都粘在船上,不能旋转。
喷气式飞机只能在其轴线方向(绿色)上向太空船施加力 由于胶水,轴与飞船一起旋转。
所有喷气机都可以施加一定的力量(矢量,Fi
)(标量,fi
):
i
- 喷气机只能在Fi
范围内施加力(axis
= fi
x min_i<= fi <=max_i
)。
min_i
和max_i
都是已知值的常量。
要明确,min_i
,fi
,max_i
的单位是牛顿。
例如如果范围不包括0,则意味着喷气机无法关闭。
宇宙飞船的质量= m
和惯性张量= I
。
宇宙飞船的当前变换= Tran0
,速度= V0
,angularVelocity = W0
。
宇宙飞船物理学家遵循众所周知的物理规则: -
Torque=r x F
F=ma
angularAcceleration = I^-1 x Torque
linearAcceleration = m^-1 x F
I
对于每个方向都不同,但为了简单起见,它对于每个方向(类似球体)具有相同的值。因此,I
可以被认为是标量而不是矩阵3x3。
如何控制所有喷气机(所有fi
)以降落位置= 0且角度= 0的船舶?
类似数学的规范:查找fi(time)
的函数,其最短时间达到position=(0,0,0)
,orient=identity
,最终angularVelocity
和velocity
=零。
更具体地说,解决这个问题的技术名称或相关算法是什么?
如果宇宙是1D(因此,没有旋转),问题将很容易解决 (感谢Gavin Lock,https://stackoverflow.com/a/40359322/3577745)
首先,找到值MIN_BURN=sum{min_i}/m
和MAX_BURN=sum{max_i}/m
。
其次,以相反的方式思考,假设x=0
处的v=0
(位置)和t=0
,
然后使用x''=MIN_BURN
和x''=MAX_BURN
创建两个抛物线
(假设二阶导数在一段时间内是常数,所以它是抛物线。)
唯一剩下的工作是将两个抛物线加在一起 红色虚线是他们加入的地方。
在x''=MAX_BURN
期间,所有fi=max_i
在x''=MIN_BURN
,所有fi=min_i
。
它对1D非常有效,但在3D中,问题要困难得多。
注意:
只是一个粗略的指导指向我正确的方向非常感谢
我不需要完美的AI,例如它可能需要比最佳时间多一点的时间
我想了一个多星期,仍然没有发现任何线索。
其他尝试/意见
编辑:&#34;近0假设&#34; (可选)
Tran0
通常接近身份,V0
和W0
通常 与0没有太大不同,例如|Seta0|<30 degree
,|W0|<5 degree per time-step
。 以上问题也可能如下所示:
我希望使用最少的时间步长将所有六个values
和六个values'
(一阶导数)调整为0。
下表显示了AI可能面临的可能情况: -
乘数表存储原始问题中的inertia^-1 * r
和mass^-1
。
乘数和范围是常量。
每个时间步,AI都会被要求选择一个值为fi
的元组,每个[min_i,max_i]
- 喷射器必须在i+1
范围内。
例如从表格中,AI可以选择(f0=1,f1=0.1,f2=-1)
。
然后,来电者将使用fi
与乘数表相乘得到values''
。
Px'' = f0*0.2+f1*0.0+f2*0.7
Py'' = f0*0.3-f1*0.9-f2*0.6
Pz'' = ....................
SetaX''= ....................
SetaY''= ....................
SetaZ''= f0*0.0+f1*0.0+f2*5.0
之后,来电者将使用公式values'
更新所有values' += values''
Px' += Px''
.................
SetaZ' += SetaZ''
最后,来电者将使用公式values
更新所有values += values'
Px += Px'
.................
SetaZ += SetaZ'
每个时间步都只会询问一次AI。
AI的目标是返回fi
的元组(对于不同的时间步长可以是不同的),以制作Px
,Py
,Pz
,{{ 1}},SetaX
,SetaY
,SetaZ
,Px'
,Py'
,Pz'
,SetaX'
,{{1} } = 0(或非常接近),
通过使用尽可能少的时间步骤。
我希望提供另一种问题的观点会使事情变得更容易 这不是完全相同的问题,但我觉得可以解决这个版本的解决方案可以让我非常接近原始问题的答案。
这个替代问题的答案非常有用。
这是上一个备选方案的有损简化版本。
唯一的区别是世界现在是2D,SetaY'
也是2D(x,y)。
因此,我必须至少使用SetaZ'
,Fi
,Px
,Py
,SetaZ
,Px'
= 0进行调整尽可能多的时间步数。
这个最简单的替代问题的答案可以被认为是有用的。
答案 0 :(得分:6)
我会尽量保持这种简短和甜蜜。
在模拟中经常用于解决这些问题的一种方法是Rapidly-Exploring Random Tree。为了给我的帖子至少提供一点可信度,我承认我研究了这些,运动规划是我研究实验室的专业领域(概率运动规划)。
关于这些的规范性论文是Steven LaValle的Rapidly-exploring random trees: A new tool for path planning,自那以后,已经发表了一百万篇论文,所有论文都以某种方式对其进行了改进。
首先,我将介绍RRT的最基本描述,然后我将描述当你有动态约束时它是如何变化的。之后,我会随便摆弄它:
你的宇宙飞船的状态可以通过它的三维位置(x,y,z)及其三维旋转(alpha,beta,gamma)来描述(我使用那些希腊名称,因为它们是{{3 }})。
状态空间是您的飞船可以居住的所有可能的位置和旋转。当然这是无限的。
碰撞空间是所有&#34;无效&#34;状态。即实际上不可能的位置。这些是你的飞船与某些障碍相撞的状态(与其他机构相比,这也包括与自身的碰撞,例如规划一段链条)。缩写为C-Space。
自由空间是任何非碰撞空间。
对于没有动态约束的身体,这种方法相当简单:
我将简要讨论每一步
在最基本的情况下采样状态意味着为状态空间中的每个条目选择随机值。如果我们使用您的太空飞船执行此操作,我们会在所有可能值(随机均匀采样)中随机抽样x,y,z,alpha,beta,gamma。
当然,你的空间通常比自由空间更多是障碍空间(因为你通常会将你的对象限制在某些环境中......你想在里面移动)。因此,常见的做法是采用环境的边界立方体并在其中采样位置(x,y,z),现在我们有更高的机会在自由空间中进行采样。
在RRT中,您将随机大多数随机抽样。但有一些概率你实际上会选择你的下一个样本作为你的目标状态(玩它,从0.05开始)。这是因为您需要定期测试以查看从开始到目标的路径是否可用。
你选择了一些固定的整数&gt; 0.让我们调用整数k
。您的k
最近邻居在州空间附近。这意味着您有一些距离指标可以告诉您各州之间的距离。最基本的距离指标是Euler angles,它只考虑物理距离并且不关心旋转角度(因为在最简单的情况下,您可以在一个时间步长内旋转360度)。
最初你只有你的起始位置,所以它将是最近邻居名单中唯一的候选人。
这称为本地计划。在现实场景中,您可以了解自己的去向,以及躲避其他人和移动物体的方式。我们在这里不担心这些事情。在我们的规划世界中,我们假设宇宙是静态的,但对我们而言。
最常见的是假设采样状态与其最近邻居之间存在一些线性插值。邻居(即已经在树中的节点)逐位沿着该线性插值移动,直到它到达采样配置,或者它行进一些最大距离(调用您的距离度量)。
这里发生的是你的树正朝着样本增长。当我说你一步一步地踩着&#34;我的意思是你定义一些&#34; delta&#34; (一个非常小的值)并沿着线性插值移动每个 timestep 。在每个点上,您检查新状态是否与某个障碍物碰撞。如果你遇到了障碍,你可以将最后一个有效的配置保留为树的一部分(不要忘记以某种方式存储边缘!)所以你当地规划人员需要的是:
当然,如果我们假设你可以在状态之间进行线性插值,那么我们就会违反你为宇宙飞船定义的物理特性。所以我们修改RRT如下:
之前,当我们对随机状态进行采样时,我们真正在做的是选择一个方向(在状态空间中)来移动。现在我们有了约束,我们随机抽样控件,这实际上是相同的,除非我们保证不会违反我们的约束。
在固定时间间隔(或直到碰撞)应用控件后,将一个节点添加到树中,控件存储在边缘上。你的树会快速生长,探索空间。该控制应用程序取代了树状态和采样状态之间的线性插值。
你有n
个喷气机,它们可以分别拥有一些最小和最大的力量。在每个喷射的最小和最大力范围内进行采样。
您可以随意选择,或者您可以偏向选择以选择最接近目标状态的节点(需要距离度量)。随着时间的推移,这种偏见会尝试使节点更接近目标。
现在,通过这种方法,您不可能完全达到目标,因此您需要定义一些&#34;足够接近&#34;的定义。也就是说,您将使用距离度量来查找目标状态的最近邻居,然后测试它们&#34;足够接近&#34;。这个&#34;足够接近&#34;度量标准可能与您的距离度量标准不同。如果您正在使用欧几里德距离,但是目标配置也正确旋转非常重要,那么您可能希望修改&#34;足够接近&#34;用于查看角度差异的指标。
什么是&#34;足够接近&#34;完全取决于你。还有一些东西供您调整,而且有一百万篇论文试图让您更加接近。
这种随机抽样可能听起来很荒谬,但是你的树会变得非常快速地探索你的自由空间。在RRT上查看一些有关路径规划的YouTube视频。我们无法保证所谓的“概率完整性”#34;有动力约束,但它通常足够好&#34;。有时候解决方案不存在是可能的,所以你需要在那里放一些逻辑来停止在一段时间后生长树(例如20,000个样本)
从这些开始,然后开始查看他们的引用,然后开始研究谁在引用他们。
答案 1 :(得分:5)
这不是一个答案,但作为评论放置时间太长了。
首先,真正的解决方案将涉及linear programming(对于将在许多子步骤中使用的约束的多变量优化)以及trajectory optimization和/或控制理论中使用的技术。这是一个非常复杂的问题,如果你能解决它,你可以在你选择的任何公司找到一份工作。唯一可以使这个问题变得更糟的是摩擦(阻力)效应或外部人体引力效应。理想情况下,真正的解决方案还可以使用Verlet集成或4阶Runge Kutta,它们提供了与您在此处实施的Euler集成相比的改进。
其次,我相信您上面问题的&#34;第二替代版本&#34; 已经省略了在每个时间步长添加到位置的位移矢量的旋转影响。虽然射流轴相对于船舶的参照系保持固定,但它们相对于您用于降落船舶的全球坐标系保持固定 (在全球坐标{{1}处})。因此,[0, 0, 0]
向量(根据船舶的参照系计算)必须在应用于全球位置坐标之前在所有3个维度中进行适当的旋转。
第三,您未能指定一些隐含的假设。例如,一个维度应定义为&#34;着陆深度&#34;应禁止尺寸和负坐标值(除非您接受火热的碰撞)。我为此开发了一个模型模型,其中我假设[Px', Py', Pz']
维度为着陆维度。这个问题对初始状态和喷射器上的约束非常敏感。我使用上述示例初始条件的所有尝试均无法降落。例如,在我的模型中(没有上面提到的3d位移矢量旋转),喷射约束仅允许在z轴上沿一个方向旋转。因此,如果z
在任何时候变为负值(通常是这种情况),船舶实际上必须在该轴上完成另一次完整旋转,然后才能再次接近零度。此外,如果没有三维位移矢量旋转,您会发现aZ
只会使用您的示例初始条件和约束变为负值,并且船舶被迫崩溃或分叉越来越远到负X轴上它试图操纵。解决这个问题的唯一方法是真正结合旋转或允许足够的正负喷射力。
然而,即使我放松了你的最小/最大力量限制,我也无法让我的模型成功降落,这表明这里可能需要复杂的规划。除非可以在线性编程空间中完全解决这个问题,否则我认为你需要采用先进的计划或随机决策树,这些都是“智能”和“#34;足以连续使用旋转方法将最灵活的喷嘴重新定向到当前最必要的轴上。
最后,正如我在评论部分所指出的那样,&#34; 2015年5月14日,Space Engineers的源代码在GitHub上向公众免费提供。&#34;如果你认为游戏已经包含了这个逻辑,那应该是你的起点。但是,我怀疑你一定很失望。大多数太空游戏着陆序列只是控制船只而不是模拟真实的#34;力矢量。一旦你控制了一个三维模型,就可以很容易地预先确定一个旋转的三维样条,这样可以使船在预定的时间内轻柔地着陆并具有完美的方位。为什么任何游戏程序员都会通过这个级别的工作来完成着陆序列?这种逻辑可以控制ICBM导弹或行星漫游车再入飞行器,这对游戏来说简直过分嘲讽(除非游戏的目的是为了看看你是否可以使用任意喷气式飞机降落受损太空船而不会发生碰撞)
答案 2 :(得分:1)
对于这些问题,有两种技术可用:强力搜索和启发式扫描。 Bruteforce意味着将问题识别为具有输入和输出参数的黑盒,目的是获得正确的输入参数以赢得游戏。为了对这种强力搜索进行编程,游戏物理学在模拟循环(物理模拟)中运行,并通过随机搜索(minimax,alpha-beta-prunning)尝试每种可能性。强力搜索的缺点是高CPU消耗。
其他技术利用有关游戏的知识。关于运动原语和评估的知识。这些知识使用普通的计算机语言编写,如C ++或Java。这种想法的缺点是,通常很难掌握知识。
解决太空飞船导航的最佳实践是将两种想法结合到一个混合系统中。为了解决这个具体问题的源代码,我估计需要近2000行代码。这些问题在许多程序员的大型项目中都是正常的,大约需要6个月。
答案 3 :(得分:1)
我可以在提出的(很棒的)答案的混合中引入另一种技术。
更多的是AI,并提供接近最佳的解决方案。它被称为Machine Learning,更具体地称为Q-Learning。它实施起来非常简单,但很难做到。
优点是学习可以离线完成,因此算法在使用时可以快速超级。
你可以在船舶建造或发生某些事情时进行学习(推进器破坏,大块撕裂......)。
我发现你正在寻找接近最优的解决方案。使用抛物线的方法有利于最佳控制。你做的是这个:
这对3D中的人来说非常棘手(太多情况下,会让你疯狂)然而机器可能会在每个维度上分析抛物线的位置,并通过以下方式设计最佳策略本身。
Q-learning与我们的工作方式非常相似:
对于每个州,有一个初始化的准随机地图,它将每个州映射到一个行动(这是策略)。同时为每个状态分配一个满意度(最初为零,1000000到目标状态(X = 0,V = 0)。
训练AI(离线阶段):
一段时间后,出现了全球航行战略。然后存储它,在游戏循环中,您只需对策略进行采样并将其应用于每种情况。
该策略可能仍会在此阶段学习,但可能更慢(因为它实时发生)。 (顺便说一句,我梦想有一个游戏,人工智能会从每个用户的反馈中学习,所以我们可以集体训练它^^)
在一个简单的一维问题中尝试这个问题,它可以非常快速地设计一个策略(几秒钟)。
在2D中,我相信可以在一小时内获得优异的结果。
对于3D ......你正在寻找一夜之间的计算。尝试加速这个过程还有一些事情要做:
尝试永远不会忘记&#39; 之前的计算,并将其作为初始的最佳猜测提供。战略。将其保存到文件中!
你可能会丢掉一些状态(比如船舶滚动?)而不会失去太多的导航最优性,但会大大提高计算速度。也许更改参考因此船舶总是在X轴上,这样你就可以放弃x&amp; y尺寸了!
更频繁遇到的国家将拥有可靠且非常优化的战略。也许规范化状态,使您的船舶状态始终接近标准&#39;状态?
通常情况下,旋转速度的间隔可以安全地限制(您不希望船只在一定程度上翻滚,因此策略将永远是“#wind;#wind&#34;那个速度”。当然,旋转角度也是有限的。
您也可能非线性地离散位置,因为离目标越远,精度就越不会影响策略。