First, let make a distinction based on the ROS API:
-
rospy.spin()- used by ROS Python API. -
ros::spin()andros::spinOnce()- used by ROS C++ API.
That said, what are they for?
-
They are all used in connection with subscribers.
-
rospy.spin()andros::spin()both block the main thread from exiting until ROS invokes a shutdown - via aCtrl + Cfor example. They are written as the last line of code of the main thread of the program. -
For ROS Python,
rospy.spin()can be replaced by a while loop, so it is not mandatory to use it when working with subscribers. The three code snippets below are equivalent as they prevent the main thread from exiting until a shutdown is requested in some way.
# setup subscribers and callbacks (and anything else)
rospy.spin()
while not rospy.is_shutdown():
# do some work or nothing
while not ctrl_c:
# do some work or nothing
- For ROS C++,
ros::spin()is mandatory for subscribers. If you are subscribing messages, services or actions you must callros::spin()to process the events. WhilespinOnce()handles the events and returns immediately,spin()blocks until ROS invokes a shutdown.spinOnce()is used where other lines of code need to be executed along with processing arriving messages.
// ros::spin()
ros::init(argc, argv, "my_node");
ros::NodeHandle nh;
ros::Subscriber sub = nh.subscribe(...);
...
ros::spin();
// ros::spinOnce()
ros::Rate r(10); // 10 hz
while (should_continue)
{
// ... do some work, publish some messages, etc. ...
ros::spinOnce();
r.sleep();
}