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}
1// Include the basic eCAL header
2#include <ecal_c/ecal.h>
3
4#include <string.h> //memset()
5#include <stdio.h> //printf()
6
7int main()
8{
9 /*
10 Now we create a configuration object.
11 By default, when you use the eCAL::Init::Configuration() function, the ecal.yaml file will be read.
12 With that you have your main systems configuration.
13
14 If you want to use the defaults only, you can use directly eCAL::Configuration struct and use it the same way.
15 */
16 eCAL_Configuration* my_config = eCAL_Init_Configuration();
17
18 /*
19 Let's set some configuration parameters.
20 We want our eCAL application to communicate over the network (e.g. to monitor it from another machine).
21
22 Furthermore we set the default layer for future publishers and subscribers to SHM and deactivate the other layers.
23
24 This will overwrite the settings that were set in the ecal.yaml file.
25 */
26 my_config->communication_mode = eCAL_eCommunicationMode_network;
27 my_config->publisher.layer.shm.enable = 1;
28 my_config->publisher.layer.udp.enable = 0;
29 my_config->publisher.layer.tcp.enable = 0;
30
31 /*
32 Now we can pass the configuration object to eCAL::Initialize().
33 */
34 eCAL_Initialize("cake send c", NULL, my_config);
35
36 /*
37 Now we create publishers and subscribers that will communicat via different layers.
38 */
39 const char* topic_name = "cake";
40
41 /*
42 We start with the default configuration, which we set before via the configuration object.
43 This means we will use the SHM layer for publishing and subscribing.
44 */
45 eCAL_Publisher* publisher_shm = eCAL_Publisher_New(topic_name, NULL, NULL, NULL);
46
47 /*
48 Next we alter the configuration in order to have the communication via UDP.
49 */
50 struct eCAL_Publisher_Configuration custom_publisher_config;
51 memcpy(&custom_publisher_config, eCAL_GetPublisherConfiguration(), sizeof(struct eCAL_Publisher_Configuration));
52 custom_publisher_config.layer.udp.enable = 1;
53 custom_publisher_config.layer.shm.enable = 0;
54
55 eCAL_Publisher* publisher_udp = eCAL_Publisher_New(topic_name, NULL, NULL, &custom_publisher_config);
56
57 /*
58 Last we create a publisher and subscriber that will communicate via TCP.
59 */
60 custom_publisher_config.layer.tcp.enable = 1;
61 custom_publisher_config.layer.udp.enable = 0;
62
63 eCAL_Publisher* publisher_tcp = eCAL_Publisher_New(topic_name, NULL, NULL, &custom_publisher_config);
64
65 /*
66 Now we can start the publisher and subscriber.
67 The publisher will send a message every 500ms.
68 The subscriber will print the received messages to the console.
69 */
70 unsigned int counter = 0;
71 char message_shm[256];
72 char message_udp[256];
73 char message_tcp[256];
74
75 while(eCAL_Ok())
76 {
77 /*
78 Now we send the messages via the different layers.
79 Only the subscriber that listens to the same layer will receive the message.
80
81 We will have some delay between the messages, so there will be overlapping messages.
82 */
83 snprintf(message_shm, sizeof(message_shm), "Hello from SHM publisher (%d)", counter);
84 eCAL_Publisher_Send(publisher_shm, message_shm, strlen(message_shm), NULL);
85 eCAL_Process_SleepMS(100);
86
87 snprintf(message_udp, sizeof(message_udp), "Hello from UDP publisher (%d)", counter);
88 eCAL_Publisher_Send(publisher_udp, message_udp, strlen(message_udp), NULL);
89 eCAL_Process_SleepMS(100);
90
91 snprintf(message_tcp, sizeof(message_tcp), "Hello from TCP publisher (%d)", counter);
92 eCAL_Publisher_Send(publisher_tcp, message_tcp, strlen(message_tcp), NULL);
93
94 ++counter;
95
96 eCAL_Process_SleepMS(500);
97 }
98
99 /*
100 New we delete all the handles we created.
101 */
102 eCAL_Publisher_Delete(publisher_shm);
103 eCAL_Publisher_Delete(publisher_udp);
104 eCAL_Publisher_Delete(publisher_tcp);
105 eCAL_Configuration_Delete(my_config);
106
107 /*
108 And as always we need to finalize the eCAL API.
109 */
110 eCAL_Finalize();
111
112 return(0);
113}
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}
1// Include the basic eCAL header
2#include <ecal_c/ecal.h>
3
4#include <string.h> //memset()
5#include <stdio.h> //printf()
6
7void OnReceive(const struct eCAL_STopicId* topic_id_, const struct eCAL_SDataTypeInformation* data_type_information_, const struct eCAL_SReceiveCallbackData* callback_data_, void* user_argument_) {
8 (void*)data_type_information_;
9 const char* layer = (const char*)user_argument_;
10
11 printf("---------------------------------------------------\n");
12 printf(" Received %s message in C\n", layer);
13 printf("---------------------------------------------------\n");
14 printf(" Topic : %s\n", topic_id_->topic_name);
15 printf(" Size : %lld\n", callback_data_->buffer_size);
16 printf(" Time : %lld\n", callback_data_->send_timestamp);
17 printf(" Clock : %lld\n", callback_data_->send_clock);
18 printf(" Message : %.*s\n", (int)(callback_data_->buffer_size), (char*)(callback_data_->buffer));
19 printf("\n");
20};
21
22int main()
23{
24 /*
25 Now we create a configuration object.
26 By default, when you use the eCAL::Init::Configuration() function, the ecal.yaml file will be read.
27 With that you have your main systems configuration.
28
29 If you want to use the defaults only, you can use directly eCAL::Configuration struct and use it the same way.
30 */
31 eCAL_Configuration* my_config = eCAL_Init_Configuration();
32
33 /*
34 Let's set some configuration parameters.
35 We want our eCAL application to communicate over the network (e.g. to monitor it from another machine).
36
37 Furthermore we set the default layer for future subscribers to SHM and deactivate the other layers.
38
39 This will overwrite the settings that were set in the ecal.yaml file.
40 */
41 my_config->communication_mode = eCAL_eCommunicationMode_network;
42 my_config->subscriber.layer.shm.enable = 1;
43 my_config->subscriber.layer.udp.enable = 0;
44 my_config->subscriber.layer.tcp.enable = 0;
45
46 /*
47 Now we can pass the configuration object to eCAL::Initialize().
48 */
49 eCAL_Initialize("cake receive c", NULL, my_config);
50
51 /*
52 Now we create subscribers that will communicat via different layers.
53 */
54 const char* topic_name = "cake";
55
56 /*
57 We start with the default configuration, which we set before via the configuration object.
58 This means we will use the SHM layer for subscribing.
59 */
60 eCAL_Subscriber* subscriber_shm = eCAL_Subscriber_New(topic_name, NULL, NULL, NULL);
61
62 eCAL_Subscriber_SetReceiveCallback(subscriber_shm, OnReceive, "SHM");
63
64 /*
65 Next we alter the configuration in order to have the communication via UDP.
66 */
67 struct eCAL_Subscriber_Configuration custom_subscriber_config;
68 memcpy(&custom_subscriber_config, eCAL_GetSubscriberConfiguration(), sizeof(struct eCAL_Subscriber_Configuration));
69 custom_subscriber_config.layer.udp.enable = 1;
70 custom_subscriber_config.layer.shm.enable = 0;
71
72 eCAL_Subscriber* subscriber_udp = eCAL_Subscriber_New(topic_name, NULL, NULL, &custom_subscriber_config);
73
74 eCAL_Subscriber_SetReceiveCallback(subscriber_udp, OnReceive, "UDP");
75
76 /*
77 Last we create subscriber that will communicate via TCP.
78 */
79 custom_subscriber_config.layer.tcp.enable = 1;
80 custom_subscriber_config.layer.udp.enable = 0;
81
82 eCAL_Subscriber* subscriber_tcp = eCAL_Subscriber_New(topic_name, NULL, NULL, &custom_subscriber_config);
83
84 eCAL_Subscriber_SetReceiveCallback(subscriber_tcp, OnReceive, "TCP");
85
86 /*
87 Stay in a loop and let the callbacks to their work until the user stops the program.
88 */
89 while(eCAL_Ok())
90 {
91 eCAL_Process_SleepMS(500);
92 }
93
94 /*
95 New we delete all the handles we created.
96 */
97 eCAL_Subscriber_Delete(subscriber_shm);
98 eCAL_Subscriber_Delete(subscriber_udp);
99 eCAL_Subscriber_Delete(subscriber_tcp);
100 eCAL_Configuration_Delete(my_config);
101
102 /*
103 And as always we need to finalize the eCAL API.
104 */
105 eCAL_Finalize();
106
107 return(0);
108}
7.3.4. Cake Receiver Files#
├─ C++ │ └─cake_receive.cpp
│ └─ C └─cake_receive_c.c