最新消息:

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

ROS2/二代机器人系统 少儿编程 1900浏览 0评论
ROS2探索总结
本文转载自古月居,原作者古月,原文链接:https://www.guyuehome.com/2368。
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

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

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

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

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

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

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

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

小车很快就会动起来。

 

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

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

 

二、探究仿真背后的内容

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

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

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仿真例程,包含了多种传感器和常用功能:

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

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

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

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

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

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

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

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

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

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

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

 

 

更多内容欢迎关注:

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

新浪微博:古月春旭

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

您必须 登录 才能发表评论!