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

How to use select() or poll() in a ROS c++ node

asked 2013-01-09 21:07:28 -0500

acorn gravatar image

How do I use select() or poll() to sleep a (c++) ros node's main thread until either a subscribed message arrives or until some other file descriptor is readable?

For example I have a node that is subscribed to a topic and also listening to a serial port. I want the process to sleep (in select() or poll()) until either the serial port is readable or the socket(s) that ROS is using to receive subscribed messages is readable. I think I can accomplish this in either of 2 ways:

A) If I can get a list of file descriptors that ROS is using I can call select myself. (When any of the ROS file descriptors are readable I would call ros::spinOnce() so ros can read messages and call callbacks.)


B) If I can pass a file descriptor (the serial port) to ROS with a callback to call when the fd is readable then ROS can add the fd to its own select/poll list (and I can call ros::spin() and wait for callbacks).

It looks like ros::PollSet::addSocket() is supposed to allow (B), but I am not sure how to use it. (E.g. how do I get a pointer to the ros::PollSet?)

I am currently using fuerte on Ubuntu 10.04.

Thanks! -Acorn

edit retag flag offensive close merge delete


Do you need a callback functionality like that? The common way of solving this would be to do this manually in the main loop, i.e. polling everything and calling ros::spinOnce().

dornhege gravatar image dornhege  ( 2013-01-09 22:39:51 -0500 )edit

Polling does work, but I prefer not to tie up the processor until something actually arrives on the serial port. Sleeping in select() allows other processes to use 100% of the cpu (or allows the cpu to go idle to save pwr), and also allows the process to wake up quickly when serial traffic arrives.

acorn gravatar image acorn  ( 2013-01-10 07:07:23 -0500 )edit

Lorenz, thanks for the answer and suggestions. It sounds like the basic answer to my question is "you cannot do that" which is fine -- I'll use one of the other methods suggested. Thanks.

acorn gravatar image acorn  ( 2013-01-10 13:47:42 -0500 )edit

1 Answer

Sort by » oldest newest most voted

answered 2013-01-10 10:25:07 -0500

Lorenz gravatar image

You should not use low level classes such as ros::PollSet since they are internal.

The easiest way to run the ROS event loop and a serial connection is to use select or poll with a timeout and call spinOnce before re-entering select or poll. The impact on your CPU will surely not be noticeable but message callbacks can be delayed since they are only invoked by spinOnce. If you want an immediate reaction, use an async spinner (the class ros::AsyncSpinner) to spin in the background and call select or poll in the main thread.

edit flag offensive delete link more


+1 for AsyncSpinner + select in the main thread.

mikepurvis gravatar image mikepurvis  ( 2014-02-13 08:51:36 -0500 )edit

Question Tools


Asked: 2013-01-09 21:07:28 -0500

Seen: 1,859 times

Last updated: Jan 10 '13