Acrobot¶
概述¶
Acrobot机器人系统是强化学习中的经典控制问题。该系统包括两个关节和两个连杆,其中两个连杆之间的关节可以被驱动。系统的初始状态是向下悬挂的。目标是在驱动关节上施加力矩,使连杆的自由端摆动到指定高度。如下图所示。
安装¶
安装方法¶
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
。
参考资料¶
Acrobot 源码