我需要编写AI来控制游戏中宇宙飞船的多个推进喷射器。
为了简化:-
设空间为一维。
宇宙飞船是一个点,且只有一个喷射器。
规则和问题
设x
、v
和a
分别是宇宙飞船的位置、速度和加速度。
设F
是施加在飞船上的喷射器的力。
我知道宇宙飞船的质量m
,假设m
=1。
这里是总结:-
acceleration = F/m;v = vOld + acceleration*timestep;x = xOld + v*timestep;
目标是在某个位置以0速度着陆飞船:- x
=0和v
=0。
AI可以“加速”或“减速”喷射器:-
F+=flexibility;or F-=flexibility;
AI可以访问当前的x
、v
和F
。AI也可以缓存这些值。
我应该如何编程AI?
我的拙劣解决方案
想法1:最后,x
应该等于0。
假设a
是常数:-
(current x) + (current v) * t + 1/2 * a * t * t = 0
t
是一个魔法数字 – 需要多少时间才能使宇宙飞船的x
=0。
想法2:最后,v
应该等于0。
(current v) + a*t = 0
我混合了这两个想法:-
如果|x|>=thresholdX
–> 使用想法1
如果|x|~0
–> 使用想法2
在两者之间 –> 两个想法的加权平均
这里,thresholdX
是另一个魔法数字。
我使用方程中的a
来找到合适的F
。(F=ma
)
结果如下:-
图表噪声较大,因为质量是由另一个AI近似计算的,并且存在一些小的随机外部力。
如果有人问,我可以发布我的C++代码(约100行)。
回答:
首先 – 你计划在有质量的物体上着陆,还是在太空中某个任意点停止?你的问题中提到“着陆”,所以我假设是前者,在这种情况下,你还需要考虑重力因素。这应该很容易做到:F_actual = F_engine - F_gravity
。
其次 – 在现实生活中你会怎么做?现实生活中的飞行员希望在“下滑道”上“建立”他们的飞机(在到达跑道之前),并使飞机“调整”到理想条件下(无风等)可以自行着陆的状态(我简化了一些,忽略了起飞等)。
对于火箭,我可能会希望自己处于一种状态,即在离地面一定安全高度时,我的下降速度使得在发动机以某种恒定功率运行的情况下,火箭可以自行降落到地面,而无需我额外的输入,除了在触地时关闭发动机。(实际上,我希望飞行系统允许我在触地时自动关闭发动机。)
为了了解这将如何工作,只需反向运行问题。从x=0, v=0
开始,设a=发动机可以产生的某个常数和合理的加速度
,绘制火箭上升时随时间变化的x
和v
。显然,v=at
(一条直线),而x
是这些值的总和(一个抛物线)。
这个抛物线就是你的“下滑道”。现在,与其试图同时使x=0
和v=0
(且x
从不变为负值),你的问题变成了“如何在安全高度上击中下滑道?”。所以你的逻辑可能是这样的:
- 如果
x=0
,关闭发动机。 - 否则,如果你在下滑道上,设定发动机功率为所需的(恒定)减速度。坐下来等待物理完成所有艰难的工作。
- 否则,如果
x < min_approach_height
且你不在下滑道上,足够努力地燃烧以爬升。 - 否则,调整发动机功率以到达下滑道。
一些注意事项:
- 通过“下滑道”,我并不是指水平运动。我只是通过类比固定翼飞机使用这个术语。我的意思是
v
对x
的绘图,允许恒定的a
产生一个无需额外控制输入的轻柔触地。 - 你着陆的物体有大气层吗?如果有,你的火箭将有一个终端速度,在这种情况下,逻辑简化为:以足够快的速度进入大气层,以在下滑道上方达到终端速度。等待下滑道。当你击中斜坡时,以恒定功率点火发动机。在你触地时关闭发动机。
- 到目前为止,我忽略了“近似”质量和“随机外部力”。只要这些不会让你离下滑道太远,小幅调整功率应该能让你回到斜坡上。在下降过程中持续进行这些修正。如果你偏离斜坡太远,全力燃烧并重新尝试。
- 顺便说一句,如果不是因为这些随机效应,这种下滑道方法使得用只有两个设置的发动机(恒定减速度功率和关闭)轻轻着陆变得相当简单。
- 我并没有解决你的问题,只是把它变成了另一个问题 – 但是,解决这个新问题应该能让你的游戏更真实(希望能提高沉浸感)。此外,这个问题可能比原来的问题更简单(见上面的注释2和4)。最后,在下滑道上早早设置,然后只进行小的修正调整,意味着你的AI不需要处理极端情况,或提供极端的控制输入。
嗯 – 即使经过编辑,这篇文章还是很长。我认为我应该就此打住…..现在。