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 + C
for 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();
}