我是靠谱客的博主 暴躁草丛,这篇文章主要介绍奥特学园ROS笔记--6(227-285)227节228-230节 概述231节 URDF集成Rviz基本流程232节 上一节优化------------URDF语法-----------233节 URDF语法-0 (robot标签)232-237节 URDF语法-1 link238-241节 URDF语法-2 joint-1242节 优化244-248节 URDF练习249节 URDF工具 ------------URDF优化_xacro------------250节251节 Xacro快速,现在分享给大家,希望可以做个参考。

目录

227节

228-230节 概述

231节 URDF集成Rviz基本流程

232节 上一节优化

------------URDF语法-----------

233节 URDF语法-0 (robot标签)

238-241节 URDF语法-2 joint-1

242节 优化

244-248节 URDF练习

249节 URDF工具

 ------------URDF优化_xacro------------

250节

251节 Xacro快速体验

252节 xacro语法01

253节 xacro语法02 函数

254节 xacro语法03 宏

255节 xacro语法04 文件包含

256节 xacro完整使用流程

257-258节 补齐256节代码

259-263节 xacro实操

------------使用arbotix------------

264节 控制机器人运动

265节 安装

266节 添加 Arbotix 配置文件

267节 集成arbotix节点

------------URDF集成Gazebo------------

270-271节 基本集成流程案例

273节 urdf集成gazebo相关设置

273-275 URDF集成Gazebo实操

276节 gazebo仿真环境载入

277节 gazebo创建仿真环境

------------URDF、GAZEBO、Rviz综合应用------------

279节 roscontrol简介

280节 运动控制实现流程

281节 rviz查看里程计消息

282节 雷达仿真及其显示

283节 摄像头仿真

284节 深度相机仿真

285节 点云数据显示

本章小结


227节

本章会介绍:

  • 如何创建并显示机器人模型;  URDF
  • 如何搭建仿真环境;  Gazebo
  • 如何实现机器人模型与仿真环境的交互。  RVIZ

围绕以上三个软件展开

本章预期的学习目标如下:

  • 能够独立使用URDF创建机器人模型,并在Rviz和Gazebo中分别显示;
  • 能够使用Gazebo搭建仿真环境;
  • 能够使用机器人模型中的传感器(雷达、摄像头、编码器...)获取仿真环境数据。

228-230节 概述

机器人建模(URDF)、创建仿真环境(Gazebo)以及感知环境(Rviz)

URDF是 Unified Robot Description Format 的首字母缩写,直译为统一(标准化)机器人描述格式,可以以一种 XML 的方式描述机器人的部分结构,比如底盘、摄像头、激光雷达、机械臂以及不同关节的自由度.....,该文件可以被 C++ 内置的解释器转换成可视化的机器人模型,是 ROS 中实现机器人仿真的重要组件

RViz 是 ROS Visualization Tool 的首字母缩写,直译为ROS的三维可视化工具。它的主要目的是以三维方式显示ROS消息,可以将 数据进行可视化表达。例如:可以显示机器人模型,可以无需编程就能表达激光测距仪(LRF)传感器中的传感 器到障碍物的距离,RealSense、Kinect或Xtion等三维距离传感器的点云数据(PCD, Point Cloud Data),从相机获取的图像值等

以“ros- [ROS_DISTRO] -desktop-full”命令安装ROS时,RViz会默认被安装。

运行使用命令rvizrosrun rviz rviz

如果rviz没有安装,请调用如下命令自行安装:

复制代码
1
sudo apt install ros-[ROS_DISTRO]-rviz

Gazebo是一款3D动态模拟器,用于显示机器人模型并创建仿真环境,能够在复杂的室内和室外环境中准确有效地模拟机器人。与游戏引擎提供高保真度的视觉模拟类似,Gazebo提供高保真度的物理模拟,其提供一整套传感器模型,以及对用户和程序非常友好的交互方式。

以“ros- [ROS_DISTRO] -desktop-full”命令安装ROS时,gzebo会默认被安装。

运行使用命令gazeborosrun gazebo_ros gazebo

是一款3D动态模拟器,用于显示机器人模型并创建仿真环境,能够在复杂的室内和室外环境中准确有效地模拟机器人。与游戏引擎提供高保真度的视觉模拟类似,Gazebo提供高保真度的物理模拟,其提供一整套传感器模型,以及对用户和程序非常友好的交互方式。

以“ros- [ROS_DISTRO] -desktop-full”命令安装ROS时,gzebo会默认被安装。

运行使用命令gazeborosrun gazebo_ros gazebo

另请参考:

  • urdf - ROS Wiki

  • rviz - ROS Wiki

  • Gazebo : Tutorial : ROS overview

三者应用中,只是创建 URDF 意义不大,一般需要结合 Gazebo 或 Rviz 使用,在 Gazebo 或 Rviz 中可以将 URDF 文件解析为图形化的机器人模型,一般的使用组合为:

  • 如果非仿真环境,那么使用 URDF 结合 Rviz 直接显示感知的真实环境信息

  • 如果是仿真环境,那么需要使用 URDF 结合 Gazebo 搭建仿真环境,并结合 Rviz 显示感知的虚拟环境信息

素材链接:

  • https://github.com/zx595306686/sim_demo.git

复制链接后找到一个文件夹下打开终端输入:

 下载不动可以试试用手机热点

231节 URDF集成Rviz基本流程

URDF 不能单独使用,需要结合 Rviz 或 Gazebo,URDF 只是一个文件,需要在 Rviz 或 Gazebo 中渲染成图形化的机器人模型

实现流程:

  1. 准备:新建功能包,导入依赖

  2. 核心:编写 urdf 文件

  3. 核心:在 launch 文件集成 URDF 与 Rviz

  4. 在 Rviz 中显示机器人模型

步骤1:

创建功能包,同时导入下图一中的依赖

在当前功能包下,再新建几个目录:

urdf: 存储 urdf 文件的目录

meshes:机器人模型渲染文件(暂不使用)

config: 配置文件

launch: 存储 launch 启动文件

 步骤2:

新建一个子级文件夹:urdf(可选),文件夹中添加一个.urdf文件,复制如下内容(创建一个盒子状态的机器人)

复制代码
1
2
3
4
5
6
7
8
9
10
<robot name="mycar"> <link name="base_link"> <visual> <geometry> <box size="0.5 0.2 0.1" /> </geometry> </visual> </link> </robot>

代码含义部分之后会介绍

步骤3:launch文件编写

复制代码
1
2
3
4
5
6
<launch> <!-- 载入urdf文件 --> <param name="robot_description" textfile="$(find urdf01_rviz)/urdf/urdf/demo01_helloworld.urdf"/> <!-- 启动rviz --> <node pkg="rviz" type="rviz" name="rviz"/> </launch>

然后c+s+b编译

然后点击左下角add,添加robotmodel

然后左边有报错:

需要修改fixed frame和之前的urdf文件中的link_name一致

 

然后左下角add添加坐标系就可以得到以下效果

232节 上一节优化

为了避免第二次打开rviz之后还需要配置上一节中的哪些步骤,:即第二次打开urdf配置好了

将其保存到onfug文件夹下,第二次使用的时候载入即可:

左上角file,save xx as,输入名字后保存即可。

读入之前配置的rviz文件:

修改上一节的.launch文件,加入args后面这段

复制代码
1
2
3
4
5
6
7
8
<launch> <!-- 载入urdf文件 --> <param name="robot_description" textfile="$(find urdf01_rviz)/urdf/urdf/demo01_helloworld.urdf"/> <!-- 启动rviz --> <node pkg="rviz" type="rviz" name="rviz" args="-d $(find urdf01_rviz)/config/show_mycar.rviz"/> </launch>

------------URDF语法-----------

233节 URDF语法-0 (robot标签)

URDF 文件是一个标准的 XML 文件,在 ROS 中预定义了一系列的标签用于描述机器人模型,机器人模型可能较为复杂,但是 ROS 的 URDF 中机器人的组成却是较为简单,可以主要简化为两部分:连杆(link标签) 与 关节(joint标签),接下来我们就通过案例了解一下 URDF 中的不同标签:

  • robot 根标签,类似于 launch文件中的launch标签
  • link 连杆标签
  • joint 关节标签
  • gazebo 集成gazebo需要使用的标签

关于gazebo标签,后期在使用 gazebo 仿真时,才需要使用到,用于配置仿真环境所需参数,比如: 机器人材料属性、gazebo插件等,但是该标签不是机器人模型必须的,只有在仿真时才需设置

另请参考:

  • urdf/XML - ROS Wiki

robot

robot标签作为根标签,所有的 link 和 joint 以及其他标签都必须包含在 robot 标签内,在该标签内可以通过 name 属性设置机器人模型的名称

232-237节 URDF语法-1 link

 link 标签用于描述机器人某个部件(也即刚体部分)的外观和物理属性,比如: 机器人底座、轮子、激光雷达、摄像头...

子标签

  • visual ---> 描述外观(对应的数据是可视的)

    • geometry 设置连杆的形状

      • 标签1: box(盒状)

        • 属性:size=长(x) 宽(y) 高(z)
      • 标签2: cylinder(圆柱)

        • 属性:radius=半径 length=高度
      • 标签3: sphere(球体)

        • 属性:radius=半径
      • 标签4: mesh(为连杆添加皮肤)

        • 属性: filename=资源路径(格式:package://<packagename>/<path>/文件)
    • origin 设置偏移量与倾斜弧度

      • 属性1: xyz=x偏移 y便宜 z偏移

      • 属性2: rpy=x翻滚 y俯仰 z偏航 (单位是弧度)

    • metrial 设置材料属性(颜色)

      • 属性: name

      • 标签: color

        • 属性: rgba=红绿蓝权重值与透明度 (每个权重值以及透明度取值[0,1])
  • collision ---> 连杆的碰撞属性

  • Inertial ---> 连杆的惯性矩阵

在此,只演示visual使用。

案例:分别生成长方体、圆柱与球体的机器人部件

launch文件配置

复制代码
1
2
3
4
5
6
7
8
<launch> <!-- 载入urdf文件 --> <param name="robot_description" textfile="$(find urdf01_rviz)/urdf/urdf/demo02_link.urdf"/> <!-- 启动rviz --> <node pkg="rviz" type="rviz" name="rviz" args="-d $(find urdf01_rviz)/config/show_mycar.rviz"/> </launch>

1形状

复制代码
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
<!-- 设置不同形状的机器人零部件 --> <robot name="mycar"> <link name="base_link"> <!-- 可视化标签 --> <visual> <!-- 形状 --> <geometry> <!-- 立方体 --> <!-- <box size="0.3 0.2 0.1"/> --> <!-- 圆柱,半径和长度 --> <!-- <cylinder radius="0.5" length="0.1" /> --> <!-- 球体,半径--> <!-- <sphere radius="0.3" /> --> <!-- 皮肤 --> <mesh filename="package://urdf01_rviz/meshes/autolabor_mini.stl"/> </geometry> <!-- 偏移量和倾斜 --> <!-- xyz用于设置xyz上的偏移量 rpy用于设置倾斜弧度r(翻滚)p(俯仰)y(偏航) --> <origin xyz="0 0 0" rpy="1.57 0 0" /> <!-- 颜色 --> </visual> </link> </robot>

<mesh>标签:可以将写好的模型stl文件进行导入

将之前下载的文件夹sim_demo里面的文件复制到下路径,然后编写mesh标签

2偏移量和欧拉角

偏移量即为空间上所处的位置,欧拉角调整的是其的姿态

上面使用mesh标签导入的时候发现小车竖起来了,我们可以调整它的欧拉角,合理需要沿着x(红色)轴顺时针旋转90度(从原点向x轴延伸方向看),即为正方向旋转0度,所以代码改为

复制代码
1
<origin xyz="0 0 0" rpy="1.57 0 0" />

即可

3颜色:

238-241节 URDF语法-2 joint-1

joint 标签用于描述机器人关节的运动学和动力学属性,还可以指定关节运动的安全极限,机器人的两个部件(分别称之为 parent link 与 child link)以"关节"的形式相连接,不同的关节有不同的运动形式: 旋转、滑动、固定、旋转速度、旋转角度限制....,比如:安装在底座上的轮子可以360度旋转,而摄像头则可能是完全固定在底座上。

joint标签对应的数据在模型中是不可见的

1.属性

  • name ---> 为关节命名

  • type ---> 关节运动形式(这里只用第一个和最后一个 )

    • continuous: 旋转关节,可以绕单轴无限旋转

    • revolute: 旋转关节,类似于 continues,但是有旋转角度限制

    • prismatic: 滑动关节,沿某一轴线移动的关节,有位置极限

    • planer: 平面关节,允许在平面正交方向上平移或旋转

    • floating: 浮动关节,允许进行平移、旋转运动

    • fixed: 固定关节,不允许运动的特殊关节

2.子标签

  • parent(必需的)

    parent link的名字是一个强制的属性:

    • link:父级连杆的名字,是这个link在机器人结构树中的名字。
  • child(必需的)

    child link的名字是一个强制的属性:

    • link:子级连杆的名字,是这个link在机器人结构树中的名字。
  • origin

    • 属性: xyz=各轴线上的偏移量 rpy=各轴线上的偏移弧度。
  • axis

    • 属性: xyz用于设置围绕哪个关节轴运动。

案例:创建机器人模型,底盘为长方体,在长方体的前面添加一摄像头,摄像头可以沿着 Z 轴 360 度旋转。

代码中的前两个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
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
<!-- 需求: 设置机器人底盘并添加摄像头 --> <robot name="mycar"> <!-- 底盘link --> <link name="base_link"> <visual> <geometry> <box size="0.3 0.2 0.1" /> </geometry> <origin xyz="0 0 0" rpy="0 0 0" /> <material name="car_color"> <color rgba="0.8 0.5 0 0.5" /> </material> </visual> </link> <!-- 摄像头link --> <link name="camera"> <visual> <geometry> <box size="0.02 0.05 0.05" /> </geometry> <!-- 先使用默认(后期需要修改) --> <origin xyz="0 0 0" rpy="0 0 0" /> <material name="camera_color"> <color rgba="0 0 1 0.5" /> </material> </visual> </link> <!-- 关节 --> <joint name="camera2base" type="continuous"> <!-- 父级link和子级link --> <parent link="base_link"/> <child link="camera" /> <!-- 需要计算两个 link 的物理中心之间的偏移量 --> <origin xyz="0.12 0 0.05" rpy="0 0 0" /> <!-- 设置旋转参考的坐标轴,这里围绕z轴旋转 --> <axis xyz="0 0 1" /> </joint> </robot>

这里要注意joint文件不能和之前那样书写,不然就会建模失败。

需要添加两个节点(注意编写玩要编译):

复制代码
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
<launch> <param name="robot_description" textfile="$(find urdf01_rviz)/urdf/urdf/demo03_joint.urdf" /> <node pkg="rviz" type="rviz" name="rviz" args="-d $(find urdf01_rviz)/config/show_mycar.rviz" /> <!-- 如果只有上述两个语句就会出现问题: 摄像头显示没有达到预期的位置 因为rviz中显示urdf时必须发布不同部件之间的坐标系关系 解决:ros中提供了关于机器人模型显示的坐标发布相关节点(两个) --> <!-- 添加关节状态发布节点 --> <node pkg="joint_state_publisher" type="joint_state_publisher" name="joint_state_publisher" /> <!-- 添加机器人状态发布节点 --> <node pkg="robot_state_publisher" type="robot_state_publisher" name="robot_state_publisher" /> <!-- 可选:用于控制关节运动的节点 --> <node pkg="joint_state_publisher_gui" type="joint_state_publisher_gui" name="joint_state_publisher_gui" /> </launch>

上图这里第三个节点用于对两个刚体之间的运动(用于测试关节是否运行正常)

运行报错的话这里可以下载:

复制代码
1
sudo apt-get install ros-melodic-joint-state-publisher-gui

然后就可以了

注:

这里可能会出现问题:摄像头并没有在车的表面,因为我们的joint相对位置是在相对于两者的几何中心的,我们并没有考虑到摄像头的体积,所以只需要在相对偏移量的基础上添加上摄像头高度的一般即可(改为0.75)。

242节 优化

前面实现的机器人模型是半沉到地下的,因为默认情况下: 底盘的中心点位于地图原点上,所以会导致这种情况产生,可以使用的优化策略,将初始 link 设置为一个尺寸极小的 link(比如半径为 0.001m 的球体,或边长为 0.001m 的立方体),然后再在初始 link 上添加底盘等刚体,这样实现,虽然仍然存在初始link半沉的现象,但是基本可以忽略了。这个初始 link 一般称之为 base_footprint

理解:之前的parentlink是baselink即车体是摄像头的parent,现在又将一个很小的物体作为车体的parent,此时只需要将这个小物体抬高,即可将整个车子抬高。以下在上一节的基础上添加了一个小的link和一个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
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
<!-- 使用 base_footprint 优化,添加一个极小的link,再去关联初始link与base_link, 关节高度刚好和baselink下沉的高度一致(半个底盘高度) --> <robot name="mycar"> <link name="base_footprint"> <visual> <geometry> <box size="0.001 0.001 0.001" /> </geometry> </visual> </link> <!-- 底盘link --> <link name="base_link"> <visual> <geometry> <box size="0.3 0.2 0.1" /> </geometry> <origin xyz="0 0 0" rpy="0 0 0" /> <material name="car_color"> <color rgba="0.8 0.5 0 0.5" /> </material> </visual> </link> <!-- 摄像头link --> <link name="camera"> <visual> <geometry> <box size="0.02 0.05 0.05" /> </geometry> <!-- 先使用默认(后期需要修改) --> <origin xyz="0 0 0.025" rpy="0 0 0" /> <material name="camera_color"> <color rgba="0 0 1 0.5" /> </material> </visual> </link> <!-- 关节 --> <joint name="camera2base" type="continuous"> <!-- 父级link和子级link --> <parent link="base_link"/> <child link="camera" /> <!-- 需要计算两个 link 的物理中心之间的偏移量 --> <origin xyz="0.12 0 0.05" rpy="0 0 0" /> <!-- 设置旋转参考的坐标轴,这里围绕z轴旋转 --> <axis xyz="0 0 1" /> </joint> <!-- 关联base_link和base_footprint --> <joint name="link2footprint" type="fixed"> <!-- 父级link和子级link --> <parent link="base_footprint"/> <child link="base_link" /> <!-- 偏移量,这里将其抬高车体的高度 --> <origin xyz="0 0 0.05" rpy="0 0 0" /> </joint> </robot>

然后编写对应的launch后进行运行:

 注:这里需要把最开始参考的fixed frame改为base_footprint

244-248节 URDF练习

需求描述:

创建一个四轮圆柱状机器人模型,机器人参数如下,底盘为圆柱状,半径 10cm,高 8cm,四轮由两个驱动轮和两个万向支撑轮组成,两个驱动轮半径为 3.25cm,轮胎宽度1.5cm,两个万向轮为球状,半径 0.75cm,底盘离地间距为 1.5cm(与万向轮直径一致)

首先创建好urdf和launch文件

注:建议优先在joint里面设置偏移量,而不是在link里面设置,这样才可以将坐标Axes区分开来

复制代码
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
<robot name="mycar"> <link name="base_footprint"> <visual> <geometry> <box size="0.001 0.001 0.001" /> </geometry> </visual> </link> <!-- 底盘参数 形状:圆柱 半径:10 cm 高度:8 cm 离地:1.5 cm --> <link name="base_link"> <visual> <geometry> <cylinder radius="0.1" length="0.08" /> </geometry> <origin xyz="0 0 0" rpy="0 0 0" /> <material name="baselink_color"> <color rgba="1 0.5 0.2 0.5" /> </material> </visual> </link> <joint name="link2base_footprint" type="fixed"> <parent link="base_footprint" /> <child link="base_link"/> <!-- 高度=车体高度/2+离地间距 --> <origin xyz="0 0 0.055" /> </joint> <!-- 添加驱动轮 --> <!-- 驱动轮是侧翻的圆柱 参数 半径: 3.25 cm 宽度: 1.5 cm 颜色: 黑色 关节设置: x = 0 y = 底盘的半径 + 轮胎宽度 / 2 z = 离地间距 + 底盘长度 / 2 - 轮胎半径 = 1.5 + 4 - 3.25 = 2.25(cm) axis = 0 1 0 --> <link name="left_wheel"> <visual> <geometry> <cylinder radius="0.0325" length="0.015" /> </geometry> <origin xyz="0 0 0" rpy="1.5708 0 0" /> <material name="wheel_color"> <color rgba="0.0 0.0 0.0 0.3" /> </material> </visual> </link> <joint name="left2base_link" type="continuous"> <parent link="base_link" /> <child link="left_wheel" /> <origin xyz="0 0.1 -0.0225" /> <axis xyz="0 1 0" /> </joint> <link name="right_wheel"> <visual> <geometry> <cylinder radius="0.0325" length="0.015" /> </geometry> <origin xyz="0 0 0" rpy="1.5708 0 0" /> <material name="wheel_color"> <color rgba="0.0 0.0 0.0 0.3" /> </material> </visual> </link> <joint name="right2base_link" type="continuous"> <parent link="base_link" /> <child link="right_wheel" /> <origin xyz="0 -0.1 -0.0225" /> <axis xyz="0 1 0" /> </joint> <!-- 添加万向轮(支撑轮) --> <!-- 参数 形状: 球体 半径: 0.75 cm 颜色: 黑色 关节设置: x = 自定义(底盘半径 - 万向轮半径) = 0.1 - 0.0075 = 0.0925(cm) y = 0 z = 底盘长度 / 2 + 离地间距 / 2 = 0.08 / 2 + 0.015 / 2 = 0.0475 axis= 1 1 1 --> <link name="front_wheel"> <visual> <geometry> <sphere radius="0.0075" /> </geometry> <origin xyz="0 0 0" rpy="0 0 0" /> <material name="wheel_color"> <color rgba="0.0 0.0 0.0 0.3" /> </material> </visual> </link> <joint name="front_wheel2base_link" type="continuous"> <parent link="base_link" /> <child link="front_wheel" /> <origin xyz="0.0925 0 -0.0475" /> <axis xyz="1 1 1" /> </joint> <link name="back_wheel"> <visual> <geometry> <sphere radius="0.0075" /> </geometry> <origin xyz="0 0 0" rpy="0 0 0" /> <material name="black"> <color rgba="0.0 0.0 0.0 0.3" /> </material> </visual> </link> <joint name="back_wheel2base_link" type="continuous"> <parent link="base_link" /> <child link="back_wheel" /> <origin xyz="-0.0925 0 -0.0475" /> <axis xyz="1 1 1" /> </joint> </robot>

249节 URDF工具

在 ROS 中,提供了一些工具来方便 URDF 文件的编写,比如:

  • check_urdf命令可以检查复杂的 urdf 文件是否存在语法问题

  • urdf_to_graphiz命令可以查看 urdf 模型结构,显示不同 link 的层级关系

当然,要使用工具之前,首先需要安装,安装命令:sudo apt install liburdfdom-tools

在集成终端中打开:

如果存在语法问题就会报出error。

然后是输出关系PDF文件:

 ------------URDF优化_xacro------------

250节

前面 URDF 文件构建机器人模型的过程中,存在若干问题。

问题1:在设计关节的位置时,需要按照一定的公式计算,公式是固定的,但是在 URDF 中依赖于人工计算,存在不便,容易计算失误,且当某些参数发生改变时,还需要重新计算。

问题2:URDF 中的部分内容是高度重复的,驱动轮与支撑轮的设计实现,不同轮子只是部分参数不同,形状、颜色、翻转量都是一致的,在实际应用中,构建复杂的机器人模型时,更是易于出现高度重复的设计,按照一般的编程涉及到重复代码应该考虑封装。

......

如果在编程语言中,可以通过变量结合函数直接解决上述问题,在 ROS 中,已经给出了类似编程的优化方案,称之为:Xacro

概念

Xacro 是 XML Macros 的缩写,Xacro 是一种 XML 宏语言,是可编程的 XML。

原理

Xacro 可以声明变量,可以通过数学运算求解,使用流程控制控制执行顺序,还可以通过类似函数的实现,封装固定的逻辑,将逻辑中需要的可变的数据以参数的方式暴露出去,从而提高代码复用率以及程序的安全性。

251节 Xacro快速体验

需求描述:

使用xacro优化上一节案例中驱动轮实现,需要使用变量封装底盘的半径、高度,使用数学公式动态计算底盘的关节点坐标,使用 Xacro 宏封装轮子重复的代码并调用宏创建两个轮子(注意: 在此,演示 Xacro 的基本使用,不必要生成合法的 URDF )。

准备:在之前创建的xacro文件夹中创建.xacro文件,然后输入以下代码

复制代码
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
<robot name="mycar" xmlns:xacro="http://wiki.ros.org/xacro"> <!-- 上一节案例中存在几个不足: 1代码复用:Xacro宏(可以理解为函数) 2参数设计:Xacro变量 --> <!-- 属性封装 --> <xacro:property name="wheel_radius" value="0.0325" /> <xacro:property name="wheel_length" value="0.0015" /> <xacro:property name="PI" value="3.1415927" /> <xacro:property name="base_link_length" value="0.08" /> <xacro:property name="lidi_space" value="0.015" /> <!-- 宏 --> <xacro:macro name="wheel_func" params="wheel_name flag" > <link name="${wheel_name}_wheel"> <visual> <geometry> <cylinder radius="${wheel_radius}" length="${wheel_length}" /> </geometry> <origin xyz="0 0 0" rpy="${PI / 2} 0 0" /> <material name="wheel_color"> <color rgba="0 0 0 0.3" /> </material> </visual> </link> <!-- 3-2.joint --> <joint name="${wheel_name}2link" type="continuous"> <parent link="base_link" /> <child link="${wheel_name}_wheel" /> <!-- x 无偏移 y 车体半径 z z= 车体高度 / 2 + 离地间距 - 车轮半径 --> <origin xyz="0 ${0.1 * flag} ${(base_link_length / 2 + lidi_space - wheel_radius) * -1}" rpy="0 0 0" /> <axis xyz="0 1 0" /> </joint> </xacro:macro> <!-- 调用函数 --> <xacro:wheel_func wheel_name="left" flag="1" /> <xacro:wheel_func wheel_name="right" flag="-1" /> </robot>

Xacro是不能直接运行的,我们需要将他转换为urdf文件才行:

这里需要运行ros内置的一个节点

首先roscore以下

然后进入xacro目录中输入以下可以输出一个urdf文件:

复制代码
1
rosrun xacro xacro demo01_helloworld.urdf.xacro >demo01_helloworld.urdf

252节 xacro语法01

xacro 提供了可编程接口,类似于计算机语言,包括变量声明调用、函数声明与调用等语法实现。在使用 xacro 生成 urdf 时,根标签robot必须包含命名空间声明:xmlns:xacro="http://wiki.ros.org/xacro"

1.属性与算数运算

用于封装 URDF 中的一些字段,比如: PAI 值,小车的尺寸,轮子半径 ....

属性定义

复制代码
1
<xacro:property name="xxxx" value="yyyy" />

属性调用

复制代码
1
${属性名称}

算数运算

复制代码
1
${数学表达式}

2.宏

类似于函数实现,提高代码复用率,优化代码结构,提高安全性

宏定义

复制代码
1
2
3
4
5
6
7
<xacro:macro name="宏名称" params="参数列表(多参数之间使用空格分隔)"> ..... 参数调用格式: ${参数名} </xacro:macro>

宏调用

复制代码
1
<xacro:宏名称 参数1=xxx 参数2=xxx/>

3.文件包含

机器人由多部件组成,不同部件可能封装为单独的 xacro 文件,最后再将不同的文件集成,组合为完整机器人,可以使用文件包含实现

文件包含

复制代码
1
2
3
4
5
6
<robot name="xxx" xmlns:xacro="http://wiki.ros.org/xacro"> <xacro:include filename="my_base.xacro" /> <xacro:include filename="my_camera.xacro" /> <xacro:include filename="my_laser.xacro" /> .... </robot>

253节 xacro语法02 函数

案例:

复制代码
1
2
3
4
5
6
7
8
9
10
11
<robot name="mycar" xmlns:xacro="http://wiki.ros.org/xacro"> <!-- 属性定义 --> <xacro:property name="PI" value="3.1415927"/> <xacro:property name="radius" value="0.03" /> <!-- 属性调用 --> <myUsePropertyxxx name="${PI}"/> <myUsePropertyxxx name="${radius}"/> <!-- 算数运算 --> <myUsePropertyxxx name="${PI/2}"/> <myUsePropertyxxx name="${radius*2}"/> </robot>

输出:

254节 xacro语法03 宏

复制代码
1
2
3
4
5
6
7
8
<robot name="mycar" xmlns:xacro="http://wiki.ros.org/xacro"> <!-- 宏定义 --> <xacro:macro name="getsum" params="num1 num2"> <result value="${num1+num2}"/> </xacro:macro> <!-- 宏调用 --> <xacro:getsum num1="1" num2="2"/> </robot>

255节 xacro语法04 文件包含

复制代码
1
2
3
4
5
6
7
8
<robot name="mycar" xmlns:xacro="http://wiki.ros.org/xacro"> <!-- 宏定义 --> <xacro:macro name="getsum" params="num1 num2"> <result value="${num1+num2}"/> </xacro:macro> <!-- 宏调用 --> <xacro:getsum num1="1" num2="2"/> </robot>

输出结果分别为demo02和demo03中的实现结果

256节 xacro完整使用流程

需求描述:

使用 Xacro 优化 URDF 版的小车底盘模型实现

编写到一半的时候可以先转成urdf再check一下()

1 编写xacro文件(这里只书写了之前那个小车案例的baselink部分)

复制代码
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
<robot name="mycar" xmlns:xacro="http://wiki.ros.org/xacro"> <!-- <xacro:property name="" value=""/> --> <xacro:property name="base_radius" value="0.1"/> <xacro:property name="base_length" value="0.08"/> <xacro:property name="lidi" value="0.015"/> <xacro:property name="base_joint_z" value="${base_length/2+lidi}"/> <link name="base_footprint"> <visual> <geometry> <box size="0.001 0.001 0.001" /> </geometry> </visual> </link> <link name="base_link"> <visual> <geometry> <cylinder radius="${base_radius}" length="${base_length}" /> </geometry> <origin xyz="0 0 0" rpy="0 0 0" /> <material name="baselink_color"> <color rgba="1 0.5 0.2 0.5" /> </material> </visual> </link> <joint name="link2base_footprint" type="fixed"> <parent link="base_footprint" /> <child link="base_link"/> <!-- 高度=车体高度/2+离地间距 --> <origin xyz="0 0 ${base_joint_z}" /> </joint> </robot>

2集成launch文件

方式1:先将 xacro 文件转换出 urdf 文件,然后集成(launch文件和之前一样,只是多一步转urdf文件的操作)

方式2:在 launch 文件中直接加载 xacro(建议使用)

核心代码:

<param name="robot_description" command="$(find xacro)/xacro $(find demo01_urdf_helloworld)/urdf/xacro/my_base.urdf.xacro" />

复制代码
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
<launch> <!-- 将 urdf 文件内容设置进参数服务器 --> <!-- <param name="robot_description" textfile="$(find urdf01_rviz)/urdf/xacro/demo05_car_base.urdf" /> --> <param name="robot_description" command="$(find xacro)/xacro $(find urdf01_rviz)/urdf/xacro/demo05_car_base.urdf.xacro" /> <!-- 启动 rivz --> <node pkg="rviz" type="rviz" name="rviz_test" args="-d $(find urdf01_rviz)/config/show_mycar.rviz" /> <!-- 启动机器人状态和关节状态发布节点 --> <node pkg="robot_state_publisher" type="robot_state_publisher" name="robot_state_publisher" /> <node pkg="joint_state_publisher" type="joint_state_publisher" name="joint_state_publisher" /> <!-- 启动图形化的控制关节运动节点 --> <node pkg="joint_state_publisher_gui" type="joint_state_publisher_gui" name="joint_state_publisher_gui" /> </launch>

注:方式1和2的launch文件的区别只用第一行的区别

257-258节 补齐256节代码

复制代码
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
<robot name="mycar" xmlns:xacro="http://wiki.ros.org/xacro"> <!-- 底盘参数 形状:圆柱 半径:10 cm 高度:8 cm 离地:1.5 cm --> <!-- <xacro:property name="" value=""/> --> <xacro:property name="base_radius" value="0.1"/> <xacro:property name="base_length" value="0.08"/> <xacro:property name="lidi" value="0.015"/> <xacro:property name="base_joint_z" value="${base_length/2+lidi}"/> <link name="base_footprint"> <visual> <geometry> <box size="0.001 0.001 0.001" /> </geometry> </visual> </link> <link name="base_link"> <visual> <geometry> <cylinder radius="${base_radius}" length="${base_length}" /> </geometry> <origin xyz="0 0 0" rpy="0 0 0" /> <material name="baselink_color"> <color rgba="1 0.5 0.2 0.5" /> </material> </visual> </link> <joint name="link2base_footprint" type="fixed"> <parent link="base_footprint" /> <child link="base_link"/> <!-- 高度=车体高度/2+离地间距 --> <origin xyz="0 0 ${base_joint_z}" /> </joint> <!-- 添加驱动轮 --> <!-- 驱动轮是侧翻的圆柱 参数 半径: 3.25 cm 宽度: 1.5 cm 颜色: 黑色 关节设置: x = 0 y = 底盘的半径 + 轮胎宽度 / 2 z = 离地间距 + 底盘长度 / 2 - 轮胎半径 = 1.5 + 4 - 3.25 = 2.25(cm) axis = 0 1 0 --> <xacro:property name="wheel_radius" value="0.0325" /> <xacro:property name="wheel_length" value="0.015" /> <xacro:property name="PI" value="3.1415927" /> <xacro:property name="wheel_joint_z" value="${-1*(base_length/2+lidi-wheel_radius)}" /> <!-- 注意结果是负数 --> <!-- 将车轮封装成宏 wheel_name:left/right flag:1/-1 表明左轮还是右轮 --> <xacro:macro name="wheel_func" params="wheel_name flag" > <link name="${wheel_name}_wheel"> <visual> <geometry> <cylinder radius="${wheel_radius}" length="${wheel_length}" /> </geometry> <origin xyz="0 0 0" rpy="${PI/2} 0 0" /> <material name="wheel_color"> <color rgba="0.0 0.0 0.0 0.3" /> </material> </visual> </link> <joint name="${wheel_name}2link" type="continuous"> <parent link="base_link" /> <child link="${wheel_name}_wheel" /> <origin xyz="0 ${0.1*flag} ${wheel_joint_z}" /> <axis xyz="0 1 0" /> </joint> </xacro:macro> <!-- 调用上面的宏 --> <xacro:wheel_func wheel_name="left" flag="1"/> <xacro:wheel_func wheel_name="right" flag="-1"/> <!-- 添加万向轮(支撑轮) --> <!-- 参数 形状: 球体 半径: 0.75 cm 颜色: 黑色 关节设置: x = 自定义(底盘半径 - 万向轮半径) = 0.1 - 0.0075 = 0.0925(cm) y = 0 z = 底盘长度 / 2 + 离地间距 / 2 = 0.08 / 2 + 0.015 / 2 = 0.0475 axis= 1 1 1 --> <xacro:property name="small_wheel_radius" value="0.0075"/> <xacro:property name="small_joint_z" value="${(base_length/2+lidi-small_wheel_radius)*-1}"/> <xacro:macro name="small_wheel_func" params="small_wheel_name flag"> <link name="${small_wheel_name}_wheel"> <visual> <geometry> <sphere radius="${small_wheel_radius}" /> </geometry> <origin xyz="0 0 0" rpy="0 0 0" /> <material name="wheel_color"> <color rgba="0.0 0.0 0.0 0.3" /> </material> </visual> </link> <joint name="${small_wheel_name}_wheel2base_link" type="continuous"> <parent link="base_link" /> <child link="${small_wheel_name}_wheel" /> <origin xyz="${0.08*flag} 0 ${small_joint_z}" /> <axis xyz="1 1 1" /> </joint> </xacro:macro> <xacro:small_wheel_func small_wheel_name="front" flag="1"/> <xacro:small_wheel_func small_wheel_name="back" flag="-1"/> </robot>

259-263节 xacro实操

需求描述:

在前面小车底盘基础之上,添加摄像头和雷达传感器。

实现流程:

  1. 首先编写摄像头和雷达的 xacro 文件

  2. 然后再编写一个组合文件,组合底盘、摄像头与雷达

  3. 最后,通过 launch 文件启动 Rviz 并显示模型

首先新创建这三个文件和launch文件

我们要将demo5、6、7、car四者结合到一起

编写car、demo6、demo7和launch代码

复制代码
1
2
3
4
5
6
7
<!-- 组合小车底盘与摄像头与雷达,包含底盘、摄像头、雷达--> <robot name="mycar" xmlns:xacro="http://wiki.ros.org/xacro"> <xacro:include filename="demo05_car_base.urdf.xacro" /> <xacro:include filename="demo06_car_camera.urdf.xacro" /> <xacro:include filename="demo07_car_laser.urdf.xacro" /> </robot>
复制代码
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
<!-- demo06摄像头相关的 xacro 文件 --> <robot name="mycar" xmlns:xacro="http://wiki.ros.org/xacro"> <!-- 摄像头属性 --> <xacro:property name="camera_length" value="0.02" /> <!-- 摄像头长度(x) --> <xacro:property name="camera_width" value="0.05" /> <!-- 摄像头宽度(y) --> <xacro:property name="camera_height" value="0.05" /> <!-- 摄像头高度(z) --> <xacro:property name="joint_camera_x" value="0.08" /> <!-- 摄像头安装的x坐标 --> <xacro:property name="joint_camera_y" value="0.0" /> <!-- 摄像头安装的y坐标 --> <xacro:property name="joint_camera_z" value="${base_length / 2 + camera_height / 2}" /> <!-- 摄像头安装的z坐标:底盘高度 / 2 + 摄像头高度 / 2 --> <!-- 摄像头关节以及link --> <link name="camera"> <visual> <geometry> <box size="${camera_length} ${camera_width} ${camera_height}" /> </geometry> <origin xyz="0.0 0.0 0.0" rpy="0.0 0.0 0.0" /> <material name="black" > <color rgba="0 0 0 0.8"/> </material> </visual> </link> <joint name="camera2base" type="fixed"> <parent link="base_link" /> <child link="camera" /> <origin xyz="${joint_camera_x} ${joint_camera_y} ${joint_camera_z}" /> </joint> </robot>
复制代码
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
<!-- 小车底盘添加雷达 --> <robot name="my_laser" xmlns:xacro="http://wiki.ros.org/xacro"> <!-- 雷达支架 --> <xacro:property name="support_length" value="0.15" /> <!-- 支架长度 --> <xacro:property name="support_radius" value="0.01" /> <!-- 支架半径 --> <xacro:property name="joint_support_x" value="0.0" /> <!-- 支架安装的x坐标 --> <xacro:property name="joint_support_y" value="0.0" /> <!-- 支架安装的y坐标 --> <xacro:property name="joint_support_z" value="${base_length / 2 + support_length / 2}" /> <!-- 支架安装的z坐标:底盘高度 / 2 + 支架高度 / 2 --> <link name="support"> <visual> <geometry> <cylinder radius="${support_radius}" length="${support_length}" /> </geometry> <origin xyz="0.0 0.0 0.0" rpy="0.0 0.0 0.0" /> <material name="red"> <color rgba="0.8 0.2 0.0 0.5" /> </material> </visual> </link> <joint name="support2base_link" type="fixed"> <parent link="base_link" /> <child link="support" /> <origin xyz="${joint_support_x} ${joint_support_y} ${joint_support_z}" /> </joint> <!-- 雷达属性 --> <xacro:property name="laser_length" value="0.05" /> <!-- 雷达长度 --> <xacro:property name="laser_radius" value="0.03" /> <!-- 雷达半径 --> <xacro:property name="joint_laser_x" value="0.0" /> <!-- 雷达安装的x坐标 --> <xacro:property name="joint_laser_y" value="0.0" /> <!-- 雷达安装的y坐标 --> <xacro:property name="joint_laser_z" value="${support_length / 2 + laser_length / 2}" /> <!-- 雷达安装的z坐标:支架高度 / 2 + 雷达高度 / 2 --> <!-- 雷达关节以及link --> <link name="laser"> <visual> <geometry> <cylinder radius="${laser_radius}" length="${laser_length}" /> </geometry> <origin xyz="0.0 0.0 0.0" rpy="0.0 0.0 0.0" /> <material name="black"> <color rgba="0 0 0 0.5"/> </material> </visual> </link> <joint name="laser2support" type="fixed"> <parent link="support" /> <child link="laser" /> <origin xyz="${joint_laser_x} ${joint_laser_y} ${joint_laser_z}" /> </joint> </robot>
复制代码
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
<launch> <!-- 将 urdf 文件内容设置进参数服务器 --> <!-- <param name="robot_description" textfile="$(find urdf01_rviz)/urdf/xacro/demo05_car_base.urdf" /> --> <param name="robot_description" command="$(find xacro)/xacro $(find urdf01_rviz)/urdf/xacro/car.urdf.xacro" /> <!-- 启动 rivz --> <node pkg="rviz" type="rviz" name="rviz_test" args="-d $(find urdf01_rviz)/config/show_mycar.rviz" /> <!-- 启动机器人状态和关节状态发布节点 --> <node pkg="robot_state_publisher" type="robot_state_publisher" name="robot_state_publisher" /> <node pkg="joint_state_publisher" type="joint_state_publisher" name="joint_state_publisher" /> <!-- 启动图形化的控制关节运动节点 --> <node pkg="joint_state_publisher_gui" type="joint_state_publisher_gui" name="joint_state_publisher_gui" /> </launch>

------------使用arbotix------------

264节 控制机器人运动

通过 URDF 结合 rviz 可以创建并显示机器人模型,不过,当前实现的只是静态模型,如何控制模型的运动呢?在此,可以调用 Arbotix 实现此功能。

Arbotix 是一款控制电机、舵机的控制板,并提供相应的 ros 功能包,这个功能包的功能不仅可以驱动真实的 Arbotix 控制板,它还提供一个差速控制器,通过接受速度控制指令更新机器人的 joint 状态,从而帮助我们实现机器人在 rviz 中的运动。

需求描述:

控制机器人模型在 rviz 中做圆周运动

实现流程:

  1. 安装 Arbotix

  2. 创建新功能包,准备机器人 urdf、xacro 文件(之前都写了)

  3. 添加 Arbotix 配置文件

  4. 编写 launch 文件配置 Arbotix

  5. 启动 launch 文件并控制机器人模型运动

265节 安装

方式1

复制代码
1
2
3
sudo apt-get install ros-<<VersionName()>>-arbotix eg:sudo apt-get install ros-nortic-arbotix

将 <<VsersionName()>> 替换成当前 ROS 版本名称,

如果提示功能包无法定位(上图),请采用方式2

先从 github 下载源码(网速慢可以使用手机流量进行下载)

复制代码
1
2
下载:git clone https://github.com/vanadiumlabs/arbotix_ros.git

将下载好的放入第一层src中

然后调用 catkin_make 即c+s+b 编译

266节 添加 Arbotix 配置文件

到config文件下创建.yaml文件

然后粘贴

复制代码
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
# 该文件是控制器配置,一个机器人模型可能有多个控制器,比如: 底盘、机械臂、夹持器(机械手).... # 因此,根 name 是 controller controllers: { # 单控制器设置 base_controller: { #类型: 差速控制器 type: diff_controller, #参考坐标 base_frame_id: base_footprint, #两个轮子之间的间距 base_width: 0.2, #控制频率 ticks_meter: 2000, #PID控制参数,使机器人车轮快速达到预期速度 Kp: 12, Kd: 12, Ki: 0, Ko: 50, #加速限制 accel_limit: 1.0 } }

这里不多做解释

267节 集成arbotix节点

创建launch文件

复制代码
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
<launch> <!-- 将 urdf 文件内容设置进参数服务器 --> <!-- <param name="robot_description" textfile="$(find urdf01_rviz)/urdf/xacro/demo05_car_base.urdf" /> --> <param name="robot_description" command="$(find xacro)/xacro $(find urdf01_rviz)/urdf/xacro/car.urdf.xacro" /> <!-- 启动 rivz --> <node pkg="rviz" type="rviz" name="rviz_test" args="-d $(find urdf01_rviz)/config/show_mycar.rviz" /> <!-- 启动机器人状态和关节状态发布节点 --> <node pkg="robot_state_publisher" type="robot_state_publisher" name="robot_state_publisher" /> <node pkg="joint_state_publisher" type="joint_state_publisher" name="joint_state_publisher" /> <!-- 集成arbotix运动控制节点并且加载参数 --> <node pkg="arbotix_python" type="arbotix_driver" name="driver" output="screen"> <rosparam file="$(find urdf01_rviz)/config/control.yaml" command="load" /> <param name="sim" value="true" /> <!-- 意味着这是一个仿真环境 --> </node> </launch>

注:运行launch文件之前,因为我的python版本是2.7,所以需要在下图中将python3改为2.7才可以。

 然后运行launch文件,将下图这里改为odom

 然后对话题发布数据来控制机器人做圆周运动

add添加这个之后就有指向箭头

------------URDF集成Gazebo------------

270-271节 基本集成流程案例

URDF 与 Gazebo 集成流程与 Rviz 实现类似,主要步骤如下:

  1. 创建功能包,导入依赖项

  2. 编写 URDF 或 Xacro 文件

  3. 启动 Gazebo 并显示机器人模型

1 创建功能包urdf02_gazebo,依赖于下图2

2编写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
<robot name="mycar"> <link name="base_link"> <visual> <geometry> <box size="0.5 0.2 0.1" /> </geometry> <origin xyz="0 0 0" rpy="0 0 0"/> <material name="yellow"> <color rgba="0.5 0.3 0 0.5"/> </material> </visual> <!-- 设置碰撞参数 --> <!-- 如果是标准几何体,直接复制visual的geometry和origin即可 --> <collision> <geometry> <box size="0.5 0.2 0.1" /> </geometry> <origin xyz="0 0 0" rpy="0 0 0"/> </collision> <!-- 设置惯性矩阵 --> <intertial> <origin xyz="0 0 0" rpy="0 0 0"/> <mass value="2"> <inertia ixx="1" ixy="0" ixz="0" iyy="1" iyz="0" izz="1" /> <!-- 惯性矩阵:通过计算的来,这里不详细解释 --> </intertial> </link> <!-- gazebo有自己的颜色设置标签 --> <gazebo reference="base_link"> <material>Gazebo/Red</material> </gazebo> </robot>

3编写launch文件

复制代码
1
2
3
4
5
6
7
8
<launch> <!-- 步骤1 需要在参数服务器中载入urdf --> <param name="robot_description" textfile="$(find urdf02_gazebo)/urdf/demo01_helloworld.urdf" /> <!-- 步骤2 启动gazebo --> <include file="$(find gazebo_ros)/launch/empty_world.launch" /> <!-- 步骤3 在gazebo中添加之前已经做好的(urdf文件中)机器人模型 --> <node pkg="gazebo_ros" type="spawn_model" name="model" args="-urdf -model mycar -param robot_description" /> </launch>

步骤3代码解释: spawn_model用于模型产卵,args参数中-urdf指的是加载的是urdf数据,-model mycar指的是加载的是名字为mycar的模型,-param robot_description指的是从参数服务器加载数据(和步骤1的param name对应的)

273节 urdf集成gazebo相关设置

1.collision

如果机器人link是标准的几何体形状,和link的 visual 属性设置一致即可。

2.inertial

惯性矩阵的设置需要结合link的质量与外形参数动态生成,标准的球体、圆柱与立方体的惯性矩阵公式如下(已经封装为 xacro 实现):

球体:

复制代码
1
2
3
4
5
6
7
8
9
10
<!-- Macro for inertia matrix --> <xacro:macro name="sphere_inertial_matrix" params="m r"> <inertial> <mass value="${m}" /> <inertia ixx="${2*m*r*r/5}" ixy="0" ixz="0" iyy="${2*m*r*r/5}" iyz="0" izz="${2*m*r*r/5}" /> </inertial> </xacro:macro>

圆柱:

复制代码
1
2
3
4
5
6
7
8
9
<xacro:macro name="cylinder_inertial_matrix" params="m r h"> <inertial> <mass value="${m}" /> <inertia ixx="${m*(3*r*r+h*h)/12}" ixy = "0" ixz = "0" iyy="${m*(3*r*r+h*h)/12}" iyz = "0" izz="${m*r*r/2}" /> </inertial> </xacro:macro>

立方体:

复制代码
1
2
3
4
5
6
7
8
9
<xacro:macro name="Box_inertial_matrix" params="m l w h"> <inertial> <mass value="${m}" /> <inertia ixx="${m*(h*h + l*l)/12}" ixy = "0" ixz = "0" iyy="${m*(w*w + l*l)/12}" iyz= "0" izz="${m*(w*w + h*h)/12}" /> </inertial> </xacro:macro>

需要注意的是,原则上,除了 base_footprint 外,机器人的每个刚体部分都需要设置惯性矩阵,且惯性矩阵必须经计算得出,如果随意定义刚体部分的惯性矩阵,那么可能会导致机器人在 Gazebo 中出现抖动,移动等现象。

3.颜色设置(注意大小写)

在 gazebo 中显示 link 的颜色,必须要使用指定的标签:

复制代码
1
2
3
4
<gazebo reference="link节点名称"> <material>Gazebo/Blue</material> </gazebo>

273-275 URDF集成Gazebo实操

需求描述:

将之前的机器人模型(xacro版)显示在 gazebo 中

实现流程:

  1. 需要编写封装惯性矩阵算法的 xacro 文件

  2. 为机器人模型中的每一个 link 添加 collision 和 inertial 标签,并且重置颜色属性

  3. 在 launch 文件中启动 gazebo 并添加机器人模型

我们将之前写的urdf01中的部分代码(car、demo5、6、7)复制过来稍作修改即可:

编写launch文件(和之前的区别杂鱼command这里):

复制代码
1
2
3
4
5
6
7
8
<launch> <!-- 需要在参数服务器中载入urdf --> <param name="robot_description" command="$(find xacro)/xacro $(find urdf02_gazebo)/urdf/car.urdf.xacro" /> <!-- 启动gazebo --> <include file="$(find gazebo_ros)/launch/empty_world.launch" /> <!-- 在gazebo中添加机器人模型 --> <node pkg="gazebo_ros" type="spawn_model" name="spawn_model" args="-urdf -model mycar -param robot_description" /> </launch>

然后修改demo05,核心多个link中添加下面两段(注:注意惯性函数在collision外面;使用参数的值的时候要加上${};<gazebo reference=中写的是当前robot的name)

复制代码
1
2
3
4
5
6
7
8
9
10
11
12
<collision> <geometry> <cylinder radius="${base_radius}" length="${base_length}" /> </geometry> <origin xyz="0 0 0" rpy="0 0 0" /> </collision> <!-- 调用head中的惯性矩阵函数 --> <xacro:cylinder_inertial_matrix m="${base_mass}" r="${base_radius}" h="${base_length}"/> <gazebo reference="base_link"> <material>Gazebo/Red</material> </gazebo>

全部demo05、06、07代码:

复制代码
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
<robot name="mycar" xmlns:xacro="http://wiki.ros.org/xacro"> <!-- 底盘参数 形状:圆柱 半径:10 cm 高度:8 cm 离地:1.5 cm --> <!-- <xacro:property name="" value=""/> --> <xacro:property name="base_radius" value="0.1"/> <xacro:property name="base_length" value="0.08"/> <xacro:property name="base_mass" value="2"/> <xacro:property name="small_wheel_mass" value="0.01"/> <xacro:property name="wheel_mass" value="0.05"/> <xacro:property name="lidi" value="0.015"/> <xacro:property name="base_joint_z" value="${base_length/2+lidi}"/> <link name="base_footprint"> <visual> <geometry> <box size="0.001 0.001 0.001" /> </geometry> </visual> </link> <link name="base_link"> <visual> <geometry> <cylinder radius="${base_radius}" length="${base_length}" /> </geometry> <origin xyz="0 0 0" rpy="0 0 0" /> <material name="baselink_color"> <color rgba="1 0.5 0.2 0.5" /> </material> </visual> <collision> <geometry> <cylinder radius="${base_radius}" length="${base_length}" /> </geometry> <origin xyz="0 0 0" rpy="0 0 0" /> </collision> <!-- 调用head中的惯性矩阵函数 --> <xacro:cylinder_inertial_matrix m="${base_mass}" r="${base_radius}" h="${base_length}"/> </link> <gazebo reference="base_link"> <material>Gazebo/Yellow</material> </gazebo> <joint name="link2base_footprint" type="fixed"> <parent link="base_footprint" /> <child link="base_link"/> <!-- 高度=车体高度/2+离地间距 --> <origin xyz="0 0 ${base_joint_z}" /> </joint> <!-- 添加驱动轮 --> <!-- 驱动轮是侧翻的圆柱 参数 半径: 3.25 cm 宽度: 1.5 cm 颜色: 黑色 关节设置: x = 0 y = 底盘的半径 + 轮胎宽度 / 2 z = 离地间距 + 底盘长度 / 2 - 轮胎半径 = 1.5 + 4 - 3.25 = 2.25(cm) axis = 0 1 0 --> <xacro:property name="wheel_radius" value="0.0325" /> <xacro:property name="wheel_length" value="0.015" /> <xacro:property name="PI" value="3.1415927" /> <xacro:property name="wheel_joint_z" value="${-1*(base_length/2+lidi-wheel_radius)}" /> <!-- 注意结果是负数 --> <!-- 将车轮封装成宏 wheel_name:left/right flag:1/-1 表明左轮还是右轮 --> <xacro:macro name="wheel_func" params="wheel_name flag" > <link name="${wheel_name}_wheel"> <visual> <geometry> <cylinder radius="${wheel_radius}" length="${wheel_length}" /> </geometry> <origin xyz="0 0 0" rpy="${PI/2} 0 0" /> <material name="wheel_color"> <color rgba="0.0 0.0 0.0 0.3" /> </material> </visual> <collision> <geometry> <cylinder radius="${wheel_radius}" length="${wheel_length}" /> </geometry> <origin xyz="0 0 0" rpy="${PI/2} 0 0" /> </collision> <xacro:cylinder_inertial_matrix m="${wheel_mass}" r="${wheel_radius}" h="${wheel_length}"/> </link> <gazebo reference="${wheel_name}_wheel"> <material>Gazebo/Red</material> </gazebo> <joint name="${wheel_name}2link" type="continuous"> <parent link="base_link" /> <child link="${wheel_name}_wheel" /> <origin xyz="0 ${0.1*flag} ${wheel_joint_z}" /> <axis xyz="0 1 0" /> </joint> </xacro:macro> <!-- 调用上面的宏 --> <xacro:wheel_func wheel_name="left" flag="1"/> <xacro:wheel_func wheel_name="right" flag="-1"/> <!-- 添加万向轮(支撑轮) --> <!-- 参数 形状: 球体 半径: 0.75 cm 颜色: 黑色 关节设置: x = 自定义(底盘半径 - 万向轮半径) = 0.1 - 0.0075 = 0.0925(cm) y = 0 z = 底盘长度 / 2 + 离地间距 / 2 = 0.08 / 2 + 0.015 / 2 = 0.0475 axis= 1 1 1 --> <xacro:property name="small_wheel_radius" value="0.0075"/> <xacro:property name="small_joint_z" value="${(base_length/2+lidi-small_wheel_radius)*-1}"/> <xacro:macro name="small_wheel_func" params="small_wheel_name flag"> <link name="${small_wheel_name}_wheel"> <visual> <geometry> <sphere radius="${small_wheel_radius}" /> </geometry> <origin xyz="0 0 0" rpy="0 0 0" /> <material name="wheel_color"> <color rgba="0.0 0.0 0.0 0.3" /> </material> </visual> <collision> <geometry> <sphere radius="${small_wheel_radius}" /> </geometry> <origin xyz="0 0 0" rpy="0 0 0" /> </collision> <xacro:sphere_inertial_matrix m="${small_wheel_mass}" r="${small_wheel_radius}"/> </link> <gazebo reference="${small_wheel_name}_wheel"> <material>Gazebo/Red</material> </gazebo> <joint name="${small_wheel_name}_wheel2base_link" type="continuous"> <parent link="base_link" /> <child link="${small_wheel_name}_wheel" /> <origin xyz="${0.08*flag} 0 ${small_joint_z}" /> <axis xyz="1 1 1" /> </joint> </xacro:macro> <xacro:small_wheel_func small_wheel_name="front" flag="1"/> <xacro:small_wheel_func small_wheel_name="back" flag="-1"/> </robot>
复制代码
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
<!-- 摄像头相关的 xacro 文件 --> <robot name="mycar" xmlns:xacro="http://wiki.ros.org/xacro"> <!-- 摄像头属性 --> <xacro:property name="camera_length" value="0.02" /> <!-- 摄像头长度(x) --> <xacro:property name="camera_width" value="0.05" /> <!-- 摄像头宽度(y) --> <xacro:property name="camera_height" value="0.05" /> <!-- 摄像头高度(z) --> <xacro:property name="camera_mass" value="0.01" /> <!-- 摄像头质量 --> <xacro:property name="joint_camera_x" value="0.08" /> <!-- 摄像头安装的x坐标 --> <xacro:property name="joint_camera_y" value="0.0" /> <!-- 摄像头安装的y坐标 --> <xacro:property name="joint_camera_z" value="${base_length / 2 + camera_height / 2}" /> <!-- 摄像头安装的z坐标:底盘高度 / 2 + 摄像头高度 / 2 --> <!-- 摄像头关节以及link --> <link name="camera"> <visual> <geometry> <box size="${camera_length} ${camera_width} ${camera_height}" /> </geometry> <origin xyz="0.0 0.0 0.0" rpy="0.0 0.0 0.0" /> <material name="black" > <color rgba="0 0 0 0.8"/> </material> </visual> <collision> <geometry> <box size="${camera_length} ${camera_width} ${camera_height}" /> </geometry> <origin xyz="0.0 0.0 0.0" rpy="0.0 0.0 0.0" /> </collision> <xacro:Box_inertial_matrix m="${camera_mass}" l="${camera_length}" w="${camera_width}" h="${camera_height}" /> </link> <gazebo reference="camera"> <material>Gazebo/Blue</material> </gazebo> <joint name="camera2base" type="fixed"> <parent link="base_link" /> <child link="camera" /> <origin xyz="${joint_camera_x} ${joint_camera_y} ${joint_camera_z}" /> </joint> </robot>
复制代码
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
<!-- 小车底盘添加雷达 --> <robot name="my_laser" xmlns:xacro="http://wiki.ros.org/xacro"> <!-- 雷达支架 --> <xacro:property name="support_length" value="0.15" /> <!-- 支架长度 --> <xacro:property name="support_radius" value="0.01" /> <!-- 支架半径 --> <xacro:property name="support_mass" value="0.1" /> <!-- 支架质量 --> <xacro:property name="joint_support_x" value="0.0" /> <!-- 支架安装的x坐标 --> <xacro:property name="joint_support_y" value="0.0" /> <!-- 支架安装的y坐标 --> <xacro:property name="joint_support_z" value="${base_length / 2 + support_length / 2}" /> <!-- 支架安装的z坐标:底盘高度 / 2 + 支架高度 / 2 --> <link name="support"> <visual> <geometry> <cylinder radius="${support_radius}" length="${support_length}" /> </geometry> <origin xyz="0.0 0.0 0.0" rpy="0.0 0.0 0.0" /> <material name="red"> <color rgba="0.8 0.2 0.0 0.5" /> </material> </visual> <collision> <geometry> <cylinder radius="${support_radius}" length="${support_length}" /> </geometry> <origin xyz="0.0 0.0 0.0" rpy="0.0 0.0 0.0" /> </collision> <xacro:cylinder_inertial_matrix m="${support_mass}" r="${support_radius}" h="${support_length}"/> </link> <gazebo reference="support"> <material>Gazebo/Gray</material> </gazebo> <joint name="support2base_link" type="fixed"> <parent link="base_link" /> <child link="support" /> <origin xyz="${joint_support_x} ${joint_support_y} ${joint_support_z}" /> </joint> <!-- 雷达属性 --> <xacro:property name="laser_length" value="0.05" /> <!-- 雷达长度 --> <xacro:property name="laser_radius" value="0.03" /> <!-- 雷达半径 --> <xacro:property name="laser_mass" value="0.15" /> <!-- 雷达质量 --> <xacro:property name="joint_laser_x" value="0.0" /> <!-- 雷达安装的x坐标 --> <xacro:property name="joint_laser_y" value="0.0" /> <!-- 雷达安装的y坐标 --> <xacro:property name="joint_laser_z" value="${support_length / 2 + laser_length / 2}" /> <!-- 雷达安装的z坐标:支架高度 / 2 + 雷达高度 / 2 --> <!-- 雷达关节以及link --> <link name="laser"> <visual> <geometry> <cylinder radius="${laser_radius}" length="${laser_length}" /> </geometry> <origin xyz="0.0 0.0 0.0" rpy="0.0 0.0 0.0" /> <material name="black"> <color rgba="0 0 0 0.5"/> </material> </visual> <collision> <geometry> <cylinder radius="${laser_radius}" length="${laser_length}" /> </geometry> <origin xyz="0.0 0.0 0.0" rpy="0.0 0.0 0.0" /> </collision> <xacro:cylinder_inertial_matrix m="${laser_mass}" r="${laser_radius}" h="${laser_length}" /> </link> <gazebo reference="laser"> <material>Gazebo/Black</material> </gazebo> <joint name="laser2support" type="fixed"> <parent link="support" /> <child link="laser" /> <origin xyz="${joint_laser_x} ${joint_laser_y} ${joint_laser_z}" /> </joint> </robot>

276节 gazebo仿真环境载入

在一开始下载的sim_demo文件夹下的box_house就是已经搭建好了的模型环境,我们这里就学习如何在gazebo中集成已经搭建好的环境。

首先创建文件夹并且把sim_demo中下载的box_house粘贴到刚刚建好的文件夹下

然后创建launch文件 (核心代码是“启动gazebo”注释下的代码)

复制代码
1
2
3
4
5
6
7
8
9
10
<launch> <!-- 需要在参数服务器中载入urdf --> <param name="robot_description" command="$(find xacro)/xacro $(find urdf02_gazebo)/urdf/car.urdf.xacro" /> <!-- 启动gazebo --> <include file="$(find gazebo_ros)/launch/empty_world.launch" > <arg name="world_name" value="$(find urdf02_gazebo)/worlds/box_house.world" /> </include> <!-- 在gazebo中添加机器人模型 --> <node pkg="gazebo_ros" type="spawn_model" name="spawn_model" args="-urdf -model mycar -param robot_description" /> </launch>

277节 gazebo创建仿真环境

Gazebo 中创建仿真实现方式有两种:

  • 方式1: 直接添加内置组件创建仿真环境

  • 方式2: 手动绘制仿真环境(更为灵活)

也还可以直接下载使用官方或第三方提高的仿真环境插件。

方式1

启动roscore后输入:

复制代码
1
rosrun gazebo_ros gazebo

如果这里一直打不开,可以参考这个网站

然后通过图形界面拖动创建仿真环境

方式2

将模型库复制进 gazebo

------------URDF、GAZEBO、Rviz综合应用------------

官方参考:

Gazebo : Tutorial : Gazebo plugins in ROS

279节 roscontrol简介

之前在rviz使用的机器人控制方法拿到gazebo中并不能使用,这里就需要设计组件roscontrol。

ros_control:是一组软件包,它包含了控制器接口,控制器管理器,传输和硬件接口。ros_control 是一套机器人控制的中间件,是一套规范,不同的机器人平台只要按照这套规范实现,那么就可以保证 与ROS 程序兼容,通过这套规范,实现了一种可插拔的架构设计,大大提高了程序设计的效率与灵活性。

gazebo 已经实现了 ros_control 的相关接口,如果需要在 gazebo 中控制机器人运动,直接调用相关接口即可

roscontrol就可以理解成是一套规范/接口,机器人平台和机器人系统这两者之间都需要按照这个规范来实现。

280节 运动控制实现流程

首先创建文件夹和文件:

然后编写代码(这部分代码直接粘贴,稍加修改)

复制代码
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
<robot name="my_car_move" xmlns:xacro="http://wiki.ros.org/xacro"> <!-- 传动实现:用于连接控制器与关节 --> <xacro:macro name="joint_trans" params="joint_name"> <!-- Transmission is important to link the joints and the controller --> <transmission name="${joint_name}_trans"> <type>transmission_interface/SimpleTransmission</type> <joint name="${joint_name}"> <hardwareInterface>hardware_interface/VelocityJointInterface</hardwareInterface> </joint> <actuator name="${joint_name}_motor"> <hardwareInterface>hardware_interface/VelocityJointInterface</hardwareInterface> <mechanicalReduction>1</mechanicalReduction> </actuator> </transmission> </xacro:macro> <!-- 每一个驱动轮都需要配置传动装置 --> <xacro:joint_trans joint_name="left2link" /> <xacro:joint_trans joint_name="right2link" /> <!-- 控制器 --> <gazebo> <plugin name="differential_drive_controller" filename="libgazebo_ros_diff_drive.so"> <rosDebugLevel>Debug</rosDebugLevel> <publishWheelTF>true</publishWheelTF> <robotNamespace>/</robotNamespace> <publishTf>1</publishTf> <publishWheelJointState>true</publishWheelJointState> <alwaysOn>true</alwaysOn> <updateRate>100.0</updateRate> <legacyMode>true</legacyMode> <leftJoint>left2link</leftJoint> <!-- 左轮 --> <rightJoint>right2link</rightJoint> <!-- 右轮 --> <wheelSeparation>${base_radius * 2}</wheelSeparation> <!-- 车轮间距 --> <wheelDiameter>${wheel_radius * 2}</wheelDiameter> <!-- 车轮直径 --> <broadcastTF>1</broadcastTF> <wheelTorque>30</wheelTorque> <wheelAcceleration>1.8</wheelAcceleration> <commandTopic>cmd_vel</commandTopic> <!-- 运动控制话题 --> <odometryFrame>odom</odometryFrame> <odometryTopic>odom</odometryTopic> <!-- 里程计话题 --> <robotBaseFrame>base_footprint</robotBaseFrame> <!-- 根坐标系 --> </plugin> </gazebo> </robot>

 然后编译执行launch文件

  这时我们发现已经存在了cmd_vel文件

 然后使用以下代码启动键盘控制节点对其进行控制

复制代码
1
rosrun teleop_twist_keyboard teleop_twist_keyboard.py _speed:=0.1 _turn:=0.3

如果没有这个功能包就使用以下语句进行安装:

复制代码
1
2
sudo apt-get install ros-melodic-teleop-twist-keyboard 这里如果ros版本是noetic就把melodic改为noetic

281节 rviz查看里程计消息

因为gazebo中无法以图形化的方式显示小车运行的里程信息,所以这里要结合rviz来实现

编写launch文件启动rviz

复制代码
1
2
3
4
5
6
7
<launch> <!-- 启动 rivz --> <node pkg="rviz" type="rviz" name="rviz_test" args="-d $(find urdf01_rviz)/config/show_mycar.rviz" /> <!-- 启动机器人状态和关节状态发布节点 --> <node pkg="robot_state_publisher" type="robot_state_publisher" name="robot_state_publisher" /> <node pkg="joint_state_publisher" type="joint_state_publisher" name="joint_state_publisher" /> </launch>

分别启动两者launch文件

 修改rviz中的一些选项:

 这里参考的是上一节代码中里程计参考的话题是odom。

 然后启动键盘控制节点,在gazebo中运动的路径就可以在rviz中显示了。

282节 雷达仿真及其显示

雷达仿真基本流程(和之前move类似):

    已经创建完毕的机器人模型,编写一个单独的 xacro 文件,为机器人模型添加雷达配置;

    将此文件集成进xacro文件;

    启动 Gazebo,使用 Rviz 显示雷达信息。

编写雷达的xacro文件(官网上可复制),主要修改reference和frameName两个标签,这里reference和framName两个的标签改为之前在gazebo中编写的laser的link的名称,可以理解为将laser装到之前的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
26
27
28
29
30
31
32
33
34
35
36
<robot name="my_sensors" xmlns:xacro="http://wiki.ros.org/xacro"> <!-- 雷达 --> <gazebo reference="laser"> <sensor type="ray" name="rplidar"> <pose>0 0 0 0 0 0</pose> <visualize>true</visualize> <!-- 显示雷达射线 --> <update_rate>5.5</update_rate> <!-- 射线更新频率 /s --> <ray> <scan> <horizontal> <samples>360</samples> <!-- 采样个数:雷达旋转一周发射的点 --> <resolution>1</resolution> <!-- 分辨率:每n个射线有一个测距的,便于降低计算压力,精度降低 --> <min_angle>-3</min_angle> <!-- 采样范围:单位是rad,这里代码中表示的是正前方正负3个弧度是我的采样范围 --> <max_angle>3</max_angle> </horizontal> </scan> <range> <min>0.10</min> <!-- 采样的距离:最短和最远的采样距离 --> <max>30.0</max> <resolution>0.01</resolution> <!-- 精度:精确到xxx米 --> </range> <noise> <type>gaussian</type> <!-- 高斯噪音:用于仿真,模拟一定误差 --> <mean>0.0</mean> <stddev>0.01</stddev> </noise> </ray> <plugin name="gazebo_rplidar" filename="libgazebo_ros_laser.so"> <topicName>/scan</topicName> <frameName>laser</frameName> </plugin> </sensor> </gazebo> </robot>

注:laser代码中的topicname就是雷达发布数据的话题。

在car.urdf.xacro中添加一行集成雷达配置文件的代码

复制代码
1
2
3
4
5
6
7
8
9
10
11
12
<!-- 组合小车底盘与摄像头与雷达,包含底盘、摄像头、雷达--> <robot name="mycar" xmlns:xacro="http://wiki.ros.org/xacro"> <xacro:include filename="head.xacro" /> <!-- 包含惯性矩阵文件 --> <xacro:include filename="demo05_car_base.urdf.xacro" /> <xacro:include filename="demo06_car_camera.urdf.xacro" /> <xacro:include filename="demo07_car_laser.urdf.xacro" /> <!-- 集成运动控制 --> <xacro:include filename="gazebo/move.xacro" /> <!-- 集成雷达配置文件 --> <xacro:include filename="gazebo/laser.xacro" /> </robot>

然后运行:

 在rviz中查看雷达消息

283节 摄像头仿真

摄像头仿真基本流程:

  1. 已经创建完毕的机器人模型,编写一个单独的 xacro 文件,为机器人模型添加摄像头配置;

  2. 将此文件集成进xacro文件;

  3. 启动 Gazebo,使用 Rviz 显示摄像头信息。

这里还是主要修改reference和frameName

复制代码
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
<robot name="my_sensors" xmlns:xacro="http://wiki.ros.org/xacro"> <!-- 被引用的link --> <gazebo reference="camera"> <!-- 类型设置为 camara --> <sensor type="camera" name="camera_node"> <update_rate>30.0</update_rate> <!-- 更新频率 --> <!-- 摄像头基本信息设置 --> <camera name="head"> <horizontal_fov>1.3962634</horizontal_fov> <image> <width>1280</width> <height>720</height> <format>R8G8B8</format> </image> <clip> <near>0.02</near> <far>300</far> </clip> <noise> <type>gaussian</type> <mean>0.0</mean> <stddev>0.007</stddev> </noise> </camera> <!-- 核心插件 --> <plugin name="gazebo_camera" filename="libgazebo_ros_camera.so"> <alwaysOn>true</alwaysOn> <updateRate>0.0</updateRate> <cameraName>/camera</cameraName> <imageTopicName>image_raw</imageTopicName> <cameraInfoTopicName>camera_info</cameraInfoTopicName> <frameName>camera</frameName> <hackBaseline>0.07</hackBaseline> <distortionK1>0.0</distortionK1> <distortionK2>0.0</distortionK2> <distortionK3>0.0</distortionK3> <distortionT1>0.0</distortionT1> <distortionT2>0.0</distortionT2> </plugin> </sensor> </gazebo> </robot>

car.urdf.xacro:添加了集成摄像头

复制代码
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
<!-- 组合小车底盘与摄像头与雷达,包含底盘、摄像头、雷达--> <robot name="mycar" xmlns:xacro="http://wiki.ros.org/xacro"> <xacro:include filename="head.xacro" /> <!-- 包含惯性矩阵文件 --> <xacro:include filename="demo05_car_base.urdf.xacro" /> <xacro:include filename="demo06_car_camera.urdf.xacro" /> <xacro:include filename="demo07_car_laser.urdf.xacro" /> <!-- 集成运动控制 --> <xacro:include filename="gazebo/move.xacro" /> <!-- 集成雷达配置文件 --> <xacro:include filename="gazebo/laser.xacro" /> <!-- 集成摄像头 --> <xacro:include filename="gazebo/camera.xacro" /> </robot>

然后运行demo03和demo04:

修改rviz

 注:这里上图中的topic参考的是camera.xacro中的这两行:

284节 深度相机仿真

kinect摄像头仿真基本流程:

  1. 已经创建完毕的机器人模型,编写一个单独的 xacro 文件,为机器人模型添加kinect摄像头配置;

  2. 将此文件集成进xacro文件;

  3. 启动 Gazebo,使用 Rviz 显示kinect摄像头信息。

创建xacro文件并且编写

复制代码
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
<robot name="my_sensors" xmlns:xacro="http://wiki.ros.org/xacro"> <gazebo reference="support"> <!-- 这里将链接摄像头的支架作为深度相机(偷懒) --> <sensor type="depth" name="camera"> <always_on>true</always_on> <update_rate>20.0</update_rate> <camera> <horizontal_fov>${60.0*PI/180.0}</horizontal_fov> <image> <format>R8G8B8</format> <width>640</width> <height>480</height> </image> <clip> <near>0.05</near> <far>8.0</far> </clip> </camera> <plugin name="kinect_camera_controller" filename="libgazebo_ros_openni_kinect.so"> <cameraName>camera</cameraName> <alwaysOn>true</alwaysOn> <updateRate>10</updateRate> <imageTopicName>rgb/image_raw</imageTopicName> <depthImageTopicName>depth/image_raw</depthImageTopicName> <pointCloudTopicName>depth/points</pointCloudTopicName> <cameraInfoTopicName>rgb/camera_info</cameraInfoTopicName> <depthImageCameraInfoTopicName>depth/camera_info</depthImageCameraInfoTopicName> <frameName>support</frameName> <baseline>0.1</baseline> <distortion_k1>0.0</distortion_k1> <distortion_k2>0.0</distortion_k2> <distortion_k3>0.0</distortion_k3> <distortion_t1>0.0</distortion_t1> <distortion_t2>0.0</distortion_t2> <pointCloudCutoff>0.4</pointCloudCutoff> </plugin> </sensor> </gazebo> </robot>

car.urdf.xacro

复制代码
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
<!-- 组合小车底盘与摄像头与雷达,包含底盘、摄像头、雷达--> <robot name="mycar" xmlns:xacro="http://wiki.ros.org/xacro"> <xacro:include filename="head.xacro" /> <!-- 包含惯性矩阵文件 --> <xacro:include filename="demo05_car_base.urdf.xacro" /> <xacro:include filename="demo06_car_camera.urdf.xacro" /> <xacro:include filename="demo07_car_laser.urdf.xacro" /> <!-- 集成运动控制 --> <xacro:include filename="gazebo/move.xacro" /> <!-- 集成雷达配置文件 --> <xacro:include filename="gazebo/laser.xacro" /> <!-- 集成摄像头 --> <xacro:include filename="gazebo/camera.xacro" /> <!-- 集成深度相机 --> <xacro:include filename="gazebo/kinect.xacro" /> </robot>

roslaunch demo03和demo04

在rviz中修改fixed name和camera的topic即可呈现不同的仿真效果

285节 点云数据显示

运行之前的demo03和demo04,add进pointcloud2

问题:在rviz中显示时错位。

原因:在kinect中图像数据与点云数据使用了两套坐标系统,且两套坐标系统位姿并不一致。

解决:

首先在插件中为kinect设置坐标系,修改配置文件的<frameName>标签内容:

 然后在launch文件中添加坐标变换

复制代码
1
2
<node pkg="tf2_ros" type="static_transform_publisher" name="static_transform_publisher" args="0 0 0 -1.57 0 -1.57 /support /support_depth" />

再次运行即可demo03、04即可

本章小结

本章主要介绍了ROS中仿真实现涉及的三大知识点:

  • URDF(Xacro)
  • Rviz
  • Gazebo

URDF 是用于描述机器人模型的 xml 文件,可以使用不同的标签具代表不同含义,URDF 编写机器人模型代码冗余,xacro 可以优化 URDF 实现,代码实现更为精简、高效、易读。容易混淆的是Rviz与Gazebo,在此我们着重比较以下二者的区别:

rviz是三维可视化工具,强调把已有的数据可视化显示;

gazebo是三维物理仿真平台,强调的是创建一个虚拟的仿真环境。

rviz需要已有数据

rviz提供了很多插件,这些插件可以显示图像、模型、路径等信息,但是前提都是这些数据已经以话题、参数的形式发布,rviz做的事情就是订阅这些数据,并完成可视化的渲染,让开发者更容易理解数据的意义。

gazebo不是显示工具,强调的是仿真,它不需要数据,而是创造数据

我们可以在gazebo中免费创建一个机器人世界,不仅可以仿真机器人的运动功能,还可以仿真机器人的传感器数据。而这些数据就可以放到rviz中显示,所以使用gazebo的时候,经常也会和rviz配合使用。当我们手上没有机器人硬件或实验环境难以搭建时,仿真往往是非常有用的利器。

综上,如果你手上已经有机器人硬件平台,并且在上边可以完成需要的功能,用rviz应该就可以满足开发需求。

如果你手上没有机器人硬件,或者想在仿真环境中做一些算法、应用的测试,gazebo+rviz应该是你需要的。

另外,rviz配合其他功能包也可以建立一个简单的仿真环境,比如rviz+ArbotiX。

最后

以上就是暴躁草丛最近收集整理的关于奥特学园ROS笔记--6(227-285)227节228-230节 概述231节 URDF集成Rviz基本流程232节 上一节优化------------URDF语法-----------233节 URDF语法-0 (robot标签)232-237节 URDF语法-1 link238-241节 URDF语法-2 joint-1242节 优化244-248节 URDF练习249节 URDF工具 ------------URDF优化_xacro------------250节251节 Xacro快速的全部内容,更多相关奥特学园ROS笔记--6(227-285)227节228-230节内容请搜索靠谱客的其他文章。

本图文内容来源于网友提供,作为学习参考使用,或来自网络收集整理,版权属于原作者所有。
点赞(79)

评论列表共有 0 条评论

立即
投稿
返回
顶部