ROS callback function and spin() method

First give a simple ROS subscriber program

#include <ros/ros.h>
#include <topic_demo/gps.h>
#include <std_msgs/Float32.h>
void gpsCallback(const topic_demo::gps::ConstPtr &msg)
{
    
    
	std_msgs::Float32 distance; //计算离原点(0,0)的距离
	distance.data = sqrt(pow(msg->x,2)+pow(msg->y,2));
	ROS_INFO("Listener: Distance to origin = %f, state: %s",distance.data,msg->state.c_str()); //输出
} 
int main(int argc, char **argv)
{
    
    
	ros::init(argc, argv, "listener");
	ros::NodeHandle n;
	ros::Subscriber sub = n.subscribe("gps_info", 1, gpsCallback); //设置回调函数gpsCallback
	ros::spin(); //ros::spin()用于调用所有可触发的回调函数, 将进入循环, 不会返回, 类似于在循环里反复调用spinOnce()
	//而ros::spinOnce()只会去触发一次
	return 0;
}

On the topic receiver, there is a more important concept, CallBack. In this example, callback is to prepare a callback function for the message from the gps_info topic in advance. You define the operation of the callback function in advance. In this example Calculate the distance to the origin. Only when there is a message, the callback function will be triggered to execute. The specific command to trigger is ros::spin(), which will repeatedly check whether there is a message, and if there is any message, it will let the callback function handle it.

Therefore, do not think that as long as the callback function is specified, the system will automatically trigger it. You must ros::spin() or ros::spinOnce() to make the callback function effective.

The callback function is passed as a parameter to another function (in this case, the function pointer is passed), and at some point in the future (when a new message arrives), it will be executed immediately. When the Subscriber receives the message, it actually puts the message in a queue first, as shown in the figure below. The length of the queue is set when the Subscriber is constructed. When the spin function is executed, the message at the head of the message queue will be processed.

Insert picture description here
Once the message subscriber knows that there is a message in the topic, it will pass the message as a parameter to the callback function, but the callback function has not been executed at this time, but the callback function is placed in the callback function queue. So when the publisher keeps sending messages to the topic, there will be a corresponding callback function into the queue, their function names are the same, but the actual parameters are different.

So when will the callback function be executed? It's about ros::spin() and ros::spinOnce().

When the spinOnce function is called, spinOnce will call the first callback function in the callback function queue, and then the callback function will be executed, and then wait until the next time the spinOnce function is called again, the second callback function in the callback function queue will be Will be called, and so on.

So, there will be a problem. Because the length of the callback function queue is limited, if the publisher sends data too fast and the spinOnce function is called too frequently, the queue will overflow, and some callback functions will be squeezed out, resulting in not being executed.

For the spin function, once it enters the spin function, it will not return, which is equivalent to an endless loop in its own function. As long as there is a callback function in the callback function queue, it will immediately execute the callback function. If not, it will block and will not take up the CPU.

Guess you like

Origin blog.csdn.net/qq_33898609/article/details/105935613