月球着陆器

../../../_images/lunar_lander.gif

此环境是 Box2D 环境的一部分,其中包含有关该环境的一般信息。

动作空间

Discrete(4)

观测空间

Box([ -2.5 -2.5 -10. -10. -6.2831855 -10. -0. -0. ], [ 2.5 2.5 10. 10. 6.2831855 10. 1. 1. ], (8,), float32)

导入

gymnasium.make("LunarLander-v3")

描述

此环境是一个经典的火箭轨迹优化问题。根据庞特里亚金最大值原理,最优做法是全速启动发动机或将其关闭。这就是此环境具有离散动作(发动机开或关)的原因。

环境有两个版本:离散版或连续版。着陆点始终位于坐标 (0,0) 处。坐标是状态向量中的前两个数字。可以在着陆点之外着陆。燃料是无限的,因此智能体可以学习飞行,然后在第一次尝试时着陆。

要查看启发式着陆,请运行

python gymnasium/envs/box2d/lunar_lander.py

动作空间

有四种离散动作可用

  • 0: 不做任何事

  • 1: 启动左侧定向发动机

  • 2: 启动主发动机

  • 3: 启动右侧定向发动机

观测空间

状态是一个 8 维向量:着陆器在 xy 中的坐标,其在 xy 中的线速度,其角度,其角速度,以及两个布尔值表示每条腿是否与地面接触。

奖励

每一步之后都会获得奖励。一个回合的总奖励是该回合内所有步骤的奖励之和。

对于每一步,奖励

  • 根据着陆器与着陆垫的距离接近或远离而增加/减少。

  • 根据着陆器的移动速度慢或快而增加/减少。

  • 着陆器倾斜越多(角度不水平),奖励减少。

  • 每条腿与地面接触时增加 10 分。

  • 每帧侧发动机启动时减少 0.03 分。

  • 每帧主发动机启动时减少 0.3 分。

如果坠毁或安全着陆,该回合会分别额外获得 -100 或 +100 点奖励。

如果一个回合得分至少 200 分,则被视为一个解决方案。

初始状态

着陆器从视口顶部中心开始,其质心受到随机初始力的作用。

回合终止

回合在以下情况下结束:

  1. 着陆器坠毁(着陆器主体与月球接触);

  2. 着陆器超出视口范围(x 坐标大于 1);

  3. 着陆器未唤醒。根据 Box2D 文档,未唤醒的物体是指不移动且不与任何其他物体碰撞的物体

当 Box2D 确定一个物体(或一组物体)已停止时,该物体进入睡眠状态,该状态的 CPU 开销非常小。如果一个物体是唤醒状态并与一个睡眠中的物体碰撞,则睡眠中的物体会醒来。如果连接到物体的关节或接触被销毁,物体也会醒来。

参数

月球着陆器有大量参数

>>> import gymnasium as gym
>>> env = gym.make("LunarLander-v3", continuous=False, gravity=-10.0,
...                enable_wind=False, wind_power=15.0, turbulence_power=1.5)
>>> env
<TimeLimit<OrderEnforcing<PassiveEnvChecker<LunarLander<LunarLander-v3>>>>>

  • continuous 决定是使用离散动作还是连续动作(对应于发动机的油门),动作空间分别为 Discrete(4)Box(-1, +1, (2,), dtype=np.float32)。对于连续动作,动作的第一个坐标决定主发动机的油门,而第二个坐标指定侧向推进器的油门。给定一个动作 np.array([main, lateral]),如果 main < 0,主发动机将完全关闭;如果 0 <= main <= 1,油门从 50% 到 100% 线性缩放(特别是,主发动机在功率低于 50% 时不工作)。类似地,如果 -0.5 < lateral < 0.5,侧向推进器将完全不启动。如果 lateral < -0.5,左侧推进器将启动;如果 lateral > 0.5,右侧推进器将启动。同样,油门在 -1 和 -0.5 之间(以及 0.5 和 1 之间)线性地从 50% 到 100% 缩放。

  • gravity 决定重力常数,其范围限制在 0 到 -12 之间。默认值为 -10.0。

  • enable_wind 决定是否对月球着陆器施加风力效果。风力使用函数 tanh(sin(2 k (t+C)) + sin(pi k (t+C)))` 生成,其中 k 设置为 0.01,C 在 -9999 和 9999 之间随机采样。

  • wind_power 决定施加到飞行器上的线性风力的最大幅度。wind_power 的推荐值在 0.0 到 20.0 之间。

  • turbulence_power 决定施加到飞行器上的旋转风力的最大幅度。turbulence_power 的推荐值在 0.0 到 2.0 之间。

版本历史

  • v3

    • 每当环境重置时,重置风力和湍流偏移量(C),以确保连续回合之间的统计独立性(相关 GitHub issue)。

    • 修复由于未能完全销毁世界而导致的非确定性行为(相关 GitHub issue)。

    • xy 坐标的观测空间从 \(\pm 1.5\) 更改为 \(\pm 2.5\),速度从 \(\pm 5\) 更改为 \(\pm 10\),角度从 \(\pm \pi\) 更改为 \(\pm 2\pi\)(相关 GitHub issue)。

  • v2: 统计能量消耗,并在 v0.24 中添加了带有风力和湍流功率参数的湍流

  • v1: 在状态向量中添加了腿与地面的接触;与地面接触奖励 +10 分,如果失去接触则奖励 -10 分;奖励重新标准化为 200;更难的初始随机推动。

  • v0: 初始版本

注意

该环境的实现中存在一些意外的错误。

  1. 着陆器侧向推进器在着陆器本体上的位置会随着着陆器的方向而变化。这反过来导致施加到着陆器上的扭矩与方向相关。

  2. 状态的单位不一致。例如:

  • 角速度的单位是 0.4 弧度/秒。为了转换为弧度/秒,该值需要乘以 2.5。

对于 VIEWPORT_W、VIEWPORT_H、SCALE 和 FPS 的默认值,比例因子等于:‘x’:10,‘y’:6.666,‘vx’:5,‘vy’:7.5,‘angle’:1,‘angular velocity’:2.5

修正后,状态的单位如下:‘x’:(单位),‘y’:(单位),‘vx’:(单位/秒),‘vy’:(单位/秒),‘angle’:(弧度),‘angular velocity’:(弧度/秒)

鸣谢

由 Oleg Klimov 创建