[ROS学习]ros创建线程进行消息发布的思路

ROS多线程消息发布

ROS消息接收再转发的程序设计中,会遇到如下需求:

  1. 现有一A话题
  2. 节点B订阅A话题
  3. 节点B接收到A话题msg消息的特定值时如 msg={"你可以停止接收了"},停止订阅A话题
  4. 节点B发布话题C

在对该需求进行程序设计时,一开始想以这样的框架完成需求

// 仅为框架,不阐述细节
#include "..."
// 订阅消息A的回调函数
void callback(Date_type& msg)
{
    if(msg=="你可以停止接收了")
    {
        // 取消订阅A
        sub_A.shutdown();
        return;
    }
}

int main(...)
{
    ...;
    sub_A = n.subscribe(A,n,callback);
    pub_C = n.advertise(C,1000,true);
    ros::Rate loop_rate(10);
    while(ros::ok())
    {
        // 发布C的消息
        pub(C_msg);
        
        ros::spinOnce();
        // 补足发布频率
        loop_rate.sleep();
	}
    ros::spin();
}

但是发现订阅消息A的回调函数callback不执行,猜测可能是由于ros消息订阅的回调函数是在 ros::spin()中触发的,我们在ros::spin()前加了while循环导致订阅A的回调不能正常触发。

如果将该问题拆分为两个节点或者三个节点来处理,应该也可以解决该需求,但显然有些繁琐。

参考VINS-MONO中的多线程操作,尝试创建一个线程来解决问题。

程序设计框架如下

// 仅为框架,不阐述细节
#include "..."
bool flag = false;

// 订阅消息A的回调函数
void callback(Date_type& msg)
{
    if(msg=="你可以停止接收了")
    {
        // 取消订阅A
        sub_A.shutdown();
        flag = true;
        return;
    }
}
void pub_process()
{
    ros::Rate loop_rate(10);
    while(ros::ok())
    {
        // 消息发布标志
        if(flag == false)continue;
        pub_C(C_msg);
        ros::spinOnce();
        loop_rate.sleep();
    }
}
int main(...)
{
    ...;
    sub_A = n.subscribe(A,n,callback);
    pub_C = n.advertise(C,1000,true);
    // 创建一个发布线程,并链接函数
    std::thread measurement_process{pub_porcess};
    ros::Rate(20);
    ros::spin();
}

该框架可以完成本文的问题的需求,但就程序设计而言,线程间的变量传递应该完成加锁与解锁的操作,后续如果有时间会补上这一部分(挖个坑先)。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值