Gazebo是3D物理仿真平台,强调的是创建一个虚拟的仿真环境。
Rviz需要已有的数据,而Gazebo可以创造数据。我们可以在Gazebo中创建一个机器人世界,不仅可以仿真机器人的运动功能,还可以仿真机器人的传感器数据,而这些数据就可以放到Rviz中显示,所以使用gazebo的时候,经常也会和rviz配合使用。
文章用提到的一些源码地址: 冰达机器人
rqt 工具:
(1) rqt_graph: 查看节点之间的发布--订阅关系
(2) rqt_plot: 实时显示一个发布到某个话题上的数据变化图形
(3) rqt_console: 显示来自所有节点的日志
(4) rqt_logger_level : 通过图形界面设置日志级别
gazebo
仿真平台,创建数据
启动:roslaunch gazebo_ros *
第一次启动会非常慢,因为服务器在国外 !
或者去网站上下载离线软件,就不用通过服务器加载,启动的速度会快很多。
安装: Ubuntu 20.04 Gazebo安装 及模型库下载_Ananke_Z的博客-优快云博客_gazebo模型下载
cd ~/.gazebo/
Gazebo 界面的介绍:
ROS 常用的shell命令:
(1) roscore
(2) rosnode list
(3) rosnode info /(info 后面需要带一个参数,节点名字 摁tab建可以提示补全)
比如:rosnode info /turtlesim(小乌龟节点),列出的信息如下:
1. 节点的名称
2. 发布的话题
3. 订阅的话题
4. 有哪些服务
5. 跟哪些节点有链接关系
(4) rostopic :
rostopis list 列出当前活跃的话题
rostopic info /话题名 可以查看话题之间的发布订阅者之间的关系,以及话题的数据类型
单独编译功能包:
catkin_make --pkg 功能包的名字 回车编译执行
比如: catkin_make --pkg LIO-SAM
功能包提前准备:
git 下载完功能包之后,查看依赖是否安装上了。。通过rosdep检查
终端进入catkin_ws 输入: rosdep check --from-path src
如果没有,输入安装 : rosdep install --from-path src
Gazebo 和 环境模型准备、机器人模型设计、为模型上装备传感器和执行器
1、实验目标和实验准备
目标:设计出一台具备激光雷达、IMU和相机的机器人仿真模型用于相关的实验。
2、GAZEBO 的使用和world 创建
(1) 确认gazebo 软件可以运行
终端输入: gazebo 来启动软件
(2) 给环境中添加
通过窗口中的 “Insert” 按钮,里面有自己的存放模型的目录,也有远端的服务器,服务器加载会比较慢。。
视频作者在Gitee上存放了模型, 使用git clone可以直接下载:
git clone https://gitee.com/bingda-robot/gazebo_models.git
模型库1.3G
(3) 下载完之后打开隐藏目录,一般是不会显示,需要通过 "Ctrl + H " 切换显示
找到 .gazebo 目录, 打开,里面有gezebo_models目录,里面存放的就是 gazebo 中提供的模型。 可以把上面下载的模型拷贝过来,命名为models。
(4) 打开gazebo, 点击 Insert 会显示本地模型的目录,如果没有的话 点击Add path 添加。【我的已有】
(5) 导入模型场景:点击里面的模型就会在界面显示,比如点击 咖啡馆模型(cafe),显示如下:
上面是从模型库里面导入场景,下面介绍自己建立自己想要的场景。
(6) 建立自己需要的场景:
点击“Edit” --> "Building Editor" 出现下面的界面。。这个主要针对室内的场景。
左边一列 可以选择特征, wall 表示墙体。。绘制完之后保存这个场景【点击file 进行保存, 保存为 home_model】
(7) 保存之后再次打开gazebo, 在Insert 下面就会有刚刚自己创建的场景,打开 home_model, 可以在当前场景下插入一些物品,如下:
将上面绘制的 world 保存为 room.world 文件。
(8) 把构建的world 文件 放到功能包当中,例如:在bingda_tutorials文件夹下,创建一个world 文件夹,里面存放刚刚保存的 room.world。
(9) 存放world文件之后 ,通过launch 文件 启动 gazebo, 并且加载 world 文件,里面的gazebo_world.launch 文件
在终端执行 roslaunch 命令,启动 gazebo 显示 保存的world 文件。
roslaunch bingda_tutorials gazebo_world.launch
即可启动打开 gazebo world文件。
3、URDF 和 机器人模型
在gazebo中,机器人模型是通过URDF文件来描述的 , URDF 本身是 xml 格式的文件。
wiki : wiki.ros.org/urdf/XML 打开网页可以看见 关于XML 中用到的标签。
robot 标签描述这是一个机器人文件
link 和 joint 分别描述机器人的 部件 和 关节。。
-
urdf : 画机器人
在 bingda_tutorials 文件夹下面 的 urdf 文件夹里面的 mybot.urdf 文件,里面是xml格式的代码,绘制了一个小车的样子。
mybot.urdf 代码解读:
<?xml version="1.0"?>
<!--robot标签(顶层标签)指定机器人的名字 叫 myrobot-->
<robot name="mybot">
<!-- link 标签 约定的坐标名称-->
<link name="base_footprint"/>
<!-- joint 标签 名字为:base_joint ,用来连接 base_footprint 和 base_link-->
<joint name="base_joint" type="fixed">
<parent link="base_footprint"/>
<child link="base_link"/>
<origin rpy="0 0 0" xyz="0 0 0"/>
</joint>
<!-- -->
<!-- base_link 的描述:设置惯性参数,重量mass是0.1公斤 inertia惯性矩阵的设置-->
<link name="base_link">
<inertial>
<origin xyz="0 0 0" rpy="0 0 0"/>
<mass value="0.1"/>
<inertia ixx="0.0001" ixy="0" ixz="0" iyy="0.0001" iyz="0" izz="0.001" />
</inertial>
// 机器人的外观设置
<visual>
<geometry>
// 长方体形状
<box size="0.25 0.16 0.05"/>
</geometry>
// 颜色设置
<origin rpy="0 0 0" xyz="0 0 0"/>
<material name="blue">
<color rgba="0 0 0.8 1"/>
</material>
</visual>
// 碰撞属性 设置的和视觉一致,在视觉中能看到的碰撞就会真实发生的碰撞,视觉上没有接触就没有碰撞发生
<collision>
<origin xyz="0 0 0" rpy="0 0 0"/>
<geometry>
<box size="0.25 0.16 0.05"/>
</geometry>
</collision>
</link>
// 上面的内容是机器人的本体
// 下面是轮子设置 同样设置 惯性,视觉 和 碰撞属性
<link name="right_wheel_link">
<inertial>
<origin xyz="0 0 0" rpy="0 0 0"/>
<mass value="0.1"/>
<inertia ixx="0.0001" ixy="0" ixz="0" iyy="0.0001" iyz="0" izz="0.0001" />
</inertial>
<visual>
<geometry>
// 轮子是圆的 所以设置为cylinder 圆柱
<cylinder length="0.02" radius="0.025"/>
</geometry>
<material name="black">
<color rgba="0 0 0 1"/>
</material>
</visual>
<collision>
<origin xyz="0 0 0" rpy="0 0 0"/>
<geometry>
<cylinder length="0.02" radius="0.025"/>
</geometry>
</collision>
</link>
// 接下来 把轮子 和 机器人本体连接起来 right_wheel_joint
<joint name="right_wheel_joint" type="continuous">
<axis xyz="0 0 -1"/>
// 父link
<parent link="base_link"/>
// 子link
<child link="right_wheel_link"/>
<origin rpy="1.5707 0 0" xyz=" 0.1 -0.09 -0.03"/>
</joint>
<link name="left_wheel_link">
<inertial>
<origin xyz="0 0 0" rpy="0 0 0"/>
<mass value="0.1"/>
<inertia ixx="0.0001" ixy="0" ixz="0" iyy="0.0001" iyz="0" izz="0.0001" />
</inertial>
<visual>
<geometry>
<cylinder length="0.02" radius="0.025"/>
</geometry>
<material name="black">
<color rgba="0 0 0 1"/>
</material>
</visual>
<collision>
<origin xyz="0 0 0" rpy="0 0 0"/>
<geometry>
<cylinder length="0.02" radius="0.025"/>
</geometry>
</collision>
</link>
// 接下来描述左轮,与右轮子一样的方式
<joint name="left_wheel_joint" type="continuous">
<axis xyz="0 0 -1"/>
<parent link="base_link"/>
<child link="left_wheel_link"/>
<origin rpy="1.5707 0 0" xyz="0.1 0.09 -0.03"/>
</joint>
// 最后加了一个万向轮 也连接到机器人本体上
<link name="ball_wheel_link">
<inertial>
<origin xyz="0 0 0" rpy="0 0 0"/>
<mass value="0.1"/>
<inertia ixx="0" ixy="0" ixz="0" iyy="0" iyz="0" izz="0" />
</inertial>
<visual>
<geometry>
<sphere radius="0.025"/>
</geometry>
<material name="black">
<color rgba="0 0 0 1"/>
</material>
</visual>
<collision>
<origin xyz="0 0 0" rpy="0 0 0"/>
<geometry>
<sphere radius="0.025"/>
</geometry>
</collision>
</link>
<joint name="ball_wheel_joint" type="fixed">
<axis xyz="0 0 1"/>
<parent link="base_link"/>
<child link="ball_wheel_link"/>
<origin rpy="0 0 0" xyz="-0.10 0 -0.03"/>
</joint>
</robot>
跳转到urdf文件所在的目录: roscd bingda_tutorials/urdf/
运行 :check_urdf mybot.urdf
这说明urdf文件准备好了。要 使用urdf 文件 通过 launch 文件启动加载。
在launch 目录下 有几个launch文件:
(1)display_robot.launch: 通过读取机器人的描述 在Rviz 中显示, 并且使用 joint_state_publisher 和 robot_state_publisher 来发布位姿变化 。
运行查看效果: roslaunch bingda_tutorials dispay_robot.launch
:::在Rviz中通过图形界面显示机器人模型:::
在这个界面中展示了在urdf中所描述的机器人模型,机器人的本体是蓝色的长方体盒子。左轮右轮是两个圆柱状的,尾部的万向轮是一个球形的。
上图 提供GUI的工具,用来快速的 让 机器人上的可动关节动起来:拖动蓝色条会有反应
如果要加载到Gazebo中 ,也是通过launch文件的方式。
(2) gazebo_robot.launch:
先通过include 引入一个 带环境模型的gazebo界面(根据上面的步骤自己创建的一个模型)。。接下来通过 spawn_model 节点 去生成刚刚创建的机器人模型(urdf 文件中创建的 )
启动运行一下:
roslaunch bingda_tutorials gazebo_robot.launch
d打开Gazebo 界面:
可以看到在环境中多了一个机器人,这个机器人目前是没法做仿真工作,并且在gazebo中也没有颜色,这是因为 在urdf 中描述的颜色材料在gazebo中是不生效的。在gazebo中指定外观需要gazebo的标签来添加。。
4、传感器和执行器安装
- xacro
xacro 是对 urdf 文件的补充。提高代码的可复用性。xacro 是用来简化代码的 不是非用不可,也可以都在urdf文件中进行操作。。
代码:mybot.xacro 完整的仿真代码
<?xml version="1.0"?>
// 不同之处 后面加了xacro的指向,指明这段代码使用xacro的规则来 解
<robot name="mybot" xmlns:xacro="http://ros.org/wiki/xacro">
// 引用了gazebo文件,单独写在一个文件里面,增加复用性。
<xacro:include filename="$(find bingda_tutorials)/urdf/mybot.gazebo.xacro" />
<link name="base_footprint"/>
<joint name="base_joint" type="fixed">
<parent link="base_footprint"/>
<child link="base_link"/>
<origin rpy="0 0 0" xyz="0 0 0"/>
</joint>
<link name="base_link">
<inertial>
<origin xyz="0 0 0" rpy="0 0 0"/>
<mass value="0.1"/>
<inertia ixx="0.0001" ixy="0" ixz="0" iyy="0.0001" iyz="0" izz="0.001" />
</inertial>
<visual>
<geometry>
<box size="0.25 0.16 0.05"/>
</geometry>
<origin rpy="0 0 0" xyz="0 0 0"/>
<material name="blue">
<color rgba="0 0 0.8 1"/>
</material>
</visual>
<collision>
<origin xyz="0 0 0" rpy="0 0 0"/>
<geometry>
<box size="0.25 0.16 0.05"/>
</geometry>
</collision>
</link>
<link name="right_wheel_link">
<inertial>
<origin xyz="0 0 0" rpy="0 0 0"/>
<mass value="0.1"/>
<inertia ixx="0.0001" ixy="0" ixz="0" iyy="0.0001" iyz="0" izz="0.0001" />
</inertial>
<visual>
<geometry>
<cylinder length="0.02" radius="0.025"/>
</geometry>
<material name="black">
<color rgba="0 0 0 1"/>
</material>
</visual>
<collision>
<origin xyz="0 0 0" rpy="0 0 0"/>
<geometry>
<cylinder length="0.02" radius="0.025"/>
</geometry>
</collision>
</link>
<joint name="right_wheel_joint" type="continuous">
<axis xyz="0 0 -1"/>
<parent link="base_link"/>
<child link="right_wheel_link"/>
<origin rpy="1.5707 0 0" xyz=" 0.1 -0.09 -0.03"/>
</joint>
<link name="left_wheel_link">
<inertial>
<origin xyz="0 0 0" rpy="0 0 0"/>
<mass value="0.1"/>
<inertia ixx="0.0001" ixy="0" ixz="0" iyy="0.0001" iyz="0" izz="0.0001" />
</inertial>
<visual>
<geometry>
<cylinder length="0.02" radius="0.025"/>
</geometry>
<material name="black">
<color rgba="0 0 0 1"/>
</material>
</visual>
<collision>
<origin xyz="0 0 0" rpy="0 0 0"/>
<geometry>
<cylinder length="0.02" radius="0.025"/>
</geometry>
</collision>
</link>
<joint name="left_wheel_joint" type="continuous">
<axis xyz="0 0 -1"/>
<parent link="base_link"/>
<child link="left_wheel_link"/>
<origin rpy="1.5707 0 0" xyz="0.1 0.09 -0.03"/>
</joint>
<link name="ball_wheel_link">
<inertial>
<origin xyz="0 0 0" rpy="0 0 0"/>
<mass value="0.1"/>
<inertia ixx="0" ixy="0" ixz="0" iyy="0" iyz="0" izz="0" />
</inertial>
<visual>
<geometry>
<sphere radius="0.025"/>
</geometry>
<material name="black">
<color rgba="0 0 0 1"/>
</material>
</visual>
<collision>
<origin xyz="0 0 0" rpy="0 0 0"/>
<geometry>
<sphere radius="0.025"/>
</geometry>
</collision>
</link>
<joint name="ball_wheel_joint" type="fixed">
<axis xyz="0 0 1"/>
<parent link="base_link"/>
<child link="ball_wheel_link"/>
<origin rpy="0 0 0" xyz="-0.10 0 -0.03"/>
</joint>
<!-- imu sensor -->
<link name="imu">
<visual>
<geometry>
<box size="0.01 0.01 0.01"/>
</geometry>
<material name="white">
<color rgba="1 1 1 1"/>
</material>
</visual>
</link>
// 添加IMU
<joint name="imu_joint" type="fixed">
<parent link="base_link"/>
<child link="imu"/>
<origin xyz="0.08 0 0.025"/>
</joint>
<!-- camera -->
<link name="base_camera_link">
<visual>
<geometry>
<box size="0.02 0.03 0.03"/>
</geometry>
<material name="white">
<color rgba="1 1 1 1"/>
</material>
</visual>
</link>
// 添加相机
<joint name="camera_joint" type="fixed">
<parent link="base_link"/>
<child link="base_camera_link"/>
<origin xyz="0.1 0 0.025"/>
</joint>
<!-- laser lidar -->
<link name="base_laser_link">
<visual>
<geometry>
<cylinder length="0.06" radius="0.04"/>
</geometry>
<material name="white">
<color rgba="1 1 1 1"/>
</material>
</visual>
</link>
//添加雷达
<joint name="laser_joint" type="fixed">
<parent link="base_link"/>
<child link="base_laser_link"/>
<origin xyz="0 0.0 0.06"/>
</joint>
</robot>
这段代码和 urdf 是高度类似的。装备传感器放在了mybot.gazebo.xacro文件里面。
mybot.xacro 和模型相关
mybot.gazebo.xacro 和仿真相关
现在的mybot.xacro 文件是一个完整的有机器人模型,有执行器和传感器 仿真,模型, 要启动的化也是要通过launch 文件的方式
launch文件: simulation.launch
这个launch文件 先启动 带环境模型的gazebo环境。 然后指定机器人描述的位置。spawn_model 来产生 机器人模型 加载在gazebo环境中。 最后robot_state_publisher 发布机器人内部的坐标变换信息。
启动:roslaunch bingda_tutorials simulation_robot.launch
可以看到机器人变化了。
新开一个终端 通过遥控的方式来控制机器人运动。
查看当前话题:rostopic list
/cmd_vel 话题是订阅的 , 查看订阅信息和发布信息:rostopic info /cmd_vel
打开一个image 界面,可以看到当前启动的 是有画面显示的
rqt_image_view
选择话题:/image_raw/compressed
再开一个终端启动键盘控制节点:: rosrun teleop_twist_keyboard teleop_twist_keyboard.py
按照上面的按键指示可操作机器人移动。。。
键盘控制:上i 下, 左j 右l 左前u 右前o 左后m 右后.
终端输入:
// 打开终端 打开bingda_tutorials/urdf文件夹
cd ../catkin_ws/src/bingda_tutorials/urdf
// 启动仿真器的launch文件, 显示gazebo 仿真环境
roslaunch bingda_tutorials simulation_robot.launch
// 打开一个终端,显示相机拍摄的画面, 在显示的画面左上方 选择话题
rqt_image_view
// 打开一个新的终端,启动键盘控制节点,通过遥控的方式控制机器人移动
// 根据按键提示,移动机器人,可以看到机器人会移动,且相机图像画面有变化
rosrun teleop_twist_keyboard teleop_twist_keyboard.py
// 打开一个新的终端,启动rviz ,选择基准坐标odom
rivz
/*打开之后add 添加TF , 添加RobotModel, 添加LaserScan (topic 选择scan, 将Size 调大一些,可以看见激光雷达也是有数据的,点云信息)*/
// 下面就打开键盘遥控的终端,通过键盘控制机器人移动 观察点云 图像变化
5、 使用Gazebo 来建图 和 导航
完成SLAM建图和导航的实验。。
先启动仿真器: roslaunch bingda_tutorials simulation_robot.launch
再启动 gmapping 算法(使用robot_navigation下的launch文件),,需要传入一个参数simulation:=true: roslaunch robot_navigation gmapping.launch simulation:=true
// 打开终端 启动仿真器
roslaunch bingda_tutorials simulation_robot.launch
// 打开新的终端 启动SLAM算法 gmapping
roslaunch robot_navigation gmapping.launch simulation:=true
// 打开新的终端 启动Rviz
roslaunch robot_navigation slam_rviz.launch
// 打开新的终端 启动键盘控制
rosrun teleop_twist_keyboard teleop_twist_keyboard.py
控制机器人移动一段距离之后就建成一张地图。。保存这张地图。。
cd ./catkin_ws/src/robot_navigation/maps
rosrun map_server map_saver -f map
此时地图已经保存,可以结束掉gmapping节点。