Shortcuts

Acrobot

概述

Acrobot机器人系统是强化学习中的经典控制问题。该系统包括两个关节和两个连杆,其中两个连杆之间的关节可以被驱动。系统的初始状态是向下悬挂的。目标是在驱动关节上施加力矩,使连杆的自由端摆动到指定高度。如下图所示。

../_images/acrobot.gif

安装

安装方法

Acrobot 环境内置在 gym 中,直接安装 gym 即可。其环境 id 是Acrobot-v1

pip install gym

验证安装

在 Python 命令行中运行如下命令验证安装成功。

import gym
env = gym.make('Acrobot-v1')
obs = env.reset()
print(obs)
assert env.observation_space.shape == (6,)
assert env.action_space == gym.spaces.Discrete(3)

环境介绍

动作空间

Acrobot 的动作空间属于离散动作空间,有 3 个离散动作,分别是施加+1力矩, -1力矩和不施加力矩。

  • -1的力矩 : 0 表示向关节施加 -1 的力矩。

  • 0的力矩 : 1 表示向关节施加 0 的力矩。

  • +1的力矩 : 2 表示向关节施加 +1 的力矩。

使用 gym 环境空间定义则可表示为:

action_space = gym.spaces.Discrete(3)

状态空间

Acrobot 的状态空间有 6 个元素,分别是:

  • Cosine of theta1 :第一个连杆和竖直方向角度的cos值,范围是 [-1, 1]

  • Sine of theta1 :第一个连杆和竖直方向角度的sin值,范围是 [-1, 1]

  • Cosine of theta2 :第二个连杆相对于第一个连杆的角度的cos值,范围是 [-1, 1]

  • Sine of theta2 :第二个连杆相对于第一个连杆的角度的sin值,范围是 [-1, 1]

  • Angular velocity of theta1 :第一个连杆相对于竖直方向的角速度,范围是 [-4 * pi, 4 * pi]

  • Angular velocity of theta2 :第二个连杆相对于第一个连杆的角速度,范围是 [-9 * pi, 9 * pi]

theta1 是第一个关节的角度,其中角度 0 表示第一个链接直接指向下方。

theta2 是相对于第一个连杆的角度。 角度 0 对应于两个链接之间具有相同的角度。

奖励空间

目标是让自由端以尽可能少的步数达到指定的目标高度,因此所有未达到目标的步数都会产生 -1 的奖励。 达到目标高度会导致终止,奖励为 0

终止条件

Acrobot 环境每个 episode 的终止条件是遇到以下任何一种情况:

  • 自由端达到目标高度,构造形式是 \(-cos(\theta_1) - cos(\theta_1 + \theta_2) > 1.0\)

  • 达到 episode 的最大 step,默认为 500

DI-zoo 可运行代码示例

完整的训练配置文件在 github link 内,对于具体的配置文件,例如acrobot_dqn_config.py,使用如下的 demo 即可运行:

from easydict import EasyDict

acrobot_dqn_config = dict(
    exp_name='acrobot_dqn_seed0',
    env=dict(
        collector_env_num=8,
        evaluator_env_num=8,
        n_evaluator_episode=8,
        stop_value=-60,
        env_id='Acrobot-v1',
        replay_path='acrobot_dqn_seed0/video',
    ),
    policy=dict(
        cuda=True,
        model=dict(
            obs_shape=6,
            action_shape=3,
            encoder_hidden_size_list=[256, 256],
            dueling=True,
        ),
        nstep=3,
        discount_factor=0.99,
        learn=dict(
            update_per_collect=10,
            batch_size=128,
            learning_rate=0.0001,
            target_update_freq=250,
        ),
        collect=dict(n_sample=96, ),
        eval=dict(evaluator=dict(eval_freq=2000, )),
        other=dict(
            eps=dict(
                type='exp',
                start=1.,
                end=0.05,
                decay=250000,
            ),
            replay_buffer=dict(replay_buffer_size=100000, ),
        ),
    ),
)
acrobot_dqn_config = EasyDict(acrobot_dqn_config)
main_config = acrobot_dqn_config
acrobot_dqn_create_config = dict(
    env=dict(type='acrobot', import_names=['dizoo.classic_control.acrobot.envs.acrobot_env']),
    env_manager=dict(type='subprocess'),
    policy=dict(type='dqn'),
    replay_buffer=dict(type='deque', import_names=['ding.data.buffer.deque_buffer_wrapper']),
)
acrobot_dqn_create_config = EasyDict(acrobot_dqn_create_config)
create_config = acrobot_dqn_create_config

if __name__ == "__main__":
    from ding.entry import serial_pipeline
    serial_pipeline((main_config, create_config), seed=0)

基准算法性能

使用 DQN 算法的实验结果如下。横坐标是step ,纵坐标是reward_mean

../_images/acrobot_dqn.png

参考资料