2、ROS开发环境搭建:Ubuntu系统安装、ROS Noetic安装、工作空间创建、功能包创建

说实话,很多初学者一上来就急着写代码,结果环境没配好,折腾一整天。我当年也干过这事——装了个不兼容的ROS版本,编译报错到怀疑人生。所以这一章,咱们把地基打牢。

2.1 Ubuntu系统安装——选对版本很重要

ROS Noetic 官方推荐的是 Ubuntu 20.04 LTS。为什么是20.04?因为Noetic是ROS1的最后一个长期支持版本,它和Ubuntu 20.04是天生一对。你想想看,要是装了个18.04或者22.04,后面各种依赖冲突会让你头大。

⚠️ 注意: 别用虚拟机跑ROS做实时控制!我有个学生用VMware装Ubuntu,结果串口通信延迟高得离谱,小车跑起来像喝醉了酒。建议直接双系统或者用实体机。

安装步骤其实很简单:

  1. 去Ubuntu官网下载20.04的ISO镜像
  2. 用Rufus或Etcher制作启动U盘
  3. BIOS里设置U盘启动,跟着向导走就行
  4. 分区时建议给根目录留至少50GB,/home可以大一点

我个人习惯把swap分区设成和内存一样大。比如你电脑有8G内存,swap就设8G。这样万一程序崩了,系统还能抢救一下。

2.2 ROS Noetic安装——一条命令搞定?没那么简单

官方给了一键安装脚本,但我不建议你直接用。为什么呢?因为网络问题。我在国内做项目时,经常遇到下载到一半卡住的情况。

正确的姿势是这样的:

# 1. 设置软件源(用中科大的镜像,快很多)
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

# 4. 安装完整版(包含所有工具和库)
sudo apt install ros-noetic-desktop-full

# 5. 初始化rosdep
sudo rosdep init
rosdep update
💡 小技巧: 如果rosdep update报错,八成是网络问题。我曾经在客户现场折腾了俩小时,最后发现换个WiFi就好了。你也可以试试用手机热点。

装完之后,别忘了设置环境变量:

echo "source /opt/ros/noetic/setup.bash" >> ~/.bashrc
source ~/.bashrc

验证一下:

roscore
# 如果看到一堆日志输出,没有报错,那就成了

2.3 工作空间创建——你的代码仓库

工作空间(workspace)说白了就是你放ROS代码的文件夹。我习惯叫它 catkin_ws,因为ROS的构建系统叫catkin。

创建步骤:

mkdir -p ~/catkin_ws/src
cd ~/catkin_ws
catkin_make

第一次编译会生成 builddevel 两个文件夹。很多人会问:这两个文件夹是干嘛的?

  • build:编译过程中的临时文件,相当于工地上的脚手架
  • devel:编译好的可执行文件和库,相当于盖好的毛坯房

记得把工作空间的环境变量也加进去:

echo "source ~/catkin_ws/devel/setup.bash" >> ~/.bashrc
source ~/.bashrc

🔑 关键点: 每次你新建了功能包或者修改了代码,都要重新 catkin_make 一下。我刚开始做项目时经常忘了这步,结果运行节点时提示找不到包,还以为是代码写错了。

2.4 功能包创建——ROS的最小单元

功能包(package)是ROS里最基本的组织单位。一个功能包可以包含节点、配置文件、launch文件等等。

创建命令:

cd ~/catkin_ws/src
catkin_create_pkg my_robot_pkg std_msgs rospy roscpp

这条命令会生成一个 my_robot_pkg 文件夹,里面自动创建了 CMakeLists.txtpackage.xml。这两个文件是功能包的身份证。

咱们来看看 package.xml 长什么样:

<package format="2">
  <name>my_robot_pkg</name>
  <version>0.0.0</version>
  <description>我的第一个ROS功能包</description>
  <maintainer email="your_email@example.com">your_name</maintainer>
  <license>BSD</license>

  <buildtool_depend>catkin</buildtool_depend>
  <build_depend>roscpp</build_depend>
  <build_depend>rospy</build_depend>
  <build_depend>std_msgs</build_depend>
  <exec_depend>roscpp</exec_depend>
  <exec_depend>rospy</exec_depend>
  <exec_depend>std_msgs</exec_depend>
</package>

这里要注意的是 build_dependexec_depend 的区别。前者是编译时需要,后者是运行时需要。我见过有人把依赖全写在 build_depend 里,结果运行时提示找不到库。

功能包创建好后,记得编译一下:

cd ~/catkin_ws
catkin_make

如果一切顺利,你会看到类似这样的输出:

[100%] Built target my_robot_pkg
📌 我的经验: 功能包的名字最好用英文小写,不要用空格或特殊字符。我之前有个项目叫"my_robot_v2.0",结果编译时ROS把点号当成了命名空间分隔符,折腾了好久才发现是名字的问题。

2.5 常见问题与避坑指南

问题 原因 解决方法
roscore启动失败 ROS环境变量没设置 检查 ~/.bashrc 里有没有 source setup.bash
catkin_make 找不到包 工作空间没source source ~/catkin_ws/devel/setup.bash
rosdep update 超时 网络问题 换源或使用代理
编译时提示缺少依赖 package.xml 没写全 用 rosdep install 自动安装

我曾经在帮客户部署机器人时,遇到一个特别诡异的问题:同样的代码,在我电脑上能跑,在他电脑上就报错。最后发现是他装ROS时用了不同的源,导致某些库的版本不一致。所以啊,环境一致性真的很重要。

嗯,到这里ROS开发环境就搭好了。下一章咱们开始写第一个ROS节点,让小车动起来。