You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何强制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

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.05.06 06:48:18