Gazebo学习笔记(2)--传感器和执行器的使用
信息量比较大,认真学习!
xacro
URDF文件不具备代码复用的特性(在上一篇文章也能发现,其实左右轮是极其相似的但还是要单独描述),一个复杂的机器人模型会拥有大量了的传感器和关节组件,这时候使用URDF文件就太难阅读了。精简化、可复用、模块化的xacro文件来了。
原理:Xacro 可以声明变量,可以通过数学运算求解,使用流程控制控制执行顺序,还可以通过类
似函数的实现,封装固定的逻辑,将逻辑中需要的可变的数据以参数的方式暴露出去,从而提高代码复用率以及程序的安全性。
参考链接:Gazebo机器人模型文件的语法_哔哩哔哩_bilibili
gazebo
较之于 rviz,gazebo在集成 URDF 时,需要做些许修改,比如:必须添加 collision 碰撞属性相关参数、必须添加 inertia 惯性矩阵相关参数,另外,如果直接移植 Rviz 中机器人的颜色设置是没有显示的,颜色设置也必须做相应的变更。
传感器和执行器的安装
我们新建立一个模型文件,用xacro的形式,这里将模型文件和gazebo仿真文件分开,便于理解。
首先建立文件名为mybot.xacro的模型文件,文件的内容如下,和上一章内容相似,只不过我们在这次模型中加入了传感器的模型。
mybot.xacro
<?xml version="1.0"?>
<robot name="mybot" xmlns:xacro="http://ros.org/wiki/xacro">
<xacro:include filename="$(find myrobot)/urdf/mybot.gazebo.xacro" />
<link name="base_footprint"/>
<joint name="base_joint" type="fixed">
<parent link="base_footprint"/>
<child link="base_link"/>
<origin rpy="0 0 0" xyz="0 0 0"/>
</joint>
<link name="base_link">
<inertial>
<origin xyz="0 0 0" rpy="0 0 0"/>
<mass value="1.0"/> <!-- 适当增加质量 -->
<inertia ixx="0.001" ixy="0" ixz="0" iyy="0.001" iyz="0" izz="0.01" />
</inertial>
<visual>
<geometry>
<box size="0.50 0.32 0.10"/> <!-- 增大尺寸 -->
</geometry>
<origin rpy="0 0 0" xyz="0 0 0"/>
<material name="blue">
<color rgba="0 0 0.8 1"/>
</material>
</visual>
<collision>
<origin xyz="0 0 0" rpy="0 0 0"/>
<geometry>
<box size="0.50 0.32 0.10"/> <!-- 同样增大尺寸 -->
</geometry>
</collision>
</link>
<link name="right_wheel_link">
<inertial>
<origin xyz="0 0 0" rpy="0 0 0"/>
<mass value="0.2"/> <!-- 适当增加质量 -->
<inertia ixx="0.001" ixy="0" ixz="0" iyy="0.001" iyz="0" izz="0.001" />
</inertial>
<visual>
<geometry>
<cylinder length="0.04" radius="0.05"/> <!-- 增大尺寸 -->
</geometry>
<material name="black">
<color rgba="0 0 0 1"/>
</material>
</visual>
<collision>
<origin xyz="0 0 0" rpy="0 0 0"/>
<geometry>
<cylinder length="0.04" radius="0.05"/> <!-- 同样增大尺寸 -->
</geometry>
</collision>
</link>
<joint name="right_wheel_joint" type="continuous">
<axis xyz="0 0 -1"/>
<parent link="base_link"/>
<child link="right_wheel_link"/>
<origin rpy="1.5707 0 0" xyz="0.2 -0.18 -0.06"/> <!-- 根据新尺寸调整位置 -->
</joint>
<link name="left_wheel_link">
<inertial>
<origin xyz="0 0 0" rpy="0 0 0"/>
<mass value="0.2"/> <!-- 适当增加质量 -->
<inertia ixx="0.001" ixy="0" ixz="0" iyy="0.001" iyz="0" izz="0.001" />
</inertial>
<visual>
<geometry>
<cylinder length="0.04" radius="0.05"/> <!-- 增大尺寸 -->
</geometry>
<material name="black">
<color rgba="0 0 0 1"/>
</material>
</visual>
<collision>
<origin xyz="0 0 0" rpy="0 0 0"/>
<geometry>
<cylinder length="0.04" radius="0.05"/> <!-- 同样增大尺寸 -->
</geometry>
</collision>
</link>
<joint name="left_wheel_joint" type="continuous">
<axis xyz="0 0 -1"/>
<parent link="base_link"/>
<child link="left_wheel_link"/>
<origin rpy="1.5707 0 0" xyz="0.2 0.18 -0.06"/> <!-- 根据新尺寸调整位置 -->
</joint>
<link name="ball_wheel_link">
<inertial>
<origin xyz="0 0 0" rpy="0 0 0"/>
<mass value="0.2"/> <!-- 适当增加质量 -->
<inertia ixx="0" ixy="0" ixz="0" iyy="0" iyz="0" izz="0" />
</inertial>
<visual>
<geometry>
<sphere radius="0.05"/> <!-- 增大尺寸 -->
</geometry>
<material name="black">
<color rgba="0 0 0 1"/>
</material>
</visual>
<collision>
<origin xyz="0 0 0" rpy="0 0 0"/>
<geometry>
<sphere radius="0.05"/> <!-- 同样增大尺寸 -->
</geometry>
</collision>
</link>
<joint name="ball_wheel_joint" type="fixed">
<axis xyz="0 0 1"/>
<parent link="base_link"/>
<child link="ball_wheel_link"/>
<origin rpy="0 0 0" xyz="-0.20 0 -0.06"/> <!-- 根据新尺寸调整位置 -->
</joint>
<!-- imu sensor -->
<link name="imu">
<visual>
<geometry>
<box size="0.05 0.05 0.05"/>
</geometry>
<material name="white">
<color rgba="1 1 1 1"/>
</material>
</visual>
</link>
<joint name="imu_joint" type="fixed">
<parent link="base_link"/>
<child link="imu"/>
<origin xyz="0.12 0 0.05"/>
</joint>
<!-- camera -->
<link name="base_camera_link">
<visual>
<geometry>
<box size="0.05 0.05 0.05"/>
</geometry>
<material name="white">
<color rgba="1 1 1 1"/>
</material>
</visual>
</link>
<joint name="camera_joint" type="fixed">
<parent link="base_link"/>
<child link="base_camera_link"/>
<origin xyz="0.2 0 0.05"/>
</joint>
<!-- laser lidar -->
<link name="base_laser_link">
<visual>
<geometry>
<cylinder length="0.1" radius="0.08"/>
</geometry>
<material name="white">
<color rgba="1 1 1 1"/>
</material>
</visual>
</link>
<joint name="laser_joint" type="fixed">
<parent link="base_link"/>
<child link="base_laser_link"/>
<origin xyz="0 0.0 0.1"/>
</joint>
</robot>
这次我详细的解释一下每个部分的意思。
1. 文件头
<?xml version="1.0"?>
<robot name="mybot" xmlns:xacro="http://ros.org/wiki/xacro">
<xacro:include filename="$(find myrobot)/urdf/mybot.gazebo.xacro" />
<?xml version="1.0"?>
:这是标准的XML文件声明。<robot name="mybot" xmlns:xacro="http://ros.org/wiki/xacro">
:定义一个名为mybot
的机器人。xacro
是XML宏语言,允许通过<xacro:include>
引入外部文件(如Gazebo配置文件),以简化代码并复用已有组件。<xacro:include>
:引入其他xacro文件。在这个例子中,加载了mybot.gazebo.xacro
文件,包含该机器人的Gazebo仿真配置。
2. Base footprint和base joint
<link name="base_footprint"/>
<joint name="base_joint" type="fixed">
<parent link="base_footprint"/>
<child link="base_link"/>
<origin rpy="0 0 0" xyz="0 0 0"/>
</joint>
<link name="base_footprint"/>
:定义了一个名为base_footprint
的link
,通常用于表示机器人与地面的接触点或投影(虚的)。<joint name="base_joint" type="fixed">
:定义了一个fixed
(固定)类型的关节,固定连接base_footprint
和base_link
。<parent link="base_footprint"/>
和<child link="base_link"/>
:表示父链接是base_footprint
,子链接是base_link
。两者通过fixed
类型的关节绑定在一起,彼此不会相对运动。<origin rpy="0 0 0" xyz="0 0 0"/>
:定义了base_link
相对于base_footprint
的位置和方向,RPY(roll, pitch, yaw)定义了旋转,XYZ定义了平移,均为零表示没有偏移。
3. Base link
<link name="base_link">
<inertial>
<origin xyz="0 0 0" rpy="0 0 0"/>
<mass value="1.0"/>
<inertia ixx="0.001" ixy="0" ixz="0" iyy="0.001" iyz="0" izz="0.01" />
</inertial>
<link name="base_link">
:定义了base_link
,这是机器人的主框架。<inertial>
:定义了该链接的惯性属性。<origin>
:惯性原点的位置和方向,这里原点在(0, 0, 0),没有旋转。<mass value="1.0"/>
:定义base_link
的质量为1.0 kg。<inertia>
:定义惯性张量,描述了该物体如何对旋转产生反作用力。具体值为ixx="0.001"
等。
<visual>
<geometry>
<box size="0.50 0.32 0.10"/>
</geometry>
<origin rpy="0 0 0" xyz="0 0 0"/>
<material name="blue">
<color rgba="0 0 0.8 1"/>
</material>
</visual>
<visual>
:定义了视觉模型,用于在仿真中显示。
<geometry>
:几何形状为一个盒子,尺寸为0.50m x 0.32m x 0.10m。<material>
:颜色为蓝色,RGBA值为(0, 0, 0.8, 1),即不透明的深蓝色。
<collision>
<origin xyz="0 0 0" rpy="0 0 0"/>
<geometry>
<box size="0.50 0.32 0.10"/>
</geometry>
</collision>
</link>
<collision>
:定义该部分在物理引擎中如何处理碰撞检测,形状同样是一个盒子,尺寸与视觉部分一致。
4. Wheels(车轮)
<link name="right_wheel_link">
<inertial>
<origin xyz="0 0 0" rpy="0 0 0"/>
<mass value="0.2"/>
<inertia ixx="0.001" ixy="0" ixz="0" iyy="0.001" iyz="0" izz="0.001" />
</inertial>
<link name="right_wheel_link">
:右车轮链接。<inertial>
:定义惯性参数,质量为0.2 kg。
<visual>
<geometry>
<cylinder length="0.04" radius="0.05"/>
</geometry>
<material name="black">
<color rgba="0 0 0 1"/>
</material>
</visual>
<visual>
:右车轮的视觉模型为一个半径为0.05m、长度为0.04m的圆柱体,颜色为黑色。
<joint name="right_wheel_joint" type="continuous">
<axis xyz="0 0 -1"/>
<parent link="base_link"/>
<child link="right_wheel_link"/>
<origin rpy="1.5707 0 0" xyz="0.2 -0.18 -0.06"/>
</joint>
<joint name="right_wheel_joint" type="continuous">
:右车轮的关节类型为continuous
,表示它可以无限旋转。<axis xyz="0 0 -1"/>
:定义了旋转轴沿z
轴方向。<parent>
和<child>
:将右车轮链接到base_link
。<origin>
:定义关节位置,相对于base_link
,放置在(0.2, -0.18, -0.06)。
5. Ball wheel(万向轮)
<link name="ball_wheel_link">
<inertial>
<origin xyz="0 0 0" rpy="0 0 0"/>
<mass value="0.2"/>
<inertia ixx="0" ixy="0" ixz="0" iyy="0" iyz="0" izz="0"/>
</inertial>
<visual>
<geometry>
<sphere radius="0.05"/>
</geometry>
<material name="black">
<color rgba="0 0 0 1"/>
</material>
</visual>
<link name="ball_wheel_link">
:定义了万向轮,它的视觉模型是一个半径为0.05米的球体。- 质量为0.2kg,惯性张量为零,表示它不会对旋转产生阻力。
<joint name="ball_wheel_joint" type="fixed">
<axis xyz="0 0 1"/>
<parent link="base_link"/>
<child link="ball_wheel_link"/>
<origin rpy="0 0 0" xyz="-0.20 0 -0.06"/>
</joint>
ball_wheel_joint
是一个fixed
类型的关节,将万向轮固定到base_link
,没有相对运动。
6. IMU(惯性测量单元)
<!-- imu sensor -->
<link name="imu">
<visual>
<geometry>
<box size="0.01 0.01 0.01"/>
</geometry>
<material name="white">
<color rgba="1 1 1 1"/>
</material>
</visual>
</link>
-
IMU链接(link):定义了一个名为
imu
的链接,表示机器人上的IMU传感器。IMU通常用于测量机器人的加速度和角速度,用于姿态估计、导航等功能。 -
视觉属性:
<geometry>
:几何形状为一个边长为0.01米的正方体(盒子)。这只是IMU的可视化模型,实际的IMU数据不依赖这个形状。<material>
:IMU的材质为白色,RGBA值为(1, 1, 1, 1),表示完全不透明的白色。
<joint name="imu_joint" type="fixed">
<parent link="base_link"/>
<child link="imu"/>
<origin xyz="0.08 0 0.025"/>
</joint>
-
IMU关节(joint):定义了一个名为
imu_joint
的关节,类型为fixed
,表示IMU传感器固定在base_link
上,没有相对运动。 -
位置(origin):
imu
相对于base_link
的位置是(0.08, 0, 0.025),即IMU被放置在主框架的前面0.08米,垂直上方0.025米。这是IMU在机器人模型中的具体物理位置。
下面我对位置和大小做出了更改,一开始的位置和大小设置的有点问题 ,可以自己动手实验一下。
7.Camera(相机)
<!-- camera -->
<link name="base_camera_link">
<visual>
<geometry>
<box size="0.02 0.03 0.03"/>
</geometry>
<material name="white">
<color rgba="1 1 1 1"/>
</material>
</visual>
</link>
-
相机链接(link):定义了一个名为
base_camera_link
的链接,表示机器人上的相机组件。 -
视觉属性:
<geometry>
:几何形状为一个尺寸为0.02 x 0.03 x 0.03米的盒子,这表示相机的外形。该尺寸的设置与实际相机模型相关,但只是视觉效果。<material>
:相机的颜色为白色,RGBA为(1, 1, 1, 1)。
<joint name="camera_joint" type="fixed">
<parent link="base_link"/>
<child link="base_camera_link"/>
<origin xyz="0.1 0 0.025"/>
</joint>
-
相机关节(joint):名为
camera_joint
的关节,类型为fixed
,将相机固定在base_link
上。 -
位置(origin):相机被放置在机器人主框架的前面0.1米,垂直上方0.025米的位置。这样相机可以向前观测,确保其在机器人移动时可以捕捉正前方的图像。
8. Laser Lidar(激光雷达)
<!-- laser lidar -->
<link name="base_laser_link">
<visual>
<geometry>
<cylinder length="0.06" radius="0.04"/>
</geometry>
<material name="white">
<color rgba="1 1 1 1"/>
</material>
</visual>
</link>
-
激光雷达链接(link):定义了
base_laser_link
,代表机器人上的激光雷达传感器。激光雷达用于测量距离,生成周围环境的点云数据,通常用于SLAM(同步定位与建图)和避障。 -
视觉属性:
<geometry>
:几何形状为一个高度为0.06米、半径为0.04米的圆柱体。这个圆柱体模型用于代表激光雷达设备的形状。<material>
:材质为白色,RGBA为(1, 1, 1, 1),表示完全不透明的白色。
<joint name="laser_joint" type="fixed">
<parent link="base_link"/>
<child link="base_laser_link"/>
<origin xyz="0 0.0 0.06"/>
</joint>
-
激光雷达关节(joint):定义了
laser_joint
,类型为fixed
,将激光雷达固定到base_link
上。 -
位置(origin):激光雷达相对于
base_link
的位置是(0, 0, 0.06),即激光雷达放置在主框架的中心点,垂直上方0.06米。这个位置使得激光雷达可以从适当高度扫描周围环境。
mybot.gazebo.xacro
从上面mybot.xacro可以看出这个文件包含mybot.gazebo.xacro文件,mybot.gazebo.xacro主要是写gazebo仿真相关的xml,也可以将这两个文件合在一起。下面新建mybot.gazebo.xacro
参考链接:
Sensors — Gazebo garden documentation (gazebosim.org)
传感器 — Gazebo ionic documentation (gazebosim.org)
Gazebo : 教程 : ROS 中的 Gazebo 插件 (gazebosim.org)
内容如下
<?xml version="1.0"?>
<robot name="mybot" xmlns:xacro="http://ros.org/wiki/xacro">
<xacro:arg name="laser_visual" default="false"/>
<xacro:arg name="camera_visual" default="false"/>
<xacro:arg name="imu_visual" default="false"/>
<gazebo reference="base_link">
<material>Gazebo/DarkGrey</material>
</gazebo>
<gazebo reference="left_wheel_link">
<mu1>0.5</mu1>
<mu2>0.5</mu2>
<kp>500000.0</kp>
<kd>10.0</kd>
<minDepth>0.001</minDepth>
<maxVel>1.0</maxVel>
<fdir1>1 0 0</fdir1>
<material>Gazebo/DarkGrey</material>
</gazebo>
<gazebo reference="right_wheel_link">
<mu1>0.5</mu1>
<mu2>0.5</mu2>
<kp>500000.0</kp>
<kd>10.0</kd>
<minDepth>0.001</minDepth>
<maxVel>1.0</maxVel>
<fdir1>1 0 0</fdir1>
<material>Gazebo/FlatBlack</material>
</gazebo>
<gazebo reference="ball_wheel_link">
<mu1>0.1</mu1>
<mu2>0.1</mu2>
<kp>500000.0</kp>
<kd>100.0</kd>
<minDepth>0.001</minDepth>
<maxVel>1.0</maxVel>
<material>Gazebo/FlatBlack</material>
</gazebo>
<gazebo reference="imu">
<sensor type="imu" name="imu">
<always_on>true</always_on>
<visualize>$(arg imu_visual)</visualize>
</sensor>
<material>Gazebo/FlatBlack</material>
</gazebo>
<gazebo>
<plugin name="mybot_controller" filename="libgazebo_ros_diff_drive.so">
<commandTopic>cmd_vel</commandTopic>
<odometryTopic>odom</odometryTopic>
<odometryFrame>odom</odometryFrame>
<odometrySource>world</odometrySource>
<publishOdomTF>true</publishOdomTF>
<robotBaseFrame>base_footprint</robotBaseFrame>
<publishWheelTF>false</publishWheelTF>
<publishTf>true</publishTf>
<publishWheelJointState>true</publishWheelJointState>
<legacyMode>false</legacyMode>
<updateRate>30</updateRate>
<leftJoint>left_wheel_joint</leftJoint>
<rightJoint>right_wheel_joint</rightJoint>
<wheelSeparation>0.180</wheelSeparation>
<wheelDiameter>0.05</wheelDiameter>
<wheelAcceleration>10</wheelAcceleration>
<wheelTorque>100</wheelTorque>
<rosDebugLevel>na</rosDebugLevel>
</plugin>
</gazebo>
<gazebo>
<plugin name="imu_plugin" filename="libgazebo_ros_imu.so">
<alwaysOn>true</alwaysOn>
<bodyName>imu</bodyName>
<frameName>imu</frameName>
<topicName>imu</topicName>
<serviceName>imu_service</serviceName>
<gaussianNoise>0.0</gaussianNoise>
<updateRate>0</updateRate>
<imu>
<noise>
<type>gaussian</type>
<rate>
<mean>0.0</mean>
<stddev>2e-4</stddev>
<bias_mean>0.0000075</bias_mean>
<bias_stddev>0.0000008</bias_stddev>
</rate>
<accel>
<mean>0.0</mean>
<stddev>1.7e-2</stddev>
<bias_mean>0.1</bias_mean>
<bias_stddev>0.001</bias_stddev>
</accel>
</noise>
</imu>
</plugin>
</gazebo>
<gazebo reference="base_laser_link">
<material>Gazebo/FlatBlack</material>
<sensor type="ray" name="rplidar_sensor">
<pose>0 0 0 0 0 0</pose>
<visualize>$(arg laser_visual)</visualize>
<update_rate>7</update_rate>
<ray>
<scan>
<horizontal>
<samples>720</samples>
<resolution>0.5</resolution>
<min_angle>0.0</min_angle>
<max_angle>6.28319</max_angle>
</horizontal>
</scan>
<range>
<min>0.120</min>
<max>12.0</max>
<resolution>0.015</resolution>
</range>
<noise>
<type>gaussian</type>
<mean>0.0</mean>
<stddev>0.01</stddev>
</noise>
</ray>
<plugin name="gazebo_ros_rplidar_controller" filename="libgazebo_ros_laser.so">
<topicName>scan</topicName>
<frameName>base_laser_link</frameName>
</plugin>
</sensor>
</gazebo>
<gazebo reference="base_camera_link">
<sensor type="camera" name="csi Camera">
<always_on>true</always_on>
<visualize>$(arg camera_visual)</visualize>
<camera>
<horizontal_fov>1.085595</horizontal_fov>
<image>
<width>640</width>
<height>480</height>
<format>R8G8B8</format>
</image>
<clip>
<near>0.03</near>
<far>100</far>
</clip>
</camera>
<plugin name="camera_controller" filename="libgazebo_ros_camera.so">
<alwaysOn>true</alwaysOn>
<updateRate>30.0</updateRate>
<cameraName>/</cameraName>
<frameName>base_camera_link</frameName>
<imageTopicName>image_raw</imageTopicName>
<cameraInfoTopicName>camera_info</cameraInfoTopicName>
<hackBaseline>0.07</hackBaseline>
<distortionK1>0.0</distortionK1>
<distortionK2>0.0</distortionK2>
<distortionK3>0.0</distortionK3>
<distortionT1>0.0</distortionT1>
<distortionT2>0.0</distortionT2>
</plugin>
</sensor>
</gazebo>
</robot>
这段代码是一个在Gazebo仿真环境中定义传感器和插件配置的URDF模型片段,主要涉及传感器的物理属性、仿真设置,以及Gazebo中的一些传感器相关插件。以下是逐行的详细解释。
1. 命名空间与参数声明
<robot name="mybot" xmlns:xacro="http://ros.org/wiki/xacro">
<xacro:arg name="laser_visual" default="false"/>
<xacro:arg name="camera_visual" default="false"/>
<xacro:arg name="imu_visual" default="false"/>
robot
标签:定义了机器人模型的整体结构,名称为mybot
。它使用了xacro
命名空间,这是一种XML宏扩展机制,允许在模型中复用代码。- 参数声明:这里使用了
xacro:arg
定义了三个参数laser_visual
、camera_visual
和imu_visual
,用于控制激光雷达、相机和IMU的可视化效果,默认值都设置为false
。
2. Gazebo材质设置与物理属性
<gazebo reference="base_link">
<material>Gazebo/DarkGrey</material>
</gazebo>
gazebo
标签:指定Gazebo仿真环境中对base_link
(机器人主体)的材质定义,使用了Gazebo/DarkGrey
这种深灰色材料。
<gazebo reference="left_wheel_link">
<mu1>0.5</mu1>
<mu2>0.5</mu2>
<kp>500000.0</kp>
<kd>10.0</kd>
<minDepth>0.001</minDepth>
<maxVel>1.0</maxVel>
<fdir1>1 0 0</fdir1>
<material>Gazebo/DarkGrey</material>
</gazebo>
left_wheel_link
的物理属性:定义了左轮在仿真中的摩擦和其他物理参数:mu1
和mu2
:轮子的两个摩擦系数,值为0.5
。kp
:弹性系数,控制接触力的响应速度,设置为500000.0
。kd
:阻尼系数,控制接触力的衰减速度,值为10.0
。minDepth
:最小渗透深度,用于防止物体穿透地面,设置为0.001
。maxVel
:最大接触速度,限制物体的接触速度,值为1.0
。fdir1
:摩擦方向向量,定义了摩擦力的作用方向为X轴正方向。material
:材质为Gazebo/DarkGrey
。
右轮和小球轮的物理属性与左轮类似,只是材质或摩擦系数不同。
3. IMU(惯性测量单元)传感器
<gazebo reference="imu">
<sensor type="imu" name="imu">
<always_on>true</always_on>
<visualize>$(arg imu_visual)</visualize>
</sensor>
<material>Gazebo/FlatBlack</material>
</gazebo>
- IMU传感器:定义了一个IMU传感器,传感器类型为
imu
,名称也是imu
。always_on
:IMU始终保持开启状态。visualize
:传感器是否可视化,由$(arg imu_visual)
参数决定。这个参数来自前面定义的imu_visual
,用于控制仿真中是否显示IMU的视觉效果。material
:IMU的材质为Gazebo/FlatBlack
。
4. 差速驱动控制插件
<gazebo>
<plugin name="mybot_controller" filename="libgazebo_ros_diff_drive.so">
<commandTopic>cmd_vel</commandTopic>
<odometryTopic>odom</odometryTopic>
<odometryFrame>odom</odometryFrame>
<odometrySource>world</odometrySource>
<publishOdomTF>true</publishOdomTF>
<robotBaseFrame>base_footprint</robotBaseFrame>
<publishWheelTF>false</publishWheelTF>
<publishTf>true</publishTf>
<publishWheelJointState>true</publishWheelJointState>
<legacyMode>false</legacyMode>
<updateRate>30</updateRate>
<leftJoint>left_wheel_joint</leftJoint>
<rightJoint>right_wheel_joint</rightJoint>
<wheelSeparation>0.180</wheelSeparation>
<wheelDiameter>0.05</wheelDiameter>
<wheelAcceleration>10</wheelAcceleration>
<wheelTorque>100</wheelTorque>
<rosDebugLevel>na</rosDebugLevel>
</plugin>
</gazebo>
- 差速驱动插件:这是一个用于控制机器人的差速驱动的Gazebo插件,插件名称为
mybot_controller
,插件文件为libgazebo_ros_diff_drive.so
。commandTopic
:控制指令的ROS话题,设置为cmd_vel
。odometryTopic
:里程计的ROS话题,设置为odom
。robotBaseFrame
:机器人基座的坐标系,设置为base_footprint
。leftJoint
和rightJoint
:分别为左右轮的关节名称,用于差速驱动控制。wheelSeparation
:左右轮之间的距离,设置为0.180
米。wheelDiameter
:轮子的直径,设置为0.05
米。updateRate
:控制器更新频率,设置为30
Hz。- 其他参数用于控制轮子加速度、扭矩、里程计发布等。
5. IMU插件
<gazebo>
<plugin name="imu_plugin" filename="libgazebo_ros_imu.so">
<alwaysOn>true</alwaysOn>
<bodyName>imu</bodyName>
<frameName>imu</frameName>
<topicName>imu</topicName>
<serviceName>imu_service</serviceName>
<gaussianNoise>0.0</gaussianNoise>
<updateRate>0</updateRate>
<imu>
<noise>
<type>gaussian</type>
<rate>
<mean>0.0</mean>
<stddev>2e-4</stddev>
<bias_mean>0.0000075</bias_mean>
<bias_stddev>0.0000008</bias_stddev>
</rate>
<accel>
<mean>0.0</mean>
<stddev>1.7e-2</stddev>
<bias_mean>0.1</bias_mean>
<bias_stddev>0.001</bias_stddev>
</accel>
</noise>
</imu>
</plugin>
</gazebo>
- IMU插件:用于仿真IMU数据,插件文件为
libgazebo_ros_imu.so
。IMU数据通过噪声模型进行模拟。bodyName
和frameName
:分别为IMU的主体和坐标系名称。topicName
:IMU数据发布到的ROS话题名称。gaussianNoise
:IMU传感器的高斯噪声,设置为0.0
(即无噪声)。noise
:定义了IMU噪声模型,包括速率(角速度)和加速度噪声的均值、标准差以及偏置。
6. 激光雷达传感器
<gazebo reference="base_laser_link">
<material>Gazebo/FlatBlack</material>
<sensor type="ray" name="rplidar_sensor">
<pose>0 0 0 0 0 0</pose>
<visualize>$(arg laser_visual)</visualize>
<update_rate>7</update_rate>
<ray>
<scan>
<horizontal>
<samples>720</samples>
<resolution>0.5</resolution>
<min_angle>0.0</min_angle>
<max_angle>6.28319</max_angle>
</horizontal>
</scan>
<range>
<min>0.120</min>
<max>12.0</max>
<resolution>0.015</resolution>
</range>
<noise>
<type>gaussian</type>
<mean>0.0</mean>
<stddev>0.01</stddev>
</noise>
</ray>
<plugin name="gazebo_ros_rplidar_controller" filename="libgazebo_ros_laser.so">
<topicName>scan</topicName>
<frameName>base_laser_link</frameName>
</plugin>
</sensor>
</gazebo>
- 激光雷达传感器:这里定义了一个RPLidar传感器,仿真中发布的数据为ROS话题
scan
,并且附加了噪声模型来模拟测量误差。samples
:水平扫描的样本数量为720。range
:激光雷达的测距范围为0.120
米到12.0
米,分辨率为0.015
。- 噪声模型为高斯噪声,标准差为
0.01
。
7. 相机传感器
<gazebo reference="base_camera_link">
<sensor type="camera" name="csi Camera">
<always_on>true</always_on>
<visualize>$(arg camera_visual)</visualize>
<camera>
<horizontal_fov>1.085595</horizontal_fov>
<image>
<width>640</width>
<height>480</height>
<format>R8G8B8</format>
</image>
<clip>
<near>0.03</near>
<far>100</far>
</clip>
</camera>
<plugin name="camera_controller" filename="libgazebo_ros_camera.so">
<alwaysOn>true</alwaysOn>
<updateRate>30.0</updateRate>
<cameraName>/</cameraName>
<frameName>base_camera_link</frameName>
<imageTopicName>image_raw</imageTopicName>
<cameraInfoTopicName>camera_info</cameraInfoTopicName>
<hackBaseline>0.07</hackBaseline>
</plugin>
</sensor>
</gazebo>
相机传感器:仿真中的相机传感器,发布ROS话题image_raw
用于传输图像数据。
simulation_robot.launch
下面开始编辑启动文件,在launch文件夹下创建simulation_robot.launch,内容如下
<launch>
<arg name="x_pos" default="0.0"/>
<arg name="y_pos" default="0.0"/>
<arg name="z_pos" default="0.0"/>
<param name="/use_sim_time" value="true" />
<include file="$(find myrobot)/launch/gazebo_world.launch"/>
<param name="robot_description" command="$(find xacro)/xacro --inorder $(find myrobot)/urdf/mybot.xacro" />
<node pkg="gazebo_ros" type="spawn_model" name="spawn_urdf" args="-urdf -model mybot.xacro -x $(arg x_pos) -y $(arg y_pos) -z $(arg z_pos) -param robot_description" />
<node name="robot_state_publisher" pkg="robot_state_publisher" type="robot_state_publisher" />
</launch>
这段代码是一个ROS(Robot Operating System)启动文件(launch file),用于启动Gazebo仿真环境并生成一个机器人模型。它定义了多个参数、仿真设置、以及与ROS相关的节点,用于在Gazebo中生成机器人并发布其状态信息。以下是逐行的详细解释:
1. 参数定义
<arg name="x_pos" default="0.0"/>
<arg name="y_pos" default="0.0"/>
<arg name="z_pos" default="0.0"/>
arg
标签:定义了三个启动参数,分别为x_pos
、y_pos
、z_pos
,它们控制机器人在Gazebo环境中的初始位置(X、Y、Z坐标),默认值均为0.0
。这些参数可以在启动时传入,也可以使用默认值。
2. 使用仿真时间
<param name="/use_sim_time" value="true" />
param
标签:设置了ROS参数/use_sim_time
,该参数为true
,意味着在ROS系统中使用仿真时间(来自Gazebo的时间)而非真实时间。这使得仿真环境与ROS的时间同步。
3. 包含Gazebo仿真世界文件
<include file="$(find myrobot)/launch/gazebo_world.launch"/>
include
标签:引入并执行另一个启动文件,这里引用了myrobot
包中的gazebo_world.launch
。这个文件通常包含启动Gazebo仿真世界的配置,例如世界文件和其他相关设置。
4. 机器人模型描述
<param name="robot_description" command="$(find xacro)/xacro --inorder $(find myrobot)/urdf/mybot.xacro" />
param
标签:定义了ROS参数robot_description
,它通过xacro
命令生成,xacro
是一个宏扩展工具,用于解析.xacro
文件(XML宏)。这里使用了--inorder
选项,确保按顺序解析.xacro
文件,最终将位于myrobot
包中的mybot.xacro
文件解析为URDF(统一机器人描述格式)模型。这个模型会被传递给ROS中的其他组件使用。
5. 生成机器人模型
<node pkg="gazebo_ros" type="spawn_model" name="spawn_urdf" args="-urdf -model mybot.xacro -x $(arg x_pos) -y $(arg y_pos) -z $(arg z_pos) -param robot_description" />
node
标签:启动一个ROS节点,来自gazebo_ros
包的spawn_model
节点,该节点用于在Gazebo中生成一个URDF机器人模型。关键参数如下:
-urdf
:指定生成的是URDF格式的机器人模型。-model mybot.xacro
:指定模型的名称为mybot.xacro
。-x $(arg x_pos) -y $(arg y_pos) -z $(arg z_pos)
:指定机器人的初始位置,X、Y、Z坐标通过启动参数传递。-param robot_description
:指定机器人的URDF描述文件,来自前面设置的ROS参数robot_description
。
6. 机器人状态发布器
<node name="robot_state_publisher" pkg="robot_state_publisher" type="robot_state_publisher" />
node
标签:启动robot_state_publisher
节点,这个节点用于发布机器人每个关节的状态(位置、速度等),它会读取robot_description
参数中的URDF描述,并根据关节状态信息发布机器人在ROS中的TF变换树(坐标变换信息)。这是机器人在ROS中移动和仿真的重要部分,用于其他ROS组件实时跟踪机器人的状态。
总结
这个launch
文件的功能是:
- 启动Gazebo仿真环境(包含外部的Gazebo世界文件)。
- 解析并加载机器人的URDF模型。
- 在Gazebo中生成机器人并设置其初始位置。
- 启动机器人状态发布器,实时发布机器人关节的状态和坐标变换。
这使得机器人模型可以在Gazebo中仿真运行,并通过ROS与其他组件(如控制器、传感器处理器等)进行交互。
查看PDF
为了方便理解我们生成pdf供理解整个模型
终端输入命令
urdf_to_graphiz mybot.xacro
打开gazebo
输入终端命令
roslaunch myrobot simulation_robot.launch
查看主题命令
rostopic list
机器人系统在ROS中发布了多个与传感器、控制和仿真相关的主题。这些主题可以帮助你进行各种操作,例如控制机器人、获取传感器数据、监听仿真状态等。下面是一些关键主题的解释:
传感器数据相关
-
/camera_info 和 /image_raw:
- 这些主题与相机相关。
/image_raw
提供原始的相机图像数据,/camera_info
则包含相机的校准和配置信息。你也有/image_raw/compressed
和/image_raw/compressedDepth
等主题,表示图像被压缩或深度图像的传输。
- 这些主题与相机相关。
-
/imu:
- 这个主题用于发布IMU(惯性测量单元)传感器的数据,通常包括加速度、角速度、姿态信息等。
-
/scan:
- 这个主题通常用于发布激光雷达(LiDAR)传感器的数据。你可以通过它获取关于机器人周围环境的距离信息,用于避障或建图等任务。
控制相关
-
/cmd_vel:
- 这个主题用于控制机器人的速度和方向。通常发布线速度(x方向)和角速度(绕z轴)的指令。
-
/odom:
- 这个主题发布机器人的里程计信息,通常包含机器人的位置、方向和速度,帮助跟踪机器人在环境中的位置。
仿真状态相关
-
/gazebo/model_states 和 /gazebo/link_states:
- 这些主题发布Gazebo仿真中的模型和链接状态信息。
/model_states
包含所有模型的位姿和速度,/link_states
则提供各个链接的状态。
- 这些主题发布Gazebo仿真中的模型和链接状态信息。
-
/gazebo/set_model_state 和 /gazebo/set_link_state:
- 这些主题用于设置模型和链接的状态。例如,你可以通过
/set_model_state
来动态改变机器人在仿真中的位置。
- 这些主题用于设置模型和链接的状态。例如,你可以通过
其他
-
/joint_states:
- 这个主题发布机器人各个关节的位置、速度和力矩信息,通常用于关节控制或状态监测。
-
/tf 和 /tf_static:
- 这些主题用于发布机器人的坐标变换信息,
/tf_static
是静态变换,而/tf
是动态变换,用于描述机器人各部分之间的空间关系。
- 这些主题用于发布机器人的坐标变换信息,
可以通过 rostopic echo /<topic_name>
来查看这些主题发布的数据,或者使用 rqt_graph
查看ROS节点和主题的通信情况。
打开rqt界面
开启新终端输入
rqt_image_view
打开控制节点
打开新终端输入命令
rosrun teleop_twist_keyboard teleop_twist_keyboard.py
如果提示未找到命令是没有安装teleop_twist_keyboard
查看你当前使用的 ROS 版本,你可以在终端中执行以下命令:
rosversion -d
我的版本是noetic,所以我下载的是
sudo apt-get install ros-noetic-teleop-twist-keyboard
今天不知道怎么回事CSDN打字特别卡,难道是过节,没人维护?
我下面在图片里描述一下吧!
打开rivz视图
rviz