Program flow of Action Client (ROS Basics, Topic 8)

Hi, i don’t understand how python program is able to run two separate codes at the same time. Is the callback function being run in a separate thread? If yes, then given a general ROS python code: how do i know/check if callback functions are called in separate threads. Is this always the case when using callbacks with ROS?

Code for reference:

Another pressing question, with respect to the feedback printed on the terminal:

How is it possible that the “Doing stuff while waiting…” is perfectly interweaving with the “[Feedback] image n.d received” even though they are run in two separate blocks of code?


ROS is asynchronous meaning it can perform several operations including callbacks at the same time and yes it does this using multiple threads but you don’t have to worry about that ROS takes care of it for you. Try not to think of it as two blocks of code but as two functions that make up one program. If you have done some programming before then you would know this is common, if not then I can understand your confusion, but you will get use to it as you proceed. You’ve taking your first step in what will be a very long journey. If you think about a typical robot it doesn’t move a few feet stop, check it’s sensors to see if everything is still OK, then start moving again. It’s constantly reading data from its sensors all while performing other tasks at the same time.

1 Like

hi @hskramer, thank you for your reply. :blush:

I understand it is asynchronous and i’ve done a little bit of multithreading with POSIX-compliant OS in school last semester, so i think i kinda know the basics. I understand a robot can do multiple different tasks at the same time due to this fact.

This was using C language though, and I understood the flow behind creating multiple threads(ie using pthread_create(func_name) that calls a ‘callback’ function to run in a separate thread). However, there seems to be a lot more going on in this case, so my question is… what exactly is the explicit flow like for an action server in ROS?

1 Like

I have provided several links for you, that should prove useful as you continue through the course however the question you are asking seems to go into the details of how ROS handles actions internally which is a bit beyond the scope of what can easily be answered here however, I have provided a more detailed answer and some diagrams that should give you some more insight into how it works. The first is the server state machine which is initiated by the action client once a goal is received by an ActionServer, the ActionServer creates a state machine to track the goal (this is where your callback function starts to work, diagrams taken from the detailed link):

The client sends the goal to the server and then it starts to tract the status via messages sent by the server. At anytime and for any reason the client can terminate the server otherwise it waits for a result succeeded message. This diagram shows the client state transitions:

As far as how the preempting is concerned it relies on the operating system to handle the bulk of the work. If you want to take direct control with python you can use a module called asyncio which is a concurrency module, but in most cases it’s best to let the OS handle it. The same is true if your writing your nodes in C++ you can take direct control but again it’s usually best to let the OS handle the concurrency. This is why ROS is considered a Meta Operating system. It requires an underlying OS to work properly and that OS provides the concurrency which allows ROS to work asynchronously. This last diagram show a goal being sent and succeeding along with the preempting.

The Links:
This one describes rospy and the functions it provides along with the api’s and source code.
This one describes the action library in detail along with a link to the github page which has the source code behind the library.
The last one goes into the detail on how actions work.

Python provides for asynchronous programming while ROS is written primarily in C++ which also allows for asynchronous programs but still relies on the underlying OS to handle the preempting. However all the python libraries are written in python and it relies on the OS too.