What is difference between rospy.spin() and while not rospy.is_shutdown()?

code-1

    import rospy
    from std_msgs.msg import Int32
    rospy.init_node('pub')
    publisherobj = rospy.Publisher('/top',Int32,queue_size=1)
    obj = Int32()
    while not rospy.is_shutdown():
                  obj.data = 536
                  publisherobj.publish(obj)
                  rospy.sleep(1)

code-2

    import rospy
    from std_msgs.msg import Int32
    rospy.init_node('pub')
    publisherobj = rospy.Publisher('/top',Int32,queue_size=1)
    obj = Int32()
    obj.data = 536
    publisherobj.publish(obj)
    rospy.sleep(1)
    rospy.spin()

In both cases the node doesn’t exit , however only cod 1 continues to publish information to topic same is not for code block 2 why ?

Hi @vasank1958,

Code 2 is not publishing continuously because it’s just “running out”; by the time the last line is executed, there’s nothing more happening, so the program ends, and forces ROS to shutdown.

Code 1, however, does not end because it has a while loop that keeps it alive unless ROS is shutting down.

Usually ROS does NOT shutdown unless you press CTRL + C or there’s an error, or the code itself stops executing (like in your case).

As for the difference you asked:

  • Usually, you use while not rospy.is_shutdown() when you want to publish to a topic at a certain rate, but in that case you use rospy.Rate.sleep(), not rospy.sleep() like you did. Read more here: Proper use of rospy.Rate or ros::Rate
  • You typically use rospy.spin() on the last line of the code when a subscriber is involved. This ensures that the program will not “run out” like your code-2 and that your subscribed messages will arrive. Read more about rospy.spin() here: What is rospy.spin(), ros::spin(), ros::spinOnce(), and what are they for?

@bayodesegun sir I think I made a mistake in the question , The code block 2 actually ends with rospy.spin(). In this case why is the publisher not constantly printing ?

@vasank1958 Adding rospy.spin() at the end should keep the program from stopping, but technically the program isn’t doing anything anymore because nothing else happens after this. spin() does not make the program go back and execute other statements, in case that’s what you are thinking.

So in this case, and for most cases involving only publishers, rospy.spin() is not appropriate.

As I mentioned earlier, rospy.spin() is usually used when a subscriber is involved, and you’re not doing any processing in the main thread. The reason it works with a subscriber is that even though it seems the program has reached the last line, the subscriber runs in a separate thread and calls a callback function from time to time, so things keep happening.

1 Like

Hi, regarding this question: what if the code has both publisher and subscriber involved at the same time?

For example, in this case:

Why is only rospy.spin() used? How is it that the topic is continuously being published without a while loop that continuously calls the Publisher?

The spin function tells ros keep this node running even if multiple functions are defined as in the case you have above running this is what rospy.spin does it’s like a spinning propeller on a airplane once started it keeps spinning this is what the rospy.spin does once the node starts it keep’s it running until you shut it down. As for having both a publisher and subscriber defined:

  1. As bayodesegun said it just prevents the node from stopping.
  2. For the subscriber it allows the callback function to remain active so it can check in from time to time as bayodesegun explained above.

Hi hskramer, thanks for the reply!

I’m abit confused as according to bayodesegun above, “Adding rospy.spin() at the end should keep the program from stopping, but technically the program isn’t doing anything anymore because nothing else happens after this. spin() does not make the program go back and execute other statements… for most cases involving only publishers, rospy.spin() is not appropriate” So, if .spin() doesn’t go back to execute the publisher continuously, how is it that "1.For the publisher it allows it to keep publishing."?

I clarified my earlier statement it’s like bayodesegun said it just prevents the program from stopping. So if a publisher is part of the node as in this case it is just carried along as part of the the entire program whether it needs to continually run or not. But their is something happening and this is the part you want to keep running the subscriber’s callback so you can get information from the subscriber anytime you need or require it. In this case if the subscriber’s callback stopped you would no longer get information from the laser which is needed to prevent collisions with obstacles. In simple terms the spin just prevents/blocks the program from stopping even though nothing follows it, if that is the part that is confusing you. It’s a ROS method designed to prevent programs from stopping.

The publisher is being used in the subscriber callback (as the code is for the topics quiz if I’m correct). As the subscriber callback is being called from time to time, the publisher publishes “continuously”.

You don’t have to use a while loop with a publisher; it depends on what you want to do. You might want to publish to a topic continuously at a certain rate (in which case a while loop might be appropriate), once, or periodically as needed as in the case of the topics quiz, where you need to publish according to the feedback from the laser scan.

1 Like