From 193336e7fbeea049d00551436a60536a773803d7 Mon Sep 17 00:00:00 2001 From: Henry Winkel Date: Wed, 18 Jan 2023 13:41:15 +0100 Subject: [PATCH] ADD: added Sensor virtual PArent class --- CMakeLists.txt | 9 +- include/SimCore/Sensor.hpp | 76 +++++++++++++ include/SimCore/SimCore.hpp | 8 ++ include/SimCore/UtilFunctions.hpp | 7 +- libs/whisper-com | 2 +- src/SimCore/Sensor.cpp | 182 ++++++++++++++++++++++++++++++ src/SimCore/UtilFunctions.cpp | 54 +++++++++ tests/test_SensorClass.cpp | 67 +++++++++++ tests/test_UtilFunctions.cpp | 13 ++- 9 files changed, 413 insertions(+), 5 deletions(-) create mode 100644 include/SimCore/Sensor.hpp create mode 100644 src/SimCore/Sensor.cpp create mode 100644 tests/test_SensorClass.cpp diff --git a/CMakeLists.txt b/CMakeLists.txt index cedbe32..4c3b893 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -57,8 +57,9 @@ add_library(SimCore STATIC include/SimCore/UtilFunctions.hpp src/SimCore/UtilFunctions.cpp - - + + include/SimCore/Sensor.hpp + src/SimCore/Sensor.cpp ) target_link_libraries(SimCore @@ -131,6 +132,10 @@ IF (${TEST_SIMCORE_LIBRARY}) target_link_libraries(test_UtilFunctions Catch2::Catch2 SimCore loguru) catch_discover_tests(test_UtilFunctions) + add_executable(test_SensorClass tests/test_SensorClass.cpp) + target_link_libraries(test_SensorClass Catch2::Catch2 SimCore loguru) + catch_discover_tests(test_SensorClass) + ENDIF() diff --git a/include/SimCore/Sensor.hpp b/include/SimCore/Sensor.hpp new file mode 100644 index 0000000..ee98978 --- /dev/null +++ b/include/SimCore/Sensor.hpp @@ -0,0 +1,76 @@ +#pragma once + + + +#include "SimCore/Messages/Track.hpp" +#include +#include + +#include +#include +#include +#include +#include +#include +#include + +namespace SimCore { + + class Sensor { + public: + Sensor(SimCore::Identifier OwnID, SimCore::Identifier ParentID, SimCore::SensorKinds SensorKind,std::uint32_t GroundTruthPort, std::uint32_t ParentPort,std::string ParentIPAddress); + ~Sensor(); + void start(); + void stop(); + + protected: + std::shared_ptr> incommingTrackMessages = nullptr; + + + std::shared_ptr> incommingGroundThruthMessages = nullptr; + std::shared_ptr> outgoingGroundThruthMessages = nullptr; + + std::shared_ptr> incommingParentMessages = nullptr; + std::shared_ptr> outgoingParentMessages = nullptr; + + virtual void specificSensorCalculations() = 0; + virtual void specificReloadCharacteristicts() = 0; + + private: + + SimCore::Identifier OwnID_; + SimCore::Identifier ParentID_; + SimCore::SensorKinds SensorKind_; + std::uint32_t GroundTruthPort_; + std::uint32_t ParentPort_; + std::string ParentIPAddress_; + + std::shared_ptr GroundTruthUDPService_ = nullptr; + std::shared_ptr ParentUDPService_ = nullptr; + + void receivingData(); + void sendingData(); + + void SensorCalculations(); + void ReloadCharacteristicts(); + + std::atomic stopReceivingGroundThruth = false; + std::atomic ReceivingGroundThruthIsRunnung = false; + + std::atomic stopsendCalculatedData = false; + std::atomic sendCalculatedDataIsRunnung = false; + + std::atomic stopCalculationData = false; + std::atomic CalculationIsRunnung = false; + + + std::thread receiveGroundTruthThread; + std::thread sendCalculatedDataThread; + + std::thread sensorCalculationThread; + + std::shared_ptr position_ = nullptr; + + + }; +} \ No newline at end of file diff --git a/include/SimCore/SimCore.hpp b/include/SimCore/SimCore.hpp index 21f3a90..1aad50a 100644 --- a/include/SimCore/SimCore.hpp +++ b/include/SimCore/SimCore.hpp @@ -37,4 +37,12 @@ enum ContactEnvironment : std::uint8_t{ }; +enum SensorKinds : std::uint32_t { + RADAR = 1, + ELOKA, + SONAR, + VISUAL +}; + + } \ No newline at end of file diff --git a/include/SimCore/UtilFunctions.hpp b/include/SimCore/UtilFunctions.hpp index 9a016fa..e51bd01 100644 --- a/include/SimCore/UtilFunctions.hpp +++ b/include/SimCore/UtilFunctions.hpp @@ -2,6 +2,7 @@ #include #include #include +#include @@ -12,9 +13,13 @@ namespace SimCore { { public: static std::vector explode(std::string const & s, char delim); + static std::string implode(const std::vector &v , char delim); static bool isNumber(const std::string& s); - + static void check_host_name(int hostname); + static void check_host_entry(struct hostent * hostentry); + static void IP_formatter(char *IPbuffer); + static std::string getOwnIP(); }; diff --git a/libs/whisper-com b/libs/whisper-com index 6b8d6ad..49bdb28 160000 --- a/libs/whisper-com +++ b/libs/whisper-com @@ -1 +1 @@ -Subproject commit 6b8d6ad2655db00509bf692dd07e1254858c81fc +Subproject commit 49bdb28535a4ef5e9e35a04fdc898d93d1f8af13 diff --git a/src/SimCore/Sensor.cpp b/src/SimCore/Sensor.cpp new file mode 100644 index 0000000..b8196c6 --- /dev/null +++ b/src/SimCore/Sensor.cpp @@ -0,0 +1,182 @@ +#include "SimCore/Messages/Track.hpp" +#include "SimCore/UtilFunctions.hpp" +#include "WHISPER/Messages/Message.hpp" +#include +#include + +namespace SimCore { + + Sensor::Sensor(SimCore::Identifier OwnID, SimCore::Identifier ParentID, SimCore::SensorKinds SensorKind,std::uint32_t GroundTruthPort, std::uint32_t ParentPort,std::string ParentIPAddress): + OwnID_(OwnID),ParentID_(ParentID),SensorKind_(SensorKind),GroundTruthPort_(GroundTruthPort),ParentPort_(ParentPort),ParentIPAddress_(ParentIPAddress) + { + + std::string ownIP = SimCore::UtilFunctions::getOwnIP(); + auto ip = SimCore::UtilFunctions::explode(ownIP, '.'); + ip[3] = "255"; + LOG_S(INFO)<>(); + outgoingGroundThruthMessages = std::make_shared>(); + + incommingParentMessages = std::make_shared>(); + outgoingParentMessages = std::make_shared>(); + + incommingTrackMessages = std::make_shared>(); + + + GroundTruthUDPService_ = std::make_shared(OwnID.getNumber(),WHISPER::SENSOR,8000,SimCore::UtilFunctions::implode(ip,'.'),ownIP); + ParentUDPService_ = std::make_shared(OwnID.getNumber(),WHISPER::SENSOR,ParentPort,ParentIPAddress_,ownIP); + + ReloadCharacteristicts(); + + }; + + + Sensor::~Sensor(){ + this->stop(); + + while (!this->incommingGroundThruthMessages.unique()) { + std::this_thread::sleep_for(std::chrono::milliseconds(100)); + } + this->incommingGroundThruthMessages.reset(); + + while (!this->outgoingGroundThruthMessages.unique()) { + std::this_thread::sleep_for(std::chrono::milliseconds(100)); + } + this->outgoingGroundThruthMessages.reset(); + + + GroundTruthUDPService_->disconnect(); + while (!this->GroundTruthUDPService_.unique()) { + std::this_thread::sleep_for(std::chrono::milliseconds(100)); + } + this->GroundTruthUDPService_.reset(); + + + ParentUDPService_->disconnect(); + while (!this->ParentUDPService_.unique()) { + std::this_thread::sleep_for(std::chrono::milliseconds(100)); + } + this->ParentUDPService_.reset(); + + + + + } + + void Sensor::start(){ + stopReceivingGroundThruth = false; + receiveGroundTruthThread = std::thread(&Sensor::receivingData,this); + + // stopsendCalculatedData = false; + // sendCalculatedDataThread = std::thread(&Sensor::sendingData,this); + + // stopCalculationData = false; + // sensorCalculationThread = std::thread(&Sensor::SensorCalculations,this); + } + + void Sensor::stop() { + + + while (ReceivingGroundThruthIsRunnung == true ) { + stopReceivingGroundThruth = true; + LOG_S(INFO)<<"waiting for receiving thread thread"; + if (receiveGroundTruthThread.joinable() == true ) { + receiveGroundTruthThread.join(); + } + } + + while (sendCalculatedDataIsRunnung == true ) { + stopsendCalculatedData = true; + LOG_S(INFO)<<"waiting for receiving thread thread"; + if (sendCalculatedDataThread.joinable() == true ) { + sendCalculatedDataThread.join(); + } + } + + while (CalculationIsRunnung == true ) { + stopCalculationData = true; + LOG_S(INFO)<<"waiting for receiving thread thread"; + if (sensorCalculationThread.joinable() == true ) { + sensorCalculationThread.join(); + } + } + + } + + + void Sensor::receivingData() + { + this->ReceivingGroundThruthIsRunnung = true; + // GroundTruthUDPService_->connect(incommingGroundThruthMessages); + // GroundTruthUDPService_->subscribe(WHISPER::MsgTopicsMap[WHISPER::MsgTopics::TRACK]); + + // while (stopReceivingGroundThruth == false) { + // if (incommingGroundThruthMessages->size() > 0) { + // WHISPER::Message msg; + // incommingGroundThruthMessages->get(msg); + // if (msg.msgType_ == WHISPER::MsgType::RAW_TRACK) { + // auto Track = SimCore::Track(msg.serialize()); + // incommingTrackMessages->addElement(Track); + // } + // } + + // if (outgoingGroundThruthMessages->size() > 0) { + // WHISPER::Message msg; + // outgoingGroundThruthMessages->get(msg); + // GroundTruthUDPService_->publish(msg.serialize(), WHISPER::MsgTopicsMap[(WHISPER::MsgTopics)msg.topic_]); + // } + + // } + // GroundTruthUDPService_->disconnect(); + this->ReceivingGroundThruthIsRunnung = false; + } + + void Sensor::sendingData() + { + this->sendCalculatedDataIsRunnung = true; + + ParentUDPService_->connect(incommingParentMessages); + ParentUDPService_->subscribe(WHISPER::MsgTopicsMap[WHISPER::MsgTopics::COMMANDS]); + + while (stopsendCalculatedData == false) { + + if (incommingParentMessages->size() > 0) { + WHISPER::Message msg; + incommingGroundThruthMessages->get(msg); + LOG_S(INFO)<< "Message received from Parent is" << msg.msgType_; + } + + if (outgoingParentMessages->size() > 0) { + WHISPER::Message msg; + outgoingParentMessages->get(msg); + ParentUDPService_->publish(msg.serialize(), WHISPER::MsgTopicsMap[(WHISPER::MsgTopics)msg.topic_]); + } + + } + + this->sendCalculatedDataIsRunnung = false; + } + + + void Sensor::SensorCalculations() + { + CalculationIsRunnung = true; + specificSensorCalculations(); + + while (!stopCalculationData) { + specificSensorCalculations(); + } + + CalculationIsRunnung = false; + } + + void Sensor::ReloadCharacteristicts() + { + LOG_S(INFO)<<"loading specs"; + + // specificReloadCharacteristicts(); + } + + + +} \ No newline at end of file diff --git a/src/SimCore/UtilFunctions.cpp b/src/SimCore/UtilFunctions.cpp index c894a72..e1a46b6 100644 --- a/src/SimCore/UtilFunctions.cpp +++ b/src/SimCore/UtilFunctions.cpp @@ -1,4 +1,8 @@ #include +#include +#include +#include +#include namespace SimCore { @@ -16,6 +20,22 @@ namespace SimCore { return result; } + std::string UtilFunctions::implode(const std::vector &v , char delim) + { + std::string ret; + + for(const auto &s : v) + { + if(!ret.empty()) + { + ret += delim; + } + ret += s; + } + return ret; + } + + bool UtilFunctions::isNumber(const std::string& s) { @@ -23,4 +43,38 @@ namespace SimCore { s.end(), [](unsigned char c) { return !std::isdigit(c); }) == s.end(); } + void UtilFunctions::check_host_name(int hostname) { //This function returns host name for local computer + if (hostname == -1) { + perror("gethostname"); + exit(1); + } + } + void UtilFunctions::check_host_entry(struct hostent * hostentry) { //find host info from host name + if (hostentry == NULL){ + perror("gethostbyname"); + exit(1); + } + } + void IP_formatter(char *IPbuffer) { //convert IP string to dotted decimal format + if (NULL == IPbuffer) { + perror("inet_ntoa"); + exit(1); + } + } + + std::string UtilFunctions::getOwnIP(){ + char host[256]; + char *IP; + struct hostent *host_entry; + int hostname; + hostname = gethostname(host, sizeof(host)); //find the host name + check_host_name(hostname); + host_entry = gethostbyname(host); //find host information + check_host_entry(host_entry); + IP = inet_ntoa(*((struct in_addr*) host_entry->h_addr_list[0])); //Convert into IP string + + + return IP; + }; + } \ No newline at end of file diff --git a/tests/test_SensorClass.cpp b/tests/test_SensorClass.cpp new file mode 100644 index 0000000..83390eb --- /dev/null +++ b/tests/test_SensorClass.cpp @@ -0,0 +1,67 @@ + +#include "SimCore/Identifier.hpp" +#include +#include +#include +#define CATCH_CONFIG_MAIN +#include +#include + +// SimCore::Identifier OwnID, SimCore::Identifier ParentID, SimCore::SensorKinds SensorKind,std::uint32_t GroundTruthPort, std::uint32_t ParentPort,std::string ParentIPAddress +class Radar : public SimCore::Sensor +{ + public: + Radar(SimCore::Identifier OwnID, + SimCore::Identifier ParentID, + SimCore::SensorKinds SensorKind, + std::uint32_t GroundTruthPort, + std::uint32_t ParentPort, + std::string ParentIPAddress, + std::string radarType):SimCore::Sensor(OwnID, ParentID, SensorKind, GroundTruthPort, ParentPort, ParentIPAddress),radarType_(radarType) + { + + } + + private: + std::string radarType_; + + void specificSensorCalculations() override + { + LOG_S(INFO)<<"calculating"; + }; + + void specificReloadCharacteristicts() override + { + LOG_S(INFO)<<"loading specifications"; + }; +}; + + + + +SCENARIO("Testing the SimCore Sensor") +{ + GIVEN("different Attributes for a Track in different forms") + { + SimCore::Identifier IDParent(0,1,false); + SimCore::Identifier IDRadar(1,1,false); + + Radar Radar(IDRadar,IDParent,SimCore::SensorKinds::RADAR,8000,8001,"127.0.0.1","APAR"); + Radar.start(); + + WHEN("constructing Track Object with data") + { + + std::this_thread::sleep_for(std::chrono::milliseconds(1000)); + THEN("check if Track attributes are correct") + { + // REQUIRE(testOperator == true); + + + + + + } //THEN + } // WHEN + } // GIVEN +} //SCENARIO \ No newline at end of file diff --git a/tests/test_UtilFunctions.cpp b/tests/test_UtilFunctions.cpp index 5ca253c..ae450fe 100644 --- a/tests/test_UtilFunctions.cpp +++ b/tests/test_UtilFunctions.cpp @@ -2,6 +2,7 @@ #include #define CATCH_CONFIG_MAIN #include +#include @@ -14,6 +15,14 @@ SCENARIO("Testing the SimCorePositionClass") std::string s1 = "hello.world.guy"; std::string s2 = "my;Name;is;henry"; + std::string ownIP = SimCore::UtilFunctions::getOwnIP(); + LOG_S(INFO)<compare("hello") == 0); - REQUIRE(v2.size() == 4); + REQUIRE(v2.size() == 4); REQUIRE(v2[1].compare("Name") == 0); + REQUIRE(ownIP.size() > 0); + REQUIRE(ip.size() == 4);