What is rospy.spin(), ros::spin(), ros::spinOnce(), and what are they for?

First, let make a distinction based on the ROS API:

  • rospy.spin() - used by ROS Python API.
  • ros::spin() and ros::spinOnce() - used by ROS C++ API.

That said, what are they for?

  • They are all used in connection with subscribers.

  • rospy.spin() and ros::spin() both block the main thread from exiting until ROS invokes a shutdown - via a Ctrl + 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)
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 call ros::spin() to process the events. While spinOnce() 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::spinOnce()
ros::Rate r(10); // 10 hz
while (should_continue)
  // ... do some work, publish some messages, etc. ...