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
更多推荐


所有评论(0)