0
$\begingroup$

Rosanswers logo

I would like to implement a node which listens to a TCP socket which receives asynchronous data, converts it into messages and publishes the latest of these messages at a fix rate in a topic.

The best solution in my eyes would be to have a dedicated thread (spinner) that always reads the latest TCP data and saves it to a variable; it stalls when there is no message. The main spinner would read this variable, convert it into a message, publish it and sleep to for predefined loop rate time.

At the moment I can only find ways to add subscribers to a callback queue but not generic functions such as the envisioned TCP listener.

Therefore my questions:

  1. How can i assign a function (the TCP listener) to a callback queue if it is no subscriber?

  2. How can I avoid concurrent modification of the data communicated between the two threads? I.e. how do I guarantee that the TCP thread is not concurrently writing to the same memory as the publisher thread is reading from?

  3. Would you see a more elegant solution to my problem? I want to make sure that the data on the TCP socket is read asap to not interrupt the program that is sending the data to the socket AND I want to make sure that the topic is only publishing the latest data but with a fixed interval (i.e. data is dropped if it arrives faster than the publishing rate).


Originally posted by John Waffle on ROS Answers with karma: 13 on 2015-08-05

Post score: 1


Original comments

Comment by Erwan R. on 2015-08-05:
Why can't you loop on your TCP listening and publish at the condition that there is new data or that enough time has elapsed ? You just need a publisher that will be invoked potentially as fast as the TCP listener or at a lower rate depending on the condition set.

Comment by John Waffle on 2015-08-05:
This is my fallback plan because it does not guarantee that the publishing rate is constant. If the TCP socket is still busy when the next topic message is due, it will be delayed. In the case of a separate thread this can be avoided by only publishing the latest full data block the node received.

$\endgroup$

1 Answer 1

0
$\begingroup$

Rosanswers logo

This is not something to be done with ROS internals only.

Have a look at the Boost::Thread Library which provides excellent tools for doing this. (Obviously, there are many other tools available.)

To your questions:

  1. I guess this cannot be done the way you propose it here. Spawn a new thread (using e.g. Boost) and read the TCP socket therein.

  2. This is what boost::mutex and boost::lock is for.

  3. I guess the solution you proposed is fine. To achieve this, the thread reading the TCP socket just needs to be running faster than the one publishing the data. If you then write to a (well protected, see question 2) ) member variable, you can use this variable to sync the data and only publish the latest one.

As an example how to do this, (even though they have it basically the other way round, publishing data from a thread) see the old slam_karto node (again, there are probably many other examples out there or directly in boost).

(During my questions, I assumed you'd be using C++ as language of choice. If you plan to do this using pyhton see the Python Threading module)


Originally posted by mgruhler with karma: 12390 on 2015-08-05

This answer was ACCEPTED on the original site

Post score: 1


Original comments

Comment by John Waffle on 2015-08-05:
Thank you! Yes, I am using C++. Sorry for not mentioning.

$\endgroup$

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.