My understanding is that rospy.sleep() will return control to ROS so that it can schedule any other processes that need a turn, and also waith the designated time before it "returns". I put that in quotes because it looks like a simple call and return but actually control is returned to ROS who decides when to pop the stack and return control to the line after rospy.sleep().
Given that, does it make sense, and is it allowed, to call rospy.sleep() or rospy.spin() or rospy.spinOnce() from inside a callback?
Originally posted by pitosalas on ROS Answers with karma: 628 on 2023-02-02
Post score: 0
Original comments
Comment by gvdhoorn on 2023-02-03:\
My understanding is that rospy.sleep() will return control to ROS so that it can schedule any other processes that need a turn [..]
could you clarify what gave you that impression? Any documentation or articles you could link?
This is the source of rospy.sleep(..)
.
At its core, sleep(..)
basically just calls time.sleep(..)
(a Python built-in) when use_sim_time==False
, or does some more complicated things when use_sim_time==True
(to deal with Time(0)
and clock resets fi).
The Python client being multithreaded by default (as much as Python can be MT), there is no explicit scheduling of "giving control back to ROS". In fact, rospy.spin()
does nothing but sleep(..)
(here).
Comment by pitosalas on 2023-02-03:
I don't remember why I got that impression but I really did believe it! Worse, I've explained it to other ROS programmers :) Now I am a new man! If ROS/Python is multi threaded, when and how does the cb dispatcher decide to do a callback? I assume it's not based on time slicing? I am going to look for doc on how the python threading works.
Comment by gvdhoorn on 2023-02-04:\
I don't remember why I got that impression but I really did believe it!
Well technically you could argue that since rospy.sleep(..)
calls time.sleep(..)
(one of its variants) it does allow Python to suspend that thread and allow other threads to become active.
Again, technically, you could describe that as "other [ROS] threads can become active". Extrapolating a bit, you could claim it means it "allows ROS to do its thing".
What I responded to however was the implication there is some special code in rospy.sleep(..)
which "allows ROS to do its thing". That's not true.
rospy.sleep(..)
just calls time.sleep(..)
. If that ends up allowing other threads (including ROS' threads) to run, that'd be a side-effect, not the main functionality.