这是一个关于如何在3D空间游戏中操控一艘可以平移和旋转的宇宙飞船的非常困难的问题。
宇宙飞船有n
个喷射器,安装在不同的位置和方向上。
第i
个喷射器相对于宇宙飞船质心的变换是常数=Ti
。
- 变换是一个位置和方向(四元数或3×3矩阵,或者不太理想的欧拉角)的元组。
- 变换也可以用一个4×4的矩阵表示。
换句话说,所有喷射器都固定在飞船上,不能旋转。
喷射器只能沿着其轴线(绿色)方向对飞船施加力。
由于固定,轴线会随飞船一起旋转。
所有喷射器可以在一定的幅度(标量,fi
)上施加力(向量,Fi
):i
个喷射器只能在范围min_i<= fi <=max_i
内施加力(Fi
= axis
x fi
)。
min_i
和max_i
都是已知值的常数。
为了清楚起见,min_i
、fi
、max_i
的单位是牛顿。
例:如果范围不包括0,则意味着喷射器不能关闭。
宇宙飞船的质量=m
,惯性张量=I
。
宇宙飞船的当前变换=Tran0
,速度=V0
,角速度=W0
。
宇宙飞船的物理体遵循众所周知的物理规则:-Torque=r x F
F=ma
angularAcceleration = I^-1 x Torque
linearAcceleration = m^-1 x F
I
在每个方向上是不同的,但为了简化起见,每个方向上的值相同(类似球体)。因此,I
可以被视为标量而不是3×3矩阵。
问题
如何控制所有喷射器(所有fi
)使飞船在位置=0和角度=0处着陆?
数学化描述:找到fi(time)
函数,使其在最短时间内达到position=(0,0,0)
,orient=identity
,最终angularVelocity
和velocity
为零。
更具体地说,解决这个问题的技术或相关算法的名称是什么?
我的研究(一维)
如果宇宙是一维的(因此没有旋转),这个问题将很容易解决。
(感谢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,例如,它可以比最优解花费更多的时间。
我已经思考这个问题超过一周了,仍然找不到线索。
其他尝试/意见
- 我认为像神经网络这样的机器学习不适合这种情况。
- 边界约束的最小二乘优化可能有用,但我不知道如何将我的两个超抛物线拟合到这种形式的问题中。
- 这可以通过多次迭代来解决,但如何做呢?
- 我已经搜索了NASA的网站,但没有找到任何有用的东西。
- “太空工程师”游戏中可能存在此功能。
- Logman评论:机械工程知识可能会有所帮助。
- AndyG评论:这是一个带有非完整约束的运动规划问题。可以通过快速探索随机树(RRTs)、围绕Lyapunov方程的理论以及线性二次调节器来解决。
- John Coleman评论:这似乎更像是最优控制而不是AI。
编辑:“近0假设”(可选)
- 在大多数情况下,AI(待设计)会持续运行(即,每个时间步都调用)。
- 因此,在AI的调整下,
Tran0
通常接近单位矩阵,V0
和W0
通常与0不太不同,例如|Seta0|<30度
,|W0|<5度每时间步
。 - 我认为基于此假设的AI在大多数情况下会工作得不错。虽然不完美,但可以被视为一个正确的解决方案(我开始认为如果没有这个假设,这个问题可能太难了)。
- 我隐约觉得这个假设可能启用一些使用“线性”近似的技巧。
第二个替代问题 – “调整12个变量”(更容易)
上述问题也可以被视为如下:
我想调整所有六个values
和六个values'
(一阶导数)为0,使用最少的时间步数。
这里是一张表,展示了AI可能面临的一种情况:
乘数表存储了原始问题中的inertia^-1 * r
和mass^-1
。
乘数和范围是常数。
每个时间步,AI将被要求选择一个值fi
的元组,这些值必须在每个i+1
个喷射器的范围[min_i,max_i]
内。
例:从表中,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
、SetaX
、SetaY
、SetaZ
、Px'
、Py'
、Pz'
、SetaX'
、SetaY'
、SetaZ'
=0(或非常接近),
使用尽可能少的时间步数。
我希望提供问题的另一种视角会使其更容易。
这不是完全相同的问题,但我觉得能够解决这个版本的解决方案可以让我非常接近原始问题的答案。
这个替代问题的答案可能会非常有用。
第三个替代问题 – “调整6个变量”(最容易)
这是前一个替代方案的简化版本,可能会损失一些信息。
唯一的区别是现在世界是2D的,Fi
也是2D的(x,y)。
因此,我只需要调整Px
、Py
、SetaZ
、Px'
、Py'
、SetaZ'
=0,使用最少的时间步数即可。
这个最简单的替代问题的答案可以被认为是有用的。
回答:
我会尽量简短而甜蜜。
在模拟中解决这些问题时经常使用的一种方法是快速探索随机树。为了给我的帖子增添一些可信度,我承认我研究过这些,运动规划是我的研究实验室的专业领域(概率运动规划)。
关于这些的经典论文是Steven LaValle的快速探索随机树:一种新的路径规划工具,自那以后已经发表了数百万篇论文,这些论文在某些方面都对其进行了改进。
首先,我将介绍RRT的最基本描述,然后我将描述当你有动态约束时它是如何变化的。之后的调整就留给你了:
术语
“空间”
你的宇宙飞船的状态可以通过其3维位置(x, y, z)和其3维旋转(alpha, beta, gamma)来描述(我使用这些希腊名称是因为它们是欧拉角)。
状态空间是你宇宙飞船可以存在的所有可能位置和旋转。当然这是无限的。
碰撞空间是所有“无效”状态。即现实中不可能的位置。这些是你的宇宙飞船与某些障碍物碰撞的状态(对于其他物体,这也包括与自身的碰撞,例如为链条长度进行规划)。简称为C空间。
自由空间是任何不是碰撞空间的东西。
一般方法(无动态约束)
对于没有动态约束的物体,方法相当简单:
- 采样一个状态
- 找到该状态的最近邻居
- 尝试规划从邻居到该状态的路线
我将简要讨论每个步骤
采样一个状态
在最基本的情况下,采样一个状态意味着随机选择状态空间中每个条目的值。如果我们对你的宇宙飞船这样做,我们将随机采样x, y, z, alpha, beta, gamma的所有可能值(均匀随机采样)。
当然,你的空间中通常有更多的障碍空间而不是自由空间(因为你通常将所讨论的物体限制在你想要在其中移动的某个“环境”中)。所以通常做的是取你的环境的边界立方体,并在其中采样位置(x, y, z),现在我们有更高的机会在自由空间中采样。
在RRT中,你将大多数时间随机采样。但在某些概率下,你实际上会选择你的下一个样本作为你的目标状态(从0.05开始尝试)。这是因为你需要定期测试从起点到目标的路径是否可用。
找到采样状态的最近邻居
你选择一个固定的整数>0。让我们称这个整数为k
。你的k
个最近邻居在状态空间中是附近的。这意味着你有一些距离度量可以告诉你状态之间的距离有多远。最基本的距离度量是欧几里得距离,它只考虑物理距离而不关心旋转角度(因为在最简单的情况下,你可以在一个时间步内旋转360度)。
最初你只会有你的起始位置,所以它将是最近邻居列表中唯一的候选者。
规划状态之间的路线
这被称为局部规划。在现实世界中,你知道你要去哪里,沿途你需要避开其他人以及移动的物体。我们在这里不担心这些事情。在我们的规划世界中,我们假设宇宙是静止的,但对我们来说是动态的。
最常见的是假设采样状态与其最近邻居之间的线性插值。邻居(即树中已有的节点)沿着这个线性插值一点一点地移动,直到它到达采样配置,或者它移动了某个最大距离(回想你的距离度量)。
这里发生的是你的树正在向样本生长。当我说你“一点一点地”移动时,我的意思是你定义一个“delta”(一个非常小的值),并在每个时间步沿着线性插值移动那么多。在每个点上,你检查新状态是否与某个障碍物碰撞。如果你碰到障碍物,你将最后一个有效配置作为树的一部分(别忘了以某种方式存储边!)所以你需要的局部规划器是:
- 碰撞检测
- 如何在两个状态之间“插值”(对于你的问题,你不需要担心这一点,因为我们会做一些不同的事情)。
- 用于时间步进的物理模拟(欧拉积分非常常见,但不如龙格-库塔稳定。幸运的是你已经有了一个物理模型!
动态约束的修改
当然,如果我们假设可以在状态之间线性插值,我们将违反你为你的宇宙飞船定义的物理。所以我们如下修改RRT:
- 不是采样随机状态,我们采样随机控制并在固定时间段内(或直到碰撞)应用这些控制。
之前,当我们采样随机状态时,我们实际上是在选择一个方向(在状态空间中)移动。现在我们有了约束,我们随机采样我们的控制,这实际上是同样的事情,除了我们保证不会违反我们的约束。
在你应用控制一段固定时间间隔(或直到碰撞)后,你将一个节点添加到树中,并将控制存储在边上。你的树将快速生长以探索空间。这种控制应用取代了树状态和采样状态之间的线性插值。
采样控制
你有n
个喷射器,每个喷射器都有可以施加的某个最小和最大力。在每个喷射器的这个最小和最大力范围内采样。
我应该将我的控制应用到哪个节点?
你可以随机选择,或者你可以偏向选择离你的目标状态最近的节点(需要距离度量)。这种偏向将尝试随着时间的推移使节点更接近目标。
现在,使用这种方法,你不太可能精确到达你的目标,所以你需要定义一些“足够接近”的定义。也就是说,你将使用你的距离度量找到离你的目标状态最近的邻居,然后测试它们是否“足够接近”。这个“足够接近”的度量可以与你的距离度量不同,或者不不同。如果你使用欧几里得距离,但你的目标配置也需要正确旋转,那么你可能想要修改“足够接近”的度量来查看角度差异。
什么是“足够接近”完全取决于你。也是你需要调整的东西,有数百万篇论文试图在第一时间让你更接近。
结论
这种随机采样听起来可能很荒谬,但你的树将很快生长以探索你的自由空间。查看一些关于RRT路径规划的youtube视频。我们不能保证在动态约束下所谓的“概率完整性”,但它通常“足够好”。有时可能不存在解决方案,所以你需要在其中加入一些逻辑来在一段时间后停止生长树(例如20,000个样本)
更多资源:
从这些开始,然后开始查看它们的引用,然后开始查看谁引用了它们。