3、开发环境搭建(下):Python虚拟环境管理(Anaconda)、ROS Noetic安装与配置、工作空间创建与编译测试

好,咱们接着上一章继续聊。环境搭了一半,剩下的这部分其实才是真正容易踩坑的地方。我个人习惯把Python环境和ROS环境分开来搞,这样万一哪个崩了,另一个还能用。你想想看,要是混在一起,出个问题排查起来头都大。

3.1 Python虚拟环境管理:为什么非用Anaconda不可?

先说Python。你可能觉得,系统自带的Python3不也能用吗?嗯,确实能用,但咱们做自动驾驶仿真,依赖的库太多了。numpy、scipy、matplotlib、opencv、pytorch……版本一冲突,你就等着哭吧。

我在项目中遇到过好几次,因为全局Python环境被污染,导致整个仿真跑不起来。后来我学乖了,每个项目都建独立的虚拟环境。Anaconda就是干这个的。

3.1.1 安装Anaconda

去官网下载Linux版本的安装脚本。我建议下载Anaconda3-2023.09-0-Linux-x86_64.sh这个版本,比较稳定。下载完后执行:

bash Anaconda3-2023.09-0-Linux-x86_64.sh

一路按回车,到问你是否同意协议时输入yes。安装路径我建议用默认的,就在家目录下。最后会问你是否要初始化conda,选yes。

注意: 安装完成后一定要重新打开终端,或者执行 source ~/.bashrc,否则conda命令找不到。

3.1.2 创建专属虚拟环境

我个人习惯给每个项目起个有意义的名字。比如咱们这个自动驾驶仿真平台,我就叫它 ato_sim

conda create -n ato_sim python=3.8

为什么选Python 3.8?因为ROS Noetic官方支持的是Python 3.8,后面你装一些ROS的Python包时,版本匹配能省很多事。我曾经试过用Python 3.10,结果装rosbag相关库时各种报错,折腾了两天才发现是版本问题。

激活环境:

conda activate ato_sim

看到命令行前面多了个 (ato_sim) 就对了。以后所有跟这个项目相关的Python操作,都在这个环境里做。

3.1.3 安装常用科学计算库

咱们做仿真,这几个库是标配:

conda install numpy scipy matplotlib
conda install opencv-python
conda install pytorch torchvision torchaudio -c pytorch
小技巧: 如果你网络不好,可以换国内镜像源。我个人用清华源,速度还不错。配置方法:conda config --add channels https://mirrors.tuna.tsinghua.edu.cn/anaconda/pkgs/free/

3.2 ROS Noetic安装与配置

ROS是咱们仿真平台的核心通信框架。说白了,它就是个消息总线,让各个模块之间能互相说话。我选Noetic版本,因为它对Ubuntu 20.04支持最好,而且社区活跃,遇到问题网上基本都能找到答案。

3.2.1 添加ROS软件源

先更新一下系统:

sudo apt update
sudo apt upgrade

然后添加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 install curl
curl -s https://raw.githubusercontent.com/ros/rosdistro/master/ros.asc | sudo apt-key add -

3.2.2 安装ROS Noetic

我建议安装完整桌面版,省得后面缺包再补:

sudo apt update
sudo apt install ros-noetic-desktop-full

这个过程大概要十几分钟,取决于你的网速。你可以去泡杯咖啡。

3.2.3 初始化rosdep

rosdep是用来解决依赖的。很多新手会忽略这一步,结果后面编译工作空间时报一堆错。

sudo rosdep init
rosdep update
踩坑提醒: 如果 sudo rosdep init 报错说文件已存在,说明你之前装过ROS。可以执行 sudo rm /etc/ros/rosdep/sources.list.d/20-default.list 再试一次。

3.2.4 配置环境变量

每次打开终端都要能自动找到ROS命令,所以要把ROS的环境变量加到bashrc里:

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

验证一下:

roscore

如果能看到ROS master启动的信息,恭喜你,ROS装好了。按Ctrl+C退出。

3.3 工作空间创建与编译测试

工作空间就是咱们放代码的地方。ROS的工作空间有固定的目录结构,你得按规矩来。

3.3.1 创建工作空间

我习惯在家目录下建一个 catkin_ws 文件夹:

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

这时候src目录下会多一个 CMakeLists.txt,那是catkin自动生成的,别删。

3.3.2 编译空工作空间

回到工作空间根目录,执行编译:

cd ~/catkin_ws
catkin_make

第一次编译会生成 builddevel 两个目录。devel目录里有个 setup.bash,你得source它才能找到自己写的包。

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

3.3.3 创建测试包

咱们写个最简单的包来验证整个流程:

cd ~/catkin_ws/src
catkin_create_pkg test_pkg roscpp rospy std_msgs

这会生成一个 test_pkg 文件夹,里面有 CMakeLists.txtpackage.xml。咱们在src目录下建一个 talker.cpp

#include "ros/ros.h"
#include "std_msgs/String.h"
#include <sstream>

int main(int argc, char **argv)
{
    ros::init(argc, argv, "talker");
    ros::NodeHandle n;
    ros::Publisher chatter_pub = n.advertise<std_msgs::String>("chatter", 1000);
    ros::Rate loop_rate(10);

    int count = 0;
    while (ros::ok())
    {
        std_msgs::String msg;
        std::stringstream ss;
        ss << "hello world " << count;
        msg.data = ss.str();
        ROS_INFO("%s", msg.data.c_str());
        chatter_pub.publish(msg);
        ros::spinOnce();
        loop_rate.sleep();
        ++count;
    }
    return 0;
}

然后修改 CMakeLists.txt,在末尾加上:

add_executable(talker src/talker.cpp)
target_link_libraries(talker ${catkin_LIBRARIES})

3.3.4 编译并测试

cd ~/catkin_ws
catkin_make

如果没报错,启动roscore,再开一个新终端运行:

rosrun test_pkg talker

你应该能看到不断打印的 "hello world X"。这说明你的ROS工作空间完全没问题了。

核心要点: 整个环境搭建下来,最关键的三个步骤是:Anaconda环境隔离、ROS完整安装、工作空间正确编译。任何一个环节出问题,后面仿真都跑不起来。我建议你把每一步都验证通过再往下走。

好了,环境搭完了。下一章咱们开始写第一个仿真节点,到时候你会觉得,前面这些折腾都是值得的。