Chapter6 机器人系统仿真(Ⅱ)---环境仿真

目录

一、RVIZ中控制机器人的运动

1.1 arbotix简介

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

1.2.1 实现流程

1.2.2 具体实现 

二、URDF集成Gazebo

2.1 本章主要内容

2.2 URDF与Gazebo基本集成流程

2.2.1 URDF与Gazebo基本集成流程

2.2.2 URDF集成Gazebo相关设置

2.2.3 案例:URDF集成Gazebo实操 

2.2.4 Gazebo仿真环境搭建

2.3 URDF、Gazebo与Rviz的综合应用

2.3.1 本节概述

2.3.2 机器人运动控制以及里程计信息显示

 2.3.3 雷达信息仿真以及显示

2.3.4 摄像头仿真以及显示 

2.3.5 kinect深度相机仿真

2.3.6 kinect点云数据显示

2.4 本章小结


一、RVIZ中控制机器人的运动

1.1 arbotix简介

1.简介

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

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

1.2.1 实现流程

  1. 安装 Arbotix

  2. 创建新功能包,准备机器人 urdf、xacro 文件

  3. 添加 Arbotix 配置文件

  4. 编写 launch 文件配置 Arbotix

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

1.2.2 具体实现 

Ⅰ.安装Arbotix

在当前工作空间下下载相应控件

git clone -b indigo-devel https://github.com/vanadiumlabs/arbotix_ros.git
cd  ..
catkin_make

 这样就是安装好啦!

Ⅱ.创建新功能包,准备机器人 urdf、xacro 文件

Ⅲ.添加arbotix所需的配置文件 control.yaml

# 该文件是控制器配置,一个机器人模型可能有多个控制器,比如: 底盘、机械臂、夹持器(机械手)....
# 因此,根 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 
    }
}

Ⅳ.编写 launch 文件配置 Arbotix

<launch>

    <param name="robot_description" command="$(find xacro)/xacro $(find urdf_rviz)/urdf/xacro/car.urdf.xacro" />
    <node pkg="rviz" type="rviz" name="rviz" args="-d $(find urdf_rviz)/config/show_mycar.rviz" /> 

    <!-- 添加关节状态发布节点 -->
    <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" />
    <!--集成arbotix 控制结点,并且加载参数-->
    <node pkg = "arbotix_python" type = "arbotix_driver" name = "driver"  output = "screen" >
        <rosparam command = "load" file = "$(find urdf_rviz)/config/control.yaml" />
        <param name = "sim" value = "true"/>
</launch>

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

liuhongwei@liuhongwei-virtual-machine:~/demo05_ws$ rostopic pub -r 10 /cmd_vel geometry_msgs/Twist "linear:
  x: 1.0
  y: 0.0
  z: 0.0
angular:
  x: 0.0
  y: 0.0
  z: 1.0" 

 

二、URDF集成Gazebo

2.1 本章主要内容

URDF 需要集成进 Rviz 或 Gazebo 才能显示可视化的机器人模型,前面已经介绍了URDF 与 Rviz 的集成,本节主要介绍:

  • URDF 与 Gazebo 的基本集成流程;
  • 如果要在 Gazebo 中显示机器人模型,URDF 需要做的一些额外配置;
  • 关于Gazebo仿真环境的搭建。

2.2 URDF与Gazebo基本集成流程

2.2.1 URDF与Gazebo基本集成流程

1.主要步骤

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

  2. 编写 URDF 或 Xacro 文件

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

2.具体实现流程 

Ⅰ.创建功能包 urdf02_gazebo ,导入依赖 urdf xacro gazebo_ros gazebo_ros_control gazebo_plugins。

Ⅱ.gazebo集成需要urdf设置碰撞参数与惯性矩阵参数

①碰撞参数的设置:如果是标准几何体,直接复制visual的geometry和origin即可

②惯性矩阵

③gazebo有自己的颜色设置

<robot name="mycar">
    <link name="base_link">
        <visual>
            <geometry>
                <box size="0.5 0.2 0.1" />
            </geometry>
            <origin xyz="0.0 0.0 0.0" rpy="0.0 0.0 0.0" />
            <material name="yellow">
                <color rgba="0.5 0.3 0.0 1" />
            </material>
        </visual>
        <collision>
            <geometry>
                <box size="0.5 0.2 0.1" />
            </geometry>
            <origin xyz="0.0 0.0 0.0" rpy="0.0 0.0 0.0" />
        </collision>
        <inertial>
            <origin xyz="0 0 0" />
            <mass value="6" />
            <inertia ixx="1" ixy="0" ixz="0" iyy="1" iyz="0" izz="1" />
        </inertial>
    </link>
    <gazebo reference="base_link">
        <material>Gazebo/Black</material>
    </gazebo>

</robot>

Ⅲ.将urdf集成到launch文件中,并启动gazebo

<launch>

    <!-- 将 Urdf 文件的内容加载到参数服务器 -->
    <param name="robot_description" textfile="$(find urdf02_gazebo)/urdf/demo01_helloworld.urdf" />

    <!-- 启动 gazebo -->
    <include file="$(find gazebo_ros)/launch/empty_world.launch" />

    <!-- 在 gazebo 中显示机器人模型 -->
    <node pkg="gazebo_ros" type="spawn_model" name="model" args="-urdf -model mycar -param robot_description"  />
</launch>

2.2.2 URDF集成Gazebo相关设置

1.collision

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

2.inertial

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

 Ⅰ.球体惯性矩阵

<!-- 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>

Ⅱ.圆柱惯性矩阵

<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>

Ⅲ.立方体惯性矩阵

 <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>

2.2.3 案例:URDF集成Gazebo实操 

1.需求

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

2.实现流程

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

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

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

3.具体实现

Ⅰ.封装惯性矩阵算法的 xacro 文件:head.xacro

<robot name="base" xmlns:xacro="http://wiki.ros.org/xacro">
    <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>

    <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>

    <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>
</robot>

Ⅱ.框架搭建

①car.urdf 修改要包含惯性矩阵文件

<robot name = "mycar" xmlns:xacro="http://www.ros.org/wiki/xacro">
    <xacro:include filename = "head.xacro"/>
    <xacro:include filename = "demo05_carbase.urdf.xacro"/>
    <xacro:include filename = "demo06_carcamera.urdf.xacro"/>
    <xacro:include filename = "demo07_carlaser.urdf.xacro"/>
</robot>

②搭建launch文件

<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="model" args="-urdf -model mycar -param robot_description"  />
</launch>

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

① 修改 demo05_carbase.urdf.xacro

<robot name = "mycar" xmlns:xacro="http://www.ros.org/wiki/xacro">

    <xacro:property name = "footfrintradius" value = "0.001"/>
    <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 }" />

    <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 = "${wheel_radius - (base_length/2 +lidi)}" />

    <xacro:property name = "small_wheel_radius" value = "0.0075" />
    <xacro:property name = "small_joint_z" value = "${-(base_length/2+lidi-small_wheel_radius)}" />



    <link name="base_footprint">
        <visual>
            <geometry>
                <sphere radius="${footfrintradius}" />
            </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="yellow">
                <color rgba="0.8 0.3 0.1 0.5" />
            </material>
        </visual>
        <collision>
            <geometry>
                <cylinder radius="${base_radius}" length="${base_length}" />
            </geometry>
            <origin xyz="0 0 0" rpy="0 0 0" />
        </collision>
        <xacro:cylinder_inertial_matrix m = "2" r = "${base_radius}" h ="${base_length}"/>
    </link>
    <gazebo reference = "base_link">
        <material>Gazebo/Yellow</material>
    </gazebo>

    <joint name="base_link2base_footprint" type="fixed">
        <parent link="base_footprint" />
        <child link="base_link"/>
        <origin xyz="0 0 ${base_joint_z}" />
    </joint>

   
    <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="black">
                    <color rgba="0.0 0.0 0.0 1.0" />
                </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 = "0.05" 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"/>


    <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="black">
                    <color rgba="0.0 0.0 0.0 1.0" />
                </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 = "0.01" r = "${small_wheel_radius}"/>
        </link>
        <gazebo reference  = "${small_wheel_name}_wheel">
            <material>Gazebo/Red</material>
        </gazebo>

        <joint name="${small_wheel_name}2link" 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>

② 修改 demo06_carcamera.urdf.xacro

<robot name = "my_camera" xmlns:xacro="http://www.ros.org/wiki/xacro">
    <xacro:property name = "camera_x" value = "0.02" />
    <xacro:property name = "camera_y" value = "0.05" />
    <xacro:property name = "camera_z" value = "0.05" />
    <xacro:property name = "joint_camera_x" value = "0.08" />
    <xacro:property name = "joint_camera_y" value = "0" />
    <xacro:property name = "base_length" value = "0.08" />
    <xacro:property name = "joint_camera_z" value = "${camera_z /2 +base_length/2 }" />
    
    <link name="camera">
        <visual>
            <geometry>
                <box size="${camera_x} ${camera_y} ${camera_z}"/>
            </geometry>
            <material name = "no" >
                <color rgba = "3 3 3 0.3"/>
            </material>
        </visual>
        <collision>
            <geometry>
                <box size="${camera_x} ${camera_y} ${camera_z}"/>
            </geometry>
        </collision>
        <xacro:Box_inertial_matrix m = "0.01" l= "${camera_x}" w="${camera_y}" h="${camera_z}" />
    </link>
    <gazebo reference = "camera">
        <material>Gazebo/Blue</material>
    </gazebo>


    <joint name="camera2baselink" type="fixed">
        <origin xyz="${joint_camera_x} ${joint_camera_y} ${joint_camera_z}" rpy="0.0 0.0 0.0"/>
        <parent link="base_link"/>
        <child link="camera"/>
        <axis xyz="0.0 0.0 0.0"/>
    </joint>
</robot>

③ 修改 demo07_carlaser.urdf.xacro

<robot name = "mylaser" xmlns:xacro="http://www.ros.org/wiki/xacro">
    <xacro:property name = "support_radius" value = "0.01" />
    <xacro:property name = "support_length" value = "0.15" />
    <xacro:property name = "laser_radius" value = "0.03" />
    <xacro:property name = "laser_length" value = "0.05" />

    <xacro:property name = "joint_support_x" value = "0.00" />
    <xacro:property name = "joint_support_y" value = "0.00" />
    <xacro:property name = "joint_support_z" value = "${base_length / 2 +support_length / 2}" />
    <xacro:property name = "joint_laser_x" value = "0.00" />
    <xacro:property name = "joint_laser_y" value = "0.00" />
    <xacro:property name = "joint_laser_z" value = "${support_length/2 + laser_length/2}" />

    <link name="support">
        <visual>
            <origin xyz="0.0 0.0 0.0" rpy="0.0 0.0 0.0"/>
            <geometry>
                <cylinder radius = "${support_radius}" length = "${support_length}"/>
            </geometry>
            <material name="sha">
                <color rgba="0.8 0.5 0.0 0.5"/>
            </material>
        </visual>
        <collision>
            <geometry>
                <cylinder radius = "${support_radius}" length = "${support_length}"/>
            </geometry>
        </collision>
        <xacro:cylinder_inertial_matrix m = "0.1" r = "${support_radius}" h="${support_length}" />
    </link>
    <gazebo reference = "support">
        <material>Gazebo/Grey</material>
    </gazebo>

    <joint name="support2base" type="fixed">
        <parent link = "base_link"/>
        <child link = "support" />
        <origin xyz = "${joint_support_x} ${joint_support_y} ${joint_support_z}" rpy = "0 0 0" />
    </joint>

    <link name="laser">
        <visual>
            <origin xyz="0.0 0.0 0.0" rpy="0.0 0.0 0.0"/>
            <geometry>
                <cylinder radius = "${laser_radius}" length = "${laser_length}"/>
            </geometry>
            <material name="shav">
                <color rgba="0.0 0.0 0.0 0.5"/>
            </material>
        </visual>
        <collision>
            <geometry>
                <cylinder radius = "${laser_radius}" length = "${laser_length}"/>
            </geometry>
        </collision>
        <xacro:cylinder_inertial_matrix m = "0.15" 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}" rpy = "0 0 0" />
    </joint>
</robot>

2.2.4 Gazebo仿真环境搭建

1.如何导入外置world文件

新建立文件夹,导入world文件,修改launch文件

<launch>

    <!-- 将 Urdf 文件的内容加载到参数服务器 -->
    <param name="robot_description" command="$(find xacro)/xacro $(find urdf02_gazebo)/urdf/car.urdf.xacro" />

    <!-- 启动 gazebo name名称固定 value定位-->
    <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="model" args="-urdf -model mycar -param robot_description"  />
</launch>

执行

2.如何搭建仿真环境

到目前为止,我们已经可以将机器人模型显示在 Gazebo 之中了,但是当前默认情况下,在 Gazebo 中机器人模型是在 empty world 中,并没有类似于房间、家具、道路、树木... 之类的仿真物,如何在 Gazebo 中创建仿真环境呢?

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

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

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

具体步骤实现:添加内置组件创建仿真环境:开启gazebo

rosrun gazebo_ros gazebo

Ⅰ.画图

Ⅱ.保存 

 具体步骤实现:手动绘制仿真环境(更为灵活)

Ⅰ.

Ⅱ.开始绘画!! 电脑比较卡!!!

2.3 URDF、Gazebo与Rviz的综合应用

2.3.1 本节概述

关于URDF(Xacro)、Rviz 和 Gazebo 三者的关系,前面已有阐述: URDF 用于创建机器人模型、Rviz 可以显示机器人感知到的环境信息,Gazebo 用于仿真,可以模拟外界环境,以及机器人的一些传感器,如何在 Gazebo 中运行这些传感器,并显示这些传感器的数据(机器人的视角)呢?本节主要介绍的重点就是将三者结合:通过 Gazebo 模拟机器人的传感器,然后在 Rviz 中显示这些传感器感知到的数据。主要内容包括:

  • 运动控制以及里程计信息显示

  • 雷达信息仿真以及显示

  • 摄像头信息仿真以及显示

  • kinect 信息仿真以及显示

2.3.2 机器人运动控制以及里程计信息显示

1.需求

gazebo 中已经可以正常显示机器人模型了,那么如何像在 rviz 中一样控制机器人运动呢?在此,需要涉及到ros中的组件: ros_control。

2.ros_control简介

Ⅰ.场景:同一套 ROS 程序,如何部署在不同的机器人系统上,比如:开发阶段为了提高效率是在仿真平台上测试的,部署时又有不同的实体机器人平台,不同平台的实现是有差异的,如何保证 ROS 程序的可移植性?ROS 内置的解决方式是 ros_control。

Ⅱ.ros_control: 

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

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

3.运动控制实现流程(Gazebo)

  1. 已经创建完毕的机器人模型,编写一个单独的 xacro 文件,为机器人模型添加传动装置以及控制器

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

  3. 启动 Gazebo 并发布 /cmd_vel 消息控制机器人运动

4.实现

Ⅰ.框架搭建

新建 move.xacro 文件,将其集成进 car.urdf.xacro 文件中

<robot name = "mycar" xmlns:xacro="http://www.ros.org/wiki/xacro">
    <xacro:include filename = "head.xacro"/>
    <xacro:include filename = "demo05_carbase.urdf.xacro"/>
    <xacro:include filename = "demo06_carcamera.urdf.xacro"/>
    <xacro:include filename = "demo07_carlaser.urdf.xacro"/>
    <!--集成运动-->
    <xacro:include filename = "move.xacro"/>

</robot>

写launch文件

<launch>

    <!-- 将 Urdf 文件的内容加载到参数服务器 -->
    <param name="robot_description" command="$(find xacro)/xacro $(find urdf02_gazebo)/urdf/car.urdf.xacro" />

    <!-- 启动 gazebo name名称固定 value定位-->
    <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="model" args="-urdf -model mycar -param robot_description"  />
</launch>

Ⅱ.move.xacro的实现

<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>

Ⅲ.控制小车动起来

此时需要下载包:参考package 'teleop_twist_keyboard' not found 解决办法icon-default.png?t=M3C8https://blog.csdn.net/Zhouzi_heng/article/details/119463953

解决完毕后:键入命令行

rosrun teleop_twist_keyboard teleop_twist_keyboard.py

 这时可以控制小车运动

Ⅳ.Rviz查看里程计消息

①配置launch文件

<launch>

    <node pkg="rviz" type="rviz" name="rviz" args="-d $(find urdf_rviz)/config/show_mycar.rviz" /> 

    <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" />

</launch>

②执行它

先执行仿真环境

roslaunch urdf02_gazebo demo03_env.launch

再执行上述launch文件

liuhongwei@liuhongwei-virtual-machine:~$ cd demo05_ws/
liuhongwei@liuhongwei-virtual-machine:~/demo05_ws$ source ./devel/setup.bash
liuhongwei@liuhongwei-virtual-machine:~/demo05_ws$ roslaunch urdf02_gazebo demo04_sensor.launch 

修改里程计配置

 

 

 2.3.3 雷达信息仿真以及显示

1.实现流程

摄像头仿真基本流程:

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

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

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

2.具体实现

Ⅰ. 编写一个单独的 xacro 文件,为雷达模型添加摄像头配置(laser.xacro)

<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>
      <ray>
        <scan>
          <horizontal>
            <samples>360</samples>
            <resolution>1</resolution>
            <min_angle>-3</min_angle>
            <max_angle>3</max_angle>
          </horizontal>
        </scan>
        <range>
          <min>0.10</min>
          <max>30.0</max>
          <resolution>0.01</resolution>
        </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>

Ⅱ.将此文件集成进car.urdf.xacro文件

<robot name = "mycar" xmlns:xacro="http://www.ros.org/wiki/xacro">
    <xacro:include filename = "head.xacro"/>
    <xacro:include filename = "demo05_carbase.urdf.xacro"/>
    <xacro:include filename = "demo06_carcamera.urdf.xacro"/>
    <xacro:include filename = "demo07_carlaser.urdf.xacro"/>
    <!--集成运动-->
    <xacro:include filename = "move.xacro"/>
    <xacro:include filename = "laser.xacro"/>

</robot>

Ⅲ.执行

首先启动gazebo

roslaunch urdf02_gazebo demo03_env.launch

启动rviz

roslaunch urdf02_gazebo demo04_sensor.launch

2.3.4 摄像头仿真以及显示 

1.基本流程

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

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

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

2.实现步骤

Ⅰ. 编写一个单独的 xacro 文件,为机器人模型添加摄像头配置 camera.xacro

<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>

Ⅱ.将此文件集成进xacro文件

<robot name = "mycar" xmlns:xacro="http://www.ros.org/wiki/xacro">
    <xacro:include filename = "head.xacro"/>
    <xacro:include filename = "demo05_carbase.urdf.xacro"/>
    <xacro:include filename = "demo06_carcamera.urdf.xacro"/>
    <xacro:include filename = "demo07_carlaser.urdf.xacro"/>
    <!--集成运动-->
    <xacro:include filename = "move.xacro"/>
    <xacro:include filename = "laser.xacro"/>
    <xacro:include filename = "camera.xacro"/>

</robot>

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

 

2.3.5 kinect深度相机仿真

1.实现流程

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

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

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

2.具体步骤

 Ⅰ.编写一个单独的 xacro 文件,为机器人模型添加kinect摄像头配置

<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>

Ⅱ.将此文件集成进xacro文件

<robot name = "mycar" xmlns:xacro="http://www.ros.org/wiki/xacro">
    <xacro:include filename = "head.xacro"/>
    <xacro:include filename = "demo05_carbase.urdf.xacro"/>
    <xacro:include filename = "demo06_carcamera.urdf.xacro"/>
    <xacro:include filename = "demo07_carlaser.urdf.xacro"/>
    <!--集成运动-->
    <xacro:include filename = "move.xacro"/>
    <xacro:include filename = "laser.xacro"/>
    <xacro:include filename = "camera.xacro"/>
    <xacro:include filename = "kinect.xacro"/>
    

</robot>

Ⅲ.演示

2.3.6 kinect点云数据显示

1.实现

Ⅰ.在上节的rviz实现中添加组件点云

Ⅱ.设置topic为 /camera/depth/points

Ⅲ.如图所示

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

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

解决:

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

<frameName>support_depth</frameName>

2.发布新设置的坐标系到kinect连杆的坐标变换关系,在启动rviz的launch中,添加:

<node pkg="tf2_ros" type="static_transform_publisher" name="static_transform_publisher" args="0 0 0 -1.57 0 -1.57 /support /support_depth" />

3.重启rviz查看

2.4 本章小结

本章主要介绍了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。

 

  • 3
    点赞
  • 4
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 2
    评论
评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

APS2023

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值