目录摘要一、colcon build 的作用1.1 colcon build 是什么1.2 colcon build 后会生成哪些目录二、单独编译某一个功能包2.1 为什么需要单独编译2.2 使用 --packages-select 编译指定功能包2.3 接口包和代码包的编译顺序三、source install/setup.bash 的作用3.1 为什么编译后还要 source3.2 不 source 会出现什么问题3.3 重新打开终端后还需要 source 吗四、ros2 run 的基本流程4.1 ros2 run 的基本格式4.2 功能包名来自 package.xml4.3 可执行文件名来自 add_executable4.4 ros2 run 为什么能找到节点1Package.xml 中功能包名称要正确2CMakeLists.txt 中要生成可执行文件3CMakeLists.txt 中把可执行文件安装到正确位置4编译后要执行5完整链路可以理解为五、修改不同文件后是否需要重新编译5.1 修改 C 源码5.2 修改 CMakeLists.txt5.3 修改 package.xml5.4 修改 msg、srv、action 接口文件5.5 修改 launch、config、Python 文件5.6 修改文件后的编译总结表六、常见问题总结6.1 colcon build 成功但 ros2 run 找不到节点6.2 修改代码后运行结果没有变化6.3 ros2 pkg list 找不到功能包6.4 找不到自定义 msg、srv、action 接口七、本章总结7.1 colcon build 的核心作用7.2 source 的核心作用7.3 ros2 run 的核心理解摘要前两篇文章已经分别讲解了 ROS2 工程结构基础以及 ROS2 C 功能包中最重要的两个配置文件package.xml和CMakeLists.txt。第一篇主要讲工作空间 功能包 src、build、install、log msg、srv、action链接如下一文搞懂 ROS2 工程结构工作空间、功能包、msg/srv/action 自定义接口-CSDN博客https://blog.csdn.net/m0_58954356/article/details/161802673?spm1001.2014.3001.5501第二篇主要讲package.xml CMakeLists.txt find_package add_executable ament_target_dependencies install链接如下ROS2 功能包配置文件详解package.xml 与 CMakeLists.txt 一文搞懂-CSDN博客https://blog.csdn.net/m0_58954356/article/details/161804636?spm1001.2014.3001.5501但是配置文件写完之后ROS2 程序并不会自动运行。我们还需要理解完整的编译与运行流程。本篇主要讲解 ROS2 中非常重要的几个命令和概念colcon build source install/setup.bash ros2 run --packages-select --symlink-install通过本篇文章需要重点理解colcon build 到底做了什么source install/setup.bash 为什么必须执行ros2 run 为什么能找到节点修改不同文件后是否需要重新编译编译成功但运行失败应该如何排查具体的 Topic、Service、Action 小车控制代码会放到下一篇代码实践中继续讲解。除此之外ROS2其他相关学习博客链接如下ROS2 常见消息类型保姆级教程-CSDN博客https://blog.csdn.net/m0_58954356/article/details/161693378?spm1001.2014.3001.5501ROS2 话题通信实战消息对象、Publisher 发布器与 Subscriber 订阅器保姆级教程-CSDN博客https://blog.csdn.net/m0_58954356/article/details/161702288?spm1001.2014.3001.5501史上最全 ROS2 常用命令保姆级教程节点、话题、消息结构、参数、服务和动作一篇讲透-CSDN博客https://blog.csdn.net/m0_58954356/article/details/161726502?spm1001.2014.3001.5501一、colcon build 的作用1.1 colcon build 是什么colcon build是 ROS2 中最常用的编译命令。一般需要在工作空间根目录执行。例如cd ~/agilex_open_class_ws colcon build这里的agilex_open_class_ws是工作空间。执行colcon build后ROS2 会扫描工作空间src目录下的功能包并根据每个功能包中的配置文件进行编译。主要会读取package.xml CMakeLists.txt其中package.xml 用来识别功能包信息和依赖关系 CMakeLists.txt 用来描述 C 编译和安装规则1.2 colcon build 后会生成哪些目录执行colcon build之后工作空间中通常会出现三个目录build install log例如agilex_open_class_ws/ ├── src ├── build ├── install └── log这三个目录的作用如下目录作用build存放编译过程中产生的中间文件install存放编译安装后的结果log存放编译过程中的日志其中最重要的是install因为后面ros2 run、ros2 launch通常都会从 install 空间中查找已经安装好的程序、脚本、接口文件等。二、单独编译某一个功能包2.1 为什么需要单独编译在实际开发中一个工作空间中可能有很多功能包。例如agilex_open_class_ws/ └── src ├── limo_learning ├── limo_msgs ├── robot_description ├── navigation_pkg └── sensor_driver如果每次都执行colcon build就会编译整个工作空间。当功能包很多时编译时间会比较长。所以实际开发中经常只编译当前修改的功能包。2.2 使用 --packages-select 编译指定功能包只编译limo_learningcolcon build --packages-select limo_learning只编译limo_msgscolcon build --packages-select limo_msgs这个命令的意思是只选择指定功能包进行编译例如修改了小车控制代码src/limo_learning/src/limo_topic_cmd.cpp那么可以执行colcon build --packages-select limo_learning source install/setup.bash这样比完整编译整个工作空间更快。2.3 接口包和代码包的编译顺序如果修改的是自定义接口包例如limo_msgs/msg/LimoStatus.msg limo_msgs/srv/LimoSrv.srv limo_msgs/action/LimoAction.action通常建议先编译接口包colcon build --packages-select limo_msgs source install/setup.bash如果代码包limo_learning依赖了limo_msgs再编译代码包colcon build --packages-select limo_learning source install/setup.bash这样可以避免代码包找不到最新接口。简单记忆先编译接口包再编译依赖接口包的代码包三、source install/setup.bash 的作用3.1 为什么编译后还要 source执行完colcon build之后虽然程序已经编译并安装到了install空间但当前终端还不一定知道这些新内容在哪里。所以还需要执行source install/setup.bash这一步的作用是刷新当前终端环境让终端知道有哪些新的功能包有哪些新的可执行文件有哪些新的自定义接口这些内容安装在什么位置所以完整流程通常是cd ~/agilex_open_class_wscolcon buildsource install/setup.bash3.2 不 source 会出现什么问题如果编译完成后没有执行source install/setup.bash可能会出现这些问题ros2 pkg list 找不到新功能包ros2 run 找不到新节点ros2 interface show 找不到新接口ros2 launch 找不到新启动文件例如你刚创建了功能包limo_learning并且已经编译成功。但是执行ros2 pkg list | grep limo却没有看到limo_learning。这时候很可能就是因为当前终端还没有 source 当前工作空间。执行source install/setup.bash后再查看功能包列表ros2 pkg list | grep limo一般就可以看到了。3.3 重新打开终端后还需要 source 吗需要source install/setup.bash只对当前终端生效否则新终端可能找不到当前工作空间中的功能包和节点。如果关闭终端再重新打开通常需要重新执行cd ~/agilex_open_class_ws source install/setup.bash如果不想每次手动 source可以把命令加入~/.bashrcecho source ~/agilex_open_class_ws/install/setup.bash ~/.bashrc source ~/.bashrc这样每次打开新终端时会自动加载这个工作空间。不过初学阶段建议先手动执行方便理解当前终端到底加载了哪个工作空间。四、ros2 run 的基本流程4.1 ros2 run 的基本格式ros2 run用来运行某个功能包中的单个可执行节点。基本格式是ros2 run 功能包名 可执行文件名例如ros2 run limo_learning limo_topic_cmd这里有两个关键参数参数含义来源limo_learning功能包名称package.xml 中的namelimo_topic_cmd可执行文件名称CMakeLists.txt 中的add_executable也就是说ros2 run 的第一个参数看 package.xmlros2 run 的第二个参数看 CMakeLists.txt4.2 功能包名来自 package.xml例如package.xml中写namelimo_learning/name那么运行节点时第一个参数就是ros2 run limo_learning ...如果功能包名称写错或者当前终端没有 source 当前工作空间ros2 run就可能找不到这个功能包。4.3 可执行文件名来自 add_executable例如CMakeLists.txt中写add_executable(limo_topic_cmd src/limo_topic_cmd.cpp)那么运行节点时第二个参数就是ros2 run limo_learning limo_topic_cmd注意ros2 run 后面写的不是 cpp 文件名而是 add_executable 中定义的可执行文件名错误理解ros2 run limo_learning limo_topic_cmd.cpp正确写法ros2 run limo_learning limo_topic_cmd如果add_executable写成add_executable(my_cmd_node src/limo_topic_cmd.cpp)那么运行命令应该是ros2 run limo_learning my_cmd_node4.4 ros2 run 为什么能找到节点ros2 run能找到节点需要满足几个条件。1Package.xml 中功能包名称要正确例如namelimo_learning/name2CMakeLists.txt 中要生成可执行文件add_executable(limo_topic_cmd src/limo_topic_cmd.cpp)3CMakeLists.txt 中把可执行文件安装到正确位置install(TARGETS limo_topic_cmd DESTINATION lib/${PROJECT_NAME} )4编译后要执行source install/setup.bash5完整链路可以理解为package.xml 定义功能包名 ↓ CMakeLists.txt 生成可执行文件 ↓ install 安装到 install 空间 ↓ source 刷新当前终端环境 ↓ ros2 run 找到并运行节点所以ros2 run能找到节点并不是偶然的而是前面每一步都配置正确后的结果。五、修改不同文件后是否需要重新编译5.1 修改 C 源码如果修改了 C 源码例如src/limo_learning/src/limo_topic_cmd.cpp需要重新编译。因为 C 源码需要重新生成可执行文件。推荐命令colcon build --packages-select limo_learning source install/setup.bash否则运行的还是 install 空间中的旧程序。5.2 修改 CMakeLists.txt如果修改了CMakeLists.txt也需要重新编译。例如新增了add_executable(...)或者修改了install(...)都属于编译规则发生变化。这时候必须重新执行colcon build --packages-select limo_learning source install/setup.bash5.3 修改 package.xml如果修改了package.xml例如新增依赖dependsensor_msgs/depend也建议重新编译并重新 source。因为依赖声明发生了变化。推荐流程colcon build --packages-select limo_learning source install/setup.bash5.4 修改 msg、srv、action 接口文件如果修改了自定义接口文件msg/LimoStatus.msg srv/LimoSrv.srv action/LimoAction.action一定要重新编译接口包。例如colcon build --packages-select limo_msgs source install/setup.bash因为.msg、.srv、.action文件本身只是接口描述文件。ROS2 需要根据这些文件生成 C、Python 等语言可用的代码。如果不重新编译程序里就无法使用新的接口字段。如果代码包依赖了接口包建议再编译代码包colcon build --packages-select limo_learning source install/setup.bash5.5 修改 launch、config、Python 文件修改launch、config、Python 脚本时是否需要重新编译要看安装方式。如果使用普通编译方式修改后重新编译最稳妥colcon build source install/setup.bash如果使用colcon build --symlink-install那么 launch、config、Python 脚本等文件通常会以软链接方式安装到 install 空间。这样修改后更容易立即生效。但是需要注意C 源码修改后仍然需要重新编译 msg/srv/action 接口修改后仍然需要重新编译5.6 修改文件后的编译总结表修改内容是否需要重新编译原因C 源码需要需要重新生成可执行文件CMakeLists.txt需要编译规则变了package.xml需要依赖声明可能变了msg/srv/action 接口文件需要需要重新生成接口代码Python 脚本一般需要使用--symlink-install时可能不需要launch 文件一般不需要使用--symlink-install更方便config 配置文件一般不需要多数情况是运行时读取最稳妥的做法是colcon build source install/setup.bash如果只改了某一个功能包可以使用colcon build --packages-select 功能包名 source install/setup.bash六、常见问题总结6.1 colcon build 成功但 ros2 run 找不到节点常见原因包括CMakeLists.txt 中没有 add_executableCMakeLists.txt 中没有 installinstall 的目标路径写错编译后没有 source install/setup.bashros2 run 后面的可执行文件名写错重点检查CMakeLists.txt中是否有add_executable(limo_topic_cmd src/limo_topic_cmd.cpp) install(TARGETS limo_topic_cmd DESTINATION lib/${PROJECT_NAME} )然后重新编译并刷新环境colcon build --packages-select limo_learning source install/setup.bash再运行ros2 run limo_learning limo_topic_cmd6.2 修改代码后运行结果没有变化最常见原因是修改了 src 里的代码但是没有重新 colcon build因为 ROS2 运行的是 install 空间里的结果不是直接运行 src 里的源代码。解决方法colcon build --packages-select limo_learning source install/setup.bash然后重新运行节点。6.3 ros2 pkg list 找不到功能包可能原因功能包没有放在工作空间 src 目录下功能包结构不完整没有执行 colcon build编译后没有 source install/setup.bash可以按下面流程检查cd ~/agilex_open_class_ws colcon build source install/setup.bash ros2 pkg list | grep limo如果还找不到需要检查功能包目录中是否有package.xml CMakeLists.txt6.4 找不到自定义 msg、srv、action 接口常见原因包括接口包没有编译接口文件修改后没有重新编译没有 source install/setup.bash代码包没有依赖接口包CMakeLists.txt 中没有 find_package(limo_msgs REQUIRED)解决方法colcon build --packages-select limo_msgs source install/setup.bash colcon build --packages-select limo_learning source install/setup.bash检查接口是否生成成功ros2 interface show limo_msgs/msg/LimoStatus ros2 interface show limo_msgs/srv/LimoSrv ros2 interface show limo_msgs/action/LimoAction七、本章总结7.1 colcon build 的核心作用colcon build用来编译 ROS2 工作空间。它会根据功能包中的package.xml CMakeLists.txt完成依赖解析、编译、安装等过程。执行后通常会生成build install log其中最关键的是install因为 ROS2 运行时通常会从 install 空间中查找可执行文件、接口文件和启动文件。7.2 source 的核心作用source install/setup.bash用来刷新当前终端环境。它让当前终端知道有哪些新的功能包有哪些新的节点有哪些新的接口这些内容安装在哪里如果没有 source就可能出现编译成功了但终端找不到功能包或节点7.3 ros2 run 的核心理解ros2 run的基本格式是ros2 run 功能包名 可执行文件名其中功能包名来自 package.xml 中的 name可执行文件名来自 CMakeLists.txt 中的 add_executable所以完整链路是package.xml 定义功能包名 ↓ CMakeLists.txt 生成可执行文件 ↓ install 安装到 install 空间 ↓ colcon build 执行编译安装 ↓ source 刷新终端环境 ↓ ros2 run 运行节点