如何实现在ros订阅一次数据后过两s再次订阅
Posted
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了如何实现在ros订阅一次数据后过两s再次订阅相关的知识,希望对你有一定的参考价值。
参考技术A 有些消息类型会带有一个头部数据结构,如下所示。信息中带有时间辍数据,可以通过这个数据进行时间同步。std_msgs/Header header
uint32 seq
time stamp
string frame_id
登录后复制
以下是一种同步的方式:Time Synchronizer
The TimeSynchronizer filter synchronizes incoming channels by the timestamps contained in their headers, and outputs them in the form of a single callback that takes the same number of channels. The C++ implementation can synchronize up to 9 channels.
#include <message_filters/subscriber.h>
#include <message_filters/time_synchronizer.h>
#include <sensor_msgs/Image.h>
#include <sensor_msgs/CameraInfo.h>
using namespace sensor_msgs;
using namespace message_filters;
void callback(const ImageConstPtr& image, const CameraInfoConstPtr& cam_info)
// Solve all of perception here...
int main(int argc, char** argv)
ros::init(argc, argv, "vision_node");
ros::NodeHandle nh;
message_filters::Subscriber<Image> image_sub(nh, "image", 1);
message_filters::Subscriber<CameraInfo> info_sub(nh, "camera_info", 1);
TimeSynchronizer<Image, CameraInfo> sync(image_sub, info_sub, 10);
sync.registerCallback(boost::bind(&callback, _1, _2));
ros::spin();
return 0;
另外一种是基于策略的同步方式,也是通过消息头部数据的时间辍进行同步。
Policy-Based Synchronizer [ROS 1.1+]:
The Synchronizer filter synchronizes incoming channels by the timestamps contained in their headers, and outputs them in the form of a single callback that takes the same number of channels. The C++ implementation can synchronize up to 9 channels.
The Synchronizer filter is templated on a policy that determines how to synchronize the channels. There are currently two policies: ExactTime and ApproximateTime.
当需要同步的所有消息都带有时间辍的头部数据:ExactTime
The message_filters::sync_policies::ExactTime policy requires messages to have exactly the same timestamp in order to match. Your callback is only called if a message has been received on all specified channels with the same exact timestamp. The timestamp is read from the header field of all messages (which is required for this policy).
#include <message_filters/subscriber.h>
#include <message_filters/synchronizer.h>
#include <message_filters/sync_policies/exact_time.h>
#include <sensor_msgs/Image.h>
#include <sensor_msgs/CameraInfo.h>
using namespace sensor_msgs;
using namespace message_filters;
void callback(const ImageConstPtr& image, const CameraInfoConstPtr& cam_info)
// Solve all of perception here...
int main(int argc, char** argv)
ros::init(argc, argv, "vision_node");
ros::NodeHandle nh;
message_filters::Subscriber<Image> image_sub(nh, "image", 1);
message_filters::Subscriber<CameraInfo> info_sub(nh, "camera_info", 1);
typedef sync_policies::ExactTime<Image, CameraInfo> MySyncPolicy;
// ExactTime takes a queue size as its constructor argument, hence MySyncPolicy(10)
Synchronizer<MySyncPolicy> sync(MySyncPolicy(10), image_sub, info_sub);
sync.registerCallback(boost::bind(&callback, _1, _2));
ros::spin();
return 0;
登录后复制

由于该同步策略是当所有需同步的话题的时间辍严格相等时,才会触发回调函数。这就会导致以下一些问题:
回调函数的触发频率必然小于等于这些话题中最小的发布频率;
回调函数的触发并不十分稳定,有时候甚至会出现长时间不被触发的情况。如下图所示,某一次的间隔甚至长达10s左右。
ROS提供了另外一种方法来实现数据的同步:ApproximateTime。与需要时间辍完全相同的ExactTime不同,该方法允许话题之间的时间辍存在一定的偏差。
The message_filters::sync_policies::ApproximateTime policy uses an adaptive algorithm to match messages based on their timestamp.
#include <message_filters/subscriber.h>
#include <message_filters/synchronizer.h>
#include <message_filters/sync_policies/approximate_time.h>
#include <sensor_msgs/Image.h>
using namespace sensor_msgs;
using namespace message_filters;
void callback(const ImageConstPtr& image1, const ImageConstPtr& image2)
// Solve all of perception here...
int main(int argc, char** argv)
ros::init(argc, argv, "vision_node");
ros::NodeHandle nh;
message_filters::Subscriber<Image> image1_sub(nh, "image1", 1);
message_filters::Subscriber<Image> image2_sub(nh, "image2", 1);
typedef sync_policies::ApproximateTime<Image, Image> MySyncPolicy;
// ApproximateTime takes a queue size as its constructor argument, hence MySyncPolicy(10)
Synchronizer<MySyncPolicy> sync(MySyncPolicy(10), image1_sub, image2_sub);
sync.registerCallback(boost::bind(&callback, _1, _2));
ros::spin();
return 0;
登录后复制

从下图可以看出,虽然该方法允许时间之间存在偏差,但实际上偏差并不大。而且比起上一种方法,这个方法的回调函数的触发频率快多了。
关于ApproximateTime,我还有一个不解的地方,这里做一下记录:
If not all messages have a header field from which the timestamp could be determined, see below for a workaround.
If some messages are of a type that doesn’t contain the header field, ApproximateTimeSynchronizer refuses by default adding such messages.
以上这两句话,似乎自相矛盾。不知道是不是我理解的问题。。。从时间同步的角度看,话题消息内容中应该必须要带上时间辍信息才能进行同步,但第一句话却说可以允许一些消息不带时间辍?
[补充于2021.2.11: 今天在使用ApproximateTime时同步了一个自定义的消息类型,发生了如下图所示的错误。后来查阅资料才发现是没有加header的原因,即没有时间辍,程序就无法根据时间进行同步。换句话说,该方法也是必须需要时间辍信息的。加上header后错误就没有了。]
另外需要注意的是,使用message_filters时,需要在CMakeLists.txt和package.xml中添加相关依赖:
# CMakeLists.txt
find_package( catkin REQUIRED COMPONENTS
...
message_filters
)
# package.xml
find_package( catkin REQUIRED COMPONENTS
<build_depend>message_filters</build_depend>
<build_export_depend>message_filters</build_export_depend>
<exec_depend>message_filters</exec_depend>
)
登录后复制

c++
衡阳市民请关注领取补贴!
巨摩互动
广告

ROS之订阅多个话题并对其进行同步处理(多传感器融合)
2.0W阅读·11评论·22点赞
2019年7月26日
ROS回顾学习(5): 订阅多个话题并对其进行同步处理
1963阅读·0评论·0点赞
2020年2月4日
ros_多消息同步回调(Synchronizer)
5149阅读·2评论·10点赞
2019年10月17日
【ros】message_filters同步点云和图像数据
1442阅读·9评论·6点赞
2020年4月21日
ROS MessageFilter订阅多个激光雷达话题进行同步处理
2690阅读·1评论·7点赞
2021年1月19日
关于不同传感器时间同步----ROS提供的时间同步函数message_filters【ROS下linux源码,】
1174阅读·2评论·4点赞
2020年7月25日
ROS多Topic接收的时间同步
1052阅读·1评论·2点赞
2020年9月20日
将时间戳不同的点云和图像进行时间戳同步;把bag包里的图像和点云分割成一帧一帧的;把pcd转成bin格式。
1491阅读·9评论·5点赞
2021年4月19日
ROS多传感器数据时间戳同步方案——message_filters::TimeSynchronizer
1539阅读·0评论·1点赞
2022年7月6日
ROS官方教程[翻译]---message_filter的使用
2.4W阅读·3评论·23点赞
2017年8月22日
ROS学习记录(二):订阅多节点时间同步
518阅读·0评论·3点赞
2020年9月18日
ROS自学实践(10):ROS节点同时订阅多个话题并进行消息时间同步
8118阅读·19评论·10点赞
2020年5月23日
ros-多订阅
551阅读·0评论·0点赞
2022年5月12日
ROS知识点——生成点云,发布、订阅ROS点云话题
1795阅读·0评论·2点赞
2022年8月9日
使用Publish/Subscribe 设计模式达到对象间数据同步
1257阅读·0评论·1点赞
2004年4月18日
message_filters学习笔记
805阅读·0评论·0点赞
2021年8月13日
ROS 搞懂多话题回调机制以及消息队列
以上是关于如何实现在ros订阅一次数据后过两s再次订阅的主要内容,如果未能解决你的问题,请参考以下文章