This article was reproduced from: http://www.cnblogs.com/liu-fa/p/5925381.html
Bo Main tip : This article is based on Ros Kinetic Kame, if there is a more (gèng) new version, there may be subtle differences, please the Big Brother to the official information prevail.
Bo Master has always been dull, if the big Brother found that the article has inappropriate, but also please speed informed.
1 function meaning
The first thing to know is that these two brothers are called the Ros message callback handler function . They usually appear in the main loop of Ros, the program needs to constantly call Ros::spin () or ros::spinonce (), the difference is that the former will not return after the call, that is, your main program is not down here to execute, The latter, after the call, can continue to execute after the program.
In fact, the principle of message callback handler is very simple. We all know that Ros has a message release subscription mechanism, what? I don't know? I don't know yet: Http://wiki.ros.org/ROS/Tutorials (the ROS official Basic tutorial).
OK, let's go ahead, if your program writes the relevant message subscription function, then in the process of execution, in addition to the main program, Ros will automatically receive the subscription message in the background in the format you specified, but the received message is not processed immediately, but must wait until the Ros:: Spin () or Ros::spinonce () is called when it is executed, which is how the message goes back to the function, how simple, and why is it so designed? Cough, well, there must be a reason for him ...
2 differences
As said above, Ros:spin () will not return after the call, that is, your main program does not go down here, and ros::spinonce () the latter after the call can continue to execute after the program.
In fact, look at the function name can also understand a similar, one is always called, and the other is called only once, if you want to call again, you need to add a loop.
It is important to remember that the Ros::spin () function generally does not appear in the loop because the program executes to spin () and does not invoke other statements, that is, the loop has no meaning, and that there must be no other statement behind the spin () function (except for return 0). And will not be executed. The use of ros::spinonce () is relatively flexible, but it is often necessary to consider the timing of the invocation of the message, the frequency of the call, and the size of the message pool, which are coordinated according to the actual situation, otherwise it will cause data loss or delay error.
3 Common use methods
Here is a special emphasis , if the Big Brother your program to write the relevant message subscription function , that Yes do not forget to add Ros::spin () or ros::spinonce () in the corresponding location function, otherwise you will never get the other side of the data or messages sent, Bo Master blood Lessons, million hope to remember ...
3.1 Ros::spin ()
Ros::spin () function is relatively simple to use, usually at the end of the main program, add the statement can be. Examples are as follows:
Send side:
| 123456789101112131415161718192021222324252627282930 |
#include "ros/ros.h"#include "std_msgs/String.h"#include <sstream>intmain(intargc, char**argv){ ros::init(argc, argv, "talker"); ros::NodeHandle n; ros::Publisher chatter_pub = n.advertise<std_msgs::String>("chatter", 1000); ros::Rate loop_rate(10); intcount = 0; while(ros::ok()) { std_msgs::String msg; std::stringstream ss; ss << "hello world "<< count; msg.data = ss.str(); ROS_INFO("%s", msg.data.c_str()); /** * 向 Topic: chatter 发送消息, 发送频率为10Hz(1秒发10次);消息池最大容量1000。 */ chatter_pub.publish(msg); loop_rate.sleep(); ++count; } return0;} |
Receiving end:
| 123456789101112131415161718192021 |
#include "ros/ros.h"#include "std_msgs/String.h"voidchatterCallback(const std_msgs::String::ConstPtr& msg){ ROS_INFO("I heard: [%s]", msg->data.c_str());}intmain(intargc, char**argv){ ros::init(argc, argv, "listener"); ros::NodeHandle n; ros::Subscriber sub = n.subscribe("chatter", 1000, chatterCallback); /** * ros::spin() 将会进入循环, 一直调用回调函数chatterCallback(),每次调用1000个数据。 * 当用户输入Ctrl+C或者ROS主进程关闭时退出, */ ros::spin(); return0;} |
3.2 Ros::spinonce ()
The use of ros::spinonce (), although more free than Ros::spin (), can appear in various parts of the program, but there are more factors to be aware of. Like what:
1 for some transmission particularly fast messages, especially need to pay attention to reasonable control of the message pool size and ros::spinonce () execution frequency; For example, message delivery frequency is 10Hz, ros::spinonce () call frequency is 5Hz, then the size of the message pool must be greater than 2, in order to ensure that the data is not lost, no delay. Receiving end:
| 123456789101112131415161718192021222324 |
#include "ros/ros.h"#include "std_msgs/String.h" voidchatterCallback(conststd_msgs::String::ConstPtr& msg){ /*...TODO...*/} intmain(intargc, char**argv){ ros::init(argc, argv, "listener"); ros::NodeHandle n; ros::Subscriber sub = n.subscribe("chatter", 2, chatterCallback); ros::Rate loop_rate(5); while(ros::ok()) { /*...TODO...*/ ros::spinOnce(); loop_rate.sleep(); } return0;} |
2 ros::spinonce () The usage is very flexible, also very extensive, the specific situation needs the concrete analysis. However, for user-defined periodic functions, it is best to perform side-by-side with Ros::spinonce, which is not recommended in the callback function;
| 1234567891011 |
/*...TODO...*/ros::Rate loop_rate(100); while (ros::ok()){ /*...TODO...*/ user_handle_events_timeout(...); ros::spinOnce(); loop_rate.sleep();} |
"Turn" Ros::spin () and ros::spinonce () differences and explanations