目录
一、 内容
- ROS机器人的相关语法解读
- ROS小车具体仿真实现
二、 语法解读
相关语法部分请参考结合官方链接进行对照:
链接
2.1 urdf 语法
URDF(Unified Robot Description Format)是一种XML文件格式,用于描述机器人模型的结构、几何形状、运动学、传感器等信息。URDF文件是ROS(Robot Operating System)中常用的一种机器人描述文件格式,它提供了一种标准化的方式来描述机器人的外观和行为。
URDF文件通常包含以下内容:
链接(Links):描述机器人模型的各个部件或连接,如机器人的基座、臂、关节等。每个链接通常包括几何形状、材质、原点位置和姿态等信息。
关节(Joints):描述链接之间的关系和运动。关节可以定义链接之间的转动或平移运动,如旋转关节、滑动关节等,同时指定了关节的类型、限制、初始位置等信息。
传感器(Sensors):描述机器人上安装的传感器,如摄像头、激光雷达、惯性测量单元等。传感器的类型、位置、参数等信息都可以在URDF文件中进行描述。
其他附加信息:URDF文件还可以包含其他的元数据,如机器人名称、作者信息、版本号等。
- 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=“”> -->:这是一个注释,用于指示关节的旋转轴。在这个例子中,该部分被注释掉了,即未定义旋转轴。
-
- 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系统中进行机器人建模、仿真和控制。
- 标签
<robot name="" xmlns:xacro="http://wiki.ros.org/xacro">
</robot>
- 传递参数
<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_name和flag。在实际使用时,可以通过${}语法引用这些参数,从而实现定制化的生成。
通过 <xacro:wheel_func> 来实例化宏。每个实例都会生成一个轮子部件,并根据传入的参数值定制化地生成名称、位置、关节等信息。在这个例子中,生成了左右两个轮子,分别具有不同的名称和方向。
2.4 gazebo 语法
- 基本框架
<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 运动语法
- 基于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
}
}
- 基于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
接下来根据提示就可以运动了