0基础在ROS系统中实现RRT算法(四)URDF集成gazebo并搭建gazebo仿真环境

2023-05-16

小白一枚,毕设突发奇想加入了ROS的内容,不知道自己还能不能毕业。以下均为通过看视频,翻博客等整理而成的笔记,并非我的原创。可能会出现一些报错的修改或者简单的代码是我自己做的。哈哈。

Gazebo是一款3D动态模拟器,用于显示机器人模型并创建仿真环境,能够在复杂的室内和室外环境中准确有效地模拟机器人。与游戏引擎提供高保真度的视觉模拟类似,Gazebo提供高保真度的物理模拟,其提供一整套传感器模型,以及对用户和程序非常友好的交互方式。

这篇主要学习:

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

如果 gazebo没有安装,请自行安装:

1.添加源:

sudo sh -c 'echo "deb http://packages.osrfoundation.org/gazebo/ubuntu-stable `lsb_release -cs` main" 
>
 /etc/apt/sources.list.d/gazebo-stable.list'
wget http://packages.osrfoundation.org/gazebo.key -O - | sudo apt-key add -

2.安装:

sudo apt update
sudo apt install gazebo11 
sudo apt install libgazebo11-dev

一、URDF与Gazebo基本集成流程与相关设置

URDF 与 Gazebo 集成流程与 Rviz 实现类似,主要步骤如下:

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

  2. 编写 URDF 或 Xacro 文件

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

接下来我们以创建盒状机器人显示在gazebo中为例,学习一下URDF集成gazebo。

1.创建功能包

在工作空间的src文件夹下打开终端进行以下操作,新建功能包urdf02_gazebo,并且导入依赖包: urdf、xacro、gazebo_ros、gazebo_ros_control、gazebo_plugins

catkin_create_pkg urdf02_gazebo urdf xacro gazebo_ros gazebo_ros_control gazebo_plugins

2.编写URDF文件

在urdf02_gazebo文件夹下新建urdf文件夹,在此文件夹下新建demo01_helloworld.urdf:

 接下来编写urdf文件,完整的文件内容:

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

接下来对上面的文件内容进行解释:

机器人的可视化部分visual:

盒装机器人,所以几何形状geometry选择为box,它在xyz上的尺寸分别是:0.5 ,0.2,0.1

颜色color为黄色,rgba为0.5 0.3 0,透明度为1

        <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:碰撞参数用于检测机器人是否与外界环境发生碰撞。

如果是标准几何体,直接复制visual的geometry和origin即可。

        <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用于设置重心偏移量,如果连杆质量均匀,设置为0 0 0。

mass质量设置为 6 kg

inertial是在不同维度上的坐标值,实际应用时要根据情况进行计算来防止机器人打滑和翻车等,在这里我们先随意设置。

    
        <inertial>
            <origin xyz="0 0 0" />
            <mass value="6" />
            <inertia ixx="1" ixy="0" ixz="0" iyy="1" iyz="0" izz="1" />
        </inertial>

gazebo自己的颜色设置:

    <gazebo reference="base_link">
        <material>Gazebo/Black</material>
    </gazebo>

3.启动Gazebo并显示模型

在/DEMO05_WS/src/urdf02_gazebo目录下新建launch文件夹,在launch文件夹下新建demo01_helloworld.launch

我们要:

  • 将 Urdf 文件的内容加载到参数服务器:调用param标签,name="robot_description",textfile定位到 urdf02_gazebo/urdf/helloworld.urdf
  • 启动 gazebo:gazebo已经内置了launch文件empty_world.launch,是一个空的世界环境,我们在这里包含这个launch文件。
  • 在 gazebo 中显示机器人模型:    在 Gazebo 中加载一个机器人模型,该功能由 gazebo_ros 下的 spawn_model 提供:
        -urdf 加载的是 urdf 文件
        -model car 模型名称是 car
        -param robot_description 从参数 robot_description 中载入模型

launch文件内容:

<launch>

    <param name="robot_description" textfile="$(find urdf02_gazebo)/urdf/helloworld.urdf" />

    <include file="$(find gazebo_ros)/launch/empty_world.launch" />

    <node pkg="gazebo_ros" type="spawn_model" name="model" args="-urdf -model mycar -param robot_description"  />
</launch>

运行一下launch文件:

milk@milk:~/DEMO05_WS$ roslaunch urdf02_gazebo demo01_helloworld.launch

可以看到gazebo中显示的盒装机器人

 (不知道为什么我第一次不显示机器人模型,等我放弃了关机之后,再开机启动launch文件就显示出来了……)

二、URDF集成Gazebo实操

需求描述:将之前的机器人模型(xacro版)显示在 gazebo 中

结果演示:

实现流程:

  1. 需要编写封装惯性矩阵算法的 xacro 文件:我们的车轮、雷达等都要涉及到惯性矩阵的计算。

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

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

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

在/DEMO05_WS/src/urdf02_gazebo/urdf目录下新建用于封装惯性矩阵算法的文件:head.xacro

这个比较复杂,在这里直接复制文件内容:

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

 接下来把之前编写过的小车底盘、雷达、摄像头、汇总文件的xacro文件复制过来:

 并且在car.urdf.xacro中包含惯性矩阵文件:<xacro:include filename="head.xacro" />

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

    <xacro:include filename="demo05_car_base.urdf.xacro" />
    <xacro:include filename="demo06_car_camera.urdf.xacro" />
    <xacro:include filename="demo07_car_laser.urdf.xacro" />
</robot>

编写launch文件:在/DEMO05_WS/src/urdf02_gazebo/launch目录下新建car.launch

<launch>

    <param name="robot_description" command="$(find xacro)/xacro $(find urdf02_gazebo)/urdf/car.urdf.xacro "/>


    <include file="$(find gazebo_ros)/launch/empty_world.launch" />

    <node pkg="gazebo_ros" type="spawn_model" name="model" args="-urdf -model mycar -param robot_description"  />
</launch>

2.复制相关 xacro 文件,并设置 collision inertial 以及 color 等参数

在demo05_car_base.urdf.xacro中

设置底盘相关参数:

连杆:找到连杆相关代码

    <link name="base_link">
      <visual>
        <geometry>
          <cylinder radius="${base_link_radius}" length="${base_link_length}" />
        </geometry>
        <origin xyz="0 0 0" rpy="0 0 0" />
        <material name="yellow">
          <color rgba="0.5 0.3 0.0 0.5" />
        </material>
      </visual>
    </link>

添加collision:只要是规则的立方体,collision都和visual中的geometry和origin一样,直接复制。

添加interial:我们前面已经把interial封装成专门的宏。打开head.xacro,由于底盘是圆柱体,我们找到圆柱体的interial宏:cylinder_inertial_matrix

添加颜色

修改完成后的小车主体部分代码如下:


    <link name="base_link">
      <visual>
        <geometry>
          <cylinder radius="${base_link_radius}" length="${base_link_length}" />
        </geometry>
        <origin xyz="0 0 0" rpy="0 0 0" />
        <material name="yellow">
          <color rgba="0.5 0.3 0.0 0.5" />
        </material>
      </visual>

      <collision>
        <geometry>
          <cylinder radius="${base_link_radius}" length="${base_link_length}" />
        </geometry>
        <origin xyz="0 0 0" rpy="0 0 0" />
      </collision>
  
      <xacro:cylinder_inertial_matrix   m= "${base_link_mass}"  r= "${base_link_radius}"  h = "${base_link_length}"   />
    </link>
    
    <gazebo reference = "base_link">
      <material>Gazebo/Yellow</material>
    </gazebo>

保存之后,执行一下代码看一下gazebo中的机器人模型:

milk@milk:~/DEMO05_WS$ source ./devel/setup.bash
milk@milk:~/DEMO05_WS$ roslaunch urdf02_gazebo demo02_car.launch

 驱动轮:

   <!-- qudonglun -->
    <xacro:property name="wheel_radius" value="0.0325" />
    <xacro:property name="wheel_length" value="0.015" />
    <xacro:property name="wheel_mass" value="0.05" />
    <xacro:macro name="add_wheels" params="name flag">
      <link name="${name}_wheel">
        <visual>
          <geometry>
            <cylinder radius="${wheel_radius}" length="${wheel_length}" />
          </geometry>
          <origin xyz="0.0 0.0 0.0" rpy="${PI / 2} 0.0 0.0" />
          <material name="black" />
        </visual>
        <collosion>
            <geometry>
            <cylinder radius="${wheel_radius}" length="${wheel_length}" />
          </geometry>
          <origin xyz="0.0 0.0 0.0" rpy="${PI / 2} 0.0 0.0" />      
        </collosion>
         <xacro:cylinder_inertial_matrix   m= "${wheel_mass}"  r= "${wheel_radius}"  h = "${wheel_length}"   />
      </link>
      <gazebo reference = "${name}_wheel">
        <material>Gazebo/Red</material>
      </gazebo>

支撑轮

      <link name="${name}_wheel">
        <visual>
            <geometry>
                <sphere radius="${support_wheel_radius}" />
            </geometry>
            <origin xyz="0 0 0" rpy="0 0 0" />
            <material name="black" />
        </visual>

        <collision>
        <geometry>
                <sphere radius="${support_wheel_radius}" />
            </geometry>
            <origin xyz="0 0 0" rpy="0 0 0" />
        </collision>
        
        <xacro:sphere_inertial_matrix   m = "${support_wheel_mass}"    r = "${support_wheel_radius}"  />
      </link>

      <gazebo reference="${name}_wheel">
        <material>Gazebo/Black</material>
      </gazebo>

demo05_car_base.urdf.xacro整体代码:

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

    <xacro:property name="PI" value="3.1415926"/>

    <material name="black">
        <color rgba="0.0 0.0 0.0 1.0" />
    </material>

    <xacro:property name="base_footprint_radius" value="0.001" /> <!-- base_footprint  -->
    <xacro:property name="base_link_radius" value="0.1" /> <!-- base_link  -->
    <xacro:property name="base_link_length" value="0.08" /> <!-- base_link  -->
        <xacro:property name="base_link_mass" value="2" /> <!-- base_link  -->
    <xacro:property name="earth_space" value="0.015" /> <!-- lidijianju -->

    <!-- dipan -->
    <link name="base_footprint">
      <visual>
        <geometry>
          <sphere radius="${base_footprint_radius}" />
        </geometry>
      </visual>
    </link>

    <link name="base_link">
      <visual>
        <geometry>
          <cylinder radius="${base_link_radius}" length="${base_link_length}" />
        </geometry>
        <origin xyz="0 0 0" rpy="0 0 0" />
        <material name="yellow">
          <color rgba="0.5 0.3 0.0 0.5" />
        </material>
      </visual>

      <collision>
        <geometry>
          <cylinder radius="${base_link_radius}" length="${base_link_length}" />
        </geometry>
        <origin xyz="0 0 0" rpy="0 0 0" />
      </collision>
  
      <xacro:cylinder_inertial_matrix   m= "${base_link_mass}"  r= "${base_link_radius}"  h = "${base_link_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 ${earth_space + base_link_length / 2 }" />
    </joint>

    <!-- qudonglun -->
    <xacro:property name="wheel_radius" value="0.0325" />
    <xacro:property name="wheel_length" value="0.015" />
    <xacro:property name="wheel_mass" value="0.05" />
    <xacro:macro name="add_wheels" params="name flag">
      <link name="${name}_wheel">
        <visual>
          <geometry>
            <cylinder radius="${wheel_radius}" length="${wheel_length}" />
          </geometry>
          <origin xyz="0.0 0.0 0.0" rpy="${PI / 2} 0.0 0.0" />
          <material name="black" />
        </visual>
        <collosion>
            <geometry>
            <cylinder radius="${wheel_radius}" length="${wheel_length}" />
          </geometry>
          <origin xyz="0.0 0.0 0.0" rpy="${PI / 2} 0.0 0.0" />      
        </collosion>
         <xacro:cylinder_inertial_matrix   m= "${wheel_mass}"  r= "${wheel_radius}"  h = "${wheel_length}"   />
      </link>
      <gazebo reference = "${name}_wheel">
        <material>Gazebo/Red</material>
      </gazebo>

      <joint name="${name}_wheel2base_link" type="continuous">
        <parent link="base_link" />
        <child link="${name}_wheel" />
        <origin xyz="0 ${flag * base_link_radius} ${-(earth_space + base_link_length / 2 - wheel_radius) }" />
        <axis xyz="0 1 0" />
      </joint>
    </xacro:macro>
    <xacro:add_wheels name="left" flag="1" />
    <xacro:add_wheels name="right" flag="-1" />
    <!-- zhichenglun -->
    <xacro:property name="support_wheel_radius" value="0.0075" />
    <xacro:property name="support_wheel_mass" value="0.0100" />
    <xacro:macro name="add_support_wheel" params="name flag" >
      <link name="${name}_wheel">
        <visual>
            <geometry>
                <sphere radius="${support_wheel_radius}" />
            </geometry>
            <origin xyz="0 0 0" rpy="0 0 0" />
            <material name="black" />
        </visual>

        <collision>
        <geometry>
                <sphere radius="${support_wheel_radius}" />
            </geometry>
            <origin xyz="0 0 0" rpy="0 0 0" />
        </collision>
        
        <xacro:sphere_inertial_matrix   m = "${support_wheel_mass}"    r = "${support_wheel_radius}"  />
      </link>

      <gazebo reference="${name}_wheel">
        <material>Gazebo/Black</material>
      </gazebo>

      <joint name="${name}_wheel2base_link" type="continuous">
          <parent link="base_link" />
          <child link="${name}_wheel" />
          <origin xyz="${flag * (base_link_radius - support_wheel_radius)} 0 ${-(base_link_length / 2 + earth_space / 2)}" />
          <axis xyz="1 1 1" />
      </joint>
    </xacro:macro>

    <xacro:add_support_wheel name="front" flag="1" />
    <xacro:add_support_wheel name="back" flag="-1" />

</robot>

 gazebo:

 设置摄像头相关参数:demo06_car_camera.urdf.xacro

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

<xacro:property  name = "camera_length"   value =  "0.02" /> 
<xacro:property  name = "camera_width"   value =  "0.05" /> 
<xacro:property  name = "camera_height"   value =  "0.05" /> 
<xacro:property  name = "camera_mass"   value =  "0.01" /> 
<xacro:property  name = "joint_camera_x"   value =  "0.08" />
<xacro:property  name = "joint_camera_y"   value =  "0" />
<xacro:property  name = "joint_camera_z"   value =  "${base_link_length / 2 + camera_height  / 2}" />
    <link   name = "camera">
            <visual>
                    <geometry>
                             <box  size = "${camera_length}  ${ camera_width}  ${camera_height}"  />
                    </geometry>

                    <material    name = "black ">
                                <color  rgba = "0  0  0  0.8"  />
                    </material>
            </visual>
            <collision>
                <geometry>
                             <box  size = "${camera_length}  ${ camera_width}  ${camera_height}"  />
                    </geometry>
            </collision>
            <xacro:Box_inertial_matrix m = "${camera_mass}" l = "${camera_length}"  w = "${camera_width}"  h = "${camera_height}" />
    </link>
    <gazebo reference = "camera">
                <material>Gazebo/Blue</material>
    </gazebo>

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

设置雷达相关参数:demo07_car_laser.urdf.xacro

<robot name="mycar" xmlns:xacro="http://wiki.ros.org/xacro">
	<xacro:property name = "support_radius"  value = "0.01"  />
	<xacro:property name = "support_length"  value = "0.15"  />
		<xacro:property name = "support_mass"  value = "0.1"  />
	<xacro:property name = "laser_radius"  value = "0.03"  />
	<xacro:property name = "laser_length"  value = "0.05"  />
		<xacro:property name = "laser_mass"  value = "0.02"  />

	<xacro:property name = "joint_support_x"  value = "0"  />
	<xacro:property name = "joint_support_y"  value = "0"  />
	<xacro:property name = "joint_support_z"  value = "${base_link_length / 2 +support_length / 2}"  />

	<xacro:property name = "joint_laser_x"  value = "0"  />
	<xacro:property name = "joint_laser_y"  value = "0"  />
	<xacro:property name = "joint_laser_z"  value = "${support_length / 2 + laser_length / 2}"  />

	<link name ="support">
		<visual>
			<geometry>
				<cylinder  radius = "${support_radius}"	length = "${support_length}"/>
			</geometry>
			<material name = "yellow">
				<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 = "${support_mass}"  r ="${support_radius}"	 h = "${support_length}"	/>
	</link>

    <gazebo reference = "support">
                <material>Gazebo/Gray</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>
			<geometry>
				<cylinder  radius = "${laser_radius}"	length = "${laser_length}"/>
			</geometry>
			<material name = "black">
				<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="${laser_mass}" 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>

gazebo:

三、Gazebo仿真环境搭建

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

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

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

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

也还可以直接下载使用官方或第三方提高的仿真环境插件。

1.创建仿真环境

首先打开新终端,启动roscore

$roscore

然后启动gazebo

$rosrun gazebo_ros gazebo

 点击上边栏的立方体添加

 2.自定义仿真环境

启动 gazebo ,打开构建面板,绘制仿真环境

 

保存构建的环境

点击: 左上角 file ---> Save (保存路径功能包下的: models)

然后 file ---> Exit Building Editor

 保存为 world 文件

可以像方式1一样再添加一些插件,然后保存为 world 文件(保存路径功能包下的: worlds)

3.使用官方提供的插件

 还可以下载官方提供的插件,下载地址:

https://github.com/osrf/gazebo_models

解压后的文件中有大量的模型:

 这些模型占用空间太大了,我下载后只留下了几个自己需要的模型。

四、启动gazebo并控制机器人运动

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

1.1 为 joint 添加传动装置以及控制器

两轮差速配置

<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="left_wheel2base_link" />
    <xacro:joint_trans joint_name="right_wheel2base_link" />

    <!-- 控制器 -->
    <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>left_wheel2base_link</leftJoint> <!-- 左轮 -->
            <rightJoint>right_wheel2base_link</rightJoint> <!-- 右轮 -->
            <wheelSeparation>${base_link_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>

1.2 xacro文件集成

最后还需要将上述 xacro 文件集成进总的机器人模型文件,代码示例如下:

<!-- 组合小车底盘与摄像头 -->
<robot name="my_car_camera" xmlns:xacro="http://wiki.ros.org/xacro">
    <xacro:include filename="my_head.urdf.xacro" />
    <xacro:include filename="my_base.urdf.xacro" />
    <xacro:include filename="my_camera.urdf.xacro" />
    <xacro:include filename="my_laser.urdf.xacro" />
    <xacro:include filename="move.urdf.xacro" />
</robot>

2.编写launch文件:demo03_env.launch

<launch>
    <!--1.需要在参数服务器中载入 urdf -->
    <param name="robot_description" command="$(find xacro)/xacro $(find urdf02_gazebo)/urdf/car.urdf.xacro" />
    <!--2.启动 Gazebo 仿真环境 -->
    <include file="$(find gazebo_ros)/launch/empty_world.launch" >
        <arg name="world_name" value="$(find urdf02_gazebo)/worlds/my_world/model.world" />
    </include>
    <!--3.在 Gazebo 中添加机器人模型 -->
    <node pkg="gazebo_ros" type="spawn_model" name="spawn_model" args="-urdf -model car -param robot_description" />
</launch>

3.启动 launch 文件

$ source ./devel/setup.bash
$ roslaunch urdf02_gazebo demo03_env.launch

使用 topic list 查看话题列表:

$ rostopic list

会发现多了 /cmd_vel 然后发布 vmd_vel 消息控制即可

使用命令控制(或者可以编写单独的节点控制)

rostopic pub -r 10 /cmd_vel geometry_msgs/Twist '{linear: {x: 0.2, y: 0, z: 0}, angular: {x: 0, y: 0, z: 0.5}}'

 机器人开始做圆周运动。

五、rviz查看里程计信息

1.启动 Rviz

launch文件:demo04_sensor.launch

<launch>
    <!-- 启动 rviz -->
    <node pkg="rviz" type="rviz" name="rviz" />

    <!-- 关节以及机器人状态发布节点 -->
    <node name="joint_state_publisher" pkg="joint_state_publisher" type="joint_state_publisher" />
    <node name="robot_state_publisher" pkg="robot_state_publisher" type="robot_state_publisher" />

</launch>

$ roslaunch urdf02_gazebo demo04_sensor.launch

 2.添加组件

添加robotmodel和odometry组件

 

本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

0基础在ROS系统中实现RRT算法(四)URDF集成gazebo并搭建gazebo仿真环境 的相关文章

  • 无刷无霍尔BLCD电机控制

    声明 xff1a 本文出自百度文库无刷无霍尔电机控制 xff0c 因为该文为繁体 xff0c 看起来特别别扭 xff0c 特此翻译 文库网址 xff1a https wenku baidu com view b99217dca0116c17
  • stl的中常用几个容器的介绍与特点。

    lt 1 gt vector容器 vector容器是一个动态数组的结构 xff0c 在内存中有一个指针指向一块连续的内存 类似数组结构一样 它的特点支持随机访问数据 xff0c 因为其在内存中的单元是连续 如此之外 xff0c 还可以vec
  • 关闭优化选项

    这里没有调用拷贝构造函数 xff0c 按照C 43 43 机制 xff0c 应该是会调用的 想起来 xff0c 以前最初写拷贝构造函数的时候也是跟预想的调用不一致 记得编译器会自动优化掉临时对象的 比如 在一个函数中 return list
  • WIFI学习一(socket介绍)

    一 什么是socket socket译为 插座 xff0c 在计算机通信领域 xff0c socket被翻译为 套接字 xff0c 它是计算机之间进行通信的一种约定或一种方式 通过这种方式 xff0c 一台计算机可以接受其他计算机的数据 x
  • 两台电脑实现串口通信

    本文主要介绍串口传输文件的练习 将两台笔记本电脑 xff0c 借助 usb转rs232 模块和杜邦线 xff0c 建立起串口连接 然后用串口助手等工具软件 xff08 带文件传输功能 xff09 将一台笔记本上的一个大文件 xff08 图片
  • VScode前进和后退按钮,非快捷键

    在网上找了半天 xff0c 不喜欢用快捷键 xff0c 喜欢鼠标点击 xff0c 费了好长时间发现这个插件 Back amp Forth xff0c 安装后可以在右上角出现前进和后退按钮 xff0c 如下图
  • Nonce验证

    验证可能会涉及 span class token keyword def span span class token function getNonce span span class token punctuation span span
  • DJI飞行器 精准降落功能测试

    概述 xff1a 该功能仅在自动返航至起飞点 Auto RTL 时生效 xff0c 飞行器降落环境需要足够的照明和没有障碍物的区域 使用该功能后 xff0c 飞行器将使用底部的两个视觉传感器记录起飞时的地形纹理信息 xff0c 并根据记录的
  • 带学生参加电赛,5个国一,2个国二!15个省奖!

    大家好 xff0c 我是张巧龙 xff0c 转眼21年的各省电赛就结束了 xff0c 今年的电赛确实让人难忘 xff0c 不管是题目还是比赛形式 xff0c 亦或是比赛时间一拖再拖 国赛结果也在前段时间公示了 xff0c 参与人数再次增长
  • 【JAVA基础篇】内部类

    定义在一个类内部的类称为内部类 内部类访问权限可以是public protected default或private xff0c 可以声明为abstract供其他内部类或外部类继承 xff0c 可以声明为static final xff0c
  • CURL 是什么

    cURL是一个利用URL语法在命令行下工作的文件传输工具 xff0c 1997年首次发行 它支持文件上传和下载 xff0c 所以是综合传输工具 xff0c 但按传统 xff0c 习惯称cURL为下载工具 cURL还包含了用于程序开发的lib
  • STM32F103C8T6 gps串口数据处理

    基于stm32f10x系列单片机demo程序修改 配置串口 void USART1 Config void GPIO InitTypeDef GPIO InitStructure USART InitTypeDef USART InitSt
  • RS-485总线布线规则及方法

    摘要 xff1a 本文阐述了RS 485双向串行总线的特点 RS 485总线在实际应用中的布线规则 拓扑结构和匹配电阻的连接方法 可供有关技术人员在RS 485总线设计和施工时做参考 关键词 xff1a RS 485 总线 规则 方法 前言
  • jetson nano 基础设置

    关闭图像界面 span class token function sudo span systemctl set default multi user target 开启图像界面 span class token function sudo
  • Android JNI Java/C++互相调用

    一 xff0c Java 调用 C 1 xff0c 首先我们创建一个文件名字叫做 xff0c JNI 其实你不创建也行 看自己 public class JNI 加载本地C语言文件库 库名字为你写的C语言文件名 static System
  • STM32串口空闲中断,中断标志位无法清除

    本节目录 今天想使用STM32的串口空闲中断作接收 xff0c 调了1个小时 xff0c 发现串口空闲中断无法被清除 xff0c 网上搜索半天发现 xff0c 能用清除的库函数清除该中断 我又回头看了一下手册 果真如此 xff0c 问题已解
  • CMake系列(八) CMake 多级目录

    CMake系列 xff08 八 xff09 CMake 多级目录 文章目录 CMake系列 xff08 八 xff09 CMake 多级目录目录结构结构说明调用关系 源文件CMakeLists txt最外层CMakeListsmain的CM
  • 【全国一等奖】F题:智能送药小车,2021年全国大学生电子设竞赛

    01 前 言 大家好 xff0c 我是张巧龙 xff0c 今天给大家带来关于21年F题的分享 xff1a 智能送药小车 xff0c 出了这个题目之后 xff0c 咋一看 xff0c 好像比较简单 不过大家慢慢做 xff0c 越往后做越发现
  • ZYNQ系列(十二)linux的DMA使用

    ZYNQ系列 xff08 十二 xff09 linux的DMA使用 文章目录 ZYNQ系列 xff08 十二 xff09 linux的DMA使用前言开发环境准备工作petalinux工程建立建立工程配置内核1 配置DMA2 配置CMA 修改
  • gtest学习笔记(四)gtest自带的sample3---Test Fixture减少测试冗余

    文章目录 前言源码学习utest语法运行 前言 第一章中已经编译出自带的sample例子 xff0c 在build googletest目录下可以看到sample的各种例子的可执行程序 Google Test 附带了10个单元测试用例 xf

随机推荐

  • VSCODE 系列(六)使用Plantuml插件制作UML类图

    文章目录 前言下载和安装支持文件格式支持绘制类型导出 语法申报要素UML类图关系参考例子参考 前言 软件设计中 xff0c 有好几种图需要画 xff0c 比如流程图 类图 组件图等 xff0c 我知道大部分人画流程图一般都会用微软的visi
  • MDK配色方案更改

    文章目录 WIN10更改护眼背景MDK软件配色方案更改 设置常用关键字参考 WIN10更改护眼背景 按windows 43 R快捷键 xff0c xff0c 打开运行 xff0c 在弹出来的输入框中写上regedit xff0c 点确定或回
  • VSCODE 系列(七)格式化工具clang-format

    文章目录 一 VS Code中使用生成 clang format文件VS Code设置 参考 一 VS Code中使用 VS Code 中自带clang format exe 生成 clang format文件 使用命令 span clas
  • MDK的格式化代码工具及添加快捷方式

    文章目录 Astyle介绍插件安装参数设置格式化整个工程参数说明快捷键设置参考 Astyle介绍 Astyle 即Artistic Style xff0c 是一个可用于C C 43 43 C 43 43 CLI Objective C C
  • cURL命令详解

    cURL是什么 cURL是用于数据传输的命令行工具 xff0c 支持多种传输协议 xff0c 包括HTTP HTTPS SCP FTP SFTP TELNET FILE SMTP POP3等等 可以使用cURL进行HTTP HTTPS请求
  • 关于单片机栈空间的总结

    1 如果定义成全局数组 xff0c 则此数组就会自动初始化为0 但如果定义成局部数组 xff0c 则必须要先初始化 2 局部变量一定要初始化 局部变量初始化 是指在使用这个局部变量前 xff0c 要对其进行初始化 这是因为局部变量是从内存堆
  • rplidar使用

    rplidar的使用 新上手的激光雷达 xff0c 第一次使用 根据网上的教程 xff0c 先搭建环境跑起来 安装rviz sudo apt get install ros kinetic rviz 通过apt get安装rviz xff0
  • 全国一等奖,H题:用电器分析识别装置

    大家好 xff0c 我是张巧龙 xff0c 今天继续给大家带来电赛题目 xff1a 用电器分析识别装置 01 视频展示 全国一等奖 21年电赛H题 xff1a 用电器分析识别装置 02 方案设计 2 1 系统总体方案 通过对赛题的仔细分析研
  • jetson-tx2-nx用户空间无法导出gpio

    1 想要导出gpio xff0c 结果如下 xff0c 导出失败 xff0c 显示gpio忙 2 查看占用状态 xff0c 发现这个脚被用成了其他功能 3 如果没有第二步的那个目录 xff0c 则执行以下语句 xff0c mount t d
  • cmake添加已编译的.a静态库

    在main下新建一个lib文件夹 将编译好的xxx a放入lib文件夹 打开main下的CMakeLists txt 添加下面两条代码 add prebuilt library prebuilt 34 lib xxx a 34 libm t
  • Android设备上直接运行C/C++程序,无需ROOT!!!

    在Android开发过程中难免和JNI NDK打交道做混合开发 xff0c 按一般方式当交叉编译完成得到so库后 xff0c 我们将so库集成到Android项目里 xff0c 打包成apk安装到手机上验证运行效果 但当我们想快速在手机上验
  • ecplice在导入现有工程时提示:某些项目因位于工作空间目录中而被隐藏

    无论是写java还是Android xff0c ecplice都是很不错的选择 xff0c 但是有时在导入工程时提示 xff1a 某些项目因位于工作空间目录中而被隐藏 xff0c 项目 和 下一步 为不可选 此类原因无非有二 xff08 1
  • CAN扩展帧过滤器设置

    纪要 CAN xff08 Controller Area Network xff09 总线是一种广泛应用于工业控制和汽车电子领域的串行通信协议 在CAN总线中 xff0c 节点间通过CAN总线发送和接收消息 每个CAN帧包含一个标准或扩展标
  • error while loading shared libraries: libQtGui.so.4: cannot open shared object file:

    qt4编写的界面在mini6410上运行失败 xff0c 总是提示错误 xff1a error while loading shared libraries libQtGui so 4 cannot open shared object f
  • 第十一课:树莓派L298N电机实验

    第一课 什么是树莓派 第二课 基于树莓派的10个经典项目 第三课 购买您的第一个树莓派 第四课 如何安装树莓派系统 第五课 树莓派C语言编程手册 第六课 树莓派led控制 第七课 树莓派按键控制 第八课 树莓派PWM 脉宽调制
  • 从旋转矩阵计算欧拉角

    旋转矩阵和欧拉角之间的正向转换关系比较好推理 xff0c 而逆向变换就显得不是那么容易了 这篇博客介绍由旋转矩阵计算欧拉角的方法 xff0c 参考了一篇Paper xff1a Computing Euler angles from a ro
  • aiohttp 异步http请求-1.快速入门 get 请求示例

    前言 在 python 的众多 http 请求库中 xff0c 大家最熟悉的就是 requests 库了 xff0c requests 库上手非常容易 xff0c 适合入门学习 如果平常工作中对发请求不追求效率和并发的情况下 xff0c r
  • Flask 学习-67.钩子函数before_request 和 before_first_request 的使用

    前言 学过pytest框架的肯定知道什么叫钩子 xff08 hook xff09 函数 钩子函数的作用是在程序运行的过程中插入一段代码做一些事情 四个钩子 请求钩子是通过装饰器的形式实现 xff0c Flask支持如下四种请求钩子 xff1
  • 30岁自学嵌入式找工作,可行吗?前景怎么样?

    大家好 xff0c 我是张巧龙 xff0c 在知乎上看到一个问题 xff1a 30岁自学嵌入式找工作 xff0c 可行吗 xff1f 看看一个高赞回答 xff1a 注 xff1a 以下内容不代表本公众号观点 xff0c 仅供参考 不可行 嵌
  • 0基础在ROS系统中实现RRT算法(四)URDF集成gazebo并搭建gazebo仿真环境

    小白一枚 xff0c 毕设突发奇想加入了ROS的内容 xff0c 不知道自己还能不能毕业 以下均为通过看视频 xff0c 翻博客等整理而成的笔记 xff0c 并非我的原创 可能会出现一些报错的修改或者简单的代码是我自己做的 哈哈 Gazeb