2. 开发环境搭建:Ubuntu系统配置、ROS/ROS2安装与工作空间创建、Eigen3与Ceres Solver库编译、VSCode调试环境配置
说实话,环境搭建这件事,很多新手觉得就是“装软件”,没什么技术含量。但我在项目里踩过的坑,十有八九都跟环境配置有关。库版本不对、编译器不兼容、路径写死——这些问题一旦出现,排查起来比写代码还痛苦。
这一章,我会带你从头搭一套能真正用于导航开发的系统环境。不是那种“装完能跑Hello World就行”的玩具环境,而是能支撑你后续做EKF融合、图优化、路径规划的生产环境。
2.1 Ubuntu系统基础配置
我个人习惯用Ubuntu 20.04 LTS,搭配ROS Noetic。如果你用22.04,那就走ROS2 Humble路线。两条路都能走通,但别混着来——我见过有人Ubuntu 20.04硬装ROS2 Galactic,结果依赖冲突到怀疑人生。
2.1.1 换源与基础工具链
装完系统第一件事,换源。别用官方源,国内速度太慢。
# 备份原源
sudo cp /etc/apt/sources.list /etc/apt/sources.list.bak
# 替换为清华源(Ubuntu 20.04)
sudo sed -i 's/archive.ubuntu.com/mirrors.tuna.tsinghua.edu.cn/g' /etc/apt/sources.list
sudo sed -i 's/security.ubuntu.com/mirrors.tuna.tsinghua.edu.cn/g' /etc/apt/sources.list
sudo apt update && sudo apt upgrade -y
然后装基础工具链。这些是后面编译各种库的基石:
sudo apt install -y build-essential cmake git wget curl \
python3-pip python3-dev python3-vcstool \
libeigen3-dev libgoogle-glog-dev libgflags-dev \
libatlas-base-dev libsuitesparse-dev
htop和neofetch。前者看资源占用,后者确认系统版本。调试时一眼就能知道是不是环境问题。
2.1.2 显卡驱动与CUDA(可选但推荐)
如果你要用到Ceres Solver的自动求导加速,或者跑一些视觉导航算法,NVIDIA显卡驱动和CUDA是必须的。我建议用ubuntu-drivers自动安装:
sudo ubuntu-drivers autoinstall
sudo reboot
# 验证
nvidia-smi
CUDA我一般装11.8,兼容性最好。别追最新版,很多库还没适配。
2.2 ROS/ROS2安装与工作空间创建
ROS是导航开发的骨架。消息通信、TF变换、可视化——全得靠它。我建议你两个都装,但日常开发只用其中一个。我自己是ROS Noetic为主,ROS2 Humble为辅做测试。
2.2.1 ROS Noetic(Ubuntu 20.04)
# 添加ROS源
sudo sh -c 'echo "deb http://packages.ros.org/ros/ubuntu $(lsb_release -sc) main" > /etc/apt/sources.list.d/ros-latest.list'
sudo apt-key adv --keyserver 'hkp://keyserver.ubuntu.com:80' --recv-key C1CF6E31E6BADE8868B172B4F42ED6FBAB17C654
sudo apt update
sudo apt install -y ros-noetic-desktop-full
# 初始化rosdep
sudo rosdep init
rosdep update
# 环境变量
echo "source /opt/ros/noetic/setup.bash" >> ~/.bashrc
source ~/.bashrc
2.2.2 ROS2 Humble(Ubuntu 22.04)
# 添加ROS2源
sudo apt install software-properties-common
sudo add-apt-repository universe
sudo apt update && sudo apt install curl -y
sudo curl -sSL https://raw.githubusercontent.com/ros/rosdistro/master/ros.key -o /usr/share/keyrings/ros-archive-keyring.gpg
echo "deb [arch=$(dpkg --print-architecture) signed-by=/usr/share/keyrings/ros-archive-keyring.gpg] http://packages.ros.org/ros2/ubuntu $(lsb_release -sc) main" | sudo tee /etc/apt/sources.list.d/ros2.list > /dev/null
sudo apt update
sudo apt install -y ros-humble-desktop
# 环境变量
echo "source /opt/ros/humble/setup.bash" >> ~/.bashrc
source ~/.bashrc
setup.bash不能同时source。我见过有人两个都写进.bashrc,结果rosrun命令都找不到。建议用别名切换,或者写个脚本按需加载。
2.2.3 创建工作空间
工作空间是ROS项目的容器。我习惯用catkin_tools(ROS1)或colcon(ROS2)来管理。
# ROS1 - catkin_tools
sudo apt install -y python3-catkin-tools
mkdir -p ~/nav_ws/src
cd ~/nav_ws
catkin init
catkin build
# ROS2 - colcon
mkdir -p ~/nav2_ws/src
cd ~/nav2_ws
colcon build
# 别忘了source
echo "source ~/nav_ws/devel/setup.bash" >> ~/.bashrc
为什么要用catkin_tools而不是catkin_make?因为前者支持并行编译、增量编译,还能单独编译某个包。我在项目里编译整个导航栈时,catkin_tools能省一半时间。
2.3 Eigen3与Ceres Solver库编译
这两个库是导航算法的数学引擎。Eigen3做矩阵运算,Ceres Solver做非线性优化。别用apt直接装——版本太老,而且缺少一些关键模块。
2.3.1 编译Eigen3
Eigen3是头文件库,但为了后续Ceres能找到它,我建议还是走一遍cmake流程:
cd ~
git clone https://gitlab.com/libeigen/eigen.git
cd eigen
mkdir build && cd build
cmake ..
sudo make install
# 验证
pkg-config --modversion eigen3
/usr/local/include/eigen3。如果Ceres编译时找不到,可以手动设置-DEIGEN3_INCLUDE_DIR。
2.3.2 编译Ceres Solver
Ceres的依赖比较多,尤其是SuiteSparse和glog。我之前在服务器上编译,缺了libcxsparse,结果Ceres的稀疏矩阵求解器直接罢工。
# 确保依赖齐全
sudo apt install -y libgoogle-glog-dev libgflags-dev \
libatlas-base-dev libsuitesparse-dev
cd ~
git clone https://ceres-solver.googlesource.com/ceres-solver
cd ceres-solver
mkdir build && cd build
cmake .. -DCMAKE_BUILD_TYPE=Release \
-DEIGEN3_INCLUDE_DIR=/usr/local/include/eigen3 \
-DCXSPARSE=ON \
-DGFLAGS=ON \
-DGLOG=ON
make -j$(nproc)
sudo make install
# 验证
ceres_version=$(pkg-config --modversion ceres)
echo "Ceres version: $ceres_version"
编译完成后,可以用Ceres自带的示例测试:
./bin/simple_bundle_adjuster ../data/problem-16-22106-pre.txt
如果看到优化迭代输出,说明安装成功。
SuiteSparse的BLAS库不兼容。后来改用-DSUITESPARSE=OFF,用Eigen的稀疏求解器替代,才跑通。如果你在嵌入式平台上编译,可以试试这个方案。
2.4 VSCode调试环境配置
写导航算法,调试是家常便饭。VSCode配合CMake和GDB,能让你在代码里打断点、看变量、甚至可视化矩阵数据。
2.4.1 安装插件
我必装的几个插件:
| 插件名 | 用途 |
|---|---|
| C/C++ (ms-vscode.cpptools) | 语法高亮、智能提示、调试 |
| CMake Tools (ms-vscode.cmake-tools) | CMake项目一键配置与编译 |
| ROS (ms-iot.vscode-ros) | ROS消息、节点、launch文件支持 |
| Python | Python调试与代码补全 |
2.4.2 配置launch.json
调试ROS节点时,launch.json是关键。我一般这样配:
{
"version": "0.2.0",
"configurations": [
{
"name": "ROS: Launch Node",
"type": "cppdbg",
"request": "launch",
"program": "${workspaceFolder}/devel/lib/${input:packageName}/${input:nodeName}",
"args": [],
"stopAtEntry": false,
"cwd": "${workspaceFolder}",
"environment": [],
"externalConsole": false,
"MIMode": "gdb",
"setupCommands": [
{
"description": "Enable pretty-printing for gdb",
"text": "-enable-pretty-printing",
"ignoreFailures": true
}
],
"preLaunchTask": "build",
"miDebuggerPath": "/usr/bin/gdb"
}
],
"inputs": [
{
"id": "packageName",
"type": "promptString",
"description": "Enter the package name"
},
{
"id": "nodeName",
"type": "promptString",
"description": "Enter the node executable name"
}
]
}
这样每次调试时,只需要输入包名和节点名,VSCode会自动编译并启动GDB。
2.4.3 调试Eigen矩阵
调试导航算法时,经常要看Eigen矩阵的值。GDB默认显示不了,需要装eigen-gdb-pretty-printer:
# 下载pretty-printer
git clone https://gitlab.com/libeigen/eigen.git
cp -r eigen/eigen/debug/gdb/pretty_printer ~/.gdbinit.d/
# 在~/.gdbinit中添加
echo "source ~/.gdbinit.d/pretty_printer/eigen.py" >> ~/.gdbinit
echo "eigen::register_eigen_pretty_printers()" >> ~/.gdbinit
配置好后,在调试时输入print my_matrix,就能看到矩阵的完整内容,而不是一堆地址。
source ROS2的环境变量。我习惯在VSCode的tasks.json里加上"options": {"env": {"ROS_DISTRO": "humble"}},避免每次手动设置。
2.5 环境验证与常见问题
环境搭完了,怎么确认没问题?我一般跑一个最小测试:
# 测试Eigen3
cat > test_eigen.cpp << EOF
#include
#include
int main() {
Eigen::Matrix3d m;
m << 1, 2, 3, 4, 5, 6, 7, 8, 9;
std::cout << "Eigen works!\n" << m << std::endl;
return 0;
}
EOF
g++ -I/usr/local/include/eigen3 test_eigen.cpp -o test_eigen
./test_eigen
# 测试Ceres
cat > test_ceres.cpp << EOF
#include
int main() {
ceres::Problem problem;
std::cout << "Ceres works!" << std::endl;
return 0;
}
EOF
g++ test_ceres.cpp -o test_ceres -lceres -lglog -lgflags
./test_ceres
如果都能正常输出,恭喜你,环境搭好了。
- 找不到
ros.h:检查source了没有,或者工作空间有没有编译。 - Ceres编译报错
undefined reference to 'cholmod_l_*':缺libcholmod,装libsuitesparse-dev。 - VSCode调试时断点不生效:检查
CMakeLists.txt里有没有加-g -O0编译选项。
嗯,环境搭建这部分就到这里。别嫌麻烦——一个干净、可复现的环境,能让你在后续的算法调试中少走很多弯路。我每次换新机器,都会按这个流程走一遍,确保所有库的版本一致。这样出了问题,至少能确定不是环境的问题。