Best practices for optimized data transmission

asked 2018-09-13 16:31:43 -0600

alsora gravatar image

updated 2018-09-18 02:45:03 -0600

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

edit retag flag offensive close merge delete

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)
Delb gravatar image Delb  ( 2018-09-17 01:29:02 -0600 )edit
  • 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)
Delb gravatar image Delb  ( 2018-09-17 01:31:18 -0600 )edit

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.

gvdhoorn gravatar image gvdhoorn  ( 2018-09-17 01:33:01 -0600 )edit
  • 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.
Delb gravatar image Delb  ( 2018-09-17 01:34:19 -0600 )edit

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

Delb gravatar image Delb  ( 2018-09-17 01:37:51 -0600 )edit

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

gvdhoorn gravatar image gvdhoorn  ( 2018-09-17 01:39:18 -0600 )edit

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

Delb gravatar image Delb  ( 2018-09-17 01:45:34 -0600 )edit

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?

alsora gravatar image alsora  ( 2018-09-17 16:20:43 -0600 )edit