ROS与gazebo联合仿真

 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入门(三):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节点。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值