4、传感器仿真:配置激光雷达(LaserScan)和IMU传感器,在Gazebo中验证数据输出
传感器是机器人的眼睛和耳朵。没有它们,避障就是瞎撞。
这一章,我们来搞定两个最关键的传感器:激光雷达和IMU。我个人习惯先把它们配好,再去做避障算法。因为数据不准,后面全是白费功夫。
4.1 激光雷达(LaserScan)的配置
激光雷达在Gazebo里其实就是一个射线传感器。它发射一束束激光,碰到物体就返回距离信息。
嗯,这里要注意:Gazebo里的激光雷达是理想化的。它没有真实传感器的噪声和抖动。所以你在仿真里跑得好好的,上了真车可能就翻车了。我当年就吃过这个亏。
4.1.1 在URDF中定义激光雷达
我们先写一个简单的URDF片段。把它放到你的机器人模型里就行。
<link name="laser_link">
<visual>
<geometry>
<cylinder length="0.05" radius="0.05"/>
</geometry>
<origin xyz="0 0 0" rpy="0 0 0"/>
</visual>
</link>
<joint name="laser_joint" type="fixed">
<parent link="base_link"/>
<child link="laser_link"/>
<origin xyz="0.2 0 0.1" rpy="0 0 0"/>
</joint>
<gazebo reference="laser_link">
<sensor type="ray" name="head_laser">
<pose>0 0 0 0 0 0</pose>
<visualize>true</visualize>
<update_rate>10</update_rate>
<ray>
<scan>
<horizontal>
<samples>360</samples>
<resolution>1</resolution>
<min_angle>-3.14159</min_angle>
<max_angle>3.14159</max_angle>
</horizontal>
</scan>
<range>
<min>0.1</min>
<max>10.0</max>
<resolution>0.01</resolution>
</range>
<noise>
<type>gaussian</type>
<mean>0.0</mean>
<stddev>0.01</stddev>
</noise>
</ray>
</sensor>
</gazebo>
这段代码里,我设置了360度扫描,10米范围。为什么是360度?因为避障需要全向感知。你想想看,如果只有180度,侧面撞上墙都不知道。
visualize设为true,你可以在Gazebo里看到激光射线。调试时特别有用。但跑正式仿真时记得关掉,否则会拖慢速度。
4.1.2 验证LaserScan数据
启动Gazebo后,用rostopic命令看看数据有没有出来。
rostopic echo /scan
你会看到类似这样的输出:
header:
seq: 123
stamp:
secs: 1234567890
nsecs: 123456789
frame_id: "laser_link"
angle_min: -3.14159
angle_max: 3.14159
angle_increment: 0.0174533
time_increment: 0.0002778
scan_time: 0.1
range_min: 0.1
range_max: 10.0
ranges: [0.5, 0.5, 0.5, ...]
ranges数组就是距离数据。如果全是inf或者0,说明你的传感器没对准。我曾经有一次搞了半天,结果是激光雷达装反了,朝天上扫。
4.2 IMU传感器的配置
IMU提供角速度和线加速度。避障时,它帮你判断机器人是不是在打滑,或者是不是撞到了东西。
4.2.1 在URDF中定义IMU
IMU的配置比激光雷达简单。看代码:
<link name="imu_link">
<visual>
<geometry>
<box size="0.02 0.02 0.02"/>
</geometry>
</visual>
</link>
<joint name="imu_joint" type="fixed">
<parent link="base_link"/>
<child link="imu_link"/>
<origin xyz="0 0 0.05" rpy="0 0 0"/>
</joint>
<gazebo reference="imu_link">
<sensor type="imu" name="imu_sensor">
<pose>0 0 0 0 0 0</pose>
<update_rate>50</update_rate>
<imu>
<noise>
<type>gaussian</type>
<rate>
<mean>0.0</mean>
<stddev>0.0002</stddev>
<bias_mean>0.0</bias_mean>
<bias_stddev>0.00001</bias_stddev>
</rate>
<accel>
<mean>0.0</mean>
<stddev>0.001</stddev>
<bias_mean>0.0</bias_mean>
<bias_stddev>0.0001</bias_stddev>
</accel>
</noise>
</imu>
</sensor>
</gazebo>
这里我加了噪声参数。为什么?因为真实IMU一定有噪声。如果你在仿真里不加噪声,后面做滤波算法时就会觉得「怎么这么简单」,一上真车就傻眼。
4.2.2 验证IMU数据
同样用rostopic查看:
rostopic echo /imu/data
输出示例:
header:
seq: 456
stamp:
secs: 1234567890
nsecs: 987654321
frame_id: "imu_link"
orientation:
x: 0.0
y: 0.0
z: 0.0
w: 1.0
angular_velocity:
x: 0.0
y: 0.0
z: 0.0
linear_acceleration:
x: 0.0
y: 0.0
z: 9.81
注意看linear_acceleration的z轴。静止时应该是9.81,也就是重力加速度。如果不是,说明你的IMU坐标系没对准。我见过有人把z轴和x轴搞反了,结果机器人明明是平的,IMU却说它在侧翻。
4.3 传感器数据可视化
光看数字不够直观。我们用RViz来看。
rosrun rviz rviz
在RViz里:
- 添加LaserScan话题,选择/scan
- 添加Imu话题,选择/imu/data
你会看到激光雷达的点云和IMU的坐标轴。如果一切正常,激光雷达应该能扫出周围环境的轮廓,IMU的坐标轴应该稳定不动。
4.4 本章知识体系
下面这张图总结了传感器配置的核心逻辑:
说白了,传感器配置就是三步走:定义、加载、验证。每一步都不能跳过。我见过太多人急着调算法,结果传感器数据都是错的,浪费了好几天时间。
好了,传感器配好了,数据也验证了。接下来就可以放心地去做避障算法了。