ROS2探索总结(十一)—— ROS 2 gazebo仿真入门

11534
20
2019年1月8日 23时05分

~欢迎关注~
微信公众号:古月居
新浪微博:古月春旭
知乎专栏:古月居

 

gazebo是ROS中常用的三维物理仿真环境,在ROS 2中已经支持,这里我们就来小试牛刀。

前提条件

已经安装了ROS 2和gazebo 9(或者ROS melodic)

安装接口

$ sudo apt install ros-crystal-gazebo-ros-pkgs

一、gazebo例程跑起来

gazebo例程跑起来:

$ gazebo --verbose /opt/ros/crystal/share/gazebo_plugins/worlds/gazebo_ros_diff_drive_demo.world

终端中可以看到如下加载信息:

Screenshot from 2018-12-28 11-06-32

gazebo仿真环境很快就会打开:

Screenshot from 2018-12-28 10-53-40

想要看看系统有没有跑起来,关键是看话题有没有发布/订阅:

Screenshot from 2018-12-28 11-02-29

ROS2探索总结(十一)—— ROS 2 gazebo仿真入门插图(3)

可以看到,其中有一个cmd_demo的话题,相当于ROS 1中的cmd_vel,发布该话题就可以让gazebo中的小车模型动起来了:

$ ros2 topic pub /demo/cmd_demo geometry_msgs/Twist '{linear: {x: 1.0}}' -1

小车很快就会动起来:

ROS2探索总结(十一)—— ROS 2 gazebo仿真入门插图(4)

话题列表中还有一个odom_demo,可以实时反馈小车的里程计信息:

Screenshot from 2018-12-28 11-05-18

 

二、探究仿真背后的内容

gazebo仿真例程跑起来了,各种数据我们也都可以看到,回过头来,我们再看下运行以上例程的文件gazebo_ros_diff_drive_demo.world,该文件可以在以下路径中找到:

Screenshot from 2018-12-28 11-10-03

gazebo_ros_diff_drive_demo.world文件内容并不算多,主要是sdf模型文件的描述。

头部注释里是该例程的使用方法,大家也都可以试一下:

  Gazebo ROS differential drive plugin demo

  Try sending commands:

    ros2 topic pub /demo/cmd_demo geometry_msgs/Twist '{linear: {x: 1.0}}' -1

    ros2 topic pub /demo/cmd_demo geometry_msgs/Twist '{angular: {z: 0.1}}' -1

  Try listening to odometry:

    ros2 topic echo /demo/odom_demo

  Try listening to TF:

    ros2 run tf2_ros tf2_echo odom chassis

    ros2 run tf2_ros tf2_echo chassis right_wheel

    ros2 run tf2_ros tf2_echo chassis left_wheel

接下来是sdf模型相关的描述,除了ground和sun模型的调用外,重点是小车模型vehicle的描述,和URDF建模的语法差别不大:

  <world name="default">

    <include>
      <uri>model://ground_plane</uri>
    </include>

    <include>
      <uri>model://sun</uri>
    </include>

    <model name='vehicle'>
      <pose>0 0 0.325 0 -0 0</pose>

      <link name='chassis'>
        <pose>-0.151427 -0 0.175 0 -0 0</pose>
        <inertial>
          <mass>1.14395</mass>
          <inertia>
            <ixx>0.126164</ixx>
            <ixy>0</ixy>
            <ixz>0</ixz>
            <iyy>0.416519</iyy>
            <iyz>0</iyz>
            <izz>0.481014</izz>
          </inertia>
        </inertial>
        <visual name='visual'>
          <geometry>
            <box>
              <size>2.01142 1 0.568726</size>
            </box>
          </geometry>
        </visual>
        <collision name='collision'>
          <geometry>
            <box>
              <size>2.01142 1 0.568726</size>
            </box>
          </geometry>
        </collision>
      </link>

      <link name='left_wheel'>
        <pose>0.554283 0.625029 -0.025 -1.5707 0 0</pose>
        <inertial>
          <mass>2</mass>
          <inertia>
            <ixx>0.145833</ixx>
            <ixy>0</ixy>
            <ixz>0</ixz>
            <iyy>0.145833</iyy>
            <iyz>0</iyz>
            <izz>0.125</izz>
          </inertia>
        </inertial>
        <visual name='visual'>
          <geometry>
            <sphere>
              <radius>0.3</radius>
            </sphere>
          </geometry>
        </visual>
        <collision name='collision'>
          <geometry>
            <sphere>
              <radius>0.3</radius>
            </sphere>
          </geometry>
          <surface>
            <friction>
              <ode>
                <mu>1</mu>
                <mu2>1</mu2>
                <slip1>0</slip1>
                <slip2>0</slip2>
              </ode>
            </friction>
            <contact>
              <ode>
                <soft_cfm>0</soft_cfm>
                <soft_erp>0.2</soft_erp>
                <kp>1e+13</kp>
                <kd>1</kd>
                <max_vel>0.01</max_vel>
                <min_depth>0.01</min_depth>
              </ode>
            </contact>
          </surface>
        </collision>
      </link>

      <link name='right_wheel'>
        <pose>0.554282 -0.625029 -0.025 -1.5707 0 0</pose>
        <inertial>
          <mass>2</mass>
          <inertia>
            <ixx>0.145833</ixx>
            <ixy>0</ixy>
            <ixz>0</ixz>
            <iyy>0.145833</iyy>
            <iyz>0</iyz>
            <izz>0.125</izz>
          </inertia>
        </inertial>
        <visual name='visual'>
          <geometry>
            <sphere>
              <radius>0.3</radius>
            </sphere>
          </geometry>
        </visual>
        <collision name='collision'>
          <geometry>
            <sphere>
              <radius>0.3</radius>
            </sphere>
          </geometry>
          <surface>
            <friction>
              <ode>
                <mu>1</mu>
                <mu2>1</mu2>
                <slip1>0</slip1>
                <slip2>0</slip2>
              </ode>
            </friction>
            <contact>
              <ode>
                <soft_cfm>0</soft_cfm>
                <soft_erp>0.2</soft_erp>
                <kp>1e+13</kp>
                <kd>1</kd>
                <max_vel>0.01</max_vel>
                <min_depth>0.01</min_depth>
              </ode>
            </contact>
          </surface>
        </collision>
      </link>

      <link name='caster'>
        <pose>-0.957138 -0 -0.125 0 -0 0</pose>
        <inertial>
          <mass>1</mass>
          <inertia>
            <ixx>0.1</ixx>
            <ixy>0</ixy>
            <ixz>0</ixz>
            <iyy>0.1</iyy>
            <iyz>0</iyz>
            <izz>0.1</izz>
          </inertia>
        </inertial>
        <visual name='visual'>
          <geometry>
            <sphere>
              <radius>0.2</radius>
            </sphere>
          </geometry>
        </visual>
        <collision name='collision'>
          <geometry>
            <sphere>
              <radius>0.2</radius>
            </sphere>
          </geometry>
        </collision>
      </link>

      <joint name='left_wheel_joint' type='revolute'>
        <parent>chassis</parent>
        <child>left_wheel</child>
        <axis>
          <xyz>0 0 1</xyz>
          <limit>
            <lower>-1.79769e+308</lower>
            <upper>1.79769e+308</upper>
          </limit>
        </axis>
      </joint>

      <joint name='right_wheel_joint' type='revolute'>
        <parent>chassis</parent>
        <child>right_wheel</child>
        <axis>
          <xyz>0 0 1</xyz>
          <limit>
            <lower>-1.79769e+308</lower>
            <upper>1.79769e+308</upper>
          </limit>
        </axis>
      </joint>

      <joint name='caster_wheel' type='ball'>
        <parent>chassis</parent>
        <child>caster</child>
      </joint>

重点是最下边的差速控制器插件配置,其中的参数配置和ROS 1是一致的:

      <plugin name='diff_drive' filename='libgazebo_ros_diff_drive.so'>

        <ros>
          <namespace>/demo</namespace>
          <argument>cmd_vel:=cmd_demo</argument>
          <argument>odom:=odom_demo</argument>
        </ros>

        <!-- wheels -->
        <left_joint>left_wheel_joint</left_joint>
        <right_joint>right_wheel_joint</right_joint>

        <!-- kinematics -->
        <wheel_separation>1.25</wheel_separation>
        <wheel_diameter>0.6</wheel_diameter>

        <!-- limits -->
        <max_wheel_torque>20</max_wheel_torque>
        <max_wheel_acceleration>1.0</max_wheel_acceleration>

        <!-- output -->
        <publish_odom>true</publish_odom>
        <publish_odom_tf>true</publish_odom_tf>
        <publish_wheel_tf>true</publish_wheel_tf>

        <odometry_frame>odom_demo</odometry_frame>
        <robot_base_frame>chassis</robot_base_frame>

      </plugin>

三、更多仿真例程

在以上例程同样的路径下,还可以看到不少其他gazebo仿真例程,包含了多种传感器和常用功能:

Screenshot from 2018-12-28 11-10-03

这里仅以其中一个传感器的demo为例进行演示:

$ gazebo --verbose /opt/ros/crystal/share/gazebo_plugins/worlds/gazebo_ros_ray_sensor_demo.world

Screenshot from 2018-12-28 11-18-21

启动后可以看到如下gazebo界面:

Screenshot from 2018-12-28 11-17-46

ROS2探索总结(十一)—— ROS 2 gazebo仿真入门插图(3)

该仿真包含的传感器有:激光、点云、声纳。

Screenshot from 2018-12-28 11-18-41

在rviz中可以看到这些传感器的可视化效果:

Screenshot from 2018-12-28 11-16-59

 

更多内容欢迎关注:

微信公众号:古月居 (guyue_home)

新浪微博:古月春旭

知乎专栏:古月居 (https://zhuanlan.zhihu.com/guyuehome)

发表评论

后才能评论

评论列表(20条)

  • 安好 2020年4月29日 上午9:53

    胡老师 你好 最近在学习gazebo 想请教您两个问题 1、urdf文件里的惯性参数怎么设置?有没有什么方法可以计算,之前尝试用solidworks,但是导进去stl文件都分开了,我的能力组合不起来,请问有别的方法获得惯性参数么? 2、gazebo可以远程仿真么,我知道V-REP可以通过改变ip,实现在服务器上训练算法,笔记本上运行V-REP显示渲染的动画。请问gazebo有这种功能么?有的话怎么实现呢 万分感谢!

  • 蓝莲花已开 2019年8月14日 上午10:34

    [ERROR] [1565748764.993149722, 74.846000000]: Unable to identify any set of controllers that can actuate the specified joints: [ joint1 joint2 joint3 joint4 joint5 joint6 ]
    [ERROR] [1565748764.993170195, 74.846000000]: Known controllers and their joints:

    你好胡老师,我在用您的书《ROS机器人开发实践》,在第十章的最后,用MoveIt!控制Gazebo中的机械臂时,出现以上错误如何解决呢?困扰我好几天了,期待您的回复,万分感谢!

  • Pumpkin 2019年7月24日 上午10:40

    古月老师您好
    请问gazebo如何加载第三方的模型呢?

  • 梁同学 2019年6月5日 上午9:50

    CMake Error at /home/lenovo/catkin_ws/devel/share/hardware_interface/cmake/hardware_interfaceConfig.cmake:113 (message):
    Project ‘hardware_interface’ specifies
    ‘/home/lenovo/catkin_ws/src/ros_control/hardware_interface/include’ as an
    include dir, which is not found. It does neither exist as an absolute
    directory nor in ‘/home/lenovo/catkin_ws/src/ros_control/hardware_interface//home/lenovo/catkin_ws/src/ros_control/hardware_interface/include’.
    Check the issue tracker
    ‘https://github.com/ros-controls/ros_control/issues’ and consider creating
    a ticket if the problem has not been reported yet.
    Call Stack (most recent call first):
    /opt/ros/kinetic/share/controller_interface/cmake/controller_interfaceConfig.cmake:172 (find_package)
    /opt/ros/kinetic/share/catkin/cmake/catkinConfig.cmake:76 (find_package)
    my_controller/CMakeLists.txt:4 (find_package)
    — Configuring incomplete, errors occurred!
    See also “/home/lenovo/catkin_ws/build/CMakeFiles/CMakeOutput.log”.
    See also “/home/lenovo/catkin_ws/build/CMakeFiles/CMakeError.log”.
    Makefile:1956: recipe for target ‘cmake_check_build_system’ failed
    make: *** [cmake_check_build_system] Error 1
    Invoking “make cmake_check_build_system” failed

    古老师,这个错误找了好久,有的说要安装 sudo apt-get install ros-kinetic-ros-controller-manager,但是安装的时候显示无法定位软件包。您能帮忙解答一下吗?

    • 古月 回复 梁同学 2019年6月5日 上午11:28

      安装ros-control,ros-controllers、gazeo-ros-control功能包

    • 梁同学 回复 古月 2019年6月6日 上午9:08

      这三个都是 sudo apt install 过了这三个功能包,但是还是出现这个错误

  • 伍六七 2019年5月6日 上午11:05

    古老师,如果我要控制的输出量是电机的转矩,那么是不是不能使用速度控制?速度控制和位置控制的区别是啥?gazebo中有电机的转矩控制吗?

    • 古月 回复 伍六七 2019年5月8日 下午4:19

      需要用力控制器,输入信息和控制量不同

  • 何洋 2019年4月14日 下午2:05

    老师你好,我是ROS初学者,买了您的书,在看第六章的时候我有问题想请教一下您,我在运行Gazebo跑模型的时候发现,您原来德例程是没有问题的,如果我改变了模型,甚至是仅仅删除Plate_2_link,模型就无法使用键盘控制了,打开rqt文件,发现节点都在,但是都没有连起来,不知道是什么问题,请教一下

    • 古月 回复 何洋 2019年4月15日 下午6:25

      模型中link都是互相连接的,删掉后可能有影响,具体看下模型内容

  • 梁同学 2019年4月10日 上午10:05

    古老师,如果差速控制不用PID,使用自己的算法控制,是不是需要去修改ros_control
    的底层?

    • 古月 回复 梁同学 2019年4月10日 下午9:35

      ros_control里边提供了一些API接口,可以基于它的硬件抽象层上写一些算法,或者完全抛开ros_control自己实现也可以

    • 梁同学 回复 古月 2019年5月7日 上午9:40

      古老师,有没有什么推荐的文章之类的可以写您说的api的接口?现在在抽象层写一些算法还是比较难。

    • 古月 回复 梁同学 2019年5月8日 下午4:22

      参考ros_control wiki,在官方的github上有一个简单的教程

  • Trivas 2019年3月28日 下午4:08

    古月老师您好
    请问这篇博客里的两张gazebo截图,为什么第一张的地面是黑色的,而第二张是亮色的呢?.world文件里应该都已经加上sun了吧?

  • Leander 2019年1月10日 下午1:58

    老师您好,请问如何实现四轮后驱小车的前轮转向装置描述呀?谢谢老师。

    • 古月 回复 Leander 2019年1月11日 下午11:09

      可以参考ROS中类似模型的设计,看你什么类型的转向装置了,一般是用类似的关节模拟出来