7.3. Runtime Configuration#

In eCAL it is also possible to configure the environment at runtime. The eCAL API provides a set of structures that reflect the yaml configuration file (ecal.yaml).

You can pass this configuration structure to eCAL::Initialize().

But there is more: You can also modifiy the configuration of each publisher and subscriber individually. This allows you to be more flexible in the design of your application.

Important

Once set and passed to eCAL::Initialize(), the configuration is set. The getters for the configuration structures, e.g. eCAL::GetConfiguration(), return a constant struct. So it is has no effect to modify the configuration object without passing it to eCAL::Initialize().

In our example we will create multiple publishers and subscribers. They will communicate on different layers and will not interfere with each other, besides the same topic name.

7.3.1. Cake Publisher#

 1/*
 2  Include the eCAL main header.
 3  In addition, as we want to send simple strings, we include the string publisher header.
 4*/
 5#include <ecal/ecal.h>
 6#include <ecal/msg/string/publisher.h>
 7
 8#include <iostream>
 9
10int main()
11{
12  /*
13    Now we create a configuration object.
14    By default, when you use the eCAL::Init::Configuration() function, the ecal.yaml file will be read.
15    With that you have your main systems configuration.
16
17    If you want to use the defaults only, you can use directly eCAL::Configuration struct and use it the same way.
18  */
19  eCAL::Configuration my_config = eCAL::Init::Configuration();
20
21  /*
22    Let's set some configuration parameters.
23    We want our eCAL application to communicate over the network (e.g. to monitor it from another machine).
24
25    Furthermore we set the default layer for future publishers to SHM and deactivate the other layers.
26
27    This will overwrite the settings that were set in the ecal.yaml file.
28  */
29  my_config.communication_mode = eCAL::eCommunicationMode::network;
30  my_config.publisher.layer.shm.enable = true;
31  my_config.publisher.layer.udp.enable = false;
32  my_config.publisher.layer.tcp.enable = false;
33  
34  /*
35    Now we can pass the configuration object to eCAL::Initialize().
36  */
37  eCAL::Initialize(my_config, "cake send");
38
39  /*
40    Now we create publishers that will communicat via different layers.
41  */
42  const std::string topic_name = "cake";
43  
44  /*
45    We start with the default configuration, which we set before via the configuration object.
46    This means we will use the SHM layer for publishing.
47  */
48  eCAL::string::CPublisher publisher_shm(topic_name);
49
50  /*
51    Next we alter the configuration in order to have the communication via UDP.
52  */
53  auto custom_publisher_config = eCAL::GetPublisherConfiguration();
54  custom_publisher_config.layer.udp.enable = true;
55  custom_publisher_config.layer.shm.enable = false;
56 
57  eCAL::string::CPublisher publisher_udp(topic_name, custom_publisher_config);
58
59  /*
60    Last we create a publisher that will communicate via TCP.
61  */
62  custom_publisher_config.layer.tcp.enable = true;
63  custom_publisher_config.layer.udp.enable = false;
64
65  eCAL::string::CPublisher publisher_tcp(topic_name, custom_publisher_config);
66
67  /*
68    Now we can start the publisher.
69    The publisher will send a message every 500ms.
70  */
71  unsigned int counter = 0;
72
73  while(eCAL::Ok())
74  {
75    /*
76      Now we send the messages via the different layers.
77      Only the subscriber that listens to the same layer will receive the message.
78
79      We will have some delay between the messages, so there will be overlapping messages.
80    */
81    publisher_shm.Send("Hello from SHM publisher " + std::to_string(counter));
82    eCAL::Process::SleepMS(100);
83    publisher_udp.Send("Hello from UDP publisher " + std::to_string(counter));
84    eCAL::Process::SleepMS(100);
85    publisher_tcp.Send("Hello from TCP publisher " + std::to_string(counter));
86
87    ++counter;
88
89    eCAL::Process::SleepMS(300);
90  }
91
92  /*
93    And as always we need to finalize the eCAL API.
94  */
95  eCAL::Finalize();
96
97  return(0);
98}

7.3.2. Cake Publisher Files#


├─  C++
│  └─  cake_send.cpp
│
└─  C
   └─  cake_send_c.c

7.3.3. Cake Receiver#

  1/*
  2  Include the eCAL main header.
  3  In addition, as we want to send simple strings, we include the string subscriber header.
  4*/
  5#include <ecal/ecal.h>
  6#include <ecal/msg/string/subscriber.h>
  7
  8#include <iostream>
  9
 10void printLayerHeader(const std::string& layer_name_) {
 11  std::cout << "---------------------------------------------------" << "\n";
 12  std::cout << " Received " << layer_name_ << " message in C++" << "\n";
 13  std::cout << "---------------------------------------------------" << "\n";
 14};
 15
 16void printCallbackInformation(const eCAL::STopicId& publisher_id_, const std::string& message_, long long time_, long long clock_) { 
 17  std::cout << " Topic   : " << publisher_id_.topic_name << "\n";
 18  std::cout << " Size    : " << message_.size()          << "\n";
 19  std::cout << " Time    : " << time_                    << "\n";
 20  std::cout << " Clock   : " << clock_                   << "\n";
 21  std::cout << " Message : " << message_                 << "\n";
 22  std::cout << "\n";
 23};
 24
 25int main()
 26{
 27  /*
 28    Now we create a configuration object.
 29    By default, when you use the eCAL::Init::Configuration() function, the ecal.yaml file will be read.
 30    With that you have your main systems configuration.
 31
 32    If you want to use the defaults only, you can use directly eCAL::Configuration struct and use it the same way.
 33  */
 34  eCAL::Configuration my_config = eCAL::Init::Configuration();
 35
 36  /*
 37    Let's set some configuration parameters.
 38    We want our eCAL application to communicate over the network (e.g. to monitor it from another machine).
 39
 40    Furthermore we set the default layer for future subscribers to SHM and deactivate the other layers.
 41
 42    This will overwrite the settings that were set in the ecal.yaml file.
 43  */
 44  my_config.communication_mode = eCAL::eCommunicationMode::network;
 45  my_config.subscriber.layer.shm.enable = true;
 46  my_config.subscriber.layer.udp.enable = false;
 47  my_config.subscriber.layer.tcp.enable = false;
 48  
 49  /*
 50    Now we can pass the configuration object to eCAL::Initialize().
 51  */
 52  eCAL::Initialize(my_config, "cake receive");
 53
 54  /*
 55    Now we create subscribers that will communicat via different layers.
 56  */
 57  const std::string topic_name = "cake";
 58  
 59  /*
 60    We start with the default configuration, which we set before via the configuration object.
 61    This means we will use the SHM layer for subscribing.
 62  */
 63  eCAL::string::CSubscriber subscriber_shm(topic_name);
 64  subscriber_shm.SetReceiveCallback([](const eCAL::STopicId& publisher_id_, const std::string& message_, long long time_, long long clock_) { 
 65    printLayerHeader("SHM");
 66    printCallbackInformation(publisher_id_, message_, time_, clock_);
 67  });
 68
 69  /*
 70    Next we alter the configuration in order to have the communication via UDP.
 71  */
 72  auto custom_subscriber_config = eCAL::GetSubscriberConfiguration();
 73  custom_subscriber_config.layer.udp.enable = true;
 74  custom_subscriber_config.layer.shm.enable = false;
 75 
 76  eCAL::string::CSubscriber subscriber_udp(topic_name, custom_subscriber_config);
 77
 78  subscriber_udp.SetReceiveCallback([](const eCAL::STopicId& publisher_id_, const std::string& message_, long long time_, long long clock_) { 
 79    printLayerHeader("UDP");
 80    printCallbackInformation(publisher_id_, message_, time_, clock_);
 81  });
 82
 83  /*
 84    Last we create a subscriber that will communicate via TCP.
 85  */
 86  custom_subscriber_config.layer.tcp.enable = true;
 87  custom_subscriber_config.layer.udp.enable = false;
 88
 89  eCAL::string::CSubscriber subscriber_tcp(topic_name, custom_subscriber_config);
 90
 91  subscriber_tcp.SetReceiveCallback([](const eCAL::STopicId& publisher_id_, const std::string& message_, long long time_, long long clock_) { 
 92    printLayerHeader("TCP");
 93    printCallbackInformation(publisher_id_, message_, time_, clock_);
 94  });
 95
 96  /*
 97    Stay in a loop and let the callbacks to their work until the user stops the program.
 98  */
 99  while(eCAL::Ok())
100  {
101    eCAL::Process::SleepMS(500);
102  }
103
104  /*
105    And as always we need to finalize the eCAL API.
106  */
107  eCAL::Finalize();
108
109  return(0);
110}

7.3.4. Cake Receiver Files#


├─  C++
│  └─  cake_receive.cpp
│
└─  C
   └─  cake_receive_c.c