openai-gym 的 LunarLander 模拟自杀烧伤
Simulation of suicide burn in openai-gym's LunarLander
我想模拟suicide burn来学习和理解火箭着陆。 OpenAI gym 已经有一个 LunarLander 环境,用于训练强化学习代理。我正在使用这个环境来模拟 python 中的自杀式烧伤。我从该环境的状态向量的前两个值中提取了坐标 (x,y)
。根据这些值,将 y
坐标视为高度;我已经使用这些方程计算了下落着陆器的速度和加速度
velocity(v) = delta_y/ delta_t
acceleartion(a) = delta_v/delta_t
由于模拟是逐步递增的,时间差delta_t
被取为1。无法找到LunarLander的重力参数,我给它一个默认值g=1
。然后使用 reddit comment
中的以下等式
altitude to start suicide burn = [ (current altitude)(acceleration of gravity) + (1/2)(current velocity)2 ] / (acceleration of engines)
我试图计算高度以开始自杀式燃烧。这是我的完整 python 代码。我只打算使用四个可能的动作中的两个动作 0(什么都不做)和 2(启动主机)。
import gym
env = gym.make('LunarLander-v2')
env.seed(0)
g = 1
delta_t = 1
action = 0
state = env.reset()
# x0 = state[0]
y0 = state[1]
v0 = 0
for t in range(3000):
state, reward, done, _ = env.step(action)
y = state[1]
if done or y <0:
break
v = (y-y0)/delta_t # velocity
a = (v - v0)/delta_t # acceleration
# (altitude to start suicide burn) = [ (current altitude)(acceleration of gravity) + (1/2)(current velocity)2 ] / (acceleration of engines)
alt_burn = [y*g+0.5*v*v]/a
v0 = v
y0 = y
print(" y",round(y,5)," v",round(v,5)," a",round(a,5)," Alt_burn",round(alt_burn[0],5))
输出结果看起来像这样
y 1.41542 v 0.00196 a 0.00196 Alt_burn 722.35767
y 1.41678 v 0.00136 a -0.0006 Alt_burn -2362.78166
y 1.41754 v 0.00076 a -0.0006 Alt_burn -2362.63867
y 1.4177 v 0.00016 a -0.0006 Alt_burn -2362.43506
y 1.41726 v -0.00044 a -0.0006 Alt_burn -2362.64046
y 1.41622 v -0.00104 a -0.0006 Alt_burn -2359.03148
y 1.41458 v -0.00164 a -0.0006 Alt_burn -2358.17355
y 1.41233 v -0.00224 a -0.0006 Alt_burn -2353.50518
y 1.40949 v -0.00284 a -0.0006 Alt_burn -2349.24118
y 1.40605 v -0.00344 a -0.0006 Alt_burn -2343.51016
y 1.40201 v -0.00404 a -0.0006 Alt_burn -2336.31535
y 1.39737 v -0.00464 a -0.0006 Alt_burn -2329.04954
如果我们查看海拔高度 (y),它是一个小于 1.5 的非常小的值,而计算出的开始自杀式燃烧的海拔高度非常高。我该如何解决这个问题?
在reddit评论中他们只提到了启动引擎而没有提到关闭它。有人知道动态关闭引擎的数学原理吗?
您的代码有两个问题:
delta_t
根据 lunar_lander
source 应该是 1.0/50.0
FPS = 50
#...
self.world.Step(1.0/FPS, 6*30, 2*30)
其中 Box2D
documentation 表示
的典型时间步长
# [...]Typically we use a time step of 1/60 of a
# second (60Hz) and 6 velocity/2 position iterations. This provides a
# high quality simulation in most game scenarios.
timeStep = 1.0 / 60
- 引擎的加速度不应像
中那样定义为当前加速度
alt_burn = [y*g+0.5*v*v]/a
但是由于引擎的推动,定义here为
MAIN_ENGINE_POWER = 13.0
着陆器的质量没有在creation of the lander body中指定,而是使用
env.lander.mass
我们可以发现质量是 4.82
。鉴于此,发动机的正确加速度为1
alt_burn = (y * g + 0.5 * v*v) / (13.0 / env.lander.mass * 0.5)
如果我们运行将代码进行上述修改,
import gym
env = gym.make('LunarLander-v2')
env.seed(0)
g = 1.0
delta_t = 1.0/50.0
action = 0
state = env.reset()
y0 = state[1]
for t in range(3000):
state, reward, done, _ = env.step(action)
y = state[1]
v = (y - y0) / delta_t
y0 = y
if done or y < 0:
break
alt_burn = (y*g+0.5*v*v)/(13.0 / env.lander.mass * 0.5)
print(" y",round(y,5)," v",round(v,5)," Alt_burn",round(alt_burn,5))
我们得到了更合理的燃烧高度答案:
y 1.41542 v 0.09797 Alt_burn 1.05242
y 1.41678 v 0.06799 Alt_burn 1.05158
y 1.41754 v 0.03799 Alt_burn 1.05097
y 1.4177 v 0.00799 Alt_burn 1.05057
y 1.41726 v -0.02201 Alt_burn 1.0504
y 1.41622 v -0.05202 Alt_burn 1.05045
y 1.41458 v -0.08202 Alt_burn 1.05073
y 1.41233 v -0.11202 Alt_burn 1.05123
y 1.40949 v -0.14202 Alt_burn 1.05194
y 1.40605 v -0.17202 Alt_burn 1.05289
y 1.40201 v -0.20202 Alt_burn 1.05405
y 1.39737 v -0.23202 Alt_burn 1.05544
y 1.39213 v -0.26203 Alt_burn 1.05705
y 1.38629 v -0.29202 Alt_burn 1.05887
...
y 0.56683 v -1.58312 Alt_burn 1.34863
y 0.53456 v -1.61311 Alt_burn 1.36025
y 0.5017 v -1.64311 Alt_burn 1.37209
y 0.46824 v -1.67311 Alt_burn 1.38416
y 0.43418 v -1.70311 Alt_burn 1.39644
y 0.39951 v -1.73311 Alt_burn 1.40895
y 0.36425 v -1.76311 Alt_burn 1.42168
y 0.32839 v -1.79311 Alt_burn 1.43463
y 0.29193 v -1.82311 Alt_burn 1.44781
y 0.25487 v -1.85311 Alt_burn 1.46121
y 0.2172 v -1.88311 Alt_burn 1.47483
y 0.17894 v -1.91311 Alt_burn 1.48867
y 0.14008 v -1.94311 Alt_burn 1.50274
y 0.10062 v -1.97311 Alt_burn 1.51702
y 0.06055 v -2.00311 Alt_burn 1.53154
y 0.01989 v -2.03311 Alt_burn 1.54626
自杀燃烧的执行2现在很简单,我们只需要在着陆器低于燃烧高度时启动引擎,并在着陆器低于截止高度时停用它们高度。
import gym
env = gym.make('LunarLander-v2')
env.seed(0)
g = 1.0
delta_t = 1.0/50.0
action = 0
state = env.reset()
y0 = state[1]
v0 = 0
cut_off = 0.01
for t in range(3000):
env.render()
state, reward, done, _ = env.step(action)
y = state[1]
v = (y - y0)/delta_t
if done or y < 0 or v == 0.001:
break
alt_burn = (y*g+0.5*v*v)/(13.0 / env.lander.mass * 0.5)
v0 = v
y0 = y
if y < alt_burn and y > cut_off:
action = 2
else:
action = 0
print(" y",round(y,5)," v",round(v,5)," Alt_burn",round(alt_burn,5))
着陆器将悬停:
1可耻的是我找不到这个等式的来源。我拥有应用物理学学位,重点是天体物理学,并且有 1000 多个小时的 KSP - 所以我绝对确定这个方程是正确的,但我永远记不起我是从哪里得到它的。
2这种自杀式烧伤也被称为 hoverslam。 SpaceX 创造了这个术语,因为当猎鹰 9 号助推器着陆时,一台发动机在最小推力下产生的 TWR 大于 1.00,这意味着没有像阿波罗任务那样的 Powered Descent 容量。因此,只有瞬时悬停 - 因此 hoverslam.
我想模拟suicide burn来学习和理解火箭着陆。 OpenAI gym 已经有一个 LunarLander 环境,用于训练强化学习代理。我正在使用这个环境来模拟 python 中的自杀式烧伤。我从该环境的状态向量的前两个值中提取了坐标 (x,y)
。根据这些值,将 y
坐标视为高度;我已经使用这些方程计算了下落着陆器的速度和加速度
velocity(v) = delta_y/ delta_t
acceleartion(a) = delta_v/delta_t
由于模拟是逐步递增的,时间差delta_t
被取为1。无法找到LunarLander的重力参数,我给它一个默认值g=1
。然后使用 reddit comment
altitude to start suicide burn = [ (current altitude)(acceleration of gravity) + (1/2)(current velocity)2 ] / (acceleration of engines)
我试图计算高度以开始自杀式燃烧。这是我的完整 python 代码。我只打算使用四个可能的动作中的两个动作 0(什么都不做)和 2(启动主机)。
import gym
env = gym.make('LunarLander-v2')
env.seed(0)
g = 1
delta_t = 1
action = 0
state = env.reset()
# x0 = state[0]
y0 = state[1]
v0 = 0
for t in range(3000):
state, reward, done, _ = env.step(action)
y = state[1]
if done or y <0:
break
v = (y-y0)/delta_t # velocity
a = (v - v0)/delta_t # acceleration
# (altitude to start suicide burn) = [ (current altitude)(acceleration of gravity) + (1/2)(current velocity)2 ] / (acceleration of engines)
alt_burn = [y*g+0.5*v*v]/a
v0 = v
y0 = y
print(" y",round(y,5)," v",round(v,5)," a",round(a,5)," Alt_burn",round(alt_burn[0],5))
输出结果看起来像这样
y 1.41542 v 0.00196 a 0.00196 Alt_burn 722.35767
y 1.41678 v 0.00136 a -0.0006 Alt_burn -2362.78166
y 1.41754 v 0.00076 a -0.0006 Alt_burn -2362.63867
y 1.4177 v 0.00016 a -0.0006 Alt_burn -2362.43506
y 1.41726 v -0.00044 a -0.0006 Alt_burn -2362.64046
y 1.41622 v -0.00104 a -0.0006 Alt_burn -2359.03148
y 1.41458 v -0.00164 a -0.0006 Alt_burn -2358.17355
y 1.41233 v -0.00224 a -0.0006 Alt_burn -2353.50518
y 1.40949 v -0.00284 a -0.0006 Alt_burn -2349.24118
y 1.40605 v -0.00344 a -0.0006 Alt_burn -2343.51016
y 1.40201 v -0.00404 a -0.0006 Alt_burn -2336.31535
y 1.39737 v -0.00464 a -0.0006 Alt_burn -2329.04954
如果我们查看海拔高度 (y),它是一个小于 1.5 的非常小的值,而计算出的开始自杀式燃烧的海拔高度非常高。我该如何解决这个问题?
在reddit评论中他们只提到了启动引擎而没有提到关闭它。有人知道动态关闭引擎的数学原理吗?
您的代码有两个问题:
delta_t
根据lunar_lander
source 应该是
1.0/50.0
FPS = 50 #... self.world.Step(1.0/FPS, 6*30, 2*30)
其中 Box2D
documentation 表示
# [...]Typically we use a time step of 1/60 of a # second (60Hz) and 6 velocity/2 position iterations. This provides a # high quality simulation in most game scenarios. timeStep = 1.0 / 60
- 引擎的加速度不应像 中那样定义为当前加速度
alt_burn = [y*g+0.5*v*v]/a
但是由于引擎的推动,定义here为
MAIN_ENGINE_POWER = 13.0
着陆器的质量没有在creation of the lander body中指定,而是使用
env.lander.mass
我们可以发现质量是 4.82
。鉴于此,发动机的正确加速度为1
alt_burn = (y * g + 0.5 * v*v) / (13.0 / env.lander.mass * 0.5)
如果我们运行将代码进行上述修改,
import gym
env = gym.make('LunarLander-v2')
env.seed(0)
g = 1.0
delta_t = 1.0/50.0
action = 0
state = env.reset()
y0 = state[1]
for t in range(3000):
state, reward, done, _ = env.step(action)
y = state[1]
v = (y - y0) / delta_t
y0 = y
if done or y < 0:
break
alt_burn = (y*g+0.5*v*v)/(13.0 / env.lander.mass * 0.5)
print(" y",round(y,5)," v",round(v,5)," Alt_burn",round(alt_burn,5))
我们得到了更合理的燃烧高度答案:
y 1.41542 v 0.09797 Alt_burn 1.05242
y 1.41678 v 0.06799 Alt_burn 1.05158
y 1.41754 v 0.03799 Alt_burn 1.05097
y 1.4177 v 0.00799 Alt_burn 1.05057
y 1.41726 v -0.02201 Alt_burn 1.0504
y 1.41622 v -0.05202 Alt_burn 1.05045
y 1.41458 v -0.08202 Alt_burn 1.05073
y 1.41233 v -0.11202 Alt_burn 1.05123
y 1.40949 v -0.14202 Alt_burn 1.05194
y 1.40605 v -0.17202 Alt_burn 1.05289
y 1.40201 v -0.20202 Alt_burn 1.05405
y 1.39737 v -0.23202 Alt_burn 1.05544
y 1.39213 v -0.26203 Alt_burn 1.05705
y 1.38629 v -0.29202 Alt_burn 1.05887
...
y 0.56683 v -1.58312 Alt_burn 1.34863
y 0.53456 v -1.61311 Alt_burn 1.36025
y 0.5017 v -1.64311 Alt_burn 1.37209
y 0.46824 v -1.67311 Alt_burn 1.38416
y 0.43418 v -1.70311 Alt_burn 1.39644
y 0.39951 v -1.73311 Alt_burn 1.40895
y 0.36425 v -1.76311 Alt_burn 1.42168
y 0.32839 v -1.79311 Alt_burn 1.43463
y 0.29193 v -1.82311 Alt_burn 1.44781
y 0.25487 v -1.85311 Alt_burn 1.46121
y 0.2172 v -1.88311 Alt_burn 1.47483
y 0.17894 v -1.91311 Alt_burn 1.48867
y 0.14008 v -1.94311 Alt_burn 1.50274
y 0.10062 v -1.97311 Alt_burn 1.51702
y 0.06055 v -2.00311 Alt_burn 1.53154
y 0.01989 v -2.03311 Alt_burn 1.54626
自杀燃烧的执行2现在很简单,我们只需要在着陆器低于燃烧高度时启动引擎,并在着陆器低于截止高度时停用它们高度。
import gym
env = gym.make('LunarLander-v2')
env.seed(0)
g = 1.0
delta_t = 1.0/50.0
action = 0
state = env.reset()
y0 = state[1]
v0 = 0
cut_off = 0.01
for t in range(3000):
env.render()
state, reward, done, _ = env.step(action)
y = state[1]
v = (y - y0)/delta_t
if done or y < 0 or v == 0.001:
break
alt_burn = (y*g+0.5*v*v)/(13.0 / env.lander.mass * 0.5)
v0 = v
y0 = y
if y < alt_burn and y > cut_off:
action = 2
else:
action = 0
print(" y",round(y,5)," v",round(v,5)," Alt_burn",round(alt_burn,5))
着陆器将悬停:
1可耻的是我找不到这个等式的来源。我拥有应用物理学学位,重点是天体物理学,并且有 1000 多个小时的 KSP - 所以我绝对确定这个方程是正确的,但我永远记不起我是从哪里得到它的。
2这种自杀式烧伤也被称为 hoverslam。 SpaceX 创造了这个术语,因为当猎鹰 9 号助推器着陆时,一台发动机在最小推力下产生的 TWR 大于 1.00,这意味着没有像阿波罗任务那样的 Powered Descent 容量。因此,只有瞬时悬停 - 因此 hoverslam.