How to check callback queue?
Hello,
I have a node that subscribes to 3 topics that are being published by individual nodes. In the subscriber node, I have 3 callbacks, one for each. I would like to know if it is possible to know whether there are messages in callback queue. What I am trying to do is to avoid that the same topic triggers its callback twice in a row if there are messages from the other 2 topics available in the callback queue.
This is the code I have now:
#include "ros/ros.h"
#include "sensor_msgs/Image.h"
#include "sensor_msgs/LaserScan.h"
#include "geometry_msgs/TwistStamped.h"
// Callbacks
void pc_pub_img_callback(const sensor_msgs::Image::ConstPtr& msg){
//ROS_INFO("Received from pc_pub_img");
ROS_INFO("Img:Callback(%d)", msg->header.seq);
ros::Duration(0.2).sleep();
// Serialization
sensor_msgs::Image Image;
uint32_t serial_size = ros::serialization::serializationLength(*msg);
boost::shared_array<uint8_t> buffer(new uint8_t[serial_size]);
ROS_INFO("Img:Serialized");
}
void pc_pub_laser_callback(const sensor_msgs::LaserScan::ConstPtr& msg){
//ROS_INFO("Received from pc_pub_laser");
ROS_INFO("Laser:Callback(%d)", msg->header.seq);
// Serialization
sensor_msgs::Image LaserScan;
uint32_t serial_size = ros::serialization::serializationLength(*msg);
boost::shared_array<uint8_t> buffer(new uint8_t[serial_size]);
ROS_INFO("Laser:Serialized");
}
void pc_pub_twist_callback(const geometry_msgs::TwistStamped::ConstPtr& msg){
//ROS_INFO("Received from pc_pub_img");
ROS_INFO("Twist:Callback(%d)", msg->header.seq);
// Serialization
geometry_msgs::Twist Twist;
uint32_t serial_size = ros::serialization::serializationLength(*msg);
boost::shared_array<uint8_t> buffer(new uint8_t[serial_size]);
ROS_INFO("Twist:Serialized");
}
int main(int argc, char **argv)
{
ros::init(argc, argv, "arm_to_fpga");
ros::NodeHandle n;
ros::Subscriber sub_img = n.subscribe("/pc_pub_img", 1000, pc_pub_img_callback);
ros::Subscriber sub_laser = n.subscribe("/pc_pub_laser", 1000, pc_pub_laser_callback);
ros::Subscriber sub_twist = n.subscribe("/pc_pub_twist", 1000, pc_pub_twist_callback);
ros::spin();
return 0;
}
Thanks.
EDIT: I've changed the frequencies for the 3 publishers at 30, 60 and 60 respectively and removed the serialization part to make the output simpler. Then, I got the following:
[ INFO] [1632761598.718118783]: Twist:Callback
[ INFO] [1632761598.720308913]: Laser:Callback
[ INFO] [1632761598.735116602]: Img:Callback
[ INFO] [1632761598.736248825]: Twist:Callback
[ INFO] [1632761598.736324787]: Laser:Callback
[ INFO] [1632761598.750847497]: Twist:Callback
[ INFO] [1632761598.753741510]: Laser:Callback
[ INFO] [1632761598.762706367]: Img:Callback
[ INFO] [1632761598.764424037]: Twist:Callback
[ INFO] [1632761598.766623670]: Laser:Callback
[ INFO] [1632761598.778012548]: Img:Callback
[ INFO] [1632761598.781003259]: Twist:Callback
[ INFO] [1632761598.783278070]: Laser:Callback
[ INFO] [1632761598.798151580]: Twist:Callback
[ INFO] [1632761598.800334432]: Laser:Callback
[ INFO] [1632761598.817158784]: Img:Callback
[ INFO] [1632761598.817276101]: Twist:Callback
[ INFO] [1632761598.817368705]: Laser:Callback
[ INFO] [1632761598.831502251]: Twist:Callback
[ INFO] [1632761598.833594552]: Laser:Callback
[ INFO] [1632761598.848181492]: Twist:Callback
[ INFO] [1632761598.850259481]: Laser:Callback
[ INFO] [1632761598.853909133]: Img:Callback
[ INFO] [1632761598.864712495]: Twist:Callback
[ INFO] [1632761598.866926431]: Laser:Callback
[ INFO] [1632761598.881360624]: Twist:Callback
[ INFO] [1632761598.885404560]: Img:Callback
[ INFO] [1632761598.885498932]: Laser:Callback
[ INFO] [1632761598.898164827]: Twist:Callback
[ INFO] [1632761598.900324819]: Laser:Callback
[ INFO] [1632761598.914681449]: Twist:Callback
[ INFO] [1632761598.918684480]: Img:Callback
[ INFO] [1632761598.918797223]: Laser:Callback
[ INFO] [1632761598.931412780]: Twist:Callback
[ INFO] [1632761598.953476288]: Img:Callback
[ INFO] [1632761598.953735208]: Twist:Callback
[ INFO] [1632761598.960459469]: Laser:Callback
[ INFO] [1632761598.960576034]: Laser:Callback
[ INFO] [1632761598.965029298]: Twist:Callback
[ INFO] [1632761598.980162791]: Img:Callback
[ INFO] [1632761598.981067892]: Twist:Callback
[ INFO] [1632761598.997919124]: Twist ...
I think you'll need to write your own CallbackQueue and spinner like mentioned here. Unfortunately, I haven't done that in ROS 1 so I can't provide more help than that but I thought I'd mention it.
it seems this is the way to go. Unfortunately I haven't found any example that shows how to check which queue for the messages has data available. I would assume that at some point, all queues for the 3 messages have received at least one and I would like to know at a given frequency, which ones has something in their queue. I found something similar here but that only gives priority to one node. I would first like to know whether there is a message in each callback queue and then decide myself from which queue to read first.