Ignoring the "rospy.sleep(..)
gives back control to ROS" comment, there is a general answer to your question:
does it make sense, and is it allowed, to call rospy.sleep() or rospy.spin() or rospy.spinOnce() from inside a callback?
No, I cannot think of any reason to call rospy.spin()
in a callback. It would completely block the execution of the callback, and that part of your node would stop working (ie: no further messages processed, no other timer events handled, etc).
You could theoretically call rospy.sleep(..)
in a callback. It would just introduce a delay, similar to what time.sleep(..)
would do (but taking use_sim_time
into account). Would that be useful? Depends on the rest of the code in the callback.
Would I recommend doing it? Probably not. If, in an event based system, you need to introduce an explicit sleep(..)
somewhere, it's likely you should be using callbacks more/differently (ie: instead of sleep(..)
ing to wait for something, register your interest in whatever it is you're waiting for and register a callback to be notified whenever what you're interested in happens).
(Note that rospy.spinOnce()
does not exist)
Are you allowed to call those functions? Of course. In the sense that no one will prevent you from calling them, nor will rospy
"complain".
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 callstime.sleep(..)
(a Python built-in) whenuse_sim_time==False
, or does some more complicated things whenuse_sim_time==True
(to deal withTime(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 butsleep(..)
(here).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.
Well technically you could argue that since
rospy.sleep(..)
callstime.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 callstime.sleep(..)
. If that ends up allowing other threads (including ROS' threads) to run, that'd be a side-effect, not the main functionality.