0 背景
项目中有多个Sensor的Topic需要订阅,Topic的更新频率各不相同,假设Topic A为25Hz,Topic B为10Hz,Topic A为关键数据,需求是当收到TopicA后即进行数据的处理。这里就需要对Callback的调用机制进行区别。
1 SpinOnce机制
SpinOnce与Spin的区别比较简单,这里就不具体说明了。在ROS中,当收到可以激活Callback函数的时机时,会将其压入一个队列,这个队列就是ros::CallbackQueue。当调用Spin或SpinOnce时,就会检查这个队列,如果队列为空,也就是没收到注册的Topic,则返回继续执行主函数;如果不为空,则从其中取出Callback函数来invoke,也就是会依次处理收到的数据。在文档中,提到会处理Callback最新一次的数据,但在实际执行过程中,发现在一次SpinOnce中同一个Topic可能会收到多个数据后进行多次处理,这就背离了项目中需要及时处理TopicA的需求。
[ INFO] [1625046678.916048760, 1624994932.711482997]: 7-PubPart = 0.006226
[ INFO] [1625046678.916618409, 1624994932.711482997]: PC1 Stamp = 1624994932.629655
[ INFO] [1625046678.916675676, 1624994932.711482997]: Current Laser Stamp = 1624994932.688399
[ INFO] [1625046678.916714987, 1624994932.711482997]: Ls Stamp = 1624994932.688399
Failed to find match for field 'rgb'.
[ INFO] [1625046678.983832186, 1624994932.785528414]: here 1
[ INFO] [1625046678.984639276, 1624994932.785528414]: PC2 Stamp = 1624994932.659626
[ INFO] [1625046678.984701021, 1624994932.785528414]: Current Laser Stamp = 1624994932.759400
[ INFO] [1625046678.984720163, 1624994932.785528414]: Ls Stamp = 1624994932.759400
Failed to find match for field 'rgb'.
[ INFO] [1625046679.037698877, 1624994932.839306189]: here 1