如何用Pybullet移动机器人手臂
我觉得"我安装了Pybullet来进行机器人仿真,但是日语中的文章和说明太少了……",所以我从构建Pybullet环境开始,解释了Pybullet的功能,并实际介绍了该机器人。移动它的过程。
运行环境
-
Windows10
-
WSL2
-
Ubuntu18.04
准备
这是一章,适用于尚未准备运行Pybullet的人员,因此人们可以跳过它,说" Pybullet正在运行!"是可以的。
搭建环境的过程
我将简要解释在Windows 10上运行Pybullet的流程。
要使Pybullet正常工作,请在安装Pybullet本身之前先
是必需的。
1.创建WSL2环境
为了在Windows 10上使用Pybullet,最好先创建一个WSL(Linux的Windows子系统)环境。
- WSL2安装过程(官方页面)
2.安装Ubuntu 18.04
准备好WSL2后,下一步就是安装Ubuntu。
可以从Microsoft Store轻松完成安装。 Store中有各种版本的Ubuntu,但是我认为安装Ubuntu 18.04基本上是安全的。
Pybullet可以直接在Ubuntu上直接运行,但是我在Windows Terminal上使用Ubuntu。
安装Ubuntu之后,启动Ubuntu并设置WSL2。
-
如何在Windows终端机上使用Ubuntu
-
如何在Ubuntu
上启用WSL2
此处省略
。
3.安装Xserver
为了用Pybullet执行机器人仿真,这很自然,但是有必要查看仿真状态。 Xserver充当监视器,以查看模拟情况。
- Xserver的安装(VcXsrv)(官方页面)
↑请注意,单击
后,安装将自动开始
安装Xserver后
-
Xserver设置
-
允许Windows防火墙中的Xserver
是必需的。这里也省略了。
安装Pybullet
当Xserver安全运行时,终于可以安装Pybullet了。在安装Pybullet时,请确保记住在WSL上的安装位置以及安装位置。
除了Pybullet,
-
matplotlib
-
numpy
-
数学
如果您安装诸如
之类的库,以后会很方便。
药丸运行检查
移至Pybullet的安装目录,然后
1 2 | $ cd bullet3/examples/pybullet/examples $ ls |
如果运行
,您将看到Pybullet安装随附的示例代码。
如果您正确启动了任何示例代码并且可以正常运行,则可以认为Pybullet的操作环境已准备就绪。
(示例)执行人形机器人的手动操作程序
1 | $ python3 humanoid_manual_control.py |
结果
如果使用鼠标移动右侧的栏,则机器人将一前一后地移动
如何使用Pybullet
humanoid_manual_control.py代码描述
顾名思义,Pybullet可与Python一起使用。
例如,我前面提到的
humanoid_manual_control.py
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 | import pybullet as p import time import pybullet_data p.connect(p.GUI) p.setAdditionalSearchPath(pybullet_data.getDataPath()) obUids = p.loadMJCF("mjcf/humanoid.xml") humanoid = obUids[1] gravId = p.addUserDebugParameter("gravity", -10, 10, -10) jointIds = [] paramIds = [] p.setPhysicsEngineParameter(numSolverIterations=10) p.changeDynamics(humanoid, -1, linearDamping=0, angularDamping=0) for j in range(p.getNumJoints(humanoid)): p.changeDynamics(humanoid, j, linearDamping=0, angularDamping=0) info = p.getJointInfo(humanoid, j) #print(info) jointName = info[1] jointType = info[2] if (jointType == p.JOINT_PRISMATIC or jointType == p.JOINT_REVOLUTE): jointIds.append(j) paramIds.append(p.addUserDebugParameter(jointName.decode("utf-8"), -4, 4, 0)) p.setRealTimeSimulation(1) while (1): p.setGravity(0, 0, p.readUserDebugParameter(gravId)) for i in range(len(paramIds)): c = paramIds[i] targetPos = p.readUserDebugParameter(c) p.setJointMotorControl2(humanoid, jointIds[i], p.POSITION_CONTROL, targetPos, force=5 * 240.) time.sleep(0.01) |
Pybullet功能用
因此,如果您具有基本的Python知识(例如if语句,for语句,列表等),则只需使用Pybullet函数就可以轻松进行模拟。
现在,从这里开始,我将简要解释上面的代码。
如果您可以理解此代码的内容,则应该能够理解Pybullet。顺便说一句,Pybullet有官方的入门指南,因此,如果您想了解更多有关Pybullet功能的信息,请参阅此。 (用英语...)
- Pybullet入门指南
1.代码的前半部分
1 2 3 4 5 6 7 8 9 | import pybullet as p import time import pybullet_data p.connect(p.GUI) p.setAdditionalSearchPath(pybullet_data.getDataPath()) obUids = p.loadMJCF("mjcf/humanoid.xml") humanoid = obUids[1] |
使用
换句话说,上一个图像中显示的人形机器人不是使用Python文件创建的,而是使用单独的MCDF文件创建的。
在此示例代码中,读取了MJCF中描述的机械手,但是除了MJCF以外,还以SDF和URDF等格式进行了描述。
2.中码
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 | gravId = p.addUserDebugParameter("gravity", -10, 10, -10) jointIds = [] paramIds = [] p.setPhysicsEngineParameter(numSolverIterations=10) p.changeDynamics(humanoid, -1, linearDamping=0, angularDamping=0) for j in range(p.getNumJoints(humanoid)): p.changeDynamics(humanoid, j, linearDamping=0, angularDamping=0) info = p.getJointInfo(humanoid, j) #print(info) jointName = info[1] jointType = info[2] if (jointType == p.JOINT_PRISMATIC or jointType == p.JOINT_REVOLUTE): jointIds.append(j) paramIds.append(p.addUserDebugParameter(jointName.decode("utf-8"), -4, 4, 0)) |
因此,对于参数
我已将模拟过程中在栏上方显示的参数的名称设置为
句子中的
换句话说,if语句部分是"仅调试PRISMATIC或REVOLUTE关节"的代码。
稍后写URDF时,PRISMATIC(平移关节)和REVOLUTE(轴旋转关节)将正确显示。
顺便说一句,if语句限制关节类型的原因是,还有其他不动的关节,例如FIXED(固定关节)。
3.代码后半部分
1 2 3 4 5 6 7 8 | p.setRealTimeSimulation(1) while (1): p.setGravity(0, 0, p.readUserDebugParameter(gravId)) for i in range(len(paramIds)): c = paramIds[i] targetPos = p.readUserDebugParameter(c) p.setJointMotorControl2(humanoid, jointIds[i], p.POSITION_CONTROL, targetPos, force=5 * 240.) time.sleep(0.01) |
顺便说一句,我前一段时间所做的是模拟的准备工作。而我们在这里所做的就是主要的模拟。
使用Pybullet模拟时,请将其放在while语句之前。每当while语句出现时,仿真就会运行。
首先,
for语句的内容是用户移动每个关节参数的代码。
这是移动机器人的功能。
指定要使用
大致来说,
由于程序(模拟)在
例如,如果设置time.sleep(1),则参数将每秒更新一次,因此机器人的动作将变得生涩。
实际上,如果您只想移动机械臂,则只需将代码前半部分的
调整humanoid_manual_control.py代码以移动机器人手臂
在
中,我们将立即使用
首先,让我们复制代码以防万一。
1 | $ cp humanoid_manual_control.py robotArm_manual_control.py |
从这里开始,我们将处理复制的
首先,让我们用机器人手臂代替类人机器人。
robotArm_manual_control.py
1 2 3 4 5 6 7 8 9 10 | import pybullet as p import time #import pybullet_data #必要ないので削除 p.connect(p.GUI) #p.setAdditionalSearchPath(pybullet_data.getDataPath()) #必要ないので削除 kukaId = p.loadURDF("kuka_iiwa/model.urdf", [0, 0, 0], useFixedBase=True) #追加 #obUids = p.loadMJCF("mjcf/humanoid.xml") #削除 #humanoid = obUids[1] #削除 |
在安装Pybullet时,将附加一个称为kuka_iiwa的机械手作为示例机械手,因此这次我们将使用它。
如果像上述代码一样替换它,请将其余代码的所有
如果可以正确更改所有内容,请执行并检查。
1 | $ python3 robotArm_manual_control.py |
结果
人形机器人已成功转换为机械臂。如果移动右侧的栏,则可以正确移动手臂。
但是,与以前不同,地板已经消失了。
也许删除的
因此,接下来我们将添加一个地板。
robotArm_manual_control.py
1 2 3 4 5 6 | import pybullet as p import time p.connect(p.GUI) p.loadURDF("plane.urdf", [0, 0, 0], useFixedBase=True) #追加 kukaId = p.loadURDF("kuka_iiwa/model.urdf", [0, 0, 0], useFixedBase=True) |
结果
这样,如果您有要使用的机械手或要放置的物体,则可以使用
但是,如果您想从一开始就使用Pybullet随附的示例以外的其他示例,则需要单独编写URDF或使用CAD创建它。
编写URDF以创建对象
最后,我将解释一些有关如何编写URDF的信息。
一旦您可以编写URDF,就可以创建简单的对象和机械手。
首先,让我们编写创建一个简单盒子的urdf。
box.urdf
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 | <?xml version="1.0" ?> <robot name="box"> <link name="base"> <inertial> <origin rpy = "0 0 0" xyz = "0 0 0" /> <mass value = "0.0001" /> <inertia ixx = "0.0001" ixy = "0" ixz = "0" iyy = "0.0001" iyz = "0" izz = "0.0001" /> </inertial> </link> <link name="box"> <contact> <lateral_friction value="1"/> </contact> <inertial> <origin rpy="0 0 0" xyz="0 0 0"/> <mass value="0.01"/> <inertia ixx="0.005" ixy="0" ixz="0" iyy="0.005" iyz="0" izz="0.005"/> </inertial> <visual> <origin rpy="0 0 0" xyz="0 0 0"/> <geometry> <box size="0.02 0.02 0.02"/> </geometry> <material name="Purple"> <color rgba="1 0 1 1" /> </material> </visual> <collision> <origin rpy="0 0 0" xyz="0 0 0"/> <geometry> <box size="0.02 0.02 0.02"/> </geometry> </collision> </link> <joint name="base_box" type="fixed" > <parent link = "base" /> <child link = "box" /> <origin rpy = "0 0 0" xyz = "0.000 0.000 0.00" /> </joint> </robot> |
让我们用Pybullet
显示它
小而混乱,但是会产生紫色方块。
此多维数据集由
您可能会想,"我是否必须编写这么长而烦人的代码才能生成这么多的盒子……",但是由于我只是根据固定的框架编写它,因此您可以相对轻松地编写复制和微调。
基本上,通过重复将零件
例如,在上面的
从这里,我将解释每个链接和关节。
基本链接
base_link
1 2 3 4 5 6 7 | <link name="base"> <inertial> <origin rpy = "0 0 0" xyz = "0 0 0" /> <mass value = "0.0001" /> <inertia ixx = "0.0001" ixy = "0" ixz = "0" iyy = "0.0001" iyz = "0" izz = "0.0001" /> </inertial> </link> |
基础链接是大小(体积)为0且质量为一分钟的链接。
创建此链接的??目的是确定所创建对象的基本位置。
安装由仿真创建的对象时,位置由此基础链接的坐标指定,因此
当执行
框链接
box_link
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 | <link name="box"> <contact> <lateral_friction value="1"/> </contact> <inertial> <origin rpy="0 0 0" xyz="0 0 0"/> <mass value="0.01"/> <inertia ixx="0.005" ixy="0" ixz="0" iyy="0.005" iyz="0" izz="0.005"/> </inertial> <visual> <origin rpy="0 0 0" xyz="0 0 0"/> <geometry> <box size="0.02 0.02 0.02"/> </geometry> <material name="Purple"> <color rgba="1 0 1 1" /> </material> </visual> <collision> <origin rpy="0 0 0" xyz="0 0 0"/> <geometry> <box size="0.02 0.02 0.02"/> </geometry> </collision> </link> |
箱形链接是边长为0.02(m)的立方链接。
这是
让我们一一看一下代码。
请注意,编写URDF时,必须使用
(示例1)在
(示例2)与
base_box关节
base_box_joint
1 2 3 4 5 | <joint name="base_box" type="fixed" > <parent link = "base" /> <child link = "box" /> <origin rpy = "0 0 0" xyz = "0.000 0.000 0.00" /> </joint> |
base_box关节连接基本链接和box链接。
在不熟悉URDF之前很难对其进行描述,但是不需要编程能力是件好事,因为您只需要连接链接和关节即可。
但是,一个警告是,当您在URDF描述中犯了一个错误时,您将不会得到关于错误发生位置的错误代码。因此请注意,如果您不经常运行并检查它,则必须逐行检查代码。
我认为以下文章将对如何编写URDF有所帮助。
-
具有URDF的PyBullet(统一的机器人描述格式)URDF说明(1)
-
第4章创建.urdf
-
为移动机器人创建URDF
我认为以下文章将对惯性(惯性矩)有所帮助。
- 使用ROS(机器人操作系统)
最后
本文是早稻田大学绪方实验室活动的一部分。
我正在研究机器人和深度学习,因此,如果您有兴趣,请访问以下实验室网站。
- 绪方哲也实验室