sudo apt-get install ros-melodic-urdf-tutorial
首先,我们将探讨一种简单的形状。 尽可能简单地做到此操作。
切换行号显示
1 <?xml version="1.0"?>
2 <robot name="myfirst">
3 <link name="base_link">
4 <visual>
5 <geometry>
6 <cylinder length="0.6" radius="0.2"/>
7 </geometry>
8 </visual>
9 </link>
10 </robot>
将XML转换为英语,这是一个名为myfirst的机器人,它仅包含一个链接(也称为部件),其可视组件仅为0.6米长的圆柱体,半径为0.2米。 对于一个简单的“ hello world”类型的示例来说,这看起来好像包含了很多标签,但是请相信,它将变得更加复杂。
要检查模型,请启动display.launch文件:
roslaunch urdf_tutorial display.launch model:=urdf/01-myfirst.urdf
这做三件事:
请注意,上面的roslaunch行假定您正在urdf_tutorial软件包目录中执行它(即urdf目录是当前工作目录的直接子目录)。 如果不是这种情况,则指向01-myfirst.urdf的相对路径将无效,当roslaunch尝试将urdf加载到参数服务器时,您将收到如下错误消息:
输入之后,就遇到了如下问题:
No such file or directory: urdf/01-myfirst.urdf
RLException: Invalid tag: Cannot load command parameter [robot_description]: command [['/opt/ros/melodic/share/xacro/xacro.py', 'urdf/01-myfirst.urdf']] returned with code [2].
Param xml is
The traceback for the exception was written to the log file
需要稍加修改的参数使它不管当前的工作目录如何都可以工作:
roslaunch urdf_tutorial display.launch model:='$(find urdf_tutorial)/urdf/01-myfirst.urdf'
接着出现了新的问题,但可以出现RVIZ图像:
[ERROR] [1593878383.918701]: Could not find the GUI, install the 'joint_state_publisher_gui' package
[joint_state_publisher-1] process has died [pid 16100, exit code 1, cmd /opt/ros/melodic/lib/joint_state_publisher/joint_state_publisher __name:=joint_state_publisher __log:=/home/li/.ros/log/96f100ec-be0d-11ea-938c-c83dd494a8c1/joint_state_publisher-1.log].
log file: /home/li/.ros/log/96f100ec-be0d-11ea-938c-c83dd494a8c1/joint_state_publisher-1*.log
解决方法:sudo apt-get install ros-melodic-joint-state-publisher-gui
注意事项:
现在让我们看一下如何添加多个形状/链接。 如果我们仅向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
roslaunch urdf_tutorial display.launch model:='$(find urdf_tutorial)/urdf/02-multipleshapes.urdf'
这两个形状彼此重叠,因为它们共享相同的原点。 如果我们不希望它们重叠,则必须定义更多的原点。
因此,R2D2的腿在侧面附着在他的躯干的上半部分。 这就是我们指定JOINT的原点的地方。 另外,它不附着在腿的中部,而是附着在腿的上部,因此我们也必须偏移腿的原点。 我们还旋转了腿使其直立。
切换行号显示
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
roslaunch urdf_tutorial display.launch model:='$(find urdf_tutorial)/urdf/03-origins.urdf'
“好吧,”我听到你说。 “这很可爱,但并不是每个人都拥有B21。 我的机器人和R2D2不是红色的!” 那是个很好的观点。 让我们看一下材料标签。
切换行号显示
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
41
42
43
44
45
46
47
48
49
50
51
52
53
54
roslaunch urdf_tutorial display.launch model:='$(find urdf_tutorial)/urdf/04-materials.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
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
roslaunch urdf_tutorial display.launch model:='$(find urdf_tutorial)/urdf/05-visual.urdf'
在本教程中,我们将修改在上一教程中制作的R2D2模型,使其具有活动关节。 在以前的模型中,所有关节都是固定的。 现在,我们将探讨三种其他重要的关节类型:连续关节,旋转关节和棱柱关节。
roslaunch urdf_tutorial display.launch model:='$(find urdf_tutorial)/urdf/06-flexible.urdf'
切换行号显示
1
2
3
4
5
6
身体和头部之间的连接是连续的关节,这意味着它可以采用从负无穷大到正无穷大的任意角度。 车轮也这样建模,以便它们可以永远在两个方向上滚动。
我们唯一需要添加的其他信息是旋转轴,此处由xyz三元组指定,该轴指定了头部将围绕其旋转的向量。 因为我们希望它绕z轴运动,所以我们指定矢量“ 0 0 1”。
切换行号显示
1
2
3
4
5
6
7
左右抓爪关节均建模为旋转关节。 这意味着它们以与连续关节相同的方式旋转,但是它们具有严格的限制。 因此,我们必须包含limit标签,以指定关节的上限和下限(以弧度为单位)。 我们还必须为此关节指定最大速度和最大力度,但是实际值对我们的目的并不重要。
切换行号显示
1
2
3
4
5
6
夹臂是另一种关节,即棱柱形关节。 这意味着它沿轴运动,而不是绕轴运动。 这种平移运动使我们的机器人模型可以伸展和缩回其抓臂。
棱柱形臂的极限以与旋转关节相同的方式指定,除了单位是米而非弧度。
还有两种其他关节在太空中移动。 棱柱形接头只能沿一维运动,而平面形接头可以在一个平面或二维中运动。 此外,浮动接头不受限制,并且可以在这三个维度中的任何一个处移动。 这些关节不能仅用一个数字指定,因此本教程中不包括。
在GUI中四处移动滑块时,模型将在Rviz中移动。 怎么做? 首先,GUI解析URDF,并找到所有非固定关节及其边界。 然后,它使用滑块的值来发布sensor_msgs / JointState消息。 然后,robot_state_publisher使用这些变量来计算不同部分之间的所有转换。 然后将生成的变换树用于显示Rviz中的所有形状。
在本教程中,我们将研究如何向URDF模型添加一些基本的物理属性以及如何指定其碰撞属性。
到目前为止,我们仅用单个子元素指定了链接,即视觉元素,该元素定义了机器人的外观(毫不奇怪)。 但是,为了使碰撞检测正常工作或在Gazebo之类的设备中模拟机器人,我们还需要定义一个碰撞元素。 这是具有碰撞和物理特性的新urdf。
这是我们新的基本链接的代码。
切换行号显示
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
冲突元素是链接对象的直接子元素,与可视标签处于同一级别
碰撞元素以与视觉元素相同的方式定义其形状,并带有一个几何标签。几何标签的格式在这里与视觉格式完全相同。
您还可以使用与碰撞标签的子元素相同的方式指定原点(与视觉标记一样)
在许多情况下,您希望碰撞的几何图形和原点与视觉的几何图形和原点完全相同。但是,在两种主要情况下您不会这样做。
为了使您的模型正确仿真,您需要定义机器人的几个物理属性,即像Gazebo这样的物理引擎所需的属性。
每个要模拟的链接元素都需要一个惯性标签。 这是一个简单的例子。
切换行号显示
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
ixx ixy ixz
ixy iyy iyz
ixz iyz izz
您还可以定义链接相互接触时的行为。 这是通过碰撞标签的一个名为contact_coefficients的子元素完成的。 有三个属性可以指定:
关节如何通过关节的动力学标签定义。 这里有两个属性:
如果未指定,则这些系数默认为零。
在纯URDF领域(即不包括 Gazebo-specific tags),剩下的两个标签可用于定义关节:校准和安全控制器。 查看spc,因为它们未包含在本教程中。
到现在为止,如果您在家中按照自己的机器人设计步骤执行所有这些步骤,则可能会厌倦了进行各种数学运算以获得非常简单的机器人描述以正确解析的方法。 幸运的是,您可以使用xacro软件包来简化您的生活。 它做三件事非常有帮助。
在本教程中,我们将介绍所有这些快捷方式,以帮助减少URDF文件的整体大小并使其更易于阅读和维护。
顾名思义,xacro是一种宏语言。 xacro程序将运行所有宏并输出结果。 典型用法如下所示:
xacro --inorder model.xacro> model.urdf
您还可以在启动文件中自动生成urdf。 这很方便,因为它可以保持最新状态并且不占用硬盘驱动器空间。 但是,生成确实需要时间,因此请注意,启动文件可能需要更长的时间才能启动。
切换行号显示
1
在URDF文件的顶部,必须指定名称空间,以便文件能够正确解析。 例如,以下是有效的xacro文件的前两行:
切换行号显示
1
2
让我们快速浏览一下R2D2中的base_link。
切换行号显示
1
2
3
4
5
6
7
8
9
10
11
12
13
这里的信息有点多余。 我们指定圆柱体的长度和半径两次。 更糟糕的是,如果我们想更改它,我们需要在两个不同的地方进行更改。
幸运的是,xacro允许您指定用作常量的属性。 相反,我们可以编写以上代码。
切换行号显示
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
这两个值在前两行中指定。 在使用它们之前或之后,可以在任何位置,任何级别(假定有效的XML)对其进行定义。 通常他们排在最前面。
我们没有在几何元素中指定实际半径,而是使用美元符号和大括号来表示值。
该代码将生成上面显示的相同代码。
然后,使用$ {}构造的内容值替换$ {}。 这意味着您可以将其与属性中的其他文本组合。
切换行号显示
1
2
这将产生
切换行号显示
1
但是,$ {}中的内容不必只是一个属性,这使我们进入了下一个观点…
您可以使用四个基本运算符(+,-,*,/),一元减号和括号在$ {}构造中构建任意复杂的表达式。 例子:
切换行号显示
1
2
所有的数学运算都是使用浮点数完成的,因此
切换行号显示
1
评估为:
切换行号显示
1
这是xacro软件包最大,最有用的组件。
让我们看一个简单的无用的macro。
切换行号显示
1
2
3
4
(这是没有用的,因为如果未指定原点,则它具有与此相同的值。)此代码将生成以下内容。
切换行号显示
1
您还可以参数化宏,以使它们不会每次都生成完全相同的文本。 与数学功能结合使用时,它的功能更加强大。
首先,让我们以R2D2中使用的简单宏为例。
切换行号显示
1
2
3
4
7
8
可以与代码一起使用
切换行号显示
1
参数的行为就像属性一样,您可以在表达式中使用它们
您也可以将整个块用作参数。
切换行号显示
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
xacro语言在允许您执行操作时非常灵活。 除了上面显示的默认惯性宏以外,还有一些在R2D2模型中使用xacro的有用方法。
要查看xacro文件生成的模型,请运行与以前的教程相同的命令:
roslaunch urdf_tutorial display.launch model:= '$(find urdf_tutorial)/urdf/08-macroed.urdf.xacro'
(启动文件一直在运行xacro命令,但是由于没有宏要扩展,所以没关系)
通常,您想在不同位置创建多个外观相似的对象。 通常,这些位置会有些对称。 您可以使用宏和一些简单的数学运算来减少必须编写的代码量,就像R2的两条腿一样。
切换行号显示
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
随时在此处添加您自己的技巧。
请从github或使用aptitude下载URDF模拟教程,即用于ROS melodic:
sudo apt-get install ros-melodic-urdf-sim-tutorial
我们可以使用gazebo.launch将已经创建的模型生成到Gazebo中:
roslaunch urdf_sim_tutorial gazebo.launch
这个启动文件
将宏教程中的urdf加载到参数描述中(如前所述)
启动一个空的Gazebo世界
运行脚本以从参数读取urdf并将其生成在Gazebo中。
默认情况下,Gazebo gui也将显示,如下所示:
注意:如果直接从git下载软件包,请创建一个工作区并将这两个文件夹放在$ your work space folder / src下,并使用catkin_make命令进行编译。
但是,它无能为力,并且缺少ROS使用此机器人所需的许多关键信息。 以前,我们一直使用joint_state_publisher来指定每个关节的姿势。 但是,机器人本身应在现实世界或Gazebo中提供该信息。 但是,如果不指定具体信息,Gazebo不知道要发布这些信息。
为了使机器人能够与您和ROS进行交互,我们需要指定两件事:插件和传输。(Plugins and Transmissions)
为了使ROS与Gazebo进行交互,我们必须动态链接到ROS库,该库将告诉Gazebo该怎么做。 从理论上讲,这允许其他机器人操作系统以通用方式与Gazebo进行交互。 实际上,它只是ROS。
要链接Gazebo和ROS,我们在UR robot>标记之前指定URDF中的插件:
切换行号显示
1
2
3 /
4
5
您可以在https://github.com/ros/urdf_sim_tutorial/blob/master/urdf/09-publishjoints.urdf.xacro并运行:
roslaunch urdf_sim_tutorial gazebo.launch model:='$(find urdf_sim_tutorial)/urdf/09-publishjoints.urdf.xacro'
但是,这不会做任何新的事情。 为此,我们需要在URDF之外指定更多信息。
现在我们已经将ROS和Gazebo链接起来,我们需要指定要在Gazebo中运行的ROS代码的一些位,我们通常将其称为控制器。 这些最初被加载到ROS参数空间中。 我们有一个yaml文件joints.yaml,它指定了我们的第一个控制器。
type: "joint_state_controller/JointStateController"
publish_rate: 50
该控制器位于joint_state_controller程序包中,可直接从Gazebo将机器人关节的状态发布到ROS中。在09-joints.launch中,您可以看到如何将这个yaml文件加载到r2d2_joint_state_controller命名空间中。 然后,我们使用该名称空间调用controller_manager / spawner`脚本,将其加载到Gazebo中。您可以启动它,但是它仍然还不够。
roslaunch urdf_sim_tutorial 09-joints.launch
这将运行控制器,并实际上在/ joint_states主题上发布…但其中没有任何内容。
header:
seq: 652
stamp:
secs: 13
nsecs: 331000000
frame_id: ''
name: []
position: []
velocity: []
effort: []
您还想要Gazebo吗? 好吧,它想知道要发布有关哪些关节的信息。
对于每个非固定关节,我们都需要指定一种传输方式,该方式告诉Gazebo如何处理关节。 让我们从头部关节开始。 将以下内容添加到您的URDF中:
切换行号显示
1
2 transmission_interface/SimpleTransmission
3
4 1
5
6
7 PositionJointInterface
8
9
您可以使用我们先前的启动配置来运行此URDF。
roslaunch urdf_sim_tutorial 09-joints.launch model:='$(find urdf_sim_tutorial)/urdf/10-firsttransmission.urdf.xacro '
现在,因为在joint_states消息中列出了头部关节,所以头部可以在RViz中正确显示。
header:
seq: 220
stamp:
secs: 4
nsecs: 707000000
frame_id: ''
name: ['head_swivel']
position: [-2.9051283156888985e-08]
velocity: [7.575990694887896e-06]
effort: [0.0]
我们可以继续为所有非固定关节添加变速箱(并且我们将这样做),以便所有关节均已正确发布。 但是,生活不仅限于看机器人。 我们要控制它们。 因此,让我们在这里获得另一个控制器。
这是我们要添加的下一个控制器配置。
type: "position_controllers/JointPositionController"
joint: head_swivel
这指定使用position_controllers包中的JointPositionController来控制head_swivel传输。 请注意,此接口的URDF中的硬件接口与控制器类型匹配。
现在,我们可以像roslaunch urdf_sim_tutorial 10-head.launch
之前那样使用添加的配置启动它。
现在,Gazebo已订阅了一个新主题,然后您可以通过在ROS中发布一个值来控制头部的位置。 rostopic pub / r2d2_head_controller / command std_msgs / Float64“ data:-0.707”
发布此命令后,位置将立即更改为指定值。 这是因为我们没有在urdf中指定关节的任何限制。 但是,如果更改关节,它将逐渐移动。
切换行号显示
1
2
3
4
5
6
7
roslaunch urdf_sim_tutorial 10-head.launch model:='$(find urdf_sim_tutorial)/urdf/11-limittransmission.urdf.xacro'
我们可以以类似的方式更改夹爪接头的URDF。 但是,我们可能希望将它们分组在一起,而不是用其自己的ROS主题单独控制抓爪的每个关节。 为此,我们只需要在ROS参数中指定其他控制器即可。
type: "position_controllers/JointGroupPositionController"
joints:
- gripper_extension
- left_gripper_joint
- right_gripper_joint
要启动此程序:
roslaunch urdf_sim_tutorial 12-gripper.launch
这样,我们可以改为使用浮点数数组指定位置。 打开和退出:
rostopic pub /r2d2_gripper_controller/command std_msgs/Float64MultiArray "layout:
dim:
- label: ''
size: 3
stride: 1
data_offset: 0
data: [0, 0.5, 0.5]"
关闭和缩回:
rostopic pub /r2d2_gripper_controller/command std_msgs/Float64MultiArray "layout:
dim:
- label: ''
size: 3
stride: 1
data_offset: 0
data: [-0.4, 0, 0]"
为了驱动机器人,我们从车轮宏中为每个车轮指定了另一个传动装置。
切换行号显示
1
2 transmission_interface/SimpleTransmission
3
4 1
5
6
7 VelocityJointInterface
8
9
就像其他传输一样,除了
由于车轮实际上将要接触地面并因此与地面进行物理交互,因此我们还指定了一些有关车轮材料的附加信息。
切换行号显示
1
2
3
4
5
6 Gazebo/Grey
7
有关更多详细信息,请参见http://gazebosim.org/tutorials/?tut=ros_urdf。
我们可以为每个单独的车轮指定控制器,但是这样做的乐趣何在? 相反,我们想一起控制所有轮子。 为此,我们将需要更多的ROS参数。
type: "diff_drive_controller/DiffDriveController"
publish_rate: 50
left_wheel: ['left_front_wheel_joint', 'left_back_wheel_joint']
right_wheel: ['right_front_wheel_joint', 'right_back_wheel_joint']
wheel_separation: 0.44
# Odometry covariances for the encoder output of the robot. These values should
# be tuned to your robot's sample odometry data, but these values are a good place
# to start
pose_covariance_diagonal: [0.001, 0.001, 0.001, 0.001, 0.001, 0.03]
twist_covariance_diagonal: [0.001, 0.001, 0.001, 0.001, 0.001, 0.03]
# Top level frame (link) of the robot description
base_frame_id: base_link
# Velocity and acceleration limits for the robot
linear:
x:
has_velocity_limits : true
max_velocity : 0.2 # m/s
has_acceleration_limits: true
max_acceleration : 0.6 # m/s^2
angular:
z:
has_velocity_limits : true
max_velocity : 2.0 # rad/s
has_acceleration_limits: true
max_acceleration : 6.0 # rad/s^2
DiffDriveController订阅标准的Twist cmd_vel消息,并相应地移动机器人。
roslaunch urdf_sim_tutorial 13-diffdrive.launch
除了加载上述配置之外,这还会打开RobotSteering面板,使您可以绕开R2D2机器人,同时观察其实际行为(在Gazebo中)和可视化行为(在RViz中):