硬件的史诗级更新
年前的时候,学弟抱着试一试的心态找实验室申请租用一台物理服务器,破天荒的被允许了,虽然配置不是很好,但总归比用自己电脑跑优化好多了,服务器参数如下
零部件 | 详细参数 |
---|---|
CPU | 双路E5-2680v2洋垃圾(20核心40线程)基频2.8GHz睿频3.6GHz |
内存 | 48GB DDR3内存 |
硬盘 | 500G SSD |
网络 | 50M ↑ 200M ↓ |
GPU | 想peach |
(在此不实名羡慕隔壁Miracle3D
的Intel Core Ultra 9 285K
)
涉及的算法
简单列出来,不要问我原理,我也不懂
1. RL(强化学习)
2. PPO(近端策略优化)
3. MLP(多层感知机)
尝试理解自带的优化类
略读scripts/gyms/Basic_Run.py
FCPCodebase中比较复杂的优化类肯定是Basic_Run了
Basic_Run
class Basic_Run(gym.Env):
def __init__(self, ip, server_p, monitor_p, r_type, enable_draw) -> None:
'''
初始化机器人实体
初始化步数记录
初始化步态以及步态生成器
设定神经网络输入参数的数量
。。。
'''
def observe(self, init=False):
'''
神经网络需要输入,当sync方法执行后,球场的最新状态会被同步过来,此时应该收集各项参数,作为神经网络的输入
包括:
动作执行步骤数
躯干的姿态
所有的关节角度
所有的关节速度
步行的参数(步高,步长,步宽)
等等等一系列可能与跑步有关的状态参数
'''
def sync(self):
'''
执行一次就会把当前的机器人目标状态设定的参数发送到球场
然后获取球场返回的实时状态数据
'''
def reset(self):
'''
优化过程中,机器人会反复执行某个任务,每次执行任务前,执行reset方法对当前环境进行重置
'''
def render(self, mode='human', close=False):
return
def close(self):
Draw.clear_all()
self.player.terminate()
def step(self, action):
'''
优化的核心步骤,该方法将被反复执行,用于训练神经网络和获取reward等
action就是神经网络的输出,我们需要在改方法中对action进行微调,然后应用于机器人,并返回奖励值
'''
Train
class Train(Train_Base):
def __init__(self, script) -> None:
super().__init__(script)
def train(self, args):
'''
此处定义了训练的各项参数,包括同时进行训练的球场个数,批量大小,总训练步数,学习率以及模型保存位置等等
'''
n_envs = min(16, os.cpu_count())
n_steps_per_env = 1024 # RolloutBuffer is of size (n_steps_per_env * n_envs)
minibatch_size = 64 # should be a factor of (n_steps_per_env * n_envs)
total_steps = 30000000
learning_rate = 3e-4
folder_name = f'Basic_Run_R{self.robot_type}'
model_path = f'./scripts/gyms/logs/{folder_name}/'
def test(self, args):
'''
对训练好的现有模型进行测试
'''
细看各个方法
大致了解每个方法的作用后,我们来详细看看部分方法的内部流程,此处最重要的当然是
reset()
和step()
reset()
def reset(self):
# 计步器归零
self.step_counter = 0
# 从世界模型中获取当前机器人个体
r = self.player.world.robot
# 移动机器人到指定为止并屈膝站立姿势
for _ in range(25):
self.player.scom.unofficial_beam((-14,0,0.50),0) # beam player continuously (floating above ground)
self.player.behavior.execute("Zero_Bent_Knees")
self.sync()
# beam player to ground
self.player.scom.unofficial_beam((-14,0,r.beam_height),0)
r.joints_target_speed[0] = 0.01 # move head to trigger physics update (rcssserver3d bug when no joint is moving)
self.sync()
# stabilize on ground
for _ in range(7):
self.player.behavior.execute("Zero_Bent_Knees")
self.sync()
# 训练过程中会记录机器人x轴的位置左边,用于计算reward
self.lastx = r.cheat_abs_pos[0]
self.act = np.zeros(self.no_of_actions,np.float32)
return self.observe(True)
step()
def step(self, action):
r = self.player.world.robot
# self.act可以理解为是各种随机生成的叠加结果
# action是神经网路训练过程中的输出,我们将两者按照一定权重进行融合(平滑处理)
self.act = 0.4 * self.act + 0.6 * action
# 此处使用了步态生成器,让机器人程序模拟一帧步态行走,步态生成器就会根据当前状态生成下一帧的各个关节角度值
# 后续步骤可以直接获取关节目标角度(注意此时步态生成器生成的目标角度并未立即生效,因为sync执行后,参数才会同步过去)
if self.step_counter == 0:
self.player.behavior.execute("Step", self.step_default_dur, self.step_default_z_span, self.step_default_z_max)
else:
step_zsp = np.clip(self.step_default_z_span + self.act[20]/300, 0, 0.07)
step_zmx = np.clip(self.step_default_z_max + self.act[21]/30, 0.6, 0.9)
self.player.behavior.execute("Step", self.step_default_dur, step_zsp, step_zmx)
# self.step_obj.values_l 和 self.step_obj.values_r就是步态生成器生成的角度中选取出来的
# 可以理解为:此处使用神经网络输出的action对默认的步态进行微调,然后再将微调后的应用于机器人行走
new_action = self.act[:20] * 2 # scale up actions to motivate exploration
new_action[[0,2,4,6,8,10]] += self.step_obj.values_l
new_action[[1,3,5,7,9,11]] += self.step_obj.values_r
new_action[12] -= 90 # arms down
new_action[13] -= 90 # arms down
new_action[16] += 90 # untwist arms
new_action[17] += 90 # untwist arms
new_action[18] += 90 # elbows at 90 deg
new_action[19] += 90 # elbows at 90 deg
# 将微调后的应用于机器人行走(直接设置下一帧机器人关节角度)
r.set_joints_target_position_direct( # commit actions:
slice(2,22), # act on all joints except head & toes (for robot type 4)
new_action, # target joint positions
harmonize=False # there is no point in harmonizing actions if the targets change at every step
)
# 执行sync,发送角度变化的命令(实际上底层是通过控制关节速度来实现的),然后获取球场返回的结果
self.sync()
self.step_counter += 1
# reward简单的设为这一帧机器人前进的x轴距离
reward = r.cheat_abs_pos[0] - self.lastx
self.lastx = r.cheat_abs_pos[0]
# 判断这次的测试是否应该终止(跌倒判断+超时判断)
terminal = r.cheat_abs_pos[2] < 0.3 or self.step_counter > 300
# 将神经网络的输出应用于机器人后的reward等数据返回回去,底层的Train_Base自动对其进行评判和处理
return self.observe(), reward, terminal, {}
尝试用默认脚本优化跑步
奇怪的报错:socket was closed by rcssserver3d!
python3 Run_Util.py
15
0
然后训练就开始了,大概五小时后基本能慢跑了,训练个两三天能跑的飞快了(稳不稳定先不谈),只图一乐
训练了几天之后的结果示例
你知道训练时候的机器人被移出场外roboviz右上角uncapable是怎么了吗
被移出场外大概率是因为倒地超过一段时间了,自动裁判会把机器人移到场外,建议做个跌倒判断,头部z轴坐标小于0.3则认为摔倒,即时停止本次训练
如果您是DreamWing的成员,可以直接QQ联系我👍
要在球场上使用basic_run训练出的pkl文件,是不是需要自行设计一个运行文件才行?其他例如dribble都有对应的dribble和env文件用于运行pkl文件
训练出的模型在test里效果就很好,但用自己写的运行文件进行运行就效果很差,是运行文件的影响吗?
我们也遇到了一样的问题🙃,在训练踢球时能踢的很远,但是一实际运行就会有所削弱