/* * (c) 2019 Copyright, Real-Time Innovations, Inc. All rights reserved. * * RTI grants Licensee a license to use, modify, compile, and create derivative * works of the Software. Licensee has the right to distribute object form * only for use with RTI products. The Software is provided "as is", with no * warranty of any type, including any warranty for fitness for any purpose. * RTI is under no obligation to maintain or support the Software. RTI shall * not be liable for any incidental or consequential damages arising out of the * use or inability to use the software. */ #include #include #include #include // for sleep() #include "CameraImage.hpp" #include "application.hpp" const int PIXEL_COUNT = 10; // Simplest way to create the data sample void build_data_sample(CameraImageBuilder &builder, int seed) { builder.add_format(Format::RGB); if (seed % 3 == 0) { // All fields in a mutable FlatData type are in effect optional. For // illustration purposes, we will omit the resolution field in some // samples auto resolution_offset = builder.add_resolution(); resolution_offset.height(100); resolution_offset.width(200); } auto string_builder = builder.build_source(); string_builder.set_string("CAM-1"); string_builder.finish(); // Method 1 - Build the pixel sequence element by element auto pixels_builder = builder.build_pixels(); for (int i = 0; i < PIXEL_COUNT; i++) { auto pixel = pixels_builder.add_next(); pixel.red((seed + i) % 100); pixel.green((seed + i + 1) % 100); pixel.blue((seed + i + 2) % 100); } pixels_builder.finish(); } // Creates the same data sample using a faster method // to populate the pixel sequence void build_data_sample_fast(CameraImageBuilder &builder, int seed) { // The initialization of these members doesn't change builder.build_source().set_string("CAM-1"); builder.add_format(Format::RGB); auto resolution_offset = builder.add_resolution(); resolution_offset.height(100); resolution_offset.width(200); // Populate the pixel sequence accessing the byte buffer directly, instead // of iterating through each element Offset // 1) Use the builder to add all the elements at once. This operation is // cheap (it just advances the underlying buffer without initializing // anything) auto pixels_builder = builder.build_pixels(); pixels_builder.add_n(PIXEL_COUNT); auto pixels = pixels_builder.finish(); // 2) Use plain_cast to access the buffer as an array of regular C++ Pixels // (pixel_array's type is PixelPlainHelper*) auto pixel_array = rti::flat::plain_cast(pixels); for (int i = 0; i < PIXEL_COUNT; i++) { auto &pixel = pixel_array[i]; pixel.red((seed + i) % 100); pixel.green((seed + i + 1) % 100); pixel.blue((seed + i + 2) % 100); } } void run_publisher_application( unsigned int domain_id, unsigned int sample_count) { // Create a DomainParticipant with default Qos dds::domain::DomainParticipant participant(domain_id); // Create a Topic -- and automatically register the type dds::topic::Topic topic(participant, "Example CameraImage"); // Create a DataWriter with default Qos (Publisher created in-line) dds::pub::DataWriter writer( dds::pub::Publisher(participant), topic); for (unsigned int samples_written = 0; !application::shutdown_requested && samples_written < sample_count; samples_written++) { CameraImageBuilder builder = rti::flat::build_data(writer); // Build the CameraImage data sample using the builder if (samples_written % 2 == 0) { build_data_sample(builder, samples_written); // method 1 } else { build_data_sample_fast(builder, samples_written); // method 2 } // Create the sample CameraImage *sample = builder.finish_sample(); std::cout << "Writing CameraImage, count " << samples_written << std::endl; writer.write(*sample); rti::util::sleep(dds::core::Duration(4)); } } int main(int argc, char *argv[]) { using namespace application; // Parse arguments and handle control-C auto arguments = parse_arguments(argc, argv); if (arguments.parse_result == ParseReturn::exit) { return EXIT_SUCCESS; } else if (arguments.parse_result == ParseReturn::failure) { return EXIT_FAILURE; } setup_signal_handlers(); // Sets Connext verbosity to help debugging rti::config::Logger::instance().verbosity(arguments.verbosity); try { run_publisher_application(arguments.domain_id, arguments.sample_count); } catch (const std::exception &ex) { // This will catch DDS exceptions std::cerr << "Exception in run_publisher_application(): " << ex.what() << std::endl; return EXIT_FAILURE; } // Releases the memory used by the participant factory. Optional at // application exit dds::domain::DomainParticipant::finalize_participant_factory(); return EXIT_SUCCESS; }