为了实现在每次迭代过程中绘制角度和角速度的关系曲线,而不是重新建模获取这些数据,我们可以利用 gym
环境中的现有数据,并在每次数据更新时实时绘制。假设我们使用的是 gym
的某个物理环境(例如 CartPole-v1
),我们可以从环境中直接获取角度和角速度,并使用 matplotlib
库动态绘制这些数据点。
注意,这里仅仅使用原始的cartpole-v1环境,并没有使用更优化的RL算法进行训练,后续还会利用DQN, DDPG,SAC等进行训练。以下为示例代码,展示了如何在每次迭代中从 gym
环境中获取角度和角速度,并实时绘制它们的关系曲线:
import gym
import matplotlib.pyplot as plt
import numpy as np
from collections import deque
import time
# 创建一个绘图窗口和坐标轴
plt.ion() # 开启交互模式
fig, ax = plt.subplots()
line, = ax.plot([], [], 'r-') # 初始化一条红色的线
ax.set_xlim(-np.pi, np.pi) # 设置x轴的范围,这里假设角度在 -π 到 π 之间
ax.set_ylim(-10, 10) # 设置y轴的范围,这里假设角速度的合理范围
plt.xlabel('Angle (rad)')
plt.ylabel('Angular Velocity (rad/s)')
# 初始化环境
env = gym.make('CartPole-v1', render_mode="human")
obs = env.reset()
# 初始化一个队列来存储最近的点(角度,角速度),用于绘图
points = deque(maxlen=100) # 最多存储100个点
def update_plot(points):
# 提取角度和角速度
angles, angular_velocities = zip(*points)
# 更新绘图数据
line.set_data(angles, angular_velocities)
plt.draw()
plt.pause(0.01) # 暂停一小段时间以更新图形
# 进行多次迭代
for episode in range(1000):
print("Episode finished after {} timesteps".format(episode))
env.render()
env.setp(env.action_space.sample())
action = env.action_space.sample() # 随机采样一个动作
obs, reward, done, info, _ = env.step(action) #加下划线(由于版本更新),否则报参数过多的错
# 获取角度和角速度
angle = obs[2]
angular_velocity = obs[3]
# 添加新点到队列
points.append((angle, angular_velocity))
# 更新图形
update_plot(points)
# 如果游戏结束,则重置环境
if done:
obs = env.reset()
# 可选:添加一些延迟以便更好地观察图形变化
time.sleep(0.01)
# 关闭环境
env.close()
# 关闭绘图窗口
plt.ioff()
plt.show()
解释
- 环境初始化:使用
gym.make('CartPole-v1')
创建一个CartPole环境,并使用env.reset()
重置环境以获取初始状态,这里注意要加上render_mode。 - 绘图初始化:使用
matplotlib
创建一个绘图窗口和坐标轴,并初始化一条红色的线。 - 实时更新:
- 在每次迭代中,从环境状态中提取角度和角速度。
- 将新的(角度,角速度)点添加到队列中。
- 调用
update_plot(points)
函数更新图形。
- 图形更新函数:
update_plot(points)
函数从队列中提取所有点,并更新绘图数据。 - 迭代和延迟:进行多次迭代,每次迭代后如果游戏结束则重置环境,并添加一些延迟以便更好地观察图形变化。
- 关闭环境和绘图窗口:在迭代结束后关闭环境和绘图窗口。
通过这种方式,我们可以在每次迭代过程中实时绘制角度和角速度的关系曲线。
注:部分为GPT生成,仅供个人备忘所用。