C++#
eCAL - enhanced communication abstraction layer#
- page index
Introduction
The enhanced communication abstraction layer (eCAL) is a middleware that enables scalable, high performance interprocess communication on a single computer node or between different nodes in a computer network. The design is inspired by known Data Distribution Service for Real-Time Systems (see Data distribution service on wikipedia). The current eCAL implementation realizes a subset of such a DDS system, there is no support for Quality of Service (QoS) driven data transport. eCAL is designed for typical cloud computing scenarios where different processes exchange there I/O’s using a publisher/subscriber pattern. The data exchange is based on so called topics. A topic wraps the payload that should be exchanged with additional informations like a unique name, a type and a description. A topic can be connected to more then one publisher and/or subscriber. These are the basic elements of the eCAL API.
Topic: The most basic description of the data to be published and subscribed.
Publisher: A Publisher is the object responsible for the actual dissemination of publications.
Subscriber: A Subscriber is the object responsible for the actual reception of the data resulting from its subscriptions.
Callback: A Callback can be used to react on incoming messages.
A simple hello world example
Now lets see a minimal publisher/subscriber example exchanging the famous “hello world” message :-). First the publisher ..
#include <ecal/ecal.h> int main(int argc, char **argv) { // initialize eCAL API eCAL::Initialize(argc, argv, "minimal_pub"); // create a publisher (topic name "foo", type "std::string") eCAL::CPublisher pub("foo", "std::string"); // send the content pub.Send("hello world"); // finalize eCAL API eCAL::Finalize(); }
and the minimal subscriber ..
#include <ecal/ecal.h> int main(int argc, char **argv) { // initialize eCAL API eCAL::Initialize(argc, argv, "minimal_sub"); // create a subscriber (topic name "foo", type "std::string") eCAL::CSubscriber sub("foo", "std::string"); // receive content std::string msg; sub.Receive(msg); // finalize eCAL API eCAL::Finalize(); }
Trigger on incoming topics
A callback function can be used to react on events of multiple subscribers. An extended “hello world” example could look like this. First the publisher part
// create 2 publishers eCAL::CPublisher pub1("foo1", "std::string"); eCAL::CPublisher pub2("foo2", "std::string"); // sending "hello world" on 2 different topics while(eCAL::Ok()) { pub1.Send("hello"); eCAL::Process::SleepMS(1000); pub2.Send("world"); }
We use a callback function to react on incoming topics (with “old school” function pointer)
// define a subscriber callback function void OnReceive(const char* topic_name_, const struct eCAL::SReceiveCallbackData* data_, const void* par_) { printf("We received %s on topic %s\n.", (char*)data_->buf, topic_name_.c_str()); } // create 2 subscriber eCAL::CSubscriber sub1("foo1", "std::string"); eCAL::CSubscriber sub2("foo2", "std::string"); // register subscriber callback function sub1.AddReceiveCallback(OnReceive); sub2.AddReceiveCallback(OnReceive); // idle main thread while(eCAL::Ok()) { // sleep 100 ms std::this_thread::sleep_for(std::chrono::milliseconds(100)); }
or we can connect to a callback function using std::bind and a specialized string message subscriber
// define a subscriber callback function void OnReceive(const char* topic_name_, const std::string& message_) { printf("We received %s on topic %s\n.", message_.c_str(), topic_name_.c_str()); } // create 2 subscriber eCAL::string::CSubscriber sub1("foo1"); eCAL::string::CSubscriber sub2("foo2"); // register subscriber callback function auto callback = std::bind(OnReceive, std::placeholders::_1, std::placeholders::_2); sub1.AddReceiveCallback(callback); sub2.AddReceiveCallback(callback); // idle main thread while(eCAL::Ok()) { // sleep 100 ms std::this_thread::sleep_for(std::chrono::milliseconds(100)); }
(De)Serialization of objects
The eCAL middleware does not provide a mechanism to serialize or deserialize message objects. This has to be implemented in a higher level API. See google flatbuffers, cap’n proto or google protobuf for more details. Here a typical example using google protobuf. First you have to define a so called .proto file for the structure you want to serialize and deserialize. A simple Shape struct will be defined as follows ..
message Shape { enum ShapeType { CIRCLE = 0; TRIANGLE = 1; RECTANGLE = 2; } required ShapeType type = 1 [default = CIRCLE]; required int32 size = 2; }
After compiling that .proto file using the protobuf compiler you will receive a shape.pb.cc and shape.pb.h file that you have to include into your project. The serialization and deserialization is then quite simple ..
// create a publisher (topic name "shape") eCAL::protobuf::CPublisher<Shape> pub("shape"); // and generate a class instance of Shape class Shape shape; // modify type and size of the shape object shape.set_type(Shape_ShapeType_CIRCLE); shape.set_size(42); // send the shape object pub.Send(shape);
And last not least the matching deserialization ..
// create a subscriber (topic name "shape") eCAL::protobuf::CSubscriber<Shape> sub("shape"); // and generate a class instance of Shape class Shape shape; // receive the shape object sub.Receive(shape);
A similar way can be used to work with google flatbuffers. The flatbuffer message schema looks like this
namespace Game.Sample; enum Color:byte { Red = 0, Green, Blue = 2 } union Any { Monster } // add more elements.. struct Vec3 { x:float; y:float; z:float; } table Monster { pos:Vec3; mana:short = 150; hp:short = 100; name:string; friendly:bool = false (deprecated); inventory:[ubyte]; color:Color = Blue; } root_type Monster;
After compiling the flatbuffer message we can send it the same way like a protocol buffer.
// create a publisher (topic name "monster") eCAL::flatbuffers::CPublisher<flatbuffers::FlatBufferBuilder> pub("monster"); // the generic builder instance flatbuffers::FlatBufferBuilder builder; // generate a class instance of Monster auto vec = Game::Sample::Vec3(1, 2, 3); auto name = builder.CreateString("Monster"); unsigned char inv_data[] = { 0, 1, 2, 3, 4, 5, 6, 7, 8, 9 }; auto inventory = builder.CreateVector(inv_data, 10); // shortcut for creating monster with all fields set: auto mloc = Game::Sample::CreateMonster(builder, &vec, 150, 80, name, inventory, Game::Sample::Color_Blue); // finalize the message builder.Finish(mloc); // and send the monster pub.Send(builder, -1);
Finally let’s receive it via receive callback. So first we define a callback function for the flatbuffer message.
void OnMonster(const char* topic_name_, const flatbuffers::FlatBufferBuilder& msg_, const long long time_) { // create monster auto monster = Game::Sample::GetMonster(msg_.GetBufferPointer()); // print content std::cout << "monster pos x : " << monster->pos()->x() << std::endl; std::cout << "monster pos y : " << monster->pos()->y() << std::endl; std::cout << "monster pos z : " << monster->pos()->z() << std::endl; std::cout << "monster name : " << monster->name()->c_str() << std::endl; }
and implement the flatbuffer subscriber.
// create a subscriber (topic name "monster") eCAL::flatbuffers::CSubscriber<flatbuffers::FlatBufferBuilder> sub("monster"); // add receive callback function (_1 = topic_name, _2 = msg, _3 = time) auto callback = std::bind(OnMonster, std::placeholders::_1, std::placeholders::_2, std::placeholders::_3); sub.AddReceiveCallback(callback);
Catching eCAL events
Beside the message receive callbacks eCAL provides an API to get informed if publisher / subscriber internal events get fired. The following example shows how to catch the connect and disconnect events of an eCAL publisher. First we define the event callback function ..
void OnEvent(const char* topic_name_, const struct eCAL::SPubEventCallbackData* data_) { std::cout << "topic name : " << topic_name_ << std::endl; switch (data_->type) { case pub_event_connected: std::cout << "event : " << "pub_event_connected" << std::endl; break; case pub_event_disconnected: std::cout << "event : " << "pub_event_disconnected" << std::endl; break; default: std::cout << "event : " << "unknown" << std::endl; break; } std::cout << std::endl; }
Then we only have to bind the event we are interested in to the event callback.
// create a publisher (topic name "person") eCAL::protobuf::CPublisher<class pb::People::Person> pub("person"); // add event callback function (_1 = topic_name, _2 = event data struct) auto evt_callback = std::bind(OnEvent, std::placeholders::_1, std::placeholders::_2); pub.AddEventCallback(pub_event_connected, evt_callback); pub.AddEventCallback(pub_event_disconnected, evt_callback);
Page Hierarchy#
Class Hierarchy#
-
- Namespace eCAL
- Namespace eCAL::Config
- Enum UdpConfigVersion
- Namespace eCAL::eh5
- Class HDF5Meas
- Namespace eCAL::QOS
- Enum eQOSPolicy_HistoryKind
- Struct SReaderQOS
- Struct SWriterQOS
- Enum eQOSPolicy_Reliability
- Namespace eCAL::TLayer
- Enum eSendMode
- Enum eTransportLayer
- Struct STLayer
- Struct SClientAttr
- Struct SClientEventCallbackData
- Struct SDataTypeInformation
- Struct SEventHandle
- Struct SPubEventCallbackData
- Struct SReceiveCallbackData
- Struct SServerEventCallbackData
- Struct SServiceAttr
- Struct SServiceMethodInformation
- Struct SServiceResponse
- Struct SSubEventCallbackData
- Struct STopicInformation
- Template Class CMsgPublisher
- Template Class CMsgSubscriber
- Class CPayloadWriter
- Class CPublisher
- Class CServiceClient
- Class CServiceServer
- Class CSubscriber
- Class CTimedCB
- Class CTimer
- Namespace eCAL::Config
- Class CDynamicSleeper
- Enum eCAL_Logging_eLogLevel
- Enum eCAL_Process_eSeverity
- Enum eCAL_Process_eSeverity_Level
- Enum eCAL_Process_eStartMode
- Namespace eCAL
File Hierarchy#
-
- File doc.hpp
- File dynamic.h
- File dynamic_sleeper.h
- File ecal.h
- File ecal_callback.h
- File ecal_clang.h
- File ecal_client.h
- File ecal_config.h
- File ecal_core.h
- File ecal_deprecate.h
- File ecal_event.h
- File ecal_eventhandle.h
- File ecal_init.h
- File ecal_log.h
- File ecal_log_level.h
- File ecal_monitoring.h
- File ecal_os.h
- File ecal_payload_writer.h
- File ecal_process.h
- File ecal_process_mode.h
- File ecal_process_severity.h
- File ecal_publisher.h
- File ecal_qos.h
- File ecal_server.h
- File ecal_service.h
- File ecal_service_info.h
- File ecal_subscriber.h
- File ecal_time.h
- File ecal_timed_cb.h
- File ecal_timer.h
- File ecal_tlayer.h
- File ecal_types.h
- File ecal_util.h
- File ecalc.h
- File ecalc_types.h
- File ecaltime.h
- File eh5_defs.h
- File eh5_meas.h
- File eh5_types.h
- File publisher.h
- File subscriber.h
Full API#
Namespaces#
Classes and Structs#
- Template Class CMsgPublisher
- Inheritance Relationships
- Class Documentation
CMsgPublisher
CMsgPublisher::CMsgPublisher()
CMsgPublisher::CMsgPublisher()
CMsgPublisher::CMsgPublisher()
CMsgPublisher::CMsgPublisher()
CMsgPublisher::CMsgPublisher()
CMsgPublisher::operator=()
CMsgPublisher::CMsgPublisher()
CMsgPublisher::operator=()
CMsgPublisher::~CMsgPublisher()
CMsgPublisher::Create()
CMsgPublisher::Create()
CMsgPublisher::Destroy()
CMsgPublisher::Send()
CMsgPublisher::Send()
- Template Class CMsgSubscriber
- Inheritance Relationships
- Class Documentation
CMsgSubscriber
CMsgSubscriber::MsgReceiveCallbackT
CMsgSubscriber::CMsgSubscriber()
CMsgSubscriber::CMsgSubscriber()
CMsgSubscriber::CMsgSubscriber()
CMsgSubscriber::~CMsgSubscriber()
CMsgSubscriber::CMsgSubscriber()
CMsgSubscriber::operator=()
CMsgSubscriber::CMsgSubscriber()
CMsgSubscriber::operator=()
CMsgSubscriber::Create()
CMsgSubscriber::Create()
CMsgSubscriber::Destroy()
CMsgSubscriber::Receive()
CMsgSubscriber::AddReceiveCallback()
CMsgSubscriber::RemReceiveCallback()
- Class CPublisher
- Inheritance Relationships
- Class Documentation
CPublisher
CPublisher::CPublisher()
CPublisher::CPublisher()
CPublisher::CPublisher()
CPublisher::CPublisher()
CPublisher::~CPublisher()
CPublisher::CPublisher()
CPublisher::operator=()
CPublisher::CPublisher()
CPublisher::operator=()
CPublisher::Create()
CPublisher::Create()
CPublisher::Create()
CPublisher::Destroy()
CPublisher::SetTypeName()
CPublisher::SetDescription()
CPublisher::SetDataTypeInformation()
CPublisher::SetAttribute()
CPublisher::ClearAttribute()
CPublisher::ShareType()
CPublisher::ShareDescription()
CPublisher::SetQOS()
CPublisher::GetQOS()
CPublisher::SetLayerMode()
CPublisher::SetMaxBandwidthUDP()
CPublisher::ShmSetBufferCount()
CPublisher::ShmEnableZeroCopy()
CPublisher::ShmSetAcknowledgeTimeout()
CPublisher::ShmSetAcknowledgeTimeout()
CPublisher::SetID()
CPublisher::Send()
CPublisher::Send()
CPublisher::Send()
CPublisher::SendSynchronized()
CPublisher::Send()
CPublisher::Send()
CPublisher::Send()
CPublisher::AddEventCallback()
CPublisher::RemEventCallback()
CPublisher::IsCreated()
CPublisher::IsSubscribed()
CPublisher::GetSubscriberCount()
CPublisher::GetTopicName()
CPublisher::GetTypeName()
CPublisher::GetDescription()
CPublisher::GetDataTypeInformation()
CPublisher::Dump()
CPublisher::DEFAULT_TIME_ARGUMENT
CPublisher::DEFAULT_ACKNOWLEDGE_ARGUMENT
- Class CServiceClient
- Class Documentation
CServiceClient
CServiceClient::CServiceClient()
CServiceClient::CServiceClient()
CServiceClient::~CServiceClient()
CServiceClient::CServiceClient()
CServiceClient::operator=()
CServiceClient::Create()
CServiceClient::Destroy()
CServiceClient::SetHostName()
CServiceClient::Call()
CServiceClient::Call()
CServiceClient::Call()
CServiceClient::CallAsync()
CServiceClient::AddResponseCallback()
CServiceClient::RemResponseCallback()
CServiceClient::AddEventCallback()
CServiceClient::RemEventCallback()
CServiceClient::GetServiceName()
CServiceClient::IsConnected()
- Class Documentation
- Class CServiceServer
- Class Documentation
CServiceServer
CServiceServer::CServiceServer()
CServiceServer::CServiceServer()
CServiceServer::~CServiceServer()
CServiceServer::CServiceServer()
CServiceServer::operator=()
CServiceServer::Create()
CServiceServer::Destroy()
CServiceServer::AddDescription()
CServiceServer::AddMethodCallback()
CServiceServer::RemMethodCallback()
CServiceServer::AddEventCallback()
CServiceServer::RemEventCallback()
CServiceServer::GetServiceName()
CServiceServer::IsConnected()
- Class Documentation
- Class CSubscriber
- Inheritance Relationships
- Class Documentation
CSubscriber
CSubscriber::CSubscriber()
CSubscriber::CSubscriber()
CSubscriber::CSubscriber()
CSubscriber::CSubscriber()
CSubscriber::~CSubscriber()
CSubscriber::CSubscriber()
CSubscriber::operator=()
CSubscriber::CSubscriber()
CSubscriber::operator=()
CSubscriber::Create()
CSubscriber::Create()
CSubscriber::Create()
CSubscriber::Destroy()
CSubscriber::SetQOS()
CSubscriber::GetQOS()
CSubscriber::SetID()
CSubscriber::SetAttribute()
CSubscriber::ClearAttribute()
CSubscriber::Receive()
CSubscriber::ReceiveBuffer()
CSubscriber::AddReceiveCallback()
CSubscriber::RemReceiveCallback()
CSubscriber::AddEventCallback()
CSubscriber::RemEventCallback()
CSubscriber::IsCreated()
CSubscriber::GetPublisherCount()
CSubscriber::GetTopicName()
CSubscriber::GetTypeName()
CSubscriber::GetDescription()
CSubscriber::GetDataTypeInformation()
CSubscriber::SetTimeout()
CSubscriber::Dump()
- Class HDF5Meas
- Class Documentation
HDF5Meas
HDF5Meas::CallbackFunction
HDF5Meas::HDF5Meas()
HDF5Meas::HDF5Meas()
HDF5Meas::~HDF5Meas()
HDF5Meas::HDF5Meas()
HDF5Meas::operator=()
HDF5Meas::HDF5Meas()
HDF5Meas::operator=()
HDF5Meas::Open()
HDF5Meas::Close()
HDF5Meas::IsOk()
HDF5Meas::GetFileVersion()
HDF5Meas::GetMaxSizePerFile()
HDF5Meas::SetMaxSizePerFile()
HDF5Meas::IsOneFilePerChannelEnabled()
HDF5Meas::SetOneFilePerChannelEnabled()
HDF5Meas::GetChannelNames()
HDF5Meas::HasChannel()
HDF5Meas::GetChannelDescription()
HDF5Meas::SetChannelDescription()
HDF5Meas::GetChannelType()
HDF5Meas::SetChannelType()
HDF5Meas::GetMinTimestamp()
HDF5Meas::GetMaxTimestamp()
HDF5Meas::GetEntriesInfo()
HDF5Meas::GetEntriesInfoRange()
HDF5Meas::GetEntryDataSize()
HDF5Meas::GetEntryData()
HDF5Meas::SetFileBaseName()
HDF5Meas::AddEntryToFile()
HDF5Meas::ConnectPreSplitCallback()
HDF5Meas::DisconnectPreSplitCallback()
- Class Documentation
Enums#
- Enum eCAL_Logging_eLogLevel
- Enum Documentation
eCAL_Logging_eLogLevel
eCAL_Logging_eLogLevel::log_level_none
eCAL_Logging_eLogLevel::log_level_all
eCAL_Logging_eLogLevel::log_level_info
eCAL_Logging_eLogLevel::log_level_warning
eCAL_Logging_eLogLevel::log_level_error
eCAL_Logging_eLogLevel::log_level_fatal
eCAL_Logging_eLogLevel::log_level_debug1
eCAL_Logging_eLogLevel::log_level_debug2
eCAL_Logging_eLogLevel::log_level_debug3
eCAL_Logging_eLogLevel::log_level_debug4
- Enum Documentation