diff --git a/.devcontainer/docker-compose-vscode.yml b/.devcontainer/docker-compose-vscode.yml index 24c56ba10..4f0dac989 100755 --- a/.devcontainer/docker-compose-vscode.yml +++ b/.devcontainer/docker-compose-vscode.yml @@ -25,7 +25,6 @@ services: - SIM_EXTERNAL_OBJECT_PORT=7576 - V2X_PORT=8686 - INFRASTRUCTURE_ID=1 - - KAFKA_BROKER_ADDRESS=127.0.0.1:9092 secrets: - mysql_password diff --git a/docs/Release_notes.md b/docs/Release_notes.md index 3ab4842c9..d7b326b3b 100644 --- a/docs/Release_notes.md +++ b/docs/Release_notes.md @@ -1,6 +1,44 @@ V2X-Hub Release Notes --------------------------------- +Version 7.5.1, released June 21st, 2023 +-------------------------------------------------------- + +**Summary:** + V2X Hub release 7.5.1 includes added functionality to integrate V2X Hub with CDASim environment. This integration includes V2X Hub registering as a Roadside Unit (RSU) in the CDASim environment, consuming and producing J2735 messages to the CDASim environment, and adding functionality to synchronize plugins to CDASim simulation time. + +**V2X Hub CDASim Functionalities ** + +Enhancements in this release: + +- Added new carma-time-lib to V2X Hub to allow services to use an external source for time value and update rate. +- Added new Plugin Client ClockAware, which extends Plugin Client and implements functionality to consume time sync messages and updates a carma-clock object from carma-time-lib. Any plugins that want to synchronize their time to simulation must extend this plugin to gain access to this functionality. +- Added CDASim Adapter plugin which is responsible for establishing connection between V2X Hub and CDASim environment. This includes a handshake that provides information about the V2X Hub simulated location and ID and message forwarding for J2735 messages and time synchronization messages. This plugin requires several environment variables to be set which are documented on the GitHub repo README.md. + +Fixes in this release: + +- PR 488: Added a simulated clock functionality with the new time library and tested. +- PR 489: Setup Kafka consumers for the time topic when running in simulation mode. +- Issue 492: Created a carma-simulation adapter shell for service that will act as adapter for CARMA Simulation integration. +- PR 509: Added a V2X Hub plugin inside the simulation platform to receive all messages from V2X Hub. This plugin contains parameters and variables that are provided in real-world scenarios. +- Issue 514: Added handshake functionality to carma-simulation ambassador instance which register’s the V2X Hub instance inside the simulator to allow multiple V2X Hub instances to connect with a single CARMA Simulation platform. +- Issue 535: Updated infrastructure registration to use a cartesian point as location over a geodetic point to allow for easier configuration of simulated location of an RSU. +- Issue 537: Fixed configuration parameters to correctly map X, Y, Z coordinates to Point for Infrastructure registration in CDASim Adapter. +- Issue 525: Fixed CDASim Adapter plugin that throws an exception while attempting CDASim handshake with CARMA-Simulation. + +Known issues in this release: + +- Issue #540: CDASim Time Synchronization is non-time-regulating. If simulation runs too fast (faster than real-time) for V2X Hub to keep up, V2X Hub can fall behind in time. +- Issue #507: SPaT plugin throws segfault when in SIM MODE +- Issue #10 in carma-time-lib (not V2X Hub repo): wait_for_initialization does not support notifying multiple threads Work around exists for services/plugins using carma-time-lib. +- Issue #543: CARMA Streets Plugin Kafka Consumers can send redundant subscription attempts on initialization and can cause subscriptions to silently fail. + +**Other ** + +Enhancements in this release: + +- Issue 511: Added new functionality get the log time for a message received in V2xHub to forward to Carma cloud, and from receiving in Carma Cloud to forward V2xhub. + Version 7.5.0, released May 5th, 2023 -------------------------------------------------------- diff --git a/src/tmx/TmxUtils/src/PluginClientClockAware.cpp b/src/tmx/TmxUtils/src/PluginClientClockAware.cpp index c8317c678..4cf87fe6b 100644 --- a/src/tmx/TmxUtils/src/PluginClientClockAware.cpp +++ b/src/tmx/TmxUtils/src/PluginClientClockAware.cpp @@ -8,11 +8,11 @@ namespace tmx::utils { : PluginClient(name) { // check for simulation mode enabled by environment variable - bool simulationMode = sim::is_simulation_mode(); + _simulation_mode = sim::is_simulation_mode(); using namespace fwha_stol::lib::time; - clock = std::make_shared(simulationMode); - if (simulationMode) { + clock = std::make_shared(_simulation_mode); + if (_simulation_mode) { AddMessageFilter(this, &PluginClientClockAware::HandleTimeSyncMessage); } @@ -25,7 +25,6 @@ namespace tmx::utils { this->getClock()->update( msg.get_timestep() ); if (sim::is_simulation_mode() ) { SetStatus(Key_Simulation_Time_Step, Clock::ToUtcPreciseTimeString(msg.get_timestep())); - } } @@ -36,4 +35,8 @@ namespace tmx::utils { } } + bool PluginClientClockAware::isSimulationMode() const { + return _simulation_mode; + } + } \ No newline at end of file diff --git a/src/tmx/TmxUtils/src/PluginClientClockAware.h b/src/tmx/TmxUtils/src/PluginClientClockAware.h index e0981b8d1..974f55060 100644 --- a/src/tmx/TmxUtils/src/PluginClientClockAware.h +++ b/src/tmx/TmxUtils/src/PluginClientClockAware.h @@ -28,7 +28,7 @@ class PluginClientClockAware : public PluginClient { * @param msg TimeSyncMessage broadcast on TMX core * @param routeableMsg */ - void HandleTimeSyncMessage(tmx::messages::TimeSyncMessage &msg, routeable_message &routeableMsg ); + virtual void HandleTimeSyncMessage(tmx::messages::TimeSyncMessage &msg, routeable_message &routeableMsg ); protected: @@ -41,6 +41,9 @@ class PluginClientClockAware : public PluginClient { } void OnStateChange(IvpPluginState state) override; + + bool isSimulationMode() const; + private: /** @@ -55,6 +58,8 @@ class PluginClientClockAware : public PluginClient { * @brief Status label to indicate whether plugin is in Simulation Mode. */ const char* Key_Simulation_Mode = "Simulation Mode "; + + bool _simulation_mode; }; diff --git a/src/tmx/TmxUtils/src/Point.h b/src/tmx/TmxUtils/src/Point.h new file mode 100644 index 000000000..b075d4430 --- /dev/null +++ b/src/tmx/TmxUtils/src/Point.h @@ -0,0 +1,19 @@ +#pragma once + +namespace tmx::utils { + + + /// Cartesian Coordinates on a . + typedef struct Point + { + Point() : X(0), Y(0), Z(0) {} + + Point(double x, double y, double z = 0.0): + X(x), Y(y), Z(z) { } + + double X; + double Y; + double Z; + } Point; + +} // namespace tmx::utils diff --git a/src/tmx/TmxUtils/src/kafka/kafka_consumer_worker.cpp b/src/tmx/TmxUtils/src/kafka/kafka_consumer_worker.cpp index a0a3d2c8f..97f9d4373 100644 --- a/src/tmx/TmxUtils/src/kafka/kafka_consumer_worker.cpp +++ b/src/tmx/TmxUtils/src/kafka/kafka_consumer_worker.cpp @@ -8,6 +8,10 @@ namespace tmx::utils _partition(partition) { } + kafka_consumer_worker::~kafka_consumer_worker() { + stop(); + FILE_LOG(logWARNING) << "Kafka consumer destroyed!" << std::endl; + } bool kafka_consumer_worker::init() { @@ -93,11 +97,12 @@ namespace tmx::utils void kafka_consumer_worker::stop() { + FILE_LOG(logWARNING) << "Stopping Kafka Consumer!" << std::endl; _run = false; //Close and shutdown the consumer. _consumer->close(); - /*Destroy kafka instance*/ // Wait for RdKafka to decommission. - RdKafka::wait_destroyed(5000); + FILE_LOG(logWARNING) << "Kafka Consumer Stopped!" << std::endl; + } void kafka_consumer_worker::subscribe() diff --git a/src/tmx/TmxUtils/src/kafka/kafka_consumer_worker.h b/src/tmx/TmxUtils/src/kafka/kafka_consumer_worker.h index 95a9c96a8..341492b17 100644 --- a/src/tmx/TmxUtils/src/kafka/kafka_consumer_worker.h +++ b/src/tmx/TmxUtils/src/kafka/kafka_consumer_worker.h @@ -68,6 +68,19 @@ namespace tmx::utils { * @param partition partition consumer should be assigned to. */ kafka_consumer_worker(const std::string &broker_str, const std::string &topic_str, const std::string & group_id, int64_t cur_offset = 0, int32_t partition = 0); + /** + * @brief Destroy the kafka consumer worker object. Calls stop on consumer to clean up resources. + */ + ~kafka_consumer_worker(); + // Rule of 5 because destructor is define (https://www.codementor.io/@sandesh87/the-rule-of-five-in-c-1pdgpzb04f) + // Delete copy constructor + kafka_consumer_worker(kafka_consumer_worker& other) = delete; + // Delete copy assigment + kafka_consumer_worker& operator=(const kafka_consumer_worker& other) = delete; + // delete move constructor + kafka_consumer_worker(kafka_consumer_worker &&consumer) = delete; + // delete move assignment + kafka_consumer_worker const & operator=(kafka_consumer_worker &&consumer) = delete; /** * @brief Initialize kafka_consumer_worker * @@ -89,7 +102,7 @@ namespace tmx::utils { /** * @brief Stop running kafka consumer. */ - virtual void stop(); + void stop(); /** * @brief Print current configurations. */ @@ -101,11 +114,6 @@ namespace tmx::utils { * @return false if kafka consumer is stopped. */ virtual bool is_running() const; - /** - * @brief Destroy the kafka consumer worker object - * - */ - virtual ~kafka_consumer_worker() = default; }; } diff --git a/src/tmx/TmxUtils/src/kafka/kafka_producer_worker.cpp b/src/tmx/TmxUtils/src/kafka/kafka_producer_worker.cpp index e81364c19..02d0a0cbb 100644 --- a/src/tmx/TmxUtils/src/kafka/kafka_producer_worker.cpp +++ b/src/tmx/TmxUtils/src/kafka/kafka_producer_worker.cpp @@ -38,6 +38,11 @@ namespace tmx::utils { } + kafka_producer_worker::~kafka_producer_worker() { + stop(); + FILE_LOG(logWARNING) << "Kafka Producer Worker Destroyed!" << std::endl; + } + bool kafka_producer_worker::init() { if(init_producer()) @@ -217,16 +222,18 @@ namespace tmx::utils { if (_producer) { - _producer->flush(10 * 1000 /* wait for max 10 seconds */); - + auto error =_producer->flush(10 * 1000 /* wait for max 10 seconds */); + if (error == RdKafka::ERR__TIMED_OUT) + FILE_LOG(logERROR) << "Flush attempt timed out!" << std::endl; if (_producer->outq_len() > 0) - FILE_LOG(logWARNING) << _producer->name() << _producer->outq_len() << " message(s) were not delivered." << std::endl; + FILE_LOG(logERROR) << _producer->name() << _producer->outq_len() << " message(s) were not delivered." << std::endl; } } catch (const std::runtime_error &e) { FILE_LOG(logERROR) << "Error encountered flushing producer : " << e.what() << std::endl; } + FILE_LOG(logWARNING) << "Kafka producer stopped!" << std::endl; } void kafka_producer_worker::printCurrConf() diff --git a/src/tmx/TmxUtils/src/kafka/kafka_producer_worker.h b/src/tmx/TmxUtils/src/kafka/kafka_producer_worker.h index 7dde427d1..ae8d0b56a 100644 --- a/src/tmx/TmxUtils/src/kafka/kafka_producer_worker.h +++ b/src/tmx/TmxUtils/src/kafka/kafka_producer_worker.h @@ -60,6 +60,19 @@ namespace tmx::utils * @param broker_str network address of kafka broker. */ explicit kafka_producer_worker(const std::string &brokers); + /** + * @brief Destroy the kafka producer worker object. Calls stop on producer to clean up resources. + */ + virtual ~kafka_producer_worker(); + // Rule of 5 because destructor is define (https://www.codementor.io/@sandesh87/the-rule-of-five-in-c-1pdgpzb04f) + // delete copy constructor + kafka_producer_worker(kafka_producer_worker& other) = delete; + // delete copy assignment + kafka_producer_worker& operator=(const kafka_producer_worker& other) = delete; + // delete move constructor + kafka_producer_worker(kafka_producer_worker &&producer) = delete; + // delete move assignment + kafka_producer_worker const & operator=(kafka_producer_worker &&producer) = delete; /** * @brief Initialize kafka_producer_worker. This method must be called before send! * @@ -100,16 +113,12 @@ namespace tmx::utils /** * @brief Stop running kafka producer. */ - virtual void stop(); + void stop(); /** * @brief Print current configurations. */ virtual void printCurrConf(); - /** - * @brief Destroy the kafka producer worker object - * - */ - virtual ~kafka_producer_worker() = default; + }; } diff --git a/src/tmx/TmxUtils/src/kafka/mock_kafka_consumer_worker.h b/src/tmx/TmxUtils/src/kafka/mock_kafka_consumer_worker.h index a2bbb888b..fc927d84c 100644 --- a/src/tmx/TmxUtils/src/kafka/mock_kafka_consumer_worker.h +++ b/src/tmx/TmxUtils/src/kafka/mock_kafka_consumer_worker.h @@ -31,7 +31,6 @@ namespace tmx::utils { MOCK_METHOD(bool, init,(),(override)); MOCK_METHOD(const char*, consume, (int timeout_ms), (override)); MOCK_METHOD(void, subscribe, (), (override)); - MOCK_METHOD(void, stop, (), (override)); MOCK_METHOD(void, printCurrConf, (), (override)); MOCK_METHOD(bool, is_running, (), (const override)); }; diff --git a/src/tmx/TmxUtils/src/kafka/mock_kafka_producer_worker.h b/src/tmx/TmxUtils/src/kafka/mock_kafka_producer_worker.h index c587169b4..cb41d8de5 100644 --- a/src/tmx/TmxUtils/src/kafka/mock_kafka_producer_worker.h +++ b/src/tmx/TmxUtils/src/kafka/mock_kafka_producer_worker.h @@ -26,7 +26,6 @@ namespace tmx::utils { MOCK_METHOD(bool, init,(),(override)); MOCK_METHOD(void, send, (const std::string &msg), (override)); MOCK_METHOD(bool, is_running, (), (const, override)); - MOCK_METHOD(void, stop, (), (override)); MOCK_METHOD(void, printCurrConf, (), (override)); }; } \ No newline at end of file diff --git a/src/tmx/TmxUtils/test/KafkaTestEnvironment.cpp b/src/tmx/TmxUtils/test/KafkaTestEnvironment.cpp new file mode 100644 index 000000000..85fd6cdfa --- /dev/null +++ b/src/tmx/TmxUtils/test/KafkaTestEnvironment.cpp @@ -0,0 +1,27 @@ +#include "gtest/gtest.h" +#include + +/** + * @brief Kafka Test Environment which allows for Setup/Teardown configuration at the + * test program level. Teardown waits on all rd_kafka_t objects to be destroyed. + */ +class KafkaTestEnvironment : public ::testing::Environment { + public: + ~KafkaTestEnvironment() override {} + + // Override this to define how to set up the environment. + void SetUp() override {} + + // Override this to define how to tear down the environment. + void TearDown() override { + std::cout << "Waiting for all RDKafka objects to be destroyed!" << std::endl; + // Wait for all rd_kafka_t objects to be destroyed + auto error = RdKafka::wait_destroyed(5000); + if (error == RdKafka::ERR__TIMED_OUT) { + std::cout << "Wait destroy attempted timed out!" << std::endl; + } + else { + std::cout << "All Objects are destroyed!" << std::endl; + } + } +}; \ No newline at end of file diff --git a/src/tmx/TmxUtils/test/Main.cpp b/src/tmx/TmxUtils/test/Main.cpp index 75163d417..7bffd67ea 100644 --- a/src/tmx/TmxUtils/test/Main.cpp +++ b/src/tmx/TmxUtils/test/Main.cpp @@ -6,9 +6,11 @@ */ #include +#include "KafkaTestEnvironment.cpp" int main(int argc, char **argv) { + ::testing::AddGlobalTestEnvironment(new KafkaTestEnvironment()); testing::InitGoogleTest(&argc, argv); return RUN_ALL_TESTS(); } diff --git a/src/tmx/TmxUtils/test/test_kafka_consumer_worker.cpp b/src/tmx/TmxUtils/test/test_kafka_consumer_worker.cpp index 2d0d680a7..ba7a33c99 100644 --- a/src/tmx/TmxUtils/test/test_kafka_consumer_worker.cpp +++ b/src/tmx/TmxUtils/test/test_kafka_consumer_worker.cpp @@ -1,5 +1,6 @@ #include "gtest/gtest.h" #include "kafka/kafka_client.h" +#include "PluginLog.h" TEST(test_kafka_consumer_worker, create_consumer) { diff --git a/src/tmx/TmxUtils/test/test_kafka_producer_worker.cpp b/src/tmx/TmxUtils/test/test_kafka_producer_worker.cpp index ca04a1e19..e6a101d3e 100644 --- a/src/tmx/TmxUtils/test/test_kafka_producer_worker.cpp +++ b/src/tmx/TmxUtils/test/test_kafka_producer_worker.cpp @@ -13,7 +13,6 @@ TEST(test_kafka_producer_worker, create_producer) std::string msg = "test message"; // // Run this unit test without launching kafka broker will throw connection refused error worker->send(msg); - worker->stop(); } TEST(test_kafka_producer_worker, create_producer_no_topic) @@ -28,5 +27,4 @@ TEST(test_kafka_producer_worker, create_producer_no_topic) std::string msg = "test message"; // // Run this unit test without launching kafka broker will throw connection refused error worker->send(msg, topic); - worker->stop(); } \ No newline at end of file diff --git a/src/v2i-hub/CARMACloudPlugin/CMakeLists.txt b/src/v2i-hub/CARMACloudPlugin/CMakeLists.txt index ad036336b..6c913e69d 100644 --- a/src/v2i-hub/CARMACloudPlugin/CMakeLists.txt +++ b/src/v2i-hub/CARMACloudPlugin/CMakeLists.txt @@ -1,4 +1,4 @@ -PROJECT ( CARMACloudPlugin VERSION 7.5.0 LANGUAGES CXX ) +PROJECT ( CARMACloudPlugin VERSION 7.5.1 LANGUAGES CXX ) SET (TMX_PLUGIN_NAME "CARMACloud") add_compile_options(-fPIC) diff --git a/src/v2i-hub/CARMAStreetsPlugin/CMakeLists.txt b/src/v2i-hub/CARMAStreetsPlugin/CMakeLists.txt index f98aebcae..53c8ca0ef 100644 --- a/src/v2i-hub/CARMAStreetsPlugin/CMakeLists.txt +++ b/src/v2i-hub/CARMAStreetsPlugin/CMakeLists.txt @@ -1,4 +1,4 @@ -PROJECT ( CARMAStreetsPlugin VERSION 7.5.0 LANGUAGES CXX ) +PROJECT ( CARMAStreetsPlugin VERSION 7.5.1 LANGUAGES CXX ) BuildTmxPlugin ( ) diff --git a/src/v2i-hub/CARMAStreetsPlugin/src/CARMAStreetsPlugin.cpp b/src/v2i-hub/CARMAStreetsPlugin/src/CARMAStreetsPlugin.cpp index c523f354d..79ed7acb6 100755 --- a/src/v2i-hub/CARMAStreetsPlugin/src/CARMAStreetsPlugin.cpp +++ b/src/v2i-hub/CARMAStreetsPlugin/src/CARMAStreetsPlugin.cpp @@ -19,24 +19,17 @@ namespace CARMAStreetsPlugin { * @param name The name to give the plugin for identification purposes */ CARMAStreetsPlugin::CARMAStreetsPlugin(string name) : - PluginClient(name) { + PluginClientClockAware(name) { AddMessageFilter < BsmMessage > (this, &CARMAStreetsPlugin::HandleBasicSafetyMessage); AddMessageFilter < tsm3Message > (this, &CARMAStreetsPlugin::HandleMobilityOperationMessage); AddMessageFilter < tsm2Message > (this, &CARMAStreetsPlugin::HandleMobilityPathMessage); AddMessageFilter < MapDataMessage > (this, &CARMAStreetsPlugin::HandleMapMessage); AddMessageFilter < SrmMessage > (this, &CARMAStreetsPlugin::HandleSRMMessage); AddMessageFilter < simulation::ExternalObject > (this, &CARMAStreetsPlugin::HandleSimulatedExternalMessage ); - - SubscribeToMessages(); + SubscribeToMessages(); } -CARMAStreetsPlugin::~CARMAStreetsPlugin() { - //Todo: It does not seem the desctructor is called. - _spat_kafka_consumer_ptr->stop(); - _scheduing_plan_kafka_consumer_ptr->stop(); - _ssm_kafka_consumer_ptr->stop(); -} void CARMAStreetsPlugin::UpdateConfigSettings() { @@ -66,6 +59,7 @@ void CARMAStreetsPlugin::UpdateConfigSettings() { _strategies.clear(); while( ss.good() ) { std::string substring; + getline( ss, substring, ','); _strategies.push_back( substring); } @@ -111,6 +105,13 @@ void CARMAStreetsPlugin::OnConfigChanged(const char *key, const char *value) { UpdateConfigSettings(); } +void CARMAStreetsPlugin::HandleTimeSyncMessage(tmx::messages::TimeSyncMessage &msg, routeable_message &routeableMsg ) { + PluginClientClockAware::HandleTimeSyncMessage(msg, routeableMsg); + if ( isSimulationMode()) { + PLOG(logINFO) << "Handling TimeSync messages!" << std::endl; + produce_kafka_msg(msg.to_string(), "time_sync"); + } +} void CARMAStreetsPlugin::HandleMobilityOperationMessage(tsm3Message &msg, routeable_message &routeableMsg ) { try { diff --git a/src/v2i-hub/CARMAStreetsPlugin/src/CARMAStreetsPlugin.h b/src/v2i-hub/CARMAStreetsPlugin/src/CARMAStreetsPlugin.h index 62c2f9317..e3cfcddaa 100755 --- a/src/v2i-hub/CARMAStreetsPlugin/src/CARMAStreetsPlugin.h +++ b/src/v2i-hub/CARMAStreetsPlugin/src/CARMAStreetsPlugin.h @@ -22,6 +22,7 @@ #include "JsonToJ2735SSMConverter.h" #include #include +#include "PluginClientClockAware.h" @@ -34,10 +35,9 @@ using namespace boost::property_tree; namespace CARMAStreetsPlugin { -class CARMAStreetsPlugin: public PluginClient { +class CARMAStreetsPlugin: public PluginClientClockAware { public: CARMAStreetsPlugin(std::string); - virtual ~CARMAStreetsPlugin(); int Main(); protected: @@ -51,6 +51,12 @@ class CARMAStreetsPlugin: public PluginClient { void HandleMobilityPathMessage(tsm2Message &msg, routeable_message &routeableMsg); void HandleBasicSafetyMessage(BsmMessage &msg, routeable_message &routeableMsg); void HandleSimulatedExternalMessage(simulation::ExternalObject &msg, routeable_message &routeableMsg); + /** + * @brief Overide PluginClientClockAware HandleTimeSyncMessage to producer TimeSyncMessage to kafka for CARMA Streets Time Synchronization. + * @param msg TimeSyncMessage received by plugin when in simulation mode. Message provides current simulation time to all processes. + * @param routeableMsg routeable_message for time sync message. + */ + void HandleTimeSyncMessage(TimeSyncMessage &msg, routeable_message &routeableMsg) override; /** * @brief Subscribe to MAP message broadcast by the MAPPlugin. This handler will be called automatically whenever the MAPPlugin is broadcasting a J2735 MAP message. * @param msg The J2735 MAP message received from the internal diff --git a/src/v2i-hub/CDASimAdapter/CMakeLists.txt b/src/v2i-hub/CDASimAdapter/CMakeLists.txt index e8e8cd794..8fbc4f376 100755 --- a/src/v2i-hub/CDASimAdapter/CMakeLists.txt +++ b/src/v2i-hub/CDASimAdapter/CMakeLists.txt @@ -1,20 +1,20 @@ -PROJECT ( CDASimAdapter VERSION 7.5.0 LANGUAGES CXX ) +PROJECT ( CDASimAdapter VERSION 7.5.1 LANGUAGES CXX ) set(CMAKE_CXX_STANDARD 17) FIND_PACKAGE( carma-clock ) BuildTmxPlugin ( ) -TARGET_LINK_LIBRARIES (${PROJECT_NAME} tmxutils ::carma-clock rdkafka++ jsoncpp) +TARGET_LINK_LIBRARIES (${PROJECT_NAME} tmxutils ::carma-clock jsoncpp) # ############ # # Testing ## # ############ ADD_LIBRARY(${PROJECT_NAME}_lib src/CDASimConnection.cpp) -TARGET_LINK_LIBRARIES(${PROJECT_NAME}_lib PUBLIC tmxutils ::carma-clock rdkafka++ jsoncpp ) +TARGET_LINK_LIBRARIES(${PROJECT_NAME}_lib PUBLIC tmxutils ::carma-clock jsoncpp ) SET(BINARY ${PROJECT_NAME}_test) FILE(GLOB_RECURSE TEST_SOURCES LIST_DIRECTORIES false test/*.h test/*.cpp) SET(SOURCES ${TEST_SOURCES} WORKING_DIRECTORY ${PROJECT_SOURCE_DIR}/test) ADD_EXECUTABLE(${BINARY} ${TEST_SOURCES}) ADD_TEST(NAME ${BINARY} COMMAND ${BINARY}) TARGET_INCLUDE_DIRECTORIES(${BINARY} PUBLIC /usr/local/lib src/) -TARGET_LINK_LIBRARIES(${BINARY} PUBLIC ${PROJECT_NAME}_lib gtest gmock tmxutils ::carma-clock rdkafka++ jsoncpp) \ No newline at end of file +TARGET_LINK_LIBRARIES(${BINARY} PUBLIC ${PROJECT_NAME}_lib gtest gmock tmxutils ::carma-clock jsoncpp) \ No newline at end of file diff --git a/src/v2i-hub/CDASimAdapter/manifest.json b/src/v2i-hub/CDASimAdapter/manifest.json index e01753f7a..aabe404be 100755 --- a/src/v2i-hub/CDASimAdapter/manifest.json +++ b/src/v2i-hub/CDASimAdapter/manifest.json @@ -14,20 +14,31 @@ "description":"The log level for this plugin" }, { - "key":"Longitude", + "key":"X", "default":"0.0", - "description":"Longitude (in degrees) of the location of the simulated infrastructure." + "description":"Cartesian X coordinate in simulated map (in meters)." }, { - "key":"Latitude", + "key":"Y", "default":"0.0", - "description":"Latitude (in degrees) of the location of the simulated infrastructure." + "description":"Cartesian Y coordinate in simulated map (in meters)." }, { - "key":"Elevation", + "key":"Z", "default":"0.0", - "description":"Elevation (in degrees) of the location of the simulated infrastructure." + "description":"Cartesian Z coordinate in simulated map (in meters)." + }, + { + "key":"MaxConnectionAttempts", + "default":"10", + "description":"Number of connection attempts CDASimAdapter plugin will execute before failing. Valid values are any integers greater than or equal to 1. Any value less than 1 will result in unlimited connection attemtps." + }, + { + "key":"ConnectionSleepTime", + "default":"4", + "description":"Number of seconds to wait after a failed CDASim connection attempt, before retrying to establish connection. Valid values are equal or greater than 1. Any value less than 1 will be treated as 1." } + ] } diff --git a/src/v2i-hub/CDASimAdapter/src/CDASimAdapter.cpp b/src/v2i-hub/CDASimAdapter/src/CDASimAdapter.cpp index 63dcd1ebe..31fe77ec8 100644 --- a/src/v2i-hub/CDASimAdapter/src/CDASimAdapter.cpp +++ b/src/v2i-hub/CDASimAdapter/src/CDASimAdapter.cpp @@ -13,11 +13,22 @@ namespace CDASimAdapter{ } void CDASimAdapter::UpdateConfigSettings() { - GetConfigValue("Longitude", location.Longitude); - GetConfigValue("Latitude", location.Latitude); - GetConfigValue("Elevation", location.Elevation); - PLOG(logINFO) << "Location of Simulated V2X-Hub updated to : {" << location.Longitude << ", " - << location.Latitude << ", " << location.Elevation << "}." << std::endl; + std::scoped_lock lock(_lock); + bool success = false; + success = GetConfigValue("X", location.X); + success = success && GetConfigValue("Y", location.Y); + success = success && GetConfigValue("Z", location.Z); + PLOG(logINFO) << "Location of Simulated V2X-Hub updated to : {" << location.X << ", " + << location.Y << ", " << location.Z << "}." << std::endl; + success = success && GetConfigValue("MaxConnectionAttempts", max_connection_attempts); + success = success && GetConfigValue("ConnectionSleepTime", connection_sleep_time); + if (connection_sleep_time < 1 ) { + PLOG(logWARNING) << "ConnectionSleepTime of " << connection_sleep_time << " is invalid. Valid values are <= 1." << std::endl; + connection_sleep_time = 1; + } + if (!success) { + PLOG(logWARNING) << "Some configuration parameters were not successfully loaded! Please ensure configuration parameter keys are correct!" << std::endl; + } } void CDASimAdapter::OnConfigChanged(const char *key, const char *value) { @@ -32,8 +43,19 @@ namespace CDASimAdapter{ UpdateConfigSettings(); // While CARMA Simulation connection is down, attempt to reconnect - while ( !connection || !connection->is_connected() ) { - connect(); + int connection_attempts = 0; + while ( (!connection || !connection->is_connected()) && (connection_attempts < max_connection_attempts || max_connection_attempts < 1 ) ) { + PLOG(logINFO) << "Attempting CDASim connection " << connection_attempts << "/" << max_connection_attempts << " ..." << std::endl; + bool success = connect(); + if (success) { + PLOG(logINFO) << "Connection to CDASim established!" << std::endl; + } + connection_attempts++; + // Sleep for configurable seconds in between connection attempts. No sleep is required on final failing attempt + if ( !connection->is_connected() && (connection_attempts < max_connection_attempts || max_connection_attempts < 1 ) ) { + PLOG(logDEBUG) << "Sleeping for " << connection_sleep_time << " seconds before next connection attempt ..." << std::endl; + std::this_thread::sleep_for(std::chrono::seconds(connection_sleep_time)); + } } if ( connection->is_connected() ) { @@ -41,40 +63,21 @@ namespace CDASimAdapter{ start_amf_msg_thread(); start_binary_msg_thread(); start_external_object_detection_thread(); + start_immediate_forward_thread(); + start_message_receiver_thread(); + }else { + PLOG(logERROR) << "CDASim connection failed!" << std::endl; } } } - bool CDASimAdapter::initialize_time_producer() { - try { - std::string _broker_str = sim::get_sim_config(sim::KAFKA_BROKER_ADDRESS); - std::string _topic = sim::get_sim_config(sim::TIME_SYNC_TOPIC); - - kafka_client client; - time_producer = client.create_producer(_broker_str,_topic); - return time_producer->init(); - - } - catch( const runtime_error &e ) { - PLOG(logWARNING) << "Initialization of time producer failed: " << e.what() << std::endl; - } - return false; - } void CDASimAdapter::forward_time_sync_message(tmx::messages::TimeSyncMessage &msg) { std::string payload =msg.to_string(); PLOG(logDEBUG1) << "Sending Time Sync Message " << msg << std::endl; this->BroadcastMessage(msg, _name, 0 , IvpMsgFlags_None); - if (time_producer && time_producer->is_running()) { - try { - time_producer->send(payload); - } - catch( const runtime_error &e ) { - PLOG(logERROR) << "Exception encountered during kafka time sync forward : " << e.what() << std::endl; - } - } } @@ -93,14 +96,11 @@ namespace CDASimAdapter{ uint external_object_detection_port = std::stoul(sim::get_sim_config(sim::SIM_EXTERNAL_OBJECT_PORT)); uint v2x_port = std::stoul(sim::get_sim_config(sim::V2X_PORT)); uint sim_v2x_port = std::stoul(sim::get_sim_config(sim::SIM_V2X_PORT)); - uint infrastructure_id = std::stoul(sim::get_sim_config(sim::INFRASTRUCTURE_ID));; + std::string infrastructure_id = sim::get_sim_config(sim::INFRASTRUCTURE_ID); PLOG(logINFO) << "CDASim connecting " << simulation_ip << "\nUsing Registration Port : " << std::to_string( simulation_registration_port) << " Time Sync Port: " << std::to_string( time_sync_port) << " and V2X Port: " << std::to_string(v2x_port) << std::endl; - if (!initialize_time_producer()) { - return false; - } if ( connection ) { connection.reset(new CDASimConnection( simulation_ip, infrastructure_id, simulation_registration_port, sim_v2x_port, local_ip, time_sync_port, external_object_detection_port, v2x_port, location )); @@ -113,36 +113,42 @@ namespace CDASimAdapter{ catch (const TmxException &e) { PLOG(logERROR) << "Exception occured attempting to initialize CDASim Connection : " << e.what() << std::endl; return false; + } + catch (const std::invalid_argument &e ) { + // std::stoul throws invalid arguement exception when provided with a string that contains characters that are not numbers. + PLOG(logERROR) << "Exception occured attempting to initialize CDASim Connection : " << e.what() << + ". Check environment variables are set to the correct type!"; + return false; } return connection->connect(); } - void CDASimAdapter::start_amf_msg_thread() { - if ( !amf_thread_timer ) { - amf_thread_timer = std::make_unique(); + void CDASimAdapter::start_immediate_forward_thread() { + if ( !immediate_forward_timer ) { + immediate_forward_timer = std::make_unique(); } - amf_msg_tick_id = amf_thread_timer->AddPeriodicTick([this]() { + immediate_forward_tick_id = immediate_forward_timer->AddPeriodicTick([this]() { this->attempt_message_from_v2xhub(); } // end of lambda expression , std::chrono::milliseconds(100) ); - amf_thread_timer->Start(); + immediate_forward_timer->Start(); } - void CDASimAdapter::start_binary_msg_thread() { - if ( !binary_thread_timer ) { - binary_thread_timer = std::make_unique(); + void CDASimAdapter::start_message_receiver_thread() { + if ( !message_receiver_timer ) { + message_receiver_timer = std::make_unique(); } - binary_msg_tick_id = binary_thread_timer->AddPeriodicTick([this]() { + message_receiver_tick_id = message_receiver_timer->AddPeriodicTick([this]() { this->attempt_message_from_simulation(); } // end of lambda expression , std::chrono::milliseconds(100) ); - binary_thread_timer->Start(); + message_receiver_timer->Start(); } @@ -210,15 +216,15 @@ namespace CDASimAdapter{ void CDASimAdapter::start_time_sync_thread_timer() { PLOG(logDEBUG) << "Creating Thread Timer for time sync" << std::endl; - if ( !thread_timer ) { - thread_timer = std::make_unique(); + if ( !time_sync_timer ) { + time_sync_timer = std::make_unique(); } - time_sync_tick_id = thread_timer->AddPeriodicTick([this]() { + time_sync_tick_id = time_sync_timer->AddPeriodicTick([this]() { PLOG(logDEBUG1) << "Listening for time sync messages from CDASim." << std::endl; this->attempt_time_sync(); } // end of lambda expression , std::chrono::milliseconds(100)); - thread_timer->Start(); + time_sync_timer->Start(); } void CDASimAdapter::attempt_time_sync() { diff --git a/src/v2i-hub/CDASimAdapter/src/CDASimConnection.cpp b/src/v2i-hub/CDASimAdapter/src/CDASimConnection.cpp index 783b5f7e8..89ca76dbb 100644 --- a/src/v2i-hub/CDASimAdapter/src/CDASimConnection.cpp +++ b/src/v2i-hub/CDASimAdapter/src/CDASimConnection.cpp @@ -6,7 +6,9 @@ using namespace tmx::utils; namespace CDASimAdapter{ CDASimConnection::CDASimConnection(const std::string &simulation_ip, const uint infrastructure_id, const uint simulation_registration_port, const uint sim_v2x_port, const std::string &local_ip, const uint time_sync_port,const uint external_object_detection_port, const uint v2x_port, - const WGS84Point &location) : + const Point &location) : + + _simulation_ip(simulation_ip), _infrastructure_id(infrastructure_id), _simulation_registration_port(simulation_registration_port), _simulation_v2x_port(sim_v2x_port), _local_ip(local_ip), _time_sync_port(time_sync_port), _external_object_detection_port(external_object_detection_port),_v2x_port(v2x_port), _location(location) { @@ -33,8 +35,9 @@ namespace CDASimAdapter{ return _connected; } + std::string CDASimConnection::get_handshake_json(const uint infrastructure_id, const std::string &local_ip, const uint time_sync_port, const uint external_object_detection_port, const uint v2x_port, - const WGS84Point &location) const + const Point &location) const { Json::Value message; @@ -45,9 +48,9 @@ namespace CDASimAdapter{ message["rxMessagePort"] = v2x_port; message["timeSyncPort"] = time_sync_port; message["ExternalObjectDetectionPort"] = external_object_detection_port; - message["location"]["latitude"] = location.Latitude; - message["location"]["longitude"] = location.Longitude; - message["location"]["elevation"] = location.Elevation; + message["location"]["x"] = location.X; + message["location"]["y"] = location.Y; + message["location"]["z"] = location.Z; Json::StyledWriter writer; message_str = writer.write(message); return message_str; @@ -55,7 +58,7 @@ namespace CDASimAdapter{ bool CDASimConnection::carma_simulation_handshake(const std::string &simulation_ip, const uint infrastructure_id, const uint simulation_registration_port, const std::string &local_ip, const uint time_sync_port, const uint external_object_detection_port, const uint v2x_port, - const WGS84Point &location) + const Point &location) { // Create JSON message with the content std::string payload = ""; diff --git a/src/v2i-hub/CDASimAdapter/src/include/CDASimAdapter.hpp b/src/v2i-hub/CDASimAdapter/src/include/CDASimAdapter.hpp index 88c5ec032..4686b6ee3 100644 --- a/src/v2i-hub/CDASimAdapter/src/include/CDASimAdapter.hpp +++ b/src/v2i-hub/CDASimAdapter/src/include/CDASimAdapter.hpp @@ -1,7 +1,7 @@ //============================================================================ -// Name : EpcwPlugin.cpp -// Author : -// Version : +// Name : CDASimAdapter.cpp +// Author : Paul Bourelly +// Version : 7.5.1 // Copyright : Your copyright notice // Description : Hello World in C++, Ansi-style //============================================================================ @@ -18,29 +18,27 @@ #include #include #include "CDASimConnection.hpp" -#include -#include #include #include "ThreadWorker.h" - - - -namespace CDASimAdapter { +namespace CDASimAdapter +{ /** - * @brief V2X-Hub Plugin that acts as a adapter for integration with CARMA-Simulation. Plugin used + * @brief V2X-Hub Plugin that acts as a adapter for integration with CARMA-Simulation. Plugin used * environment variable to be installed and enabled by default. */ - class CDASimAdapter: public tmx::utils::PluginClient{ + class CDASimAdapter : public tmx::utils::PluginClient + { public: /** * @brief CARMA-Simulation Infrastructure Adapter constructor. * @param name name of plugin. */ explicit CDASimAdapter(const std::string &name); - - int Main() override ; + + int Main() override; + protected: /** * @brief Called everytime a configuration value is changed for the plugin. @@ -60,14 +58,7 @@ namespace CDASimAdapter { */ void OnStateChange(IvpPluginState state) override; // Virtual method overrides END. - - /** - * @brief Get Kafka Connection string from environment variable KAFKA_BROKER_ADDRESS and time sync topic name from - * CARMA_INFRASTRUCTURE_TIME_SYNC_TOPIC and initialize a Kafka producer to forward time synchronization messages to - * all infrastructure services. - * @return true if initialization is successful and false if initialization fails. - */ - bool initialize_time_producer(); + /** * @brief Method to attempt to establish connection between CARMA Simulation and Infrastructure Software (V2X-Hub). * @return true if successful and false if unsuccessful. @@ -77,12 +68,12 @@ namespace CDASimAdapter { /** * @brief Method to start thread timer for processing msg from v2xhub */ - void start_amf_msg_thread(); + void start_immediate_forward_thread(); /** * @brief Method to start thread timer for processing msg from CDASimConnection */ - void start_binary_msg_thread(); + void start_message_receiver_thread(); /** * @brief Method to consume msg in amf fromat from V2Xhub and forward to CDASimConnection @@ -94,8 +85,7 @@ namespace CDASimAdapter { */ void attempt_message_from_simulation() const; /** - * @brief Forward time sychronization message to TMX message bus for other V2X-Hub Plugin and to infrastructure Kafka Broker for - * CARMA Streets services + * @brief Forward time sychronization message to TMX message bus for other V2X-Hub Plugin * @param msg TimeSyncMessage. */ void forward_time_sync_message(tmx::messages::TimeSyncMessage &msg); @@ -112,23 +102,36 @@ namespace CDASimAdapter { * @brief Method to consume time sychrononization from CDASimConnection and forward to tmx core and CARMA Streets */ void attempt_time_sync(); + /** * @brief Method to start thread timer for regular interval actions lauched on seperate thread. */ void start_external_object_detection_thread(); private: - - tmx::utils::WGS84Point location; - std::shared_ptr time_producer; + // Simulated location of RSU + tmx::utils::Point location; + // Stores configurable MaxConnectionAttempts. Any value > 1 will result in infinite connection attempts. + int max_connection_attempts; + // Time in seconds between connection attempts. Most be greater than zero! + uint connection_sleep_time; + // CDASim connection std::unique_ptr connection; + // Mutex for configuration parameter thread safety std::mutex _lock; std::unique_ptr thread_timer; std::unique_ptr external_bject_detection_thread_timer; + // Time sync thread to forward time sync messages to PluginClientClockAware V2X-Hub plugins. + std::unique_ptr time_sync_timer; + // Time sync thread id int time_sync_tick_id; - std::unique_ptr amf_thread_timer; - std::unique_ptr binary_thread_timer; - int amf_msg_tick_id; - int binary_msg_tick_id; + // Immediate forward thread to consume messages from the immediate forward plugin and send to CDASim + std::unique_ptr immediate_forward_timer; + // Immediate forward thread id + int immediate_forward_tick_id; + // Message receiver thread to consume messages from CDASim and forward them to the message receiver. + std::unique_ptr message_receiver_timer; + // Message receiver thread id + int message_receiver_tick_id; }; } \ No newline at end of file diff --git a/src/v2i-hub/CDASimAdapter/src/include/CDASimConnection.hpp b/src/v2i-hub/CDASimAdapter/src/include/CDASimConnection.hpp index 708283488..302fd9e2c 100644 --- a/src/v2i-hub/CDASimAdapter/src/include/CDASimConnection.hpp +++ b/src/v2i-hub/CDASimAdapter/src/include/CDASimConnection.hpp @@ -2,7 +2,7 @@ #include #include #include -#include +#include #include #include #include @@ -32,12 +32,10 @@ namespace CDASimAdapter { * @param time_sync_port Port on which connection listens for time synchronization messages. * @param v2x_port Port on which connecction listens for incoming v2x messages. * @param location Simulationed location of infrastructure. - * @param producer Kafka Producer for forwarding time synchronization messages. */ explicit CDASimConnection( const std::string &simulation_ip, const uint infrastructure_id, const uint simulation_registration_port, const uint sim_v2x_port, const std::string &local_ip, const uint time_sync_port, const uint external_object_detection_port, const uint v2x_port, - const tmx::utils::WGS84Point &location); - + const tmx::utils::Point &location); /** * @brief Method to forward v2x message to CARMA Simulation * @param v2x_message string @@ -105,7 +103,7 @@ namespace CDASimAdapter { */ bool carma_simulation_handshake(const std::string &simulation_ip, const uint infrastructure_id, const uint simulation_registration_port, const std::string &local_ip, const uint time_sync_port, const uint external_object_detection_port, const uint v2x_port, - const tmx::utils::WGS84Point &location); + const tmx::utils::Point &location); /** * @brief Method to setup UDP Servers and Clients after handshake to facilate message forwarding. @@ -140,17 +138,16 @@ namespace CDASimAdapter { * @return true if handshake successful and false if handshake unsuccessful. */ std::string get_handshake_json(const uint infrastructure_id, const std::string &local_ip, const uint time_sync_port, const uint external_object_detection_port, - const uint v2x_port, const tmx::utils::WGS84Point &location) const; - + const uint v2x_port, const tmx::utils::Point &location) const; std::string _simulation_ip; uint _simulation_registration_port; - uint _infrastructure_id; + std::string _infrastructure_id; uint _simulation_v2x_port; uint _external_object_detection_port; std::string _local_ip; uint _time_sync_port; uint _v2x_port; - tmx::utils::WGS84Point _location; + tmx::utils::Point _location; bool _connected = false; std::shared_ptr carma_simulation_listener; diff --git a/src/v2i-hub/CDASimAdapter/test/TestCARMASimulationConnection.cpp b/src/v2i-hub/CDASimAdapter/test/TestCARMASimulationConnection.cpp index eaded6b38..6fffad4e2 100644 --- a/src/v2i-hub/CDASimAdapter/test/TestCARMASimulationConnection.cpp +++ b/src/v2i-hub/CDASimAdapter/test/TestCARMASimulationConnection.cpp @@ -3,7 +3,6 @@ #include "include/CDASimConnection.hpp" #include "include/CDASimAdapter.hpp" #include -#include #include #include @@ -23,9 +22,8 @@ namespace CDASimAdapter { protected: void SetUp() override { // Initialize CARMA Simulation connection with (0,0,0) location and mock kafka producer. - WGS84Point location; + Point location; connection = std::make_shared("127.0.0.1", 1212, 4567, 4678, "127.0.0.1", 1213, 1214, 1215, location); - } void TearDown() override { @@ -83,16 +81,16 @@ namespace CDASimAdapter { } TEST_F( TestCARMASimulationConnection, get_handshake_json) { - WGS84Point location; - location.Elevation = 1000; - location.Latitude = 38.955; - location.Longitude = -77.149; + Point location; + location.X = 1000; + location.Y = 38.955; + location.Z = -77.149; ASSERT_EQ(connection->get_handshake_json(4566, "127.0.0.1", 4567, 4568, 4569, location), - "{\n \"ExternalObjectDetectionPort\" : 4568,\n \"infrastructureId\" : 4566,\n \"location\" : {\n \"elevation\" : 1000.0,\n \"latitude\" : 38.954999999999998,\n \"longitude\" : -77.149000000000001\n },\n \"rxMessageIpAddress\" : \"127.0.0.1\",\n \"rxMessagePort\" : 4569,\n \"timeSyncPort\" : 4567\n}\n"); + "{\n \"ExternalObjectDetectionPort\" : 4568,\n \"infrastructureId\" : 4566,\n \"location\" : {\n \"x\" : 1000.0,\n \"y\" : 38.954999999999998,\n \"z\" : -77.149000000000001\n },\n \"rxMessageIpAddress\" : \"127.0.0.1\",\n \"rxMessagePort\" : 4569,\n \"timeSyncPort\" : 4567\n}\n"); } TEST_F( TestCARMASimulationConnection, carma_simulation_handshake) { - WGS84Point location; + Point location; // UDP creation error ASSERT_FALSE(connection->carma_simulation_handshake("", 45, NULL, "", 45, 45, 45, location)); diff --git a/src/v2i-hub/CommandPlugin/CMakeLists.txt b/src/v2i-hub/CommandPlugin/CMakeLists.txt index 651e1af0a..a1543ab51 100644 --- a/src/v2i-hub/CommandPlugin/CMakeLists.txt +++ b/src/v2i-hub/CommandPlugin/CMakeLists.txt @@ -1,4 +1,4 @@ -PROJECT ( CommandPlugin VERSION 7.5.0 LANGUAGES CXX ) +PROJECT ( CommandPlugin VERSION 7.5.1 LANGUAGES CXX ) FIND_PACKAGE (OpenSSL REQUIRED) diff --git a/src/v2i-hub/CswPlugin/CMakeLists.txt b/src/v2i-hub/CswPlugin/CMakeLists.txt index 66d0d9545..5e154a2c7 100644 --- a/src/v2i-hub/CswPlugin/CMakeLists.txt +++ b/src/v2i-hub/CswPlugin/CMakeLists.txt @@ -1,4 +1,4 @@ -PROJECT ( CswPlugin VERSION 7.5.0 LANGUAGES CXX ) +PROJECT ( CswPlugin VERSION 7.5.1 LANGUAGES CXX ) SET (TMX_PLUGIN_NAME "CSW") diff --git a/src/v2i-hub/DmsPlugin/CMakeLists.txt b/src/v2i-hub/DmsPlugin/CMakeLists.txt index 4508c8084..08cf09b17 100644 --- a/src/v2i-hub/DmsPlugin/CMakeLists.txt +++ b/src/v2i-hub/DmsPlugin/CMakeLists.txt @@ -1,4 +1,4 @@ -PROJECT ( DmsPlugin VERSION 7.5.0 LANGUAGES CXX ) +PROJECT ( DmsPlugin VERSION 7.5.1 LANGUAGES CXX ) SET (TMX_PLUGIN_NAME "Dynamic Message Sign") diff --git a/src/v2i-hub/ERVCloudForwardingPlugin/CMakeLists.txt b/src/v2i-hub/ERVCloudForwardingPlugin/CMakeLists.txt index 56f71f571..cc456077a 100644 --- a/src/v2i-hub/ERVCloudForwardingPlugin/CMakeLists.txt +++ b/src/v2i-hub/ERVCloudForwardingPlugin/CMakeLists.txt @@ -1,4 +1,4 @@ -PROJECT(ERVCloudForwardingPlugin VERSION 7.5.0 LANGUAGES CXX) +PROJECT(ERVCloudForwardingPlugin VERSION 7.5.1 LANGUAGES CXX) SET(TMX_PLUGIN_NAME "ERVCloudForwarding") add_compile_options(-fPIC) diff --git a/src/v2i-hub/ImmediateForwardPlugin/CMakeLists.txt b/src/v2i-hub/ImmediateForwardPlugin/CMakeLists.txt index e3d2365a2..31e28d6ae 100644 --- a/src/v2i-hub/ImmediateForwardPlugin/CMakeLists.txt +++ b/src/v2i-hub/ImmediateForwardPlugin/CMakeLists.txt @@ -1,4 +1,4 @@ -PROJECT ( ImmediateForwardPlugin VERSION 7.5.0 LANGUAGES CXX ) +PROJECT ( ImmediateForwardPlugin VERSION 7.5.1 LANGUAGES CXX ) SET (TMX_PLUGIN_NAME "Immediate Forward") diff --git a/src/v2i-hub/LocationPlugin/CMakeLists.txt b/src/v2i-hub/LocationPlugin/CMakeLists.txt index eb929373b..5926227c4 100644 --- a/src/v2i-hub/LocationPlugin/CMakeLists.txt +++ b/src/v2i-hub/LocationPlugin/CMakeLists.txt @@ -1,4 +1,4 @@ -project( LocationPlugin VERSION 7.5.0 LANGUAGES CXX ) +project( LocationPlugin VERSION 7.5.1 LANGUAGES CXX ) SET (TMX_PLUGIN_NAME Location) diff --git a/src/v2i-hub/MapPlugin/CMakeLists.txt b/src/v2i-hub/MapPlugin/CMakeLists.txt index 7cf372de0..553f1e58a 100644 --- a/src/v2i-hub/MapPlugin/CMakeLists.txt +++ b/src/v2i-hub/MapPlugin/CMakeLists.txt @@ -1,4 +1,4 @@ -PROJECT ( MapPlugin VERSION 7.5.0 LANGUAGES CXX ) +PROJECT ( MapPlugin VERSION 7.5.1 LANGUAGES CXX ) SET (TMX_PLUGIN_NAME "MAP") diff --git a/src/v2i-hub/MapPlugin/src/MapPlugin.cpp b/src/v2i-hub/MapPlugin/src/MapPlugin.cpp index ba4a54b05..2317e7800 100644 --- a/src/v2i-hub/MapPlugin/src/MapPlugin.cpp +++ b/src/v2i-hub/MapPlugin/src/MapPlugin.cpp @@ -81,6 +81,7 @@ class MapPlugin: public PluginClientClockAware { void OnConfigChanged(const char *key, const char *value); void OnMessageReceived(IvpMessage *msg); void OnStateChange(IvpPluginState state); + private: std::atomic _mapAction {-1}; std::atomic _isMapFileNew {false}; diff --git a/src/v2i-hub/MessageLoggerPlugin/CMakeLists.txt b/src/v2i-hub/MessageLoggerPlugin/CMakeLists.txt index b63b6d6df..514b31984 100644 --- a/src/v2i-hub/MessageLoggerPlugin/CMakeLists.txt +++ b/src/v2i-hub/MessageLoggerPlugin/CMakeLists.txt @@ -1,4 +1,4 @@ -PROJECT ( MessageLoggerPlugin VERSION 7.5.0 LANGUAGES CXX ) +PROJECT ( MessageLoggerPlugin VERSION 7.5.1 LANGUAGES CXX ) SET (TMX_PLUGIN_NAME "MessageLoggerPlugin") diff --git a/src/v2i-hub/MessageReceiverPlugin/CMakeLists.txt b/src/v2i-hub/MessageReceiverPlugin/CMakeLists.txt index f77e4c1a3..908bc1e90 100644 --- a/src/v2i-hub/MessageReceiverPlugin/CMakeLists.txt +++ b/src/v2i-hub/MessageReceiverPlugin/CMakeLists.txt @@ -1,4 +1,4 @@ -PROJECT ( MessageReceiverPlugin VERSION 7.5.0 LANGUAGES CXX ) +PROJECT ( MessageReceiverPlugin VERSION 7.5.1 LANGUAGES CXX ) set(CMAKE_CXX_STANDARD 11) set(CMAKE_CXX_STANDARD_REQUIRED ON) diff --git a/src/v2i-hub/ODEForwardPlugin/CMakeLists.txt b/src/v2i-hub/ODEForwardPlugin/CMakeLists.txt index 815527534..8c594fdbe 100644 --- a/src/v2i-hub/ODEForwardPlugin/CMakeLists.txt +++ b/src/v2i-hub/ODEForwardPlugin/CMakeLists.txt @@ -1,4 +1,4 @@ -PROJECT ( ODEForwardPlugin VERSION 7.5.0 LANGUAGES CXX ) +PROJECT ( ODEForwardPlugin VERSION 7.5.1 LANGUAGES CXX ) SET (TMX_PLUGIN_NAME "ODEForwardPlugin") diff --git a/src/v2i-hub/PedestrianPlugin/CMakeLists.txt b/src/v2i-hub/PedestrianPlugin/CMakeLists.txt index 8b0ba693f..ecb8c8cec 100755 --- a/src/v2i-hub/PedestrianPlugin/CMakeLists.txt +++ b/src/v2i-hub/PedestrianPlugin/CMakeLists.txt @@ -1,4 +1,4 @@ -PROJECT ( PedestrianPlugin VERSION 7.5.0 LANGUAGES CXX ) +PROJECT ( PedestrianPlugin VERSION 7.5.1 LANGUAGES CXX ) SET (TMX_PLUGIN_NAME "Pedestrian") add_compile_options(-fPIC) diff --git a/src/v2i-hub/PortDrayagePlugin/CMakeLists.txt b/src/v2i-hub/PortDrayagePlugin/CMakeLists.txt index eb069bfd7..199be4090 100644 --- a/src/v2i-hub/PortDrayagePlugin/CMakeLists.txt +++ b/src/v2i-hub/PortDrayagePlugin/CMakeLists.txt @@ -1,4 +1,4 @@ -PROJECT ( PortDrayagePlugin VERSION 7.5.0 LANGUAGES CXX ) +PROJECT ( PortDrayagePlugin VERSION 7.5.1 LANGUAGES CXX ) SET (TMX_PLUGIN_NAME "PortDrayage") set(CMAKE_AUTOMOC ON) diff --git a/src/v2i-hub/PreemptionPlugin/CMakeLists.txt b/src/v2i-hub/PreemptionPlugin/CMakeLists.txt index eed709d13..1613c3b46 100644 --- a/src/v2i-hub/PreemptionPlugin/CMakeLists.txt +++ b/src/v2i-hub/PreemptionPlugin/CMakeLists.txt @@ -1,4 +1,4 @@ -PROJECT ( PreemptionPlugin VERSION 7.5.0 LANGUAGES CXX ) +PROJECT ( PreemptionPlugin VERSION 7.5.1 LANGUAGES CXX ) SET (TMX_PLUGIN_NAME "Preemption") diff --git a/src/v2i-hub/RtcmPlugin/CMakeLists.txt b/src/v2i-hub/RtcmPlugin/CMakeLists.txt index f10a35a31..694b04ef2 100644 --- a/src/v2i-hub/RtcmPlugin/CMakeLists.txt +++ b/src/v2i-hub/RtcmPlugin/CMakeLists.txt @@ -1,4 +1,4 @@ -PROJECT ( RtcmPlugin VERSION 7.5.0 LANGUAGES CXX ) +PROJECT ( RtcmPlugin VERSION 7.5.1 LANGUAGES CXX ) SET (TMX_PLUGIN_NAME "RTCM") diff --git a/src/v2i-hub/SpatPlugin/CMakeLists.txt b/src/v2i-hub/SpatPlugin/CMakeLists.txt index ec48c6f14..fb28fcada 100644 --- a/src/v2i-hub/SpatPlugin/CMakeLists.txt +++ b/src/v2i-hub/SpatPlugin/CMakeLists.txt @@ -1,4 +1,4 @@ -PROJECT ( SpatPlugin VERSION 7.5.0 LANGUAGES CXX ) +PROJECT ( SpatPlugin VERSION 7.5.1 LANGUAGES CXX ) SET (TMX_PLUGIN_NAME "SPAT") diff --git a/src/v2i-hub/SpatPlugin/src/SpatPlugin.h b/src/v2i-hub/SpatPlugin/src/SpatPlugin.h index a42552618..0d0b9987f 100644 --- a/src/v2i-hub/SpatPlugin/src/SpatPlugin.h +++ b/src/v2i-hub/SpatPlugin/src/SpatPlugin.h @@ -44,6 +44,7 @@ class SpatPlugin: public tmx::utils::PluginClientClockAware { void OnConfigChanged(const char *key, const char *value); void OnStateChange(IvpPluginState state); + private: diff --git a/src/v2i-hub/TimPlugin/CMakeLists.txt b/src/v2i-hub/TimPlugin/CMakeLists.txt index 79a3ac8ca..3f8c9779e 100644 --- a/src/v2i-hub/TimPlugin/CMakeLists.txt +++ b/src/v2i-hub/TimPlugin/CMakeLists.txt @@ -1,4 +1,4 @@ -PROJECT ( TimPlugin VERSION 7.5.0 LANGUAGES CXX ) +PROJECT ( TimPlugin VERSION 7.5.1 LANGUAGES CXX ) SET (TMX_PLUGIN_NAME "TIM") add_compile_options(-fPIC)