一激光雷达概述
激光雷达相当于机器人的眼睛,机器人通过激光雷达实现对周围环境的探测。激光雷达(LiDAR,Light Detection and Ranging)是ROS机器人中用于环境感知的核心传感器之一,通过发射激光束并接收反射信号,生成高精度的环境距离和轮廓信息。
二.gazebo和rvize
gazebo和rvize的区别在于gazebo是仿真环境而rviz是接受机器人传感器数据并进行反映。
以下是来自deepseek关于该点的理论介绍:
Gazebo和Rviz是ROS生态中两个互补但功能截然不同的工具,它们如同机器人的“虚拟实验室”与“数据仪表盘”,共同支撑着机器人开发的全流程。Gazebo是一个高保真的物理仿真引擎,它构建了一个可以模拟真实物理规律的数字世界,允许开发者在其中设计机器人的机械结构、传感器配置,甚至模拟复杂环境中的动态交互,比如机器人在崎岖地形行走时车轮与地面的摩擦力、激光雷达在雾天环境中的信号衰减。它内置了ODE(Open Dynamics Engine)或Bullet等物理引擎,能够计算刚体运动、关节约束、碰撞检测,甚至模拟软体变形。例如,当仿真一个搭载机械臂的移动机器人时,Gazebo不仅会渲染出机器人的三维模型,还会精确计算机械臂抓取物体时的力矩是否足以克服重力,若电机扭矩参数设置不当,仿真中会直接呈现抓取失败的场景。开发者可以在此环境中测试导航算法在极端天气下的鲁棒性,或者验证无人机在磁场干扰中的控制稳定性,而无需担心真实实验可能带来的硬件损坏风险。
Rviz则是一个高度可定制的三维可视化工具,它像手术台上的无影灯,将机器人运行时的内部状态层层剖开展现。它不关心数据来自仿真还是真实硬件,只专注于将抽象的ROS话题、坐标变换、点云、图像等信息转化为人类可直观理解的视觉元素。例如,当机器人执行SLAM建图时,Rviz可以同时显示激光雷达的实时扫描线(红色扇形区域)、逐渐生成的栅格地图(灰白网格)、机器人的运动轨迹(绿色路径箭头),以及摄像头捕捉的街景图像(浮动视窗),这些图层叠加在一起,构成一个动态的数字孪生体。开发者可以通过Rviz的插件系统扩展功能,比如嵌入一个交互式的目标点设置面板,点击地图某处即可触发导航任务;或是添加一个位姿估计工具,手动拖动机器人模型矫正初始定位误差。Rviz的强大之处在于它的“数据无关性”——无论是处理Gazebo中虚拟激光雷达产生的/scan
话题,还是解析真实机器人通过Wi-Fi传输的/odom
里程计数据,它都以一致的视觉语言呈现,使得算法从仿真到实机的过渡更为平滑。
三.运行实例
打开一个终端,运行roslaunch wpr_simulation wpb_simple.launch
另开一个终端,输入rviz
或者直接输入roslaunch wpr_simulation wpb_rviz.launch
点击在rviz下左下方的add按钮,依次加入RobotModel和LaserScan模型,并将Fixed Frame切换为base_footprint和LaserScan的Topic切换为/scan
可以得到下图,左边是传感器信息,右边是gazebo的仿真。
餐
即可看到gazebo下机器人的传感器信息,添加障碍物,发现传感器信息也随之变化。
四.编写激光雷达数据的c++节点
在ROS中,运用一个c++节点来获取激光雷达的数据。首先,了解激光雷达数据的消息类型(sensor_msgs)。
1.示例
运行机器人仿真环境:roslaunch wpr_simulation wpb_simple.launch
然后,运行rosrun wpr_simulation demo_lidar_data
得到对应的测距信息。
接下来,尝试自己编写程序实现该功能。
2.c++节点编写
与ROS机器人通过发布数据实现机器人的控制一样,ROS机器人有一个雷达数据话题/scan,连接数据获取节点,我们只需编写一个激光雷达节点,来订阅该话题/scan,便可获得对应的数据。
首先,创建功能包lidar_pkg(注意添加依赖项sensor_msgs),创建节点lidar_node。
lidar_node的代码如下:
#include<ros/ros.h>
#include<sensor_msgs/LaserScan.h>
void lidarCallback(const sensor_msgs::LaserScan msg)
{
float fMidDist = msg.ranges[180];
ROS_INFO("前方测距 range[180] = %f米",fMidDist);
}
int main(int argc, char** argv)
{
//设置中文编码
setlocale(LC_ALL,"");
//初始化节点
ros::init(argc,argv,"lidar_node");
ros::NodeHandle nh;
ros::Subscriber lidar_sub = nh.subscribe("/scan",10,&lidarCallback);
ros::spin();
}
cmake文件如下:
add_executable(lidar_node src/lidar_node.cpp)
target_link_libraries(lidar_node
${catkin_LIBRARIES}
)
3.运行
roslaunch wpr_simulation wpb_simple.launch
rosrun lidar_pkg lidar_node
改变柜子的距离,测距发生变化