Robotics StackExchange | Archived questions

Best practices for optimized data transmission

Hi, I would like to ask you which are the best practices for creating optimized ROS projects.

I'm using ROS2 bouncy, but I think the issues applies to ROS1 as well. I have some nodes which publish sensor data and many other nodes which require only the data coming from specific sensors. There are different threads, some nodes are on the same thread. All sensors data are published more or less at the same frequency.

One node provides data A and B. Then other nodes want to access this data through subscriptions or client requests. Some nodes require only A, some nodes only B and some nodes both data.

    void f1()
    {
        auto dataA = ... coming from subscription/client to dataA ...
        cout << dataA <<endl;
    }

    void f2()
    {
        auto dataB = ... coming from subscription/client to dataB ...
        cout << dataB <<endl;
    }

    void f3()
    {
        auto dataA = ... coming from subscription/client to dataA ...
        auto dataB = ... coming from subscription/client to dataB ...
        cout << dataA<< " " << dataB <<endl;
    }

How should this data be provided by the first node?

  1. create two separate publishers/services (one for A and one for B)
  2. create a message which contains both A and B, to provide it through a unique publisher/service (even if some recipients will only use part of the message)

How should the functions use the subscription/client API ? Note that they are all non method functions (i.e. they are not part of a class)

  1. each function has its own node and subscribers/clients (all global variables) initialized at the first function call
  2. there is only one node common to all functions, each function has its own subscribers/clients
  3. there is only one node with a subscriber/client for each available data

A process requires once in a while a continuous stream of sensors data for a relatively short amount of time.

    void f_loop()
    {
        while(1){

             sleep(5 minutes);
             start_time = time;
             while (time <= start_time + 15 seconds){

                   auto response1 = ... client 1 request ...
                   cout << response1->data <<endl;
      } } }

What's the best ways for accessing this data?

  1. creating a subscriber at startup and spinning only when the data is required.
  2. creating a subscriber every time data are required and then letting it go out of scope to unsubscribe
  3. use a service

Thank you a lot

Asked by alsora on 2018-09-13 16:31:43 UTC

Comments

Have you read this wiki ? Then to answer some of your questions :

  • First question : if Data A and B are related you can create a unique message, if not two publisher is fine (or a service depending of how you want to provide the data)

Asked by Delb on 2018-09-17 01:29:02 UTC

  • Second question : for a continous stream, use topics. Don't create a new subscriber each time because if the sensors are publishing the data you just have to decide when you want to use it or not. You can have a callback treating the data only when required (by setting a flag or something)

Asked by Delb on 2018-09-17 01:31:18 UTC

First question : if Data A and B are related you can create a unique message, if not two publisher is fine

If both msgs are timestamped, then using a TimeSynchronizer approach might be nicer. Correlating data based on time is the whole point of header.stamp.

Asked by gvdhoorn on 2018-09-17 01:33:01 UTC

  • Last question : i don't really get it, you can have a subscriber for each data which calls the right function. If you can't have 2 functions running at the same time maybe consider using threads to allow it.

Asked by Delb on 2018-09-17 01:34:19 UTC

@gvdhoorn I agree but from his question it seems it's more about dealing with the content of the data rather than synchronizing them

Asked by Delb on 2018-09-17 01:37:51 UTC

@Delb: it seems like the question comes down to: "if I have two consumers that might both need the same data, but not always, should I put all data in a single msg or not?"

Using the timestamp we can say: no, use separate msgs and synchronise them when the content of both is needed.

Asked by gvdhoorn on 2018-09-17 01:39:18 UTC

@gvdhoorn Yes you're right it's better with your analogy

Asked by Delb on 2018-09-17 01:45:34 UTC

Thank you for all your ideas! Yes, the first question can be reformulated as @gvdhoorn said. Using a TimeSynchronizer looks like the most elegant solution. Is it also the most efficient one?

Asked by alsora on 2018-09-17 16:20:43 UTC

@Delb I have rewritten the third question. I have not understood the reason why you suggest to not create a new subscriber every time. My doubt is if it's more efficient than letting a subscriber receive messages even when they are not needed.

Asked by alsora on 2018-09-17 16:41:31 UTC

For the TimeSynchronizer I would say that it depends of the publication rate of data A and B. Let's say that data A rate is 1Hz and data B 100Hz with the TimeSynchronizer you would get a callback every 1sec (because of A) so if some nodes need data B every 100Hz that would be problematic

Asked by Delb on 2018-09-18 01:12:12 UTC

Maybe you can add a callback for A, B and the synchronized callback for A and B. Since I'm not familiar with TimeSynchronizer I will let someone confirm or contradict me.

Asked by Delb on 2018-09-18 01:13:54 UTC

For the second question : If you have already created a subscriber why bother deleting it to recreate it later ? I presume that the sensors will publish the data on a topic eventhough there are no subscribers to it. So it would be more efficient imo to simply decide when you want to access the data

Asked by Delb on 2018-09-18 01:19:31 UTC

If msg rates are very far apart, a regular Cache might make more sense.

Asked by gvdhoorn on 2018-09-18 01:59:51 UTC

Thank you for all the useful comments guys. @gvdhoorn all the data have the same frequency. I will definitely use the TimeSynchronizer . I have cleaned a little the question. Do you have any thoughts about what is now the second question? (it was the third question before this edit)

Asked by alsora on 2018-09-18 02:49:42 UTC

Note: my comments had ROS1 in mind. I'm not sure what the status of message_filters is in ROS 2.

Asked by gvdhoorn on 2018-09-18 03:01:05 UTC

Answers