第1章:ROS环境搭建与核心概念
大家好,我是你们的讲师。做SLAM这些年,我踩过最多的坑,就是环境问题。ROS版本不对、依赖缺失、工作空间混乱……这些看似基础的东西,往往能卡住你好几天。今天咱们就从零开始,把ROS Noetic的环境搭好,再把核心概念捋一遍。
本章核心目标: 搭建一个稳定可用的ROS Noetic开发环境,理解ROS的通信机制,能独立编写launch文件。
1.1 ROS Noetic 安装与配置
ROS Noetic是ROS1的最后一个长期支持版本,搭配Ubuntu 20.04使用。我个人习惯用apt安装,干净利落。
# 1. 设置sources.list
sudo sh -c 'echo "deb http://packages.ros.org/ros/ubuntu $(lsb_release -sc) main" > /etc/apt/sources.list.d/ros-latest.list'
# 2. 添加密钥
sudo apt-key adv --keyserver 'hkp://keyserver.ubuntu.com:80' --recv-key C1CF6E31E6BADE8868B172B4F42ED6FBAB17C654
# 3. 更新并安装完整桌面版
sudo apt update
sudo apt install ros-noetic-desktop-full
# 4. 初始化rosdep
sudo rosdep init
rosdep update
# 5. 设置环境变量
echo "source /opt/ros/noetic/setup.bash" >> ~/.bashrc
source ~/.bashrc
# 6. 验证安装
roscore
注意: 如果你用的是虚拟机,记得给Ubuntu分配至少4GB内存和2个CPU核心。我曾经在2GB内存的虚拟机上跑ROS,结果roscore启动后直接卡死,排查了半天才发现是内存不够。
1.2 工作空间创建
工作空间是ROS项目的根目录。说白了,你所有的代码、包、编译产物都放在这里。我建议每个项目单独建一个工作空间,别把所有东西混在一起。
# 创建并初始化工作空间
mkdir -p ~/catkin_ws/src
cd ~/catkin_ws
catkin_make
# 每次打开新终端,记得source一下
echo "source ~/catkin_ws/devel/setup.bash" >> ~/.bashrc
source ~/.bashrc
小技巧: 用echo $ROS_PACKAGE_PATH检查你的工作空间是否被正确识别。如果输出里没有你的工作空间路径,说明source没生效。
1.3 Package结构
一个标准的ROS Package长这样:
my_package/
├── CMakeLists.txt # 编译规则
├── package.xml # 包信息与依赖
├── src/ # 源代码
├── include/ # 头文件
├── launch/ # launch文件
├── msg/ # 自定义消息
├── srv/ # 自定义服务
└── config/ # 配置文件
创建新包用这个命令:
cd ~/catkin_ws/src
catkin_create_pkg my_package roscpp rospy std_msgs
cd ~/catkin_ws
catkin_make
核心要点: package.xml里要写清楚依赖,否则编译时会报错。我见过有人漏写roscpp依赖,结果编译通过但运行时找不到节点,排查了半小时。
1.4 Topic / Service / Action 通信机制
ROS的通信机制,说白了就是节点之间怎么说话。我画了一张图帮你理解:
Topic(话题)
Topic是ROS最常用的通信方式。发布者往话题里发数据,订阅者从话题里收数据。这是单向的、异步的。比如激光雷达数据,就是通过/scan话题发布的。
# 查看所有话题
rostopic list
# 查看话题内容
rostopic echo /scan
# 查看话题发布频率
rostopic hz /scan
Service(服务)
Service是请求-响应模式。客户端发请求,服务端处理完返回结果。适合一次性的操作,比如「打开摄像头」、「重置里程计」。注意,Service是同步的,客户端会阻塞等待响应。
# 调用服务
rosservice call /gazebo/reset_world "{}"
Action(动作)
Action是Service的升级版。它适合长时间的任务,比如「导航到目标点」。客户端可以随时查询进度,也可以中途取消。Action有三个通道:goal(目标)、feedback(反馈)、result(结果)。
我的经验: 在SLAM建图时,地图保存用Service就够了。但导航任务一定要用Action,因为你可以实时看到机器人走到哪了,还能随时让它停下来。
1.5 Launch文件编写
Launch文件用来一次性启动多个节点。你想想看,每次建图都要开好几个终端,多麻烦。用launch文件,一键搞定。
<?xml version="1.0"?>
<launch>
<!-- 启动核心节点 -->
<node name="core_node" pkg="my_package" type="core_node" output="screen"/>
<!-- 启动激光雷达驱动 -->
<node name="lidar_driver" pkg="rplidar_ros" type="rplidarNode">
<param name="serial_port" value="/dev/ttyUSB0"/>
<param name="frame_id" value="laser"/>
</node>
<!-- 启动SLAM建图 -->
<include file="$(find slam_gmapping)/launch/gmapping.launch"/>
<!-- 启动可视化 -->
<node name="rviz" pkg="rviz" type="rviz" args="-d $(find my_package)/config/slam.rviz"/>
</launch>
关键点:
pkg:包名type:可执行文件名name:节点别名,可以重名output="screen":把日志输出到终端,调试时很有用include:嵌套其他launch文件
避坑指南: 我曾经在launch文件里忘了写output="screen",结果节点启动失败,但终端没有任何错误信息。后来用rosnode list发现节点根本没起来,才意识到是launch文件的问题。所以调试阶段,一定要加上output="screen"。
好了,这一章的内容就到这里。环境搭好了,概念理清了,下一章咱们就开始写第一个ROS节点,让机器人动起来。