Bootstrap

ROS机器人仿真基础

一、 内容

  1. ROS机器人的相关语法解读
  2. ROS小车具体仿真实现

二、 语法解读

相关语法部分请参考结合官方链接进行对照:
链接

2.1 urdf 语法

URDF(Unified Robot Description Format)是一种XML文件格式,用于描述机器人模型的结构、几何形状、运动学、传感器等信息。URDF文件是ROS(Robot Operating System)中常用的一种机器人描述文件格式,它提供了一种标准化的方式来描述机器人的外观和行为。
URDF文件通常包含以下内容:
链接(Links):描述机器人模型的各个部件或连接,如机器人的基座、臂、关节等。每个链接通常包括几何形状、材质、原点位置和姿态等信息。
关节(Joints):描述链接之间的关系和运动。关节可以定义链接之间的转动或平移运动,如旋转关节、滑动关节等,同时指定了关节的类型、限制、初始位置等信息。
传感器(Sensors):描述机器人上安装的传感器,如摄像头、激光雷达、惯性测量单元等。传感器的类型、位置、参数等信息都可以在URDF文件中进行描述。
其他附加信息:URDF文件还可以包含其他的元数据,如机器人名称、作者信息、版本号等。

  1. robot 基础框架
<robot name="">
    <link name="">
        <visual>
            <geometry>
            </geometry>
            <origin xyz="" rpy=""/>
            <material name="">
                <color rgba=""/>
            </material>
        </visual>
    </link>
    <joint name="" type="">
        <parent link=""/>
        <child link=""/>
        <origin xyz="" rpy=""/>
        <!-- <axis xyz=""/> -->
    </joint>
</robot>

<robot name=“”>:这是URDF文件的根元素,用于定义整个机器人模型。在`name`属性中可以指定机器人的名称。

<link name=“”>:这个元素定义了机器人的一个链接(link),即机器人的一个部件或部件的一部分。在`name`属性中指定链接的名称。

  • <visual>:这个子元素用于定义链接的可视化外观。

    • <geometry>:定义了链接的几何形状,如盒子、圆柱体、球体等。

    • <origin xyz=“” rpy=“”/>:指定了链接相对于父链接或机器人原点的位置和姿态。xyz属性指定了链接的原点相对于父链接原点的偏移量,rpy属性指定了链接的旋转姿态。

    • <material name=“”>:定义了链接的材质。

      • <color rgba=“”>:定义了材质的颜色,使用RGBA颜色空间。
  • <joint name=“” type=“”>:这个元素定义了机器人的一个关节(joint),用于连接两个链接。

    `name`属性:指定了关节的名称。
    `type`属性:指定了关节的类型,如`fixed`(固定关节)或 `revolute`(旋转关节)等。

    • <parent link=“”> :指定了关节的父链接。

    • <child link=“”>:指定了关节的子链接。

    • <origin xyz=“” rpy=“”/>:指定了关节相对于父链接或子链接的位置和姿态。

    • <!-- <axis xyz=“”> -->:这是一个注释,用于指示关节的旋转轴。在这个例子中,该部分被注释掉了,即未定义旋转轴。

  1. geometry形状标签

标签用于在URDF(Unified Robot Description Format)文件中定义机器人模型链接的几何形状。这个标签定义了链接的外观,即链接所具有的形状。在<visual>或<collision>标签中使用<geometry>标签,可以指定链接的外观在可视化或碰撞检测时的形状。

<!-- 盒状 -->
<!-- 属性:
    size="长 宽 高" -->
	<box size=""/>
<!-- 圆柱 -->
<!-- 属性:
    radius="半径" 
    length="高度"-->
    <cylinder radius="" length=""/>
<!-- 球体 -->
<!-- 属性:
    radius="半径" -->
    <sphere radius=""/>

2.2 launch 语法

Launch文件是ROS中的配置文件,用于启动一个或多个ROS节点、参数服务器和其他ROS系统组件。通过launch文件,可以指定节点的参数、命名空间和启动顺序,以及在启动过程中进行必要的设置和调整。它提供了一种方便的方式来组织和管理ROS系统的启动过程,使得节点的启动和配置变得更加简单和可控。

<launch>
    <param name="robot_description" textfile=".urdf" />
    <node pkg="rviz" type="rviz" name="rviz" args=".rviz"/>
</launch>

这个launch文件的作用是启动RViz可视化工具,并加载机器人的URDF模型和RViz配置文件。

<param name=“robot_description” textfile=“.urdf” /> :这一行指定了一个ROS参数,名称为robot_description,它将从一个URDF文件中加载机器人模型。textfile=".urdf"指定了URDF文件的路径。
<node pkg=“rviz” type=“rviz” name=“rviz” args=“.rviz”/> :这一行启动了一个名为rviz的ROS节点,它是RViz可视化工具的启动命令。pkg="rviz"指定了该节点所在的ROS软件包,type="rviz"指定了节点的类型,name=“rviz"给该节点指定了一个名称,args=”.rviz"指定了RViz的配置文件路径。

也可以从launch文件启动gazebo

<launch>
     <param name="robot_description" command="$(find xacro)/xacro $(find robot_gazebo)/urdf/car.urdf.xacro" />
    <!-- 启动gazebo仿真环境 -->
    <include file="$(find gazebo_ros)/launch/empty_world.launch"/>
    <!-- 在Gazebo中添加机器人模型 -->
    <node pkg="gazebo_ros" type="spawn_model" name="spawn_model" args="-urdf -model mycar -param robot_description"/>
</launch>

2.3 xacro语法

Xacro文件的作用在于简化和参数化URDF(Unified Robot Description Format)文件的创建和维护。它通过提供一种宏语言的方式,允许用户定义和使用参数、宏和包含其他文件,从而使得机器人模型的描述更加灵活、可维护和可重用。Xacro文件可以将机器人模型分解为更小的部件,并通过参数化来配置这些部件的属性,同时还可以通过宏来抽象常见的模式和组件,以便在多个机器人模型中重用。最终,Xacro文件可以转换为标准的URDF文件,用于在ROS系统中进行机器人建模、仿真和控制。

  1. 标签
<robot name="" xmlns:xacro="http://wiki.ros.org/xacro">
    
</robot>
  1. 传递参数
<robot name="" xmlns:xacro="http://wiki.ros.org/xacro">
<!---定义参数--->
<xacro:property name="support_radius" value="0.01" />

 <link name="support">
        <visual>
            <geometry>
                <cylinder radius="${support_radius}"length="${support_length}" />
                <!---传入参数--->
            </geometry>
            <origin xyz="0.0 0.0 0.0" rpy="0.0 0.0 0.0" />
            <material name="red">
                <color rgba="0.8 0.2 0.0 0.8" />
            </material>
        </visual>
    </link>
</robot>

<xacro:property name=“support_radius” value=“0.01” />:这行代码定义了一个名为support_radius的参数,并赋予了初始值为0.01。
<link> 元素中,使用 ${support_radius} 来引用上述定义的参数。例如:<cylinder radius=“${support_radius}” length=“${support_length}” />。这样就将参数传递给了元素的radius属性。
3. 宏定义

<!---宏定义--->
<xacro:macro name="wheel_func" params="wheel_name flag">
    <!-- 宏的内容,使用参数进行定制 -->
</xacro:macro>

<!---实例化--->
      <xacro:wheel_func wheel_name="left" flag="1"/>
      <xacro:wheel_func wheel_name="right" flag="-1"/>

在这个宏定义中,wheel_func是宏的名称,params属性指定了宏的参数列表,包括wheel_nameflag。在实际使用时,可以通过${}语法引用这些参数,从而实现定制化的生成。

通过 <xacro:wheel_func> 来实例化宏。每个实例都会生成一个轮子部件,并根据传入的参数值定制化地生成名称、位置、关节等信息。在这个例子中,生成了左右两个轮子,分别具有不同的名称和方向。

2.4 gazebo 语法

  1. 基本框架
<robot name="mycar">
	<link>
	<!---此处为robot基本框架--->

	<!---下面是gazebo所需标签--->
	<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" />
            <!---大多数情况下,此段与上面robot内的link的元素相等--->
   </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基本标签--->
  <gazebo reference="base_link">
        <material>Gazebo/Black</material>
    </gazebo>
    <!---reference与link的name属性对应,否则报错--->
</robot>



<collision>:定义了机器人模型的碰撞检测属性。
<geometry>:定义了碰撞体的几何形状,这里使用了一个长方体。
<origin>:指定了碰撞体相对于链接原点的位置和姿态。
大多数情况下,中的内容与机器人模型的元素相同,以确保仿真和现实世界的物理行为一致。
<inertial>:定义了机器人模型的惯性属性。
<origin>:指定了惯性参考点相对于链接原点的位置。
<mass>:指定了链接的质量。
<inertia>:指定了链接的惯性张量。
<gazebo>:定义了与Gazebo仿真器的关联。
reference属性:指定了与哪个链接相关联。在这个例子中,关联了机器人模型的基本链接base_link
<material>:指定了在Gazebo仿真中显示的链接的材质,颜色首字母大写

2.5 运动语法

  1. 基于rviz(需在launch文件夹中导入rviz)
    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 
    }
}
  1. 基于gazebo(需在launch文件夹中导入gazebo)
<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>

<xacro:macro name=“joint_trans” params=“joint_name”>…</xacro:macro>:这个宏定义了传动装置,用于连接控制器与关节。通过传入joint_name参数,可以定制化生成传动装置的配置。
<xacro:joint_trans joint_name=“left_wheel2base_link” />和<xacro:joint_trans joint_name=“right_wheel2base_link” />:这两行实例化了上述定义的传动装置宏,分别用于左右驱动轮与机器人的基本链接之间的连接。
<gazebo>…:这个部分是对Gazebo仿真器的配置。其中包含了一个名为differential_drive_controller的插件,用于控制差分驱动机器人的运动。

  • filename属性指定了插件的库文件名。
  • 其他属性包括了控制器的一些设置参数,如发布轮子TF、发布轮子关节状态、控制话题、里程计话题等。
  • <leftJoint>和指定了左右轮的关节名称。
  • <wheelSeparation>指定了轮子之间的间距。
  • <wheelDiameter>指定了轮子的直径。
  • 其他属性用于控制控制器的参数,如轮子的力矩和加速度等。

三、 机器人仿真

本次仿真使用gazebo三维空间

3.1 准备工作

创建robot_gazebo功能区

catkin_create_pkg ros_gazebo urdf xacro gazebo_ros gazebo_ros_control gazebo_plugins

编译一下

cd ~/[ros工作区]
catkin_make

这里建议可以使用VSCODE进行ros编程
下载好这两个插件就可以了
在这里插入图片描述
以下使用vscode进行ros代码编写

3.2 编写代码

通过vscode打开工作区

code ~/[工作区名字]

在功能包内创建目录所示文件夹:

  • launch
  • urdf
    • gazebo

在urdf文件夹
创建文件

  • car_base.urdf.xacro //小车主体
  • car_camera.urdf.xacro //小车摄像头
  • car_laser.urdf.xacro //小车雷达
  • head.xacro //小车惯性文件
  • car.urdf.xacro //小车总体文件

在car_base.urdf.xacro内写入代码

<robot name="mycar" xmlns:xacro="http://wiki.ros.org/xacro">
      
      <xacro:property name="footprint_radius" value="0.001" />
      <!-- 添加 base_footprint -->
      <link name="base_footprint">
        <visual>
            <geometry>
                <sphere radius="${footprint_radius}"/>
            </geometry>
        </visual>
    </link>

     <!-- 添加底盘 -->
    <!-- 
        形状:圆柱
        半径:0.1m
        高度:0.08m
        离地间距:0.015m
     -->
     <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="base_mass" value="2" />
    <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="baselink_color">
                <color rgba="1.0 0.5 0.2 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="${base_mass}" r="${base_radius}" h="${base_length}" />
    </link>
    <gazebo reference="base_link">
        <material>Gazebo/Black</material>
    </gazebo>
    <joint name="link2footprint" type="fixed">
        <parent link="base_footprint"/>
        <child link="base_link"/>
        <!-- 关节z上的设置 = 车体高度/2 + 离地间距 -->
        <origin xyz="0 0 ${base_joint_z}" rpy="0 0 0"/>
        <!-- <axis xyz=""/> -->
    </joint>

    <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:property name="PI" value="3.1415927" />
    <xacro:property name="wheel_joint_z" value="${ (base_length / 2 + lidi - wheel_radius) * -1}" />
    <!-- 添加驱动轮 -->
    <!-- 
        形状:圆柱
        半径:0.035m
        长度:0.015m
      -->
      <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="wheel_color">
                <color rgba="0 0 0 0.3"/>
            </material>
        </visual>
         <collision>
          <geometry>
            <cylinder radius="${wheel_radius}" length="${wheel_length}" />
          </geometry>
          <origin xyz="0.0 0.0 0.0" rpy="${PI / 2} 0.0 0.0" />
        </collision>
        <xacro:cylinder_inertial_matrix m="${wheel_mass}" r="${wheel_radius}" h="${wheel_length}" />
    </link>
    <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}" rpy="0 0 0"/>
        <axis xyz="0 1 0"/>
    </joint>
          <gazebo reference="${wheel_name}_wheel">
        <material>Gazebo/Red</material>
      </gazebo>
      </xacro:macro>
      <xacro:wheel_func wheel_name="left" flag="1"/>
      <xacro:wheel_func wheel_name="right" flag="-1"/>



    <xacro:property name="small_wheel_radius" value="0.0075" />
    <!-- Z的偏移量=车体高度 / 2 + 里地间距 - 万相轮半径-->
     <xacro:property name="small_wheel_mass" value="0.03" /> <!-- 质量  -->
    <xacro:property name="small_joint_z" value="${(base_length / 2 + lidi - small_wheel_radius) * -1}" />  
    <!-- 添加万向轮 -->
    <!-- 
        形状:球
        半径:0.0075m
     -->
<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="wheel_color">
                <color rgba="1 0 0 0.3"/>
            </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="${small_wheel_mass}" r="${small_wheel_radius}" />
    </link>
    <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}" rpy="0 0 0"/>
        <axis xyz="0 1 0"/>
    </joint>
          <gazebo reference="${small_wheel_name}_wheel">
        <material>Gazebo/Red</material>
      </gazebo>
</xacro:macro>

     
   <xacro:small_wheel_func small_wheel_name="front" flag="1"/>
   <xacro:small_wheel_func small_wheel_name="back"  flag="-1"/>
</robot>

在car_camera.urdf.xacro内写入代码

<robot name="mycar" xmlns:xacro="http://wiki.ros.org/xacro">
    <!-- 摄像头 部件 -->
    <!-- 参数 :  -->
    <!-- 1. 连杆属性: 厚度 宽度 高度
            关节属性:  x   y   z   
             -->
    <xacro:property name="camera_length" value="0.01" />   
    <xacro:property name="camera_width" value="0.025" /> 
    <xacro:property name="camera_height" value="0.025" /> 
    <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_length / 2 + camera_height / 2 }" />
     <xacro:property name="camera_mass" value="0.01" /> <!-- 摄像头质量 -->
    <!-- 设置摄像头连杆和关节 -->
    <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>
            <origin xyz="0.0 0.0 0.0" rpy="0.0 0.0 0.0" />
        </collision>
        <xacro:Box_inertial_matrix m="${camera_mass}" l="${camera_length}" w="${camera_width}" h="${camera_height}" />
    </link>
    <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 "/>
        <!-- <axis xyz=""/> -->
    </joint>
    <gazebo reference="camera">
        <material>Gazebo/Blue</material>
    </gazebo>
</robot>

在car_laser.urdf.xacro内写入代码:


<robot name="my_car_camera" xmlns:xacro="http://wiki.ros.org/xacro">
    <!-- 雷达 部件 -->
    <!-- 参数 -->
    <!-- 
        1.支架:
            支架尺寸:半径 高度
            关节偏移量: x y z
        2.雷达:
            支架尺寸:半径 高度
            关节偏移量: x y z
     -->
    <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.0" /> <!-- 支架安装的x坐标 -->
    <xacro:property name="joint_support_y" value="0.0" /> <!-- 支架安装的y坐标 -->
    <xacro:property name="joint_support_z" value="${base_length / 2 + support_length / 2}" /> <!-- 支架安装的z坐标:底盘高度 / 2 + 支架高度 / 2  -->
    <xacro:property name="joint_laser_x" value="0.0" /> <!-- 雷达安装的x坐标 -->
    <xacro:property name="joint_laser_y" value="0.0" /> <!-- 雷达安装的y坐标 -->
    <xacro:property name="joint_laser_z" value="${support_length / 2 + laser_length / 2}" /> <!-- 雷达安装的z坐标:支架高度 / 2 + 雷达高度 / 2  -->
    <xacro:property name="support_mass" value="0.02" /> <!-- 支架质量 -->
    <xacro:property name="laser_mass" value="0.1" /> <!-- 雷达质量 -->
  <link name="support">
        <visual>
            <geometry>
                <cylinder radius="${support_radius}" length="${support_length}" />
            </geometry>
            <origin xyz="0.0 0.0 0.0" rpy="0.0 0.0 0.0" />
            <material name="red">
                <color rgba="0.8 0.2 0.0 0.8" />
            </material>
        </visual>
        <collision>
            <geometry>
                <cylinder radius="${support_radius}" length="${support_length}" />
            </geometry>
            <origin xyz="0.0 0.0 0.0" rpy="0.0 0.0 0.0" />
        </collision>

        <xacro:cylinder_inertial_matrix m="${support_mass}" r="${support_radius}" h="${support_length}" />
    </link>

    <joint name="support2base_link" type="fixed">
        <parent link="base_link" />
        <child link="support" />
        <origin xyz="${joint_support_x} ${joint_support_y} ${joint_support_z}" />
    </joint>
    <gazebo reference="support">
        <material>Gazebo/White</material>
    </gazebo>

 <!-- 雷达关节以及link -->
    <link name="laser">
        <visual>
            <geometry>
                <cylinder radius="${laser_radius}" length="${laser_length}" />
            </geometry>
            <origin xyz="0.0 0.0 0.0" rpy="0.0 0.0 0.0" />
            <material name="black" />
        </visual>
        <collision>
            <geometry>
                <cylinder radius="${laser_radius}" length="${laser_length}" />
            </geometry>
            <origin xyz="0.0 0.0 0.0" rpy="0.0 0.0 0.0" />
        </collision>
        <xacro:cylinder_inertial_matrix m="${laser_mass}" r="${laser_radius}" h="${laser_length}" />
    </link>

    <joint name="laser2support" type="fixed">
        <parent link="support" />
        <child link="laser" />
        <origin xyz="${joint_laser_x} ${joint_laser_y} ${joint_laser_z}" />
    </joint>
    <gazebo reference="laser">
        <material>Gazebo/Red</material>
    </gazebo>
</robot>

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

在car.urdf.xacro里写入代码

<robot name="mycar" xmlns:xacro="http://wiki.ros.org/xacro">
    <!-- 包含惯性矩阵文件 -->
    <xacro:include filename="head.xacro"    />
    <!-- 包含底盘,摄像头与雷达的 xacro 文件 -->
    <xacro:include filename="car_base.urdf.xacro"/>
    <xacro:include filename="car_camera.urdf.xacro"/>
    <xacro:include filename="car_laser.urdf.xacro"/>

    <!-- 运动控制 -->
    <xacro:include filename="gazebo/move.xacro"/>
</robot>

在urdf/gazebo/目录下创建文件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>

然后在launch文件夹创建env.launch

<launch>
    <!-- 载入urdf -->
     <param name="robot_description" command="$(find xacro)/xacro $(find robot_gazebo)/urdf/car.urdf.xacro" />
    <!-- 启动gazebo仿真环境 -->
 <include file="$(find gazebo_ros)/launch/empty_world.launch"/>
    <!-- 在Gazebo中添加机器人模型 -->
    <node pkg="gazebo_ros" type="spawn_model" name="spawn_model" args="-urdf -model mycar -param robot_description"/>
</launch>

然后在vscode中打开终端
运行:

source devel/setup.bash
roslaunch robot_gazebo env.launch

可以看到小车已经在环境里了

在这里插入图片描述
接下来新建一个终端,运行

rosrun teleop_twist_keyboard teleop_twist_keyboard.py

如果没有下载记得:

sudo apt-get install ros-noetic-teleop-twist-keyboard

在这里插入图片描述
接下来根据提示就可以运动了
在这里插入图片描述

四 、 参考链接

  1. http://www.autolabor.com.cn/book/ROSTutorials/di-6-zhang-ji-qi-ren-xi-tong-fang-zhen/67/671-ji-qi-ren-yun-dong-kong-zhi-yi-ji-li-cheng-ji-xin-xi-xian-shi.html
;