如何强制ROS diagnostic_updater发布至其他话题?
如何让ROS diagnostic_updater发布到指定话题
好问题!我之前也碰到过类似的需求,diagnostic_updater默认确实硬绑定了/diagnostics话题,但有两种可行的方案可以实现自定义话题发布:
方案1:自定义Updater子类,替换内部发布者
diagnostic_updater的核心类Updater内部维护了一个ros::Publisher对象,默认在构造时创建为/diagnostics话题的发布者。我们可以通过继承该类,重写发布者的初始化逻辑,或者添加接口来替换发布者:
#include <diagnostic_updater/diagnostic_updater.h> class CustomTopicUpdater : public diagnostic_updater::Updater { public: // 构造函数:指定自定义话题名创建发布者 CustomTopicUpdater(ros::NodeHandle& nh, const std::string& topic_name) { // 替换父类的pub_成员,创建自定义话题的发布者 pub_ = nh.advertise<diagnostic_msgs::DiagnosticArray>(topic_name, 1); } // 可选:提供动态修改发布者的接口 void setCustomPublisher(ros::NodeHandle& nh, const std::string& topic_name) { pub_ = nh.advertise<diagnostic_msgs::DiagnosticArray>(topic_name, 1); } }; // 使用示例 int main(int argc, char** argv) { ros::init(argc, argv, "custom_diagnostic_node"); ros::NodeHandle nh; // 创建自定义话题的Updater,比如发布到/my_diagnostics CustomTopicUpdater updater(nh, "/my_diagnostics"); // 添加你的诊断任务 updater.add("Example Task", [](diagnostic_updater::DiagnosticStatusWrapper& stat) { stat.summary(diagnostic_msgs::DiagnosticStatus::OK, "Everything is fine"); stat.add("Metric", 42); }); ros::Rate rate(1.0); while (ros::ok()) { updater.update(); ros::spinOnce(); rate.sleep(); } return 0; }
方案2:手动管理诊断消息与发布者
如果不想继承子类,也可以完全绕开Updater的自动发布逻辑,手动收集诊断任务的结果,然后通过自定义发布者发送:
#include <diagnostic_updater/diagnostic_updater.h> int main(int argc, char** argv) { ros::init(argc, argv, "manual_diagnostic_node"); ros::NodeHandle nh; // 创建自定义话题的发布者 ros::Publisher diag_pub = nh.advertise<diagnostic_msgs::DiagnosticArray>("/my_diagnostics", 1); diagnostic_updater::DiagnosticArray diag_array; diag_array.header.frame_id = ""; // 定义诊断任务 auto example_task = [](diagnostic_updater::DiagnosticStatusWrapper& stat) { stat.summary(diagnostic_msgs::DiagnosticStatus::OK, "Manual task running"); stat.add("Temperature", 25.0); }; ros::Rate rate(1.0); while (ros::ok()) { diag_array.status.clear(); diag_array.header.stamp = ros::Time::now(); // 执行诊断任务并添加到消息中 diagnostic_updater::DiagnosticStatusWrapper stat; example_task(stat); diag_array.status.push_back(stat); // 发布到自定义话题 diag_pub.publish(diag_array); ros::spinOnce(); rate.sleep(); } return 0; }
注意事项
- 两种方案都需要确保你的诊断消息订阅者监听的是你指定的话题,否则无法接收消息。
- 如果使用方案1,注意父类
Updater的pub_成员是protected权限,子类直接访问修改是ROS设计允许的合法操作。
内容的提问来源于stack exchange,提问作者Guilty Spark
相关产品推荐
相关产品推荐

