ROS Resources: Documentation | Support | Discussion Forum | Index | Service Status | ros @ Robotics Stack Exchange
Ask Your Question
0

Using rospy.sleep inside a callback

asked 2023-02-02 16:09:20 -0500

pitosalas gravatar image

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?

edit retag flag offensive close merge delete

Comments

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).

gvdhoorn gravatar image gvdhoorn  ( 2023-02-03 01:24:05 -0500 )edit

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.

pitosalas gravatar image pitosalas  ( 2023-02-03 08:17:15 -0500 )edit

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.

gvdhoorn gravatar image gvdhoorn  ( 2023-02-04 02:22:58 -0500 )edit

1 Answer

Sort by ยป oldest newest most voted
2

answered 2023-02-03 01:30:38 -0500

gvdhoorn gravatar image

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".

edit flag offensive delete link more

Comments

Ah @gvdhoorn, good to see you again!

I don't remember why I got that impression but I really did believe it! What I meant about "allowed" is, does it cause problems in the threading and dispatching of ROS, more than,it's just bad practice or ugly.

If sleep is a normal sleep, and rospy is multi threaded, then is the following true? If I use sleep () in a callback, then during the sleep, the callback could be called again at that point and lead to race conditions etc.?

pitosalas gravatar image pitosalas  ( 2023-02-03 08:17:35 -0500 )edit

Does anyone know of an article or post or documentation that explains the threading in rospy?

pitosalas gravatar image pitosalas  ( 2023-02-04 16:55:47 -0500 )edit

A number of off-site articles were written (on blogs fi), but I can't find those any more (just goes to show how brittle hosting content that way is).

There are a couple of Q&As here on ROS Answers as well. See #q9543 for a start. Note the alternative answers there. I also found this article on medium.com which goes into some detail (it's not the article I remembered).

gvdhoorn gravatar image gvdhoorn  ( 2023-02-05 02:04:23 -0500 )edit

Question Tools

1 follower

Stats

Asked: 2023-02-02 16:09:20 -0500

Seen: 816 times

Last updated: Feb 03 '23