NOTE · Autonomous Systems
ROS1、catkin 与 PX4:历史工程的可验证排障链
面向 ROS Noetic 历史工程,按环境、依赖、构建、运行图和 ABI 逐层定位问题。
ROS Noetic 和 ROS1 已结束官方支持,不再获得常规安全更新、新修复或新二进制。新项目应优先评估 ROS 2;必须复现 ROS1 工程时,则把操作系统、ROS、Gazebo、PX4、CUDA/OpenCV 和编译器视为一个不可随意拆开的版本集合。参见 ROS 官方 Noetic EOL 说明。
一些历史教程推荐第三方“一键安装”脚本,并使用 HTTP 下载后直接在当前 shell 执行。本文不提供这种可复制命令:无论脚本作者是否可信,下载内容都可能变化,直接 source 还会继承当前 shell 权限。历史工程应优先使用已归档的 ROS 软件源、项目自己的容器或虚拟机定义和锁定提交;操作前保存镜像或快照。
1. 先确认当前 shell 到底加载了什么
printenv ROS_DISTRO
printenv ROS_PACKAGE_PATH
command -v roscore
python3 --version
rospack profile
工作空间示例:
source /opt/ros/noetic/setup.bash
source ~/catkin_ws/devel/setup.bash
rospack find PACKAGE_NAME
若 rospack find 找不到包,先检查:
- 包是否真的在当前工作空间的
src下; package.xml与目录结构是否完整;- 当前 shell 是否 source 了正确的
setup.bash; - 是否同时 source 了多个互相覆盖的工作空间。
不要把个人绝对路径写进公共 launch 文件或 .bashrc;优先使用 $(find package_name)、环境变量或工作空间相对路径。
旧 XTDrone 工程里常见的 Resource not found 也先按这条链检查。原错误明确混入了另一台机器的 overlay:
ROS path [0]=/opt/ros/melodic/share/ros
ROS path [1]=/home/<other-user>/catkin_ws/src
看到错误输出列出另一个用户的工作空间,通常说明当前 shell source 了错误 overlay,而不只是“缺一个包”。GAZEBO_MODEL_PATH 与 GAZEBO_PLUGIN_PATH 只有在项目确实使用非标准资源目录时才添加,并应在启动脚本中局部设置,不永久拼接未知路径。
2. catkin 构建:固定一种工具和根目录
catkin_make 应在工作空间根目录执行:
cd ~/catkin_ws
catkin_make
source devel/setup.bash
catkin build 属于 catkin_tools 的另一套工作流:
cd ~/catkin_ws
catkin config --cmake-args -DCMAKE_BUILD_TYPE=Release
catkin build PACKAGE_NAME
source devel/setup.bash
同一个工作空间里不要无意识地交替使用两套工具。遇到错误先保存完整的第一处编译错误、CMake 配置和包版本,而不是立即删除整个 build、devel。
依赖检查:
rosdep check --from-paths src --ignore-src
若决定让 rosdep 安装缺失依赖,应先确认发行版软件源和锁定版本,再执行:
rosdep install --from-paths src --ignore-src -r -y
3. xacro 与 launch 文件
Noetic 中优先调用 xacro 可执行程序,不依赖旧的 xacro.py 路径:
<param
name="robot_description"
command="$(find xacro)/xacro '$(find ROBOT_PACKAGE)/urdf/robot.xacro'" />
单独验证生成结果:
rosrun xacro xacro PATH_TO_FILE.xacro > /tmp/robot.urdf
check_urdf /tmp/robot.urdf
这能把 xacro 语法/资源路径问题与 launch、Gazebo 问题分开。
一个具体案例是 Noetic 工程仍调用 $(find xacro)/xacro.py,错误中记录了当时的工程路径:
/home/<user>/catkin_ws/src/catvehicle/urdf/catvehicle1-3.xacro
/home/<user>/PX4_Firmware/launch/outdoor3_ugv.launch
把 launch 中的 $(find xacro)/xacro.py 改成发行版实际提供的 $(find xacro)/xacro 是有价值的,但还应先单独运行上面的生成命令;如果 URDF 本身、包资源或宏参数错误,只换可执行文件名并不会修好。
4. 运行图排查
rosnode list
rosnode info /NODE_NAME
rostopic list
rostopic info /TOPIC_NAME
rostopic hz /TOPIC_NAME
rostopic echo -n 1 /TOPIC_NAME
rosservice list
数据链路至少核对:
- 发布者和订阅者是否存在;
- 消息类型是否一致;
- 时间戳是否推进;
frame_id与 TF 树是否一致;- 频率和延迟是否满足控制回路;
- 多机命名空间是否真正隔离。
只看到 topic 名称并不能证明数据有效。
5. 命令行调用 ROS 服务
先获取服务类型和请求结构:
rosservice info /SERVICE_NAME
rosservice type /SERVICE_NAME
rossrv show PACKAGE_NAME/ServiceType
无字段请求:
rosservice call /SERVICE_NAME "{}"
带字段请求:
rosservice call /SERVICE_NAME "{field_name: value}"
复杂消息先用 rossrv show 展开字段,再按照 YAML 结构填写。飞行控制服务还应在调用前核对模式、解锁状态、坐标系、单位和失联保护;“服务返回成功”不等于飞行行为安全。
Turtlesim 完整例子
下面用安全的教学例子说明流程。先在测试环境启动 turtlesim_node,再查看服务:
rosservice list
rosservice info /turtle1/teleport_absolute
rosservice type /turtle1/teleport_absolute
rossrv show turtlesim/TeleportAbsolute
该服务的请求字段通常是 x、y 和 theta。确认类型输出一致后调用:
rosservice call /turtle1/teleport_absolute "{x: 2.0, y: 3.0, theta: 1.57}"
这里 theta 使用弧度。这个例子验证的是服务发现、类型和 YAML 请求格式,不代表真实机器人服务可以跳过状态检查。
6. Gazebo、PX4 与感知包的版本冲突
以下症状经常来自版本集合不一致:
- 找不到
gazebo_rosConfig.cmake; - PX4/SITL 插件编译失败;
- 旧 CMakeLists 固定了 GPU 架构;
- Darknet、OpenCV 和
cv_bridge的 ABI 不一致; - Python 包与系统 C++ 库来自不同前缀。
先收集:
gazebo --version
pkg-config --modversion opencv4
python3 -c 'import cv2; print(cv2.__version__, cv2.__file__)'
nvcc --version
cmake --version
再检查 CMake 实际找到的 include/library 路径和编译架构。不要把以下做法当作通用修复:
- 手工覆盖
/opt/ros中自动生成的 CMake 配置; - 把一长串本机绝对
.so路径写死; - 为解决一个包而降级整机 OpenCV;
- 没有备份就清空整个工作空间的构建产物;
- 从 HTTP 下载未知脚本后直接 source 执行。
如果项目必须依赖旧 ABI,最可复现的方式通常是锁定容器/虚拟机镜像或单独的构建环境,并把补丁保存在版本库中。
旧工程中的具体症状
以下内容按“症状 → 证据”整理;不提供风险较高的整机覆盖配方:
Could not find gazebo_rosConfig.cmake:先用rospack find gazebo_ros、rosdep check和 CMake 输出确认包是否存在、当前发行版是什么以及搜索前缀来自哪里。不要因为错误文本出现gazebo_ros就跨发行版安装一个同名二进制包。FAILED: external/Stamp/sitl_gazebo/...-configure:保存 CMake 的第一处错误,核对 PX4 提交、Gazebo 主版本、编译器和子模块状态;最后一行的 stamp 失败不是根因。- Gazebo 界面不显示激光射线:可视化开关与传感器是否发布有效数据是两件事。检查对应 topic 类型、频率、时间戳和 frame,再处理 GUI 显示。
- Python 报
(e_errno, msg, *_) = e.args一类解包错误:通常应检查脚本预期的 Python/依赖版本和真实异常对象,不直接把这一行改成“能运行”的固定索引。 - Fast-Planner 或其他老包编译失败:先确认仓库提交、ROS/Gazebo/Eigen/PCL 组合以及第一处编译错误。旧博客标题不能替代构建日志。
Darknet ROS、CUDA 与 OpenCV 的历史 ABI 案例
旧机在 /home/<user>/catkin_ws/src/darknet_ros/darknet_ros/CMakeLists.txt 中曾出现 nvcc fatal: Unsupported gpu architecture 'compute_89',当时使用 CUDA 11.7,随后通过把架构改成 compute_86、源码安装 OpenCV 3.4.14、覆盖 cv_bridgeConfig.cmake 和写死本机动态库路径来推进编译。路径和版本作为历史证据保留,但这套过程不能作为通用方案:
- GPU 的实际计算能力、NVCC 支持的 code 列表和项目 CMake 声明必须同时匹配;把
89改成86可能只是生成兼容代码,不代表解决了工具链版本问题。 OpenCV 4.x+ requires enabled C++11 support首先指向编译标准/构建配置,不自动推出“必须降级到 OpenCV 3.4.14”。_IplImage::_IplImage(cv::Mat&)属于旧 C API 与新版 OpenCV 的兼容边界;临时宏只能服务锁定源码,不能证明 ABI 完整一致。/opt/ros的cv_bridge配置由软件包管理,手工写入/usr/local/lib/libopencv_*.so会让升级、卸载和复现失去一致性。
恢复这类工程时先收集:
nvidia-smi
nvcc --version
nvcc --list-gpu-code
pkg-config --modversion opencv4
python3 -c 'import cv2; print(cv2.__version__, cv2.__file__)'
rospack find cv_bridge
ldd DEVEL_SPACE/lib/LIBRARY_NAME.so
DEVEL_SPACE 和 LIBRARY_NAME 是占位符。结合 CMake cache、编译命令和 ldd 判断实际头文件/动态库来源,再决定是补项目源码、锁容器还是重建单独前缀。不要卸载整机 Python OpenCV,也不要覆盖 /opt/ros。
7. 日志
rosclean check
du -sh ~/.ros/log
rosclean purge 会删除 ROS 日志,确认不再需要排查证据后才执行。遇到 logging 配置错误时,应先核对 ROS_HOME、文件存在性和权限,不要未经确认就在 /etc 创建或覆盖配置。
遇到 WARNING: cannot load logging configuration file, logging is disabled 时,有人会直接在 /etc/ros 复制 python_logging.conf。更稳妥的顺序是先记录当前解析位置:
printf 'ROS_HOME=%s\n' "${ROS_HOME:-$HOME/.ros}"
test -r /opt/ros/noetic/etc/ros/python_logging.conf
find "${ROS_HOME:-$HOME/.ros}" -maxdepth 2 -type f -name '*logging*.conf' -print 2>/dev/null
然后结合启动日志确认它究竟请求哪个路径、由哪个用户运行、是否是环境变量或权限问题。只有确认发行版规范和目标路径后才复制配置,并保留回滚;不能把创建 /etc/ros 当成所有 logging warning 的答案。
GeographicLib 数据下载慢、PX4 子模块缺失等问题依赖具体 PX4 提交。优先使用该提交自带的安装脚本或文档并核对下载文件;不要从第三方帖子复制镜像 URL 后直接覆盖系统数据集。
8. 不建议沿用的做法
- 第三方 HTTP 一键安装脚本;
- 故障日志中的个人主目录已泛化;工程路径只作为上下文,不写成可移植配置;
- 覆盖
/opt/ros、硬编码本机 OpenCV 动态库的步骤; - 未经证实的“装某个包即可”结论;
- 与特定实验机器绑定的 CUDA 架构和删除命令;
- 旧截图和身份页脚。
保留下来的重点是故障分层:shell 环境 → 依赖 → 构建 → ROS 图 → 坐标/时间/ABI。
9. 版本化资料入口
旧 CSDN/Cnblogs 错误链接不再作为解决方案正文,但错误字符串和案例已经保留,便于按锁定版本继续检索。
参考资料与书签
以下 14 条只用于锁定旧 ROS1/PX4 工程时检索。ROS Noetic 已 EOL,第三方一键脚本和跨版本包安装尤其不能直接执行;先核对发行版、仓库提交、脚本内容、HTTPS、依赖和可回滚镜像。
- ros 安装 (推荐使用鱼香 ros 安装工具,少走很多弯路)
- 鱼香 ros 一键安装指令
- ros 清理 log 文件
- ROS logging configuration warning
- 搭建无人机仿真环境之 px4 安装中出现的一些问题的解决
- install_geographiclib_datasets.sh 安装数据集时下载很慢
- roslaunch px4 multi_uav_mavros_sitl_sdf.launch 报错
- fastplanner编译错误
- (e_errno, msg, *_) = e.args 问题
- gazebo 不显示激光雷达的射线
- px4报错FAILED: external/Stamp/sitl_gazebo/sitl_gazebo-configure 解决
- YOLO 踩坑:编译 darknet_ros 报错 no matching function for call to ‘_IplImage::_IplImage(cv::Mat&)’
- SSH key 设置教程
- Darknet ROS 同一 ABI 文章的再次引用