ROS机器人项目(Ucar)故障排查与解决方案

John Doe Lv1

ROS机器人项目(Ucar)故障排查与解决方案文档

引言

本文档全面总结Ucar ROS机器人项目的复杂故障排查过程,涵盖从C++代码逻辑错误、内存管理问题到嵌入式系统(Rockchip主板)图形驱动与ROS网络配置问题的完整解决方案。记录每个问题的症状、根本原因、解决方案及相关指令,形成可供参考的调试经验。

问题一:音频播放失败(”文件未找到”)

症状

节点播放唤醒音或回复音时出现错误:

1
play FAIL formats: can't open input file '/audio/wakeup.wav': No such file or directory

根本原因

程序代码使用硬编码绝对路径(/audio/wakeup.wav),系统从文件系统根目录查找,而非ROS功能包相对路径,导致查找失败。

解决方案

修改C++代码,动态获取功能包绝对路径并与音频文件相对路径拼接。

推荐代码实现(以AIUITester.cpp中的process_recv函数为例)

1
2
3
4
5
6
7
8
9
10
11
// 1. 包含头文件
#include <ros/package.h>

// 2. 构建完整路径
std::string package_path = ros::package::getPath("speech_command");
if (!package_path.empty()) {
// WAKEUP_RESPONSE_WAV 是Global.h中定义的相对路径 "/audio/wakeup.wav"
std::string wav_path = package_path + WAKEUP_RESPONSE_WAV;
std::string command = "play " + wav_path;
system(command.c_str());
}

问题二:音频播放失败(”无法确定文件类型”)

症状

解决”文件未找到”问题后,出现新错误:

1
play FAIL formats: can't determine type of file '/home/ucar/ucar_ws/src/speech_command'

根本原因

语音识别结果在offline_QA.txt配置文件中无完全匹配条目,导致FindDocument()函数返回空字符串,路径拼接后仅剩功能包路径(目录),程序试图播放目录而非音频文件。

解决方案

数据层面

检查并确保config/offline_QA.txt包含所有需响应的语音指令,且与程序识别文本(含标点)完全对应。

代码层面

增加代码健壮性,在播放音频前检查文件路径是否为空。

推荐代码实现(aiuiMain.cpp的data_send函数)

1
2
3
4
5
6
7
8
9
10
11
string document = FindDocument(question_str);

// 增加路径非空判断
if (!document.empty()) {
string ros_package_path1 = ros::package::getPath("speech_command");
std::string wav_path1 = ros_package_path1 + document;
std::string command1 = "play " + wav_path1;
system(command1.c_str());
} else {
cout << "未找到问题对应的音频文件: " << question_str << endl;
}

问题三:节点启动时崩溃(音频设备占用与内存错误)

症状

roslaunch启动时节点异常退出,关键错误:

根本原因

设备占用

另一进程(如其他ROS节点、系统服务)占用程序所需音频设备(实际为hw:XFMDPV0018,日志打印存在误导)。

内存错误

AIUITester.cpp中使用audioRecorder->~AudioRecorder();非标准方式调用析构函数,导致内存重复释放。

解决方案

设备占用

  1. 在机器人终端使用fuser -v /dev/snd/*命令查找并kill占用音频设备的进程。
  2. (可选)修正AIUITester.cpp中的printf语句,打印正确设备名pcm_name

内存错误

修改AIUITester.cppdestory函数,使用标准delete关键字释放对象。

代码修正

1
2
3
// 在 AIUITester::destory() 中
// 修改前: audioRecorder->~AudioRecorder();
// 修改后: delete audioRecorder;

问题四:RViz启动失败(图形驱动与主机名解析)

![在这里插入图片描述](https://i-blog.csdnimg.cn/direct/1cd08c500dac4300859417327bff6030.png

阶段A:RViz因图形驱动不兼容崩溃

症状

启动RViz时出现libGL error: unable to load driver: rockchip_dri.so错误并伴随Segmentation fault段错误。

根本原因

Ucar机器人嵌入式环境(Rockchip主板)缺少或无法加载RViz依赖的3D硬件加速驱动;启动文件ucar_gmapping.launch错误包含本地启动RViz的节点。

解决方案

  1. 修改启动文件:编辑~/ucar_ws/src/ucar_map/launch/ucar_gmapping.launch,注释掉RViz节点。
  2. 采用”PC端远程可视化”方案(ROS开发标准工作流程)。

阶段B:RViz在PC端启动但无法显示数据

症状

PC端RViz启动成功但不显示机器人数据,报错:

1
Couldn't find an AF_INET address for [superbrain]: 域名解析暂时失败

在这里插入图片描述

根本原因

PC操作系统不识别机器人主机名superbrain,无法解析为IP地址,导致节点通信失败。

解决方案

方法1(推荐):设置ROS_IP(机器人端)
1
2
3
4
5
6
7
# 启动roscore终端
export ROS_IP=<机器人IP地址>
roscore

# 启动主程序终端
export ROS_IP=<机器人IP地址>
roslaunch ucar_map ucar_gmapping.launch
方法2(备选):手动映射主机名到IP
  • Linux/Mac:编辑/etc/hosts
  • Windows:以管理员身份编辑C:\Windows\System32\drivers\etc\hosts
    添加:192.168.141.32 superbrain(IP替换为机器人实际IP)

问题五:ROS网络核心roscore启动失败

症状

机器人运行roscore时报错:

1
RLException: Unable to contact my own server at [...]

根本原因

机器人环境变量ROS_IP设置为过时或错误IP(可能固化在~/.bashrc中),导致roscore无法自通信。

解决方案

  1. 临时取消设置:unset ROS_IPunset ROS_HOSTNAME
  2. 检查并编辑~/.bashrcnano ~/.bashrc,注释掉export ROS_IP=...行。
  3. 刷新配置:source ~/.bashrc
    在这里插入图片描述

总结与最佳实践

核心开发原则

  1. 计算与可视化分离
    嵌入式项目中,计算密集型无界面节点(驱动、算法)运行在机器人上,图形工具(RViz、rqt_plot)运行在PC端。
  2. 稳健的网络配置
    多机通信优先使用IP地址配置(通过ROS_IPROS_MASTER_URI),避免主机名解析失败导致通信中断。
  3. 规范的编码与内存管理
    遵循C++标准内存管理(new/delete配对),避免非规范操作(如手动调用析构函数)。
  4. 系统性调试思路
    从日志入手,逐层分析(应用层代码逻辑→环境层驱动/网络),定位问题时采用”排除法”缩小范围。

额外建议

  • 定期检查系统资源占用(如音频设备、端口),使用fuserlsof等工具排查冲突。
  • 维护清晰的环境变量配置,避免在.bashrc中固化静态IP,改为动态设置。
  • 开发阶段保留详细调试日志,便于复现和追溯问题。
  • Title: ROS机器人项目(Ucar)故障排查与解决方案
  • Author: John Doe
  • Created at : 2025-07-25 18:17:59
  • Updated at : 2025-07-27 13:07:04
  • Link: https://redefine.ohevan.com/2025/07/25/ROS机器人项目(Ucar)故障排查与解决方案/
  • License: This work is licensed under CC BY-NC-SA 4.0.
Comments