ROS踩坑|用一个节点订阅和发布多个话题

问题描述

写了一个节点,要从激光雷达发布的话题中订阅点云信息,并将点云信息处理之后再发布出去。涉及到一个节点同时订阅和发布多个话题。
测试时发现节点只能订阅,不能发布话题,且订阅的话题数据也无法使用。

解决办法

经过查找才发现,是因为自己把发布topic的函数写在main函数中了,这就造成订阅的数据无法被发布的函数使用,因为只能在订阅的回调函数中才能使用该信息。因此我的解决办法是把发布topic的函数 写在了订阅回调中即可。
参考链接中给出了另一种解决办法:定义了一个类,把publisher和subscriber都放入类中。
这里我粘贴处第一种方法的代码 想看第二中方法的自行点击链接


```cpp
# include<ros/ros.h>
# include<std_msgs/String.h>
# include<std_msgs/Float32.h>

// 定义为全局变量
static ros::Subscriber sub1;
static ros::Subscriber sub2;
static ros::Publisher pub1;
static ros::Publisher pub2;

// 回调函数1
void callback1(const std_msgs::Float32ConstPtr& flt){ 
    std_msgs::Float32 pub_flt;
    pub_flt.data = flt->data+0.4;
    pub1.publish(pub_flt);

    std::cout<<"receive flt:"<<flt->data<<std::endl;
    std::cout<<"publish flt:"<<pub_flt.data<<std::endl;
};

// 回调函数2
void callback2(const std_msgs::StringConstPtr& str){ 
    std_msgs::String str_msg;
    str_msg.data = str->data+" hahaha";
    pub2.publish(str_msg);

    std::cout<<"receive str:"<<str->data<<std::endl;
    std::cout<<"publish str:"<<str_msg.data<<std::endl;
}


int main(int argc, char *argv[])
{ 
    // 初始化ROS并指定节点名称
    ros::init(argc, argv, "subscribe_publish2");
    // 创建节点句柄
    ros::NodeHandle nh;
    
    // 利用节点句柄对sub和pub初始化
    sub1 = nh.subscribe("topic_flt",1,callback1);
    sub2 = nh.subscribe("topic_str",1,callback2);
    pub1 = nh.advertise<std_msgs::Float32>("processed_flt", 1);
    pub2 = nh.advertise<std_msgs::String>("processed_str",1);

    // 循环执行
    ros::spin();
    return 0;
}

另外 如何想要设置发布和订阅不同的频率 可以使用pubrate函数

  ros::Rate pub_rate(50);
  //让其在主题“/cmd_vel”发布速度控制消息,启智ROS的核心节点会从这个主题获取vel_pub发布的消息,并控制机器人底盘执行消息包里的速度值。
  vel_pub.publish(vel_cmd);
    //循环等待回调函数
  pub_rate.sleep();

参考资料

http://zhaoxuhui.top/blog/2019/10/20/ros-note-7.html

    原文作者:David小伟同学
    原文地址: https://blog.csdn.net/JeSuisDavid/article/details/121304217
    本文转自网络文章,转载此文章仅为分享知识,如有侵权,请联系博主进行删除。
点赞