Weitere ähnliche Inhalte
Ähnlich wie DDS Programming with IDL to C++11 tutorial (20)
Kürzlich hochgeladen (20)
DDS Programming with IDL to C++11 tutorial
- 2. Overview
This tutorial shows how the famous DDS shapes
example can be implemented using the IDL to C++11
language mapping
It assumes basic understanding of IDL and DDS
For more information take a look at our website
www.remedy.nl
Copyright © Remedy IT2
- 3. Problems with IDL to C++
The IDL to C++ language mapping is from the 90’s
IDL to C++ could not depend on various C++
features as
• C++ namespace
• C++ exceptions
• Standard Template Library
As a result
• Mapping is hard to use correctly
• Uses its own constructs for everything
Copyright © Remedy IT3
- 4. Why a new language
mapping?
IDL to C++ language mapping is impossible to
change because
• Multiple implementations are on the market (open
source and commercial)
• A huge amount of applications have been developed
An updated IDL to C++ language mapping would
force all vendors and users to update their products
The standardization of a new C++ revision in 2011
(ISO/IEC 14882:2011, called C++11) gives the
opportunity to define a new language mapping
• C++11 features are not backward compatible with
C++03 or C++99
• A new C++11 mapping leaves the existing mapping
intact Copyright © Remedy IT4
- 5. Goals
Simplify mapping for C++
Make use of the new C++11 features to
• Reduce amount of application code
• Reduce amount of possible errors made
• Gain runtime performance
• Speedup development and testing
Faster time to market
Reduced costs
Reduced training time
Copyright © Remedy IT5
- 6. OMG Specification
IDL to C++11 is now a formal OMG standard
IDL to C++11 v1.2 available from the OMG website
as formal/2015-08-01
Revision Task Force (RTF) is active to work on
issues reported
Copyright © Remedy IT6
- 7. More information IDL to C++11
For background, details, tutorials, and examples see
the following websites
• http://taox11.remedy.nl
• http://osportal.remedy.nl
• http://www.orbzone.org
Copyright © Remedy IT7
- 9. IDL Topic Type
In order to exchange data we define in IDL a DDS
Topic Type
Based on the IDL Topic Type the following will be
generated
• C++11 type representation
• C++11 type specific DDS API
Copyright © Remedy IT9
- 11. DDS::traits<>
For each IDL Topic Type a set of DDS traits will be
generated
The DDS traits enable access to all implied DDS
entities
Together with the IDL::traits<> we can easily write
C++11 applications that use DDS and have access to
the meta type information from IDL
Copyright © Remedy IT11
- 12. DDS::traits<> overview
The following DDS reference traits are used in our
tutorial
A reference behaves like a std::shared_ptr and
for each type also a weak_ref_type is available
Copyright © Remedy IT12
Reference trait Meaning
domainparticipant_ref_type Reference to the DDS DomainParticipant
topic_ref_type Reference to the DDS Topic
publisher_ref_type Reference to the DDS Publisher
datawriter_ref_type Reference to the DDS DataWriter
typed_datawriter_ref_type Reference to the DDS Topic Type DataWriter
subscriber_ref_type Reference to the DDS Subscriber
datareader_ref_type Reference to the DDS DataReader
typed_datareader_ref_type Reference to the DDS Topic Type DataReader
- 13. Sender implementation (1)
// Create all DDS entities, if something fails we just return
DDS::ReturnCode_t retcode {DDS::RETCODE_OK};
// Create a domain participant for domain 0 with default QoS
DDS::traits<ShapeType>::domainparticipant_ref_type domain_participant =
DDS::traits<DDS::DomainParticipantFactory>::get_instance ()->create_participant (
0, DDS::PARTICIPANT_QOS_DEFAULT, nullptr, 0);
if (retcode != DDS::RETCODE_OK) return;
// Create a topic with default QoS
DDS::traits<ShapeType>::topic_ref_type topic = domain_participant->create_topic (
"Square", DDS::traits<ShapeType>::get_type_name (), DDS::TOPIC_QOS_DEFAULT, nullptr, 0);
// Create a publisher with default QoS
DDS::traits<ShapeType>::publisher_ref_type publisher =
domain_participant->create_publisher (DDS::PUBLISHER_QOS_DEFAULT, nullptr, 0);
// When we have a publisher and topic we create a datawriter with default QoS
if (publisher && topic) {
DDS::traits<ShapeType>::datawriter_ref_type dw =
publisher->create_datawriter (topic, DDS::DATAWRITER_QOS_DEFAULT, nullptr, 0);
// Narrow the base datawriter to a topic type specific datawriter
DDS::traits<ShapeType>::typed_datawriter_ref_type shape_dw =
DDS::traits<ShapeType>::narrow (dw);
}
Copyright © Remedy IT13
- 14. Sender implementation (2)
// When we have a topic type specific datawriter we register an instance to DDS and write data
if (shape_dw) {
ShapeType square {"GREEN", 10, 10, 25};
DDS::InstanceHandle_t instance_handle = shape_dw->register_instance (square);
// Write 100 samples
for (uint32_t i = 0; i < 100; ++i) {
shape_dw->write (square, instance_handle);
std::cout << "Written sample " << square << std::endl;
++square.x(); ++square.y();
std::chrono::milliseconds sleep_time (2000);
std::this_thread::sleep_for (sleep_time);
}
std::cout << std::endl << "Written 100 samples. Last sample: " << square << std::endl;
// Unregister the instance from DDS
shape_dw->unregister_instance (square, instance_handle);
}
Copyright © Remedy IT14
- 15. Receiver implementation (1)
// DDS Listener implementation that receives the samples and prints them on the console
class ShapeTypeListener final : public DDS::traits<ShapeType>::datareaderlistener_type {
public:
void ShapeTypeListener::on_data_available (DDS::traits<ShapeType>::datareader_ref_type the_reader) {
DDS::traits<ShapeType>::typed_datareader_ref_type rd =
DDS::traits<ShapeType>::narrow (the_reader);
ShapeType shape;
DDS::SampleInfo info;
for(;;) {
DDS::ReturnCode_t retcode = rd->take_next_sample(shape, info);
if (retcode == DDS::RETCODE_NO_DATA) {
/* No more samples */
break;
} else if (retcode != DDS::RETCODE_OK) {
std::cerr << "Unable to take data from data reader, error “ << retcode << std::endl;
return;
} else if (info.valid_data ()) {
std::cout << "Received <" << ++received_ << ">: " << shape << std::endl;
}
}
// Left other operations out of this class for simplicity
}
Copyright © Remedy IT15
- 16. Receiver implementation (2)
// Code that is placed in main
// Create all DDS entities, if something fails we just return
DDS::ReturnCode_t retcode {DDS::RETCODE_OK};
DDS::traits<ShapeType>::domainparticipant_ref_type domain_participant =
DDS::traits< DDS::DomainParticipantFactory >::get_instance ()->create_participant (
0, DDS::PARTICIPANT_QOS_DEFAULT, nullptr, 0);
retcode = DDS::traits<ShapeType>::register_type (domain_participant, "ShapeType");
if (retcode != DDS::RETCODE_OK) return 1;
DDS::traits<ShapeType>::topic_ref_type topic = domain_participant->create_topic (
"Square", DDS::traits<ShapeType>::get_type_name (), DDS::TOPIC_QOS_DEFAULT, nullptr, 0);
DDS::traits<ShapeType>::subscriber_ref_type subscriber =
domain_participant->create_subscriber (DDS::SUBSCRIBER_QOS_DEFAULT, nullptr, 0);
if (topic && subscriber) {
DDS::traits<ShapeType>::datareaderlistener_ref_type listener =
DDS::make_reference<ShapeTypeListener>();
// Create datareader with an instance of the listener
subscriber->create_datareader (topic, DDS::DATAREADER_QOS_DEFAULT, listener,
DDS::DATA_AVAILABLE_STATUS);
// Run the main thread in a loop, give control to a framework, ..
// DDS will do a callback on its own thread
Copyright © Remedy IT16
- 17. Contact
Copyright © Remedy IT17
Remedy IT
Postbus 81
6930 AB Westervoort
The Netherlands
tel.: +31(0)88 – 053 0000
e-mail: sales@remedy.nl
website: www.remedy.nl
Twitter: @RemedyIT
Slideshare: RemedyIT
Subscribe to our mailing list