ROS自学实践(10):ROS节点同时订阅多个话题并进行消息时间同步

一、前言

在进行SLAM建图或自动驾驶系统设计的过程中,往往涉及到多种传感器进行环境感知和信息采集,这就不仅需要一个节点接收多个传感器数据,还要求传感器数据的时间戳同步,这样才能实现环境数据的实时感知和处理。本文基于ROS操作系统,从C++和python两个角度进行试验,方便后续的开发工作。

二、创建ROS包

mkdir -p multi_receive/src
cd multi_receive/src
catkin_create_pkg multi_receive roscpp rospy sensor_msgs geometry_msgs
cd ..
catkin_make

三、创建multi_receive.cpp文件(C++版)

#include <ros/ros.h>
#include "sensor_msgs/LaserScan.h"
#include "geometry_msgs/PoseWithCovarianceStamped.h"
#include <message_filters/subscriber.h>
#include <message_filters/synchronizer.h>
#include <message_filters/sync_policies/approximate_time.h>
#include <message_filters/time_synchronizer.h>
#include <boost/thread/thread.hpp>
#include <iostream>

void multi_callback(const sensor_msgs::LaserScanConstPtr& scan, const geometry_msgs::PoseWithCovarianceStampedConstPtr& pose)
{
    std::cout << "同步完成!" << std::endl;
}

int main(int argc, char** argv)
{
    ros::init(argc, argv, "multi_receiver");
    ros::NodeHandle n;

    message_filters::Subscriber<sensor_msgs::LaserScan> subscriber_laser(n,"scan",1000,ros::TransportHints().tcpNoDelay());
    message_filters::Subscriber<geometry_msgs::PoseWithCovarianceStamped> subscriber_pose(n,"car_pose",1000,ros::TransportHints().tcpNoDelay());
    
    typedef message_filters::sync_policies::ApproximateTime<sensor_msgs::LaserScan, geometry_msgs::PoseWithCovarianceStamped> syncPolicy;
    //message_filters::TimeSynchronizer<sensor_msgs::LaserScan,geometry_msgs::PoseWithCovarianceStamped> sync(subscriber_laser, subscriber_pose, 10);
    message_filters::Synchronizer<syncPolicy> sync(syncPolicy(10), subscriber_laser, subscriber_pose);  
    sync.registerCallback(boost::bind(&multi_callback, _1, _2));
    
    std::cout << "hahah" << std::endl;

    ros::spin();
    return 0;
}

编译之前别忘了添加

add_executable(multi_receive src/multi_receive.cpp)
target_link_libraries(multi_receive ${catkin_LIBRARIES})

在这里插入图片描述

四、创建multi_receive.py文件(python版)

在/multi_receive文件夹下,添加scripts文件夹,创建multi_receive.py文件并添加如下内容:

#!/usr/bin/env python
# coding=UTF-8
import rospy,math,random
import numpy as np
import message_filters
from std_msgs.msg import String
from sensor_msgs.msg import LaserScan
from laser_geometry import LaserProjection
from geometry_msgs.msg import PoseWithCovarianceStamped

def multi_callback(Subcriber_laser,Subcriber_pose):
    print "同步完成!"

if __name__ == '__main__':
    rospy.init_node('multi_receive',anonymous=True)

    subcriber_laser = message_filters.Subscriber('scan', LaserScan, queue_size=1)
    subcriber_pose  = message_filters.Subscriber('car_pose', PoseWithCovarianceStamped, queue_size=1)
    
    sync = message_filters.ApproximateTimeSynchronizer([subcriber_laser, subcriber_pose],10,0.1,allow_headerless=True)

    sync.registerCallback(multi_callback)

    rospy.spin()

在这里插入图片描述
参考文献:
1.https://blog.csdn.net/orange_littlegirl/article/details/97425696
2.https://blog.csdn.net/weixin_33895516/article/details/93522384
3.https://www.cnblogs.com/shepherd2015/p/11995769.html

  • 14
    点赞
  • 166
    收藏
    觉得还不错? 一键收藏
  • 21
    评论
ROS 2中,可以使用`message_filters`库来现多个话题时间同步。以下是一个示例的C++代码,展示了如何同时订阅两个话题进行时间同步: ```cpp #include <rclcpp/rclcpp.hpp> #include <message_filters/subscriber.h> #include <message_filters/time_synchronizer.h> #include <sensor_msgs/msg/image.h> #include <sensor_msgs/msg/laser_scan.h> using namespace std::placeholders; void callback(const sensor_msgs::msg::Image::ConstSharedPtr& image_msg, const sensor_msgs::msg::LaserScan::ConstSharedPtr& laser_msg) { // 这里是回调函数,接收到两个话题的数据后进行处理 // image_msg 是 sensor_msgs/Image 消息类型的数据 // laser_msg 是 sensor_msgs/LaserScan 消息类型的数据 // 在这里进行时间同步后的处理逻辑 // ... } int main(int argc, char** argv) { rclcpp::init(argc, argv); auto node = rclcpp::Node::make_shared("time_sync_node"); // 创建两个订阅器,分别用来订阅两个话题 auto image_sub = message_filters::Subscriber<sensor_msgs::msg::Image>(node, "image_topic"); auto laser_sub = message_filters::Subscriber<sensor_msgs::msg::LaserScan>(node, "laser_topic"); // 创建时间同步器,指定回调函数和队列大小 auto sync = std::make_shared<message_filters::TimeSynchronizer<sensor_msgs::msg::Image, sensor_msgs::msg::LaserScan>>(image_sub, laser_sub, 10); sync->registerCallback(std::bind(&callback, _1, _2)); rclcpp::spin(node); rclcpp::shutdown(); return 0; } ``` 在这个示例中,我们创建了一个名为`time_sync_node`的ROS节点,同时订阅了名为`image_topic`和`laser_topic`的两个话题。然后,我们使用`TimeSynchronizer`类来进行时间同步,指定了回调函数`callback`和队列大小为10。当两个话题消息在时间上相近时,回调函数将被调用,并传递接收到的消息。 请注意,以上代码仅为示例,你需要根据实际情况进行适当修改和扩展。同时,确保你已经安装了`message_filters`库,并在CMakeLists.txt中添加了相应的依赖项。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 21
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值