diff --git a/.gitmodules b/.gitmodules index 1b7dc98..da86c86 100644 --- a/.gitmodules +++ b/.gitmodules @@ -10,3 +10,6 @@ [submodule "libs/OrderLibrary"] path = libs/OrderLibrary url = ssh://git@dev-gitea.ftewa.ti.unibw-hamburg.de:12000/hwinkel/OrderLibrary.git +[submodule "libs/ixwebsocket"] + path = libs/ixwebsocket + url = https://github.com/machinezone/IXWebSocket.git diff --git a/CMakeLists.txt b/CMakeLists.txt index 29c7d40..c152405 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -35,13 +35,20 @@ IF(NOT TARGET OrderLibrary) add_subdirectory(libs/OrderLibrary EXCLUDE_FROM_ALL) ENDIF() +IF(NOT TARGET ixwebsocket) + add_subdirectory(libs/ixwebsocket EXCLUDE_FROM_ALL) +ENDIF() + add_library(SimControl STATIC - include/SimControl/SimControl.hpp - src/SimControl/SimControl.cpp - include/SimControl/PodList.hpp - src/SimControl/PodList.cpp + include/SimControl/SimControl.hpp + src/SimControl/SimControl.cpp + include/SimControl/PodList.hpp + src/SimControl/PodList.cpp + + include/SimControl/Tracklist.hpp + src/SimControl/Tracklist.cpp ) @@ -53,6 +60,7 @@ target_link_libraries(SimControl kubecontrol loguru OrderLibrary + ixwebsocket ) target_include_directories(SimControl diff --git a/Dockerfile b/Dockerfile index 87df1d6..62033fc 100644 --- a/Dockerfile +++ b/Dockerfile @@ -12,6 +12,14 @@ RUN apt-get upgrade # RUN apt-get -y install +####### DEBUG packete + +RUN apt-get -y install tcpdump nano netcat-openbsd + + +######## + + # install all used libs RUN apt-get -y install libsodium23 libuuid1 libstdc++5 libcurl4 @@ -24,6 +32,7 @@ COPY build/libs/KubeControl/libs/yaml-cpp/libyaml-cpp.so.0.8 /usr/lib/ COPY build/libs/KubeControl/libs/curlpp/libcurlpp.so.1 /usr/lib/ # COPY build/libs/EntityLibrary/libs/SimCore/libs/crossguid/libcrossguid.so.0 /usr/lib/ COPY build/libs/SimCore/libs/crossguid/libcrossguid-dgb.so.0 /usr/lib/ +COPY build/libs/ixwebsocket/libixwebsocket.so.0.1.0 /usr/lib/ # Copy the current folder which contains C++ source code to the Docker image under /usr/src @@ -37,6 +46,6 @@ WORKDIR /usr/local/bin/ # RUN clang++ -o Test Test.cpp # Run the output program from the previous step -# CMD ["SimControlApplication"] +CMD ["SimControlApplication"] -CMD ["bin/bash"] \ No newline at end of file +# CMD ["bin/bash"] \ No newline at end of file diff --git a/build/libs/SimCore/libs/whisper-comm b/build/libs/SimCore/libs/whisper-comm index f794f4c..f17566c 160000 --- a/build/libs/SimCore/libs/whisper-comm +++ b/build/libs/SimCore/libs/whisper-comm @@ -1 +1 @@ -Subproject commit f794f4c5d07f8d855bb86521353b8c379ceaefec +Subproject commit f17566cba09db26b745600249fd449e1fac7bb2d diff --git a/docs/info.json b/docs/info.json deleted file mode 100644 index c68cbeb..0000000 --- a/docs/info.json +++ /dev/null @@ -1,47 +0,0 @@ - - - - - - - -{"apiVersion":"v1","kind":"Pod","metadata":{"creationTimestamp":"2023-08-11T11:36:22Z","labels":{"app.kubernetes.io/name":"hamburg"},"managedFields":[{"apiVersion":"v1","fieldsType":"FieldsV1","fieldsV1":{"f:metadata":{"f:labels":{".":{},"f:app.kubernetes.io/name":{}}},"f:spec":{"f:containers":{"k:{\"name\":\"hamburg-container\"}":{".":{},"f:env":{".":{},"k:{\"name\":\"COMMAND_PORT\"}":{".":{},"f:name":{},"f:value":{}},"k:{\"name\":\"ENTITY_ID\"}":{".":{},"f:name":{},"f:value":{}},"k:{\"name\":\"ENTITY_NAME\"}":{".":{},"f:name":{},"f:value":{}},"k:{\"name\":\"GROUNDTRUTH_PORT\"}":{".":{},"f:name":{},"f:value":{}},"k:{\"name\":\"POS_HEIGHT\"}":{".":{},"f:name":{},"f:value":{}},"k:{\"name\":\"POS_LAT\"}":{".":{},"f:name":{},"f:value":{}},"k:{\"name\":\"POS_LONG\"}":{".":{},"f:name":{},"f:value":{}}},"f:image":{},"f:imagePullPolicy":{},"f:name":{},"f:resources":{},"f:terminationMessagePath":{},"f:terminationMessagePolicy":{}}},"f:dnsPolicy":{},"f:enableServiceLinks":{},"f:restartPolicy":{},"f:schedulerName":{},"f:securityContext":{},"f:terminationGracePeriodSeconds":{}}}, -"manager":"unknown","operation":"Update","time":"2023-08-11T11:36:22Z"}, -{"apiVersion":"v1","fieldsType":"FieldsV1", -"fieldsV1":{"f:status":{"f:conditions":{"k:{\"type\":\"ContainersReady\"}":{".":{},"f:lastProbeTime":{},"f:lastTransitionTime":{},"f:status":{},"f:type":{}},"k:{\"type\":\"Initialized\"}":{".":{},"f:lastProbeTime":{},"f:lastTransitionTime":{},"f:status":{},"f:type":{}},"k:{\"type\":\"Ready\"}":{".":{},"f:lastProbeTime":{},"f:lastTransitionTime":{},"f:status":{},"f:type":{}}}, -"f:containerStatuses":{},"f:hostIP":{},"f:phase":{},"f:podIP":{}, -"f:podIPs":{".":{},"k:{\"ip\":\"10.0.3.98\"}":{".":{},"f:ip":{}}},"f:startTime":{}}}, -"manager":"kubelet","operation":"Update","subresource":"status","time":"2023-08-11T11:36:23Z"}], -"name":"ship1","namespace":"hwinkel","resourceVersion":"171734008","uid":"68ef8a8c-33c9-4160-89ea-7f51d5e6735a"}, -"spec":{"containers":[{"env":[{"name":"COMMAND_PORT","value":"\"5555\""}, -{"name":"ENTITY_ID","value":"ship1"}, -{"name":"ENTITY_NAME","value":"hamburg"}, -{"name":"GROUNDTRUTH_PORT","value":"\"8000\""}, -{"name":"POS_HEIGHT","value":"\"0\""}, -{"name":"POS_LAT","value":"\"55\""}, -{"name":"POS_LONG","value":"\"8\""}], -"image":"kmaster.ti.unibw-hamburg.de:30808/ship:latest", -"imagePullPolicy":"Always", -"name":"hamburg-container", -"resources":{}, -"terminationMessagePath":"/dev/termination-log", -"terminationMessagePolicy":"File", -"volumeMounts":[{"mountPath":"/var/run/secrets/kubernetes.io/serviceaccount","name":"kube-api-access-92lpt","readOnly":true}]}], -"dnsPolicy":"ClusterFirst", -"enableServiceLinks":true, -"nodeName":"kslave02.ti.unibw-hamburg.de", -"preemptionPolicy":"PreemptLowerPriority", -"priority":0, -"restartPolicy":"Never", -"schedulerName":"default-scheduler", -"securityContext":{}, -"serviceAccount":"default", -"serviceAccountName":"default", -"terminationGracePeriodSeconds":30, -"tolerations":[ - {"effect":"NoExecute","key":"node.kubernetes.io/not-ready","operator":"Exists","tolerationSeconds":300}, - {"effect":"NoExecute","key":"node.kubernetes.io/unreachable","operator":"Exists","tolerationSeconds":300}], - "volumes":[ - {"name":"kube-api-access-92lpt", - "projected":{ - "defaultMode":420,"sources":[{"serviceAccountToken":{"expirationSeconds":3607,"path":"token"}},{"configMap":{"items":[{"key":"ca.crt","path":"ca.crt"}],"name":"kube-root-ca.crt"}},{"downwardAPI":{"items":[{"fieldRef":{"apiVersion":"v1","fieldPath":"metadata.namespace"},"path":"namespace"}]}}]}}]},"status":{"conditions":[{"lastProbeTime":null,"lastTransitionTime":"2023-08-11T11:36:22Z","status":"True","type":"Initialized"},{"lastProbeTime":null,"lastTransitionTime":"2023-08-11T11:36:23Z","status":"True","type":"Ready"},{"lastProbeTime":null,"lastTransitionTime":"2023-08-11T11:36:23Z","status":"True","type":"ContainersReady"},{"lastProbeTime":null,"lastTransitionTime":"2023-08-11T11:36:22Z","status":"True","type":"PodScheduled"}],"containerStatuses":[{"containerID":"cri-o://c2632fb622a89b099c566b83a81de28e665176ea4f91f8ad1b17b97945c9450a","image":"kmaster.ti.unibw-hamburg.de:30808/ship:latest","imageID":"kmaster.ti.unibw-hamburg.de:30808/ship@sha256:53032573b5777e4ec30764b4700aa5b7ec3ba5b9c035cdecf5c8abe8f0e30279","lastState":{},"name":"hamburg-container","ready":true,"restartCount":0,"started":true,"state":{"running":{"startedAt":"2023-08-11T11:36:23Z"}}}],"hostIP":"192.168.252.8","phase":"Running","podIP":"10.0.3.98","podIPs":[{"ip":"10.0.3.98"}],"qosClass":"BestEffort","startTime":"2023-08-11T11:36:22Z"}} \ No newline at end of file diff --git a/include/SimControl/SimControl.hpp b/include/SimControl/SimControl.hpp index 46647f8..d524b60 100644 --- a/include/SimControl/SimControl.hpp +++ b/include/SimControl/SimControl.hpp @@ -3,11 +3,17 @@ #include "DirectCommunicationClient.hpp" #include "DirectCommunicationServer.hpp" +#include "SimControl/Tracklist.hpp" #include "SimCore/Identifier.hpp" +#include "WHISPER/InternalUDPListener.hpp" #include "crossguid/guid.hpp" +#include "ixwebsocket/IXConnectionState.h" +#include "ixwebsocket/IXWebSocketMessage.h" +#include "ixwebsocket/IXWebSocketServer.h" #include "kubecontrol/PodController.hpp" #include +#include #include #include @@ -27,35 +33,52 @@ namespace SimControl { class SimControl{ public: - SimControl(std::string CommandPort); + SimControl(bool online, std::string CommandPort,std::string GroundTruthAddr = "239.0.0.1", ushort GroundTruthPort = 10000, std::string Namespace = "simulator"); ~SimControl(); void stop(); private: - + bool online_; const SimCore::Identifier ID_; std::string CommandPort_; + + std::string GroundTruthAddr_; + ushort GroundTruthPort_; + std::string Namespace_; + void MainFunction_(); void HandleMessage(std::string msg); - void HandleExternalMessage(std::string msg); + void HandleTCPMessage(std::string msg); void startShip(std::string name); - + void startWebApp(); std::unique_ptr PodController_; - + std::unique_ptr Tracklist_; std::thread MainThread_; std::atomic stopMainThread_ = false; std::shared_ptr TCPClient_ = nullptr; - std::shared_ptr ExternalTCPServer_ = nullptr; + std::shared_ptr ExternalTCPServer_ = nullptr; + + + + std::thread WebsocketThreadThread_; + std::atomic stopWebsocketThreadThread_ = false; + int port = 9999; + std::string host = "0.0.0.0"; + std::shared_ptr WebsocketServer_ = nullptr; + void startWebsocketServer(); + void HandleWebsocketMessages(std::shared_ptr connectionState, ix::WebSocket &websocket, const ix::WebSocketMessagePtr &msg); + + std::shared_ptr BroadcastListener_; + void HandleBroadcastMessage(std::string msg); - }; diff --git a/include/SimControl/Tracklist.hpp b/include/SimControl/Tracklist.hpp new file mode 100644 index 0000000..8219a71 --- /dev/null +++ b/include/SimControl/Tracklist.hpp @@ -0,0 +1,32 @@ +#pragma once + + + + +#include "nlohmann/json_fwd.hpp" +#include +#include +#include +#include +#include +#include + +namespace SimControl +{ + class TrackList + { + public: + TrackList(); + void addTrack(std::shared_ptr Track); + std::shared_ptr getTrack(SimCore::Identifier); + + void getJsonTRackList(nlohmann::json &message); + + + private: + mutable std::mutex mx_; + std::map> TrackStore_; + + + }; +} \ No newline at end of file diff --git a/libs/KubeControl b/libs/KubeControl index 89465f0..49b3605 160000 --- a/libs/KubeControl +++ b/libs/KubeControl @@ -1 +1 @@ -Subproject commit 89465f06a5fa421fc4c424426704fc65680c4afa +Subproject commit 49b36053d7dc6f08c05d10d80928597367788046 diff --git a/libs/SimCore b/libs/SimCore index 6b5aff7..d060f9f 160000 --- a/libs/SimCore +++ b/libs/SimCore @@ -1 +1 @@ -Subproject commit 6b5aff7b6ea186f07477594aed7e04898fdfb766 +Subproject commit d060f9f2d4dcebc8fb26c07cb63307ba5ea0a757 diff --git a/libs/ixwebsocket b/libs/ixwebsocket new file mode 160000 index 0000000..ed5b1a0 --- /dev/null +++ b/libs/ixwebsocket @@ -0,0 +1 @@ +Subproject commit ed5b1a0895577eda195f126e27f34e4c65be794a diff --git a/src/SimControl/SimControl.cpp b/src/SimControl/SimControl.cpp index 7a9d8b1..f2750d5 100644 --- a/src/SimControl/SimControl.cpp +++ b/src/SimControl/SimControl.cpp @@ -1,11 +1,16 @@ #include #include #include "DirectCommunicationServer.hpp" +#include "SimControl/Tracklist.hpp" #include "SimCore/Messages/Control.hpp" #include "SimCore/Messages/SimTrack.hpp" #include "SimCore/SimCore.hpp" +#include "SimCore/UtilFunctions.hpp" +#include "WHISPER/InternalUDPListener.hpp" #include "WHISPER/Messages/Message.hpp" #include "crossguid/guid.hpp" +#include "ixwebsocket/IXConnectionState.h" +#include "ixwebsocket/IXWebSocket.h" #include "kubecontrol/KubePod.hpp" #include "kubecontrol/PodController.hpp" #include "nlohmann/json_fwd.hpp" @@ -13,31 +18,62 @@ +#include #include +#include +#include #include #include #include #include +#include namespace SimControl { - SimControl::SimControl( std::string CommandPort):CommandPort_(CommandPort),ID_(SimCore::Identifier(xg::newGuid())) + SimControl::SimControl(bool online,std::string CommandPort,std::string GroundTruthAddr, ushort GroundTruthPort,std::string Namespace): + online_(online),CommandPort_(CommandPort),GroundTruthAddr_(GroundTruthAddr),GroundTruthPort_(GroundTruthPort),Namespace_(Namespace),ID_(SimCore::Identifier(xg::newGuid())) { + // BroadcastListener_ = std::make_shared("239.0.0.1",10000); + BroadcastListener_ = std::make_shared(GroundTruthAddr_,GroundTruthPort_); + + BroadcastListener_->registerMessageCallback(std::bind(&SimControl::HandleBroadcastMessage,this,std::placeholders::_1)); + BroadcastListener_->connect(); + BroadcastListener_->subscribe(WHISPER::MsgTopics::TRACK); + PodController_ = std::make_unique("docs/config"); ExternalTCPServer_ = std::make_shared(5000); - ExternalTCPServer_->registerMessageCallback(std::bind(&SimControl::HandleExternalMessage,this,std::placeholders::_1)); + ExternalTCPServer_->registerMessageCallback(std::bind(&SimControl::HandleTCPMessage,this,std::placeholders::_1)); // TCPClient_ = std::make_unique(30200,"192.168.252.6"); // TCPClient_ = std::make_unique(5555,"127.0.0.1"); // TCPClient_->registerMessageCallback(std::bind(&SimControl::HandleMessage,this,std::placeholders::_1)); // TCPClient_->sendMessage("Hello Server"); + + + WebsocketServer_ = std::make_shared(port,host); + WebsocketServer_->setOnClientMessageCallback( [this](std::shared_ptr connectionState, ix::WebSocket &websocket, const ix::WebSocketMessagePtr &msg) + { + HandleWebsocketMessages( connectionState, websocket, msg); + }); + + + Tracklist_ = std::make_unique(); + + + this->stopMainThread_ = false; MainThread_ = std::thread(&SimControl::MainFunction_,this); + this->stopWebsocketThreadThread_ = false; + WebsocketThreadThread_ = std::thread(&SimControl::startWebsocketServer,this); + + + + } SimControl::~SimControl() @@ -51,6 +87,14 @@ namespace SimControl { } MainThread_.join(); + WebsocketServer_->stop(); + stopWebsocketThreadThread_ = true; + while (!WebsocketThreadThread_.joinable()) { + // LOG_S(INFO)<< "waiting"; + std::this_thread::sleep_for(std::chrono::milliseconds(100)); + } + WebsocketThreadThread_.join(); + TCPClient_.reset(); @@ -80,43 +124,155 @@ namespace SimControl { } - void SimControl::HandleExternalMessage(std::string msg) + void SimControl::HandleTCPMessage(std::string msg) { LOG_S(INFO)<addTrack(std::move(track)); + } + + + } + + void SimControl::startWebsocketServer() + { + auto res = WebsocketServer_->listen(); + if (!res.first) + { + // Error handling + return ; + } + WebsocketServer_->start(); + + // Block until server.stop() is called. + WebsocketServer_->wait(); + + while (!stopWebsocketThreadThread_) { + std::this_thread::sleep_for(std::chrono::milliseconds(100)); + + } + + } + void SimControl::HandleWebsocketMessages(std::shared_ptr connectionState, ix::WebSocket &websocket, const ix::WebSocketMessagePtr &msg) + { + LOG_S(INFO) << "Remote ip: " << connectionState->getRemoteIp(); + + if (msg->type == ix::WebSocketMessageType::Open) + { + LOG_S(INFO)<< "New connection" ; + + // A connection state object is available, and has a default id + // You can subclass ConnectionState and pass an alternate factory + // to override it. It is useful if you want to store custom + // attributes per connection (authenticated bool flag, attributes, etc...) + LOG_S(INFO) << "id: " << connectionState->getId(); + + // The uri the client did connect to. + LOG_S(INFO) << "Uri: " << msg->openInfo.uri ; + + LOG_S(INFO) << "Headers:" ; + for (auto it : msg->openInfo.headers) + { + LOG_S(INFO)<< "\t" << it.first << ": " << it.second; + } + } + else if (msg->type == ix::WebSocketMessageType::Message) + { + // For an echo server, we just send back to the client whatever was received by the server + // All connected clients are available in an std::set. See the broadcast cpp example. + // Second parameter tells whether we are sending the message in binary or text mode. + // Here we send it in the same mode as it was received. + // LOG_S(INFO)<< "Received: " << msg->str << std::endl; + try { + nlohmann::json j = nlohmann::json::parse(msg->str); + LOG_S(INFO)<< "Received: " << j["Data"].get() << std::endl; + + if (j["Data"] == "COP") + { + if (j["Type"] == "Request") { + nlohmann::json response; + response["Data"] = "COP"; + Tracklist_->getJsonTRackList(response); + // response.merge_patch(Tracklist_->getJsonTRackList()); + LOG_S(INFO)<str, msg->binary); + } + + } + + void SimControl::startShip(std::string name) { std::string uuid = name; - kubecontrol::KubePod ShipPod1("controller",uuid,"ship","ship:latest"); + kubecontrol::KubePod ShipPod1("controller",uuid,"ship","ship:latest",Namespace_); ShipPod1.setEnvironmentVar("ENTITY_ID", uuid); ShipPod1.setEnvironmentVar("ENTITY_NAME", "hamburg"); ShipPod1.setEnvironmentVar("POS_LAT", "\"55\""); ShipPod1.setEnvironmentVar("POS_LONG", "\"8\""); ShipPod1.setEnvironmentVar("POS_HEIGHT", "\"0\""); - ShipPod1.setEnvironmentVar("GROUNDTRUTH_PORT", "\"8000\""); + ShipPod1.setEnvironmentVar("GROUNDTRUTH_PORT", "\""+std::to_string(this->GroundTruthPort_)+"\""); + ShipPod1.setEnvironmentVar("GROUNDTRUTH_ADDR", "\""+this->GroundTruthAddr_+"\""); ShipPod1.setEnvironmentVar("COMMAND_PORT", "\""+CommandPort_+"\""); ShipPod1.createYAML(); PodController_->startPod(ShipPod1); - } + void SimControl::startWebApp() + { + + kubecontrol::KubePod Webapp("controller","webapp","webapp","webapp:latest",Namespace_); + Webapp.setEnvironmentVar("REACT_APP_WEBAPP_WS_URL", SimCore::UtilFunctions::getOwnIP()); + + Webapp.createYAML(); + + PodController_->startPod(Webapp); + + } + + void SimControl::MainFunction_() { // std::string uuid = xg::newGuid().str(); - - startShip("hamburg"); + if (online_ != false) { + startShip("hamburg"); + startWebApp(); + + } - LOG_S(INFO)<getInfoForPod("hamburg"); + // LOG_S(INFO)<getInfoForPod("hamburg"); - auto IP = PodController_->getPodsInfo("hamburg")->Ip; - TCPClient_ = std::make_shared(5555,IP); - // Orders::MoveOrder order(this->ID_); + // auto IP = PodController_->getPodsInfo("hamburg")->Ip; + // TCPClient_ = std::make_shared(5555,IP); + // // Orders::MoveOrder order(this->ID_); // order.Speed.setValue(0); // TCPClient_->sendMessage(order.buildMessage().serialize()); @@ -126,6 +282,9 @@ namespace SimControl { // TCPClient_->sendMessage(shutdown.buildMessage().serialize()); // // TCPClient_->disconnect(); // // TCPClient_.reset(); + + + while (!stopMainThread_) { diff --git a/src/SimControl/Tracklist.cpp b/src/SimControl/Tracklist.cpp new file mode 100644 index 0000000..fbedf2d --- /dev/null +++ b/src/SimControl/Tracklist.cpp @@ -0,0 +1,58 @@ +#include "SimCore/SimCore.hpp" +#include "nlohmann/json_fwd.hpp" +#include + + + + +namespace SimControl +{ + + TrackList::TrackList() + { + + TrackStore_ = std::map>(); + } + + void TrackList::addTrack(std::shared_ptr Track) + { + std::lock_guard lock(mx_); + + auto [iterator, inserted] = TrackStore_.try_emplace(Track->getIdentifier().getUUID(),Track); + if (!inserted) { iterator->second = Track; } + + + } + std::shared_ptr TrackList::getTrack(const SimCore::Identifier ID) + { + std::lock_guard lock(mx_); + + auto it = TrackStore_.find(ID.getUUID()); + return it->second; + } + + void TrackList::getJsonTRackList(nlohmann::json &message) + { + std::lock_guard lock(mx_); + try { + for (std::map>::iterator it=TrackStore_.begin(); it!=TrackStore_.end(); ++it) + { + nlohmann::json j; + j["id"] = it->first; + j["Name"] = it->second->Name.getValue(); + j["Course"] = it->second->Course.getValue(); + j["Speed"] = it->second->Speed.getValue(); + j["Position"] = {it->second->getPosition().getGeodesicPos()[SimCore::LATITUDE], it->second->getPosition().getGeodesicPos()[SimCore::LONGITUDE]}; + j["Type"] = SimCore::Kind::EntityKindMap[it->second->EntityKind.getValue()]; + j["Side"] = SimCore::Side::EntitySideMap[it->second->EntitySide.getValue()]; + + message["Entities"].push_back(j); + } + }catch (const std::exception e) { + LOG_S(ERROR)<< e.what(); + } + } + + + +} \ No newline at end of file diff --git a/src/main.cpp b/src/main.cpp index 2fc5a93..5cecff1 100644 --- a/src/main.cpp +++ b/src/main.cpp @@ -1,3 +1,4 @@ +#include "SimCore/UtilFunctions.hpp" #include #include #include @@ -33,10 +34,26 @@ int main() sigIntHandler.sa_flags = 0; sigaction(SIGINT, &sigIntHandler, NULL); + bool online = false; + const char* CommandPortChar = "5555"; if (std::getenv("COMMAND_PORT") != nullptr) { CommandPortChar = std::getenv("COMMAND_PORT"); } + const char* GroundTruthAddr = "239.0.0.1"; + if (std::getenv("GROUNDTRUTH_ADDR") != nullptr) { + CommandPortChar = std::getenv("GROUNDTRUTH_ADDR"); + } + const char* GroundTruthPort = "10000"; + if (std::getenv("GROUNDTRUTH_PORT") != nullptr) { + CommandPortChar = std::getenv("GROUNDTRUTH_PORT"); + } + + const char* Namespace = "simulator"; + if (std::getenv("NAMESPACE") != nullptr) { + Namespace = std::getenv("NAMESPACE"); + online = true; + } const char *ServerAddress = nullptr; @@ -48,13 +65,13 @@ int main() LOG_S(INFO)<