基于Pybullet搭建强化学习机械臂(一)

基于Pybullet搭建强化学习机械臂(一)

在强化学习中,常用的机器人仿真环境有 mojoco 、gazebo、pybullet 等等,这三个仿真环境中,mojoco一年的通行证费用还是让人望而却步,gazebo是基于ros的一个仿真库,ros的python版本和兼容性又是另一个让人头疼的问题。最后调研了现有的仿真环境,发现pybullet是一个开源 的、上手快的一个仿真库,所以本项目基于pybullet搭建了一个拟人机械臂的强化学习环境平台。本文描述了整个环境的搭建过程与最终的训练及结果。

完整项目地址:https://github.com/PiggyCh/RL_arm_under_sparse_reward

一. 安装pybullet

安装pybulelt: pip install pybullet

or download from the github (https://github.com/bulletphysics/bullet3) 执行命令python setup.py install

pybullet安装过程中可能需要C++的组建,在安装过程当中,可能会提示报错,自行百度下载C++组建即可。

二. 模型及pybullet初步:

对于pybullet来说,一个非常方便的点在于它可以直接加载URDF、SDF模型等等,所以如果我们要搭建自己的仿真模型,第一步肯定还是要在仿真环境里添加各种模型文件

使用loadURDF来添加物体:URDF的接口如下:

import pybullet as p
 import pybullet_data #pybullet自带的一些模型
 p.connect(p.GUI) #连接到仿真环境,p.DIREACT是不显示仿真界面,p.GUI则为显示仿真界面
 p.setGravity(0,0,-10) #设定重力
 p.resetSimulation() #重置仿真环境
 p.setAdditionalSearchPath(pybullet_data.getDataPath()) #添加pybullet的额外数据地址,使程序可以直接调用到内部的一些模型
 planeId = p.loadURDF("plane.urdf") #加载外部平台模型
 objects = p.loadURDF('URDF_model/bmirobot_description/urdf/robotarm_description.urdf',flags=9) #加载机械臂,flags=9代表取消自碰撞,详细教程可以参考pybullet的官方说明文档
 while 1:
     p.stepSimulation()

这里我们使用的是一个拟人的机械臂, 运行结果如下:

然后添加桌子:

 tableUid = p.loadURDF("table/table.urdf", basePosition=[0,0.3,-0.45],globalScaling=1)
 #loadUDRF 可以制定放置地点,比例等等

通过鼠标可以直接点击模型产生一些移动。

在ros中常用一种xacro模型文件,这种文件可以被转换成URDF模型后再放入pybullet中,下面是设定的一个方块的设定,在contact中我们设定了他的fraction value 和 inertia_scaling, 值较大让机械臂可以容易抓起,mass value是它的重量,几何形态geometry是0.04,0.04,0.08的box

<?xml version="0.0" ?>
 <robot name="cube.urdf">
   <link name="baseLink">
     <contact>
       <friction value="5.0"/>
       <inertia_scaling value="3.0"/>
     </contact>
     <inertial>
       <origin rpy="0 0 0" xyz="0 0 0"/>
        <mass value="2"/>
        <inertia ixx="1" ixy="0" ixz="0" iyy="1" iyz="0" izz="1"/>
     </inertial>
     <visual>
       <origin rpy="0 0 0" xyz="0 0 0"/>
       <geometry>
             <box size=".04 .04 .08"/>
       </geometry>
        <material name="white">
         <color rgba="1 1 1 1"/>
       </material>
     </visual>
     <collision>
       <origin rpy="0 0 0" xyz="0 0 0"/>
       <geometry>
         <box size=".04 .04 .08"/>
       </geometry>
     </collision>
   </link>
 </robot>

在通过loadURDF将方块放置在环境中,再设定一个没有collision且为红色的方块表示为目标位置

#随即方块的位置
 xpos = 0.15 +0.2 * random.random()  # 0.35
 ypos = (random.random() * 0.3) + 0.2  # 0.10 0.50
 zpos = 0.2
 ang = 3.14 * 0.5 + 3.1415925438 * random.random()
 orn = p.getQuaternionFromEuler([0, 0, ang])
 #随机目标方块的位置(在桌子上)
 xpos_target = 0.35 * random.random()  # 0.35
 ypos_target = (random.random() * 0.3) + 0.2  # 0.10 0.50
 zpos_target = 0.2
 ang_target = 3.14 * 0.5 + 3.1415925438 * random.random()
 ​
 blockUid = p.loadURDF("URDF_model/cube_small_push.urdf", xpos, ypos, zpos,
                                        orn[0], orn[1], orn[2], orn[3])
 targetUid = p.loadURDF("URDF_model/cube_small_target_push.urdf",
                                         [xpos_target, ypos_target, zpos_target],
                                         orn_target, useFixedBase=1)

至此我们就完成了基本的环境搭建,不过目前只是放置了物体和机械臂,算是皮儿了。