1 function meaning
The first thing to know is that these two brothers learn to call the ROS message callback handler function. They usually appear in the main cycle of Ros, and the program needs to constantly invoke Ros::spin () or ros::spinonce (), the difference is that the former will not return after the call, that is, your main program here is not down, and the latter can continue after the call after the execution of the program.
In fact, the principle of message callback processing functions is very simple. We all know that Ros has a message publishing subscription mechanism, what? I don't know? Don't know yet go: http://wiki.ros.org/ROS/Tutorials (Ros official Basic course).
All right, let's go. If your program writes related message subscription functions, then the program in the implementation process, in addition to the main program, Ros will automatically in the background in accordance with your prescribed format, accept the subscription message, but the message received is not immediately be processed, but must wait until Ros::spin () or ros::spinonce () to be invoked, this is the message back to the principle of the function, how, simple, as for why so design? Cough, well, there must be a reason for him ...
2 differences
As mentioned above, Ros::spin () will not return after the call, that is, your main program is not down here, and Ros::spinonce () after the call can continue to execute after the program.
Actually look at the function name can also understand a similar, one is always called, the other is only called once, if you want to call again, you need to add a loop.
It must be remembered here that the Ros::spin () function does not generally appear in the loop, because the program does not invoke other statements after executing to spin (), meaning that the loop has no meaning, and that there must be no other statements behind the spin () function (except 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, the frequency of the call, and the size of the message pool, which should be reconciled according to the reality, or it may cause data loss or latency errors.
3 Common methods of use
Here is a special emphasis, if the Big Brother your program wrote the relevant message subscription function, that Chivan don't forget to add Ros::spin () or ros::spinonce () function in the corresponding position, otherwise you will never get the other side of the data or message, Bo Lord blood Lessons , the million-hope to remember ...
3.1 Ros::spin ()
The Ros::spin () function is simple to use, generally at the end of the main program, add the statement can be. Examples are as follows:
Send end:
#include "ros/ros.h"
#include "std_msgs/string.h"
#include <sstream>
int main (int argc, char **argv )
{
ros::init (argc, argv, "talker");
Ros::nodehandle N;
Ros::P ublisher chatter_pub = n.advertise<std_msgs::string> ("chatter", 1000);
Ros::rate Loop_rate (a);
int count = 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 ());
/**
* Send a message to the Topic:chatter, send a frequency of 10Hz (1 seconds 10), the maximum capacity of the message pool 1000.
*
/Chatter_pub.publish (msg);
Loop_rate.sleep ();
++count;
}
return 0;
}
Receiving end:
#include "ros/ros.h"
#include "std_msgs/string.h"
void Chattercallback (const STD_MSGS::STRING::CONSTPTR & msg)
{
ros_info ("I heard: [%s]", MSG->DATA.C_STR ());
}
int main (int argc, char **argv)
{
ros::init (argc, argv, "listener");
Ros::nodehandle N;
Ros::subscriber sub = N.subscribe ("Chatter", 1000, chattercallback);
The/**
* Ros::spin () will go into the loop, calling the callback function Chattercallback (), calling 1000 data at a time.
* When the user input Ctrl + C or the ROS main process is closed, exit, *
*
ros::spin ();
return 0;
}
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 noted. Like what:
1 for some transmission particularly fast message, especially need to pay attention to reasonably control the message pool size and ros::spinonce () execution frequency; For example, the message delivery frequency of 10Hz, ros::spinonce () of the call frequency of 5Hz, then the size of the message pool must be greater than 2 to ensure that the data is not lost, no delay.
/** Receive-side **/<br> #include "ros/ros.h"
#include "std_msgs/string.h"
void Chattercallback (const STD_MSGS:: string::constptr& msg)
{/
* ... todo...*/
}
int main (int argc, 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 ();
}
return 0;
}
2 ros::spinonce () usage is very flexible, also very broad, the specific situation needs 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;
/*... todo...*/
ros::rate loop_rate (MB);
while (Ros::ok ())
{/
* ... todo...*/
user_handle_events_timeout (...);
Ros::spinonce ();
Loop_rate.sleep ();
}