Ubuntu22.04下ROS2+C++音频程序:crontab自启无声音问题排查
Ubuntu 22.04下ROS2 C++音频程序crontab开机自启无输出问题排查
问题描述
在Ubuntu 22.04环境下基于ROS2开发C++程序,功能为通过扬声器提示机器人目标跟随状态:
- 无目标时静音
- 检测到目标时播放music1
- 丢失目标时播放music2
手动运行程序时音频播放正常,但通过crontab设置开机自启后,程序可运行但无音频输出。两台测试PC一台正常、一台异常,需排查遗漏的配置点或可能原因。
程序代码
int g_target_detecting_state = 0; // global variable to save status void clusteringNode::timer_callback() { // Determine status, ROS code } void followingSoundPlay(void) // (const char* filename) { sf::SoundBuffer go_buffer, stop_buffer; if (!go_buffer.loadFromFile("audio/music1.wav") || !stop_buffer.loadFromFile("audio/music2.wav")) { std::cerr << "load failed!"; } sf::Sound go_sound, stop_sound; go_sound.setBuffer(go_buffer); stop_sound.setBuffer(stop_buffer); while(1) { if(g_target_detecting_state == 0) { go_sound.stop(); stop_sound.stop(); } else if(g_target_detecting_state == 1) { stop_sound.stop(); go_sound.play(); } else if(g_target_detecting_state == 2) { go_sound.stop(); stop_sound.play(); } std::this_thread::sleep_for(std::chrono::milliseconds(1000)); } } int main(int nArgc,const char* pszArgv[]) { rclcpp::init(nArgc, pszArgv); auto node = std::make_shared<clusteringNode>(); std::thread ros_thread([&](){ rclcpp::spin(node); }); std::thread play_thread(followingSoundPlay); if(ros_thread.joinable()) ros_thread.join(); if(play_thread.joinable()) play_thread.join(); rclcpp::shutdown(); return 0; }
可能的原因及解决办法
- 环境变量缺失:crontab运行时的环境变量与用户登录后差异大,音频(如
PULSE_SERVER、DISPLAY)和ROS2相关变量(如ROS_DOMAIN_ID、LD_LIBRARY_PATH)可能未加载。解决:在crontab启动命令前添加source /home/your_user/.bashrc &&,或直接在crontab中export必要变量。 - 音频设备权限不足:crontab运行程序的用户可能无音频设备访问权限。解决:检查用户是否属于
audio组(执行sudo usermod -aG audio your_user添加);若使用PulseAudio,需配置允许无桌面会话访问。 - 相对路径错误:程序中音频文件用相对路径
audio/music1.wav,但crontab默认工作目录为用户home,导致文件找不到。解决:改用绝对路径(如/home/your_user/ros_ws/src/your_package/audio/music1.wav),或启动命令前先cd到程序所在目录(cd /path/to/program && ./your_program)。 - PulseAudio会话未关联:Ubuntu默认用PulseAudio管理音频,crontab启动时未关联有效会话。解决:在启动命令中指定PulseAudio服务器(先通过
echo $PULSE_SERVER获取socket路径,再在crontab中export该变量),或先执行pulseaudio --start再启动程序。 - 线程安全问题:全局变量
g_target_detecting_state无锁,多线程访问可能导致状态判断异常。解决:添加std::mutex,在timer_callback和followingSoundPlay中访问变量时加锁。
内容的提问来源于stack exchange,提问作者chobo
相关产品推荐
相关产品推荐

