Skip to content

Commit

Permalink
Mapped datarefs to labels
Browse files Browse the repository at this point in the history
  • Loading branch information
cvu1998 committed Dec 3, 2022
1 parent 83ce242 commit f070dda
Show file tree
Hide file tree
Showing 96 changed files with 11,483 additions and 54 deletions.
24 changes: 24 additions & 0 deletions libXplane-udp-client/Subscriptions.yaml
Original file line number Diff line number Diff line change
@@ -0,0 +1,24 @@
dataref1:
tag: "sim/aircraft/view/acf_descrip[0][40]"
frequency: 10
description: "EMPTY"
dataref2:
tag: "sim/cockpit2/switches/landing_lights_on"
frequency: 10
description: "EMPTY"
dataref3:
tag: "sim/cockpit2/switches/landing_lights_on"
frequency: 10
description: "EMPTY"
dataref4:
tag: "sim/cockpit2/engine/actuators/throttle_ratio[0]"
frequency: 100
description: "EMPTY"
ipcl:
tag: "ipcl/deviation_model/value1"
frequency: 0
description: "EMPTY"
ipc2:
tag: "ipcl/deviation_model/value2"
frequency: 0
description: "EMPTY"
97 changes: 92 additions & 5 deletions libXplane-udp-client/libXplane-udp-client.vcxproj
Original file line number Diff line number Diff line change
Expand Up @@ -26,6 +26,37 @@
<ClCompile Include="src\XPlaneBeaconListener.cpp" />
<ClCompile Include="src\XPlaneUDPClient.cpp" />
<ClCompile Include="src\XPUtils.cpp" />
<ClCompile Include="vendor\yaml-cpp\src\binary.cpp" />
<ClCompile Include="vendor\yaml-cpp\src\contrib\graphbuilder.cpp" />
<ClCompile Include="vendor\yaml-cpp\src\contrib\graphbuilderadapter.cpp" />
<ClCompile Include="vendor\yaml-cpp\src\convert.cpp" />
<ClCompile Include="vendor\yaml-cpp\src\depthguard.cpp" />
<ClCompile Include="vendor\yaml-cpp\src\directives.cpp" />
<ClCompile Include="vendor\yaml-cpp\src\emit.cpp" />
<ClCompile Include="vendor\yaml-cpp\src\emitfromevents.cpp" />
<ClCompile Include="vendor\yaml-cpp\src\emitter.cpp" />
<ClCompile Include="vendor\yaml-cpp\src\emitterstate.cpp" />
<ClCompile Include="vendor\yaml-cpp\src\emitterutils.cpp" />
<ClCompile Include="vendor\yaml-cpp\src\exceptions.cpp" />
<ClCompile Include="vendor\yaml-cpp\src\exp.cpp" />
<ClCompile Include="vendor\yaml-cpp\src\memory.cpp" />
<ClCompile Include="vendor\yaml-cpp\src\node.cpp" />
<ClCompile Include="vendor\yaml-cpp\src\nodebuilder.cpp" />
<ClCompile Include="vendor\yaml-cpp\src\nodeevents.cpp" />
<ClCompile Include="vendor\yaml-cpp\src\node_data.cpp" />
<ClCompile Include="vendor\yaml-cpp\src\null.cpp" />
<ClCompile Include="vendor\yaml-cpp\src\ostream_wrapper.cpp" />
<ClCompile Include="vendor\yaml-cpp\src\parse.cpp" />
<ClCompile Include="vendor\yaml-cpp\src\parser.cpp" />
<ClCompile Include="vendor\yaml-cpp\src\regex_yaml.cpp" />
<ClCompile Include="vendor\yaml-cpp\src\scanner.cpp" />
<ClCompile Include="vendor\yaml-cpp\src\scanscalar.cpp" />
<ClCompile Include="vendor\yaml-cpp\src\scantag.cpp" />
<ClCompile Include="vendor\yaml-cpp\src\scantoken.cpp" />
<ClCompile Include="vendor\yaml-cpp\src\simplekey.cpp" />
<ClCompile Include="vendor\yaml-cpp\src\singledocparser.cpp" />
<ClCompile Include="vendor\yaml-cpp\src\stream.cpp" />
<ClCompile Include="vendor\yaml-cpp\src\tag.cpp" />
</ItemGroup>
<ItemGroup>
<ClInclude Include="libzmq-v142-x64-4_3_4\zmq.h" />
Expand Down Expand Up @@ -124,9 +155,65 @@
<ClInclude Include="vendor\spdlog\spdlog.h" />
<ClInclude Include="vendor\spdlog\tweakme.h" />
<ClInclude Include="vendor\spdlog\version.h" />
</ItemGroup>
<ItemGroup>
<Text Include="Subscriptions.txt" />
<ClInclude Include="vendor\yaml-cpp\include\yaml-cpp\anchor.h" />
<ClInclude Include="vendor\yaml-cpp\include\yaml-cpp\binary.h" />
<ClInclude Include="vendor\yaml-cpp\include\yaml-cpp\contrib\anchordict.h" />
<ClInclude Include="vendor\yaml-cpp\include\yaml-cpp\contrib\graphbuilder.h" />
<ClInclude Include="vendor\yaml-cpp\include\yaml-cpp\depthguard.h" />
<ClInclude Include="vendor\yaml-cpp\include\yaml-cpp\dll.h" />
<ClInclude Include="vendor\yaml-cpp\include\yaml-cpp\emitfromevents.h" />
<ClInclude Include="vendor\yaml-cpp\include\yaml-cpp\emitter.h" />
<ClInclude Include="vendor\yaml-cpp\include\yaml-cpp\emitterdef.h" />
<ClInclude Include="vendor\yaml-cpp\include\yaml-cpp\emittermanip.h" />
<ClInclude Include="vendor\yaml-cpp\include\yaml-cpp\emitterstyle.h" />
<ClInclude Include="vendor\yaml-cpp\include\yaml-cpp\eventhandler.h" />
<ClInclude Include="vendor\yaml-cpp\include\yaml-cpp\exceptions.h" />
<ClInclude Include="vendor\yaml-cpp\include\yaml-cpp\mark.h" />
<ClInclude Include="vendor\yaml-cpp\include\yaml-cpp\node\convert.h" />
<ClInclude Include="vendor\yaml-cpp\include\yaml-cpp\node\detail\impl.h" />
<ClInclude Include="vendor\yaml-cpp\include\yaml-cpp\node\detail\iterator.h" />
<ClInclude Include="vendor\yaml-cpp\include\yaml-cpp\node\detail\iterator_fwd.h" />
<ClInclude Include="vendor\yaml-cpp\include\yaml-cpp\node\detail\memory.h" />
<ClInclude Include="vendor\yaml-cpp\include\yaml-cpp\node\detail\node.h" />
<ClInclude Include="vendor\yaml-cpp\include\yaml-cpp\node\detail\node_data.h" />
<ClInclude Include="vendor\yaml-cpp\include\yaml-cpp\node\detail\node_iterator.h" />
<ClInclude Include="vendor\yaml-cpp\include\yaml-cpp\node\detail\node_ref.h" />
<ClInclude Include="vendor\yaml-cpp\include\yaml-cpp\node\emit.h" />
<ClInclude Include="vendor\yaml-cpp\include\yaml-cpp\node\impl.h" />
<ClInclude Include="vendor\yaml-cpp\include\yaml-cpp\node\iterator.h" />
<ClInclude Include="vendor\yaml-cpp\include\yaml-cpp\node\node.h" />
<ClInclude Include="vendor\yaml-cpp\include\yaml-cpp\node\parse.h" />
<ClInclude Include="vendor\yaml-cpp\include\yaml-cpp\node\ptr.h" />
<ClInclude Include="vendor\yaml-cpp\include\yaml-cpp\node\type.h" />
<ClInclude Include="vendor\yaml-cpp\include\yaml-cpp\noexcept.h" />
<ClInclude Include="vendor\yaml-cpp\include\yaml-cpp\null.h" />
<ClInclude Include="vendor\yaml-cpp\include\yaml-cpp\ostream_wrapper.h" />
<ClInclude Include="vendor\yaml-cpp\include\yaml-cpp\parser.h" />
<ClInclude Include="vendor\yaml-cpp\include\yaml-cpp\stlemitter.h" />
<ClInclude Include="vendor\yaml-cpp\include\yaml-cpp\traits.h" />
<ClInclude Include="vendor\yaml-cpp\include\yaml-cpp\yaml.h" />
<ClInclude Include="vendor\yaml-cpp\src\collectionstack.h" />
<ClInclude Include="vendor\yaml-cpp\src\contrib\graphbuilderadapter.h" />
<ClInclude Include="vendor\yaml-cpp\src\directives.h" />
<ClInclude Include="vendor\yaml-cpp\src\emitterstate.h" />
<ClInclude Include="vendor\yaml-cpp\src\emitterutils.h" />
<ClInclude Include="vendor\yaml-cpp\src\exp.h" />
<ClInclude Include="vendor\yaml-cpp\src\indentation.h" />
<ClInclude Include="vendor\yaml-cpp\src\nodebuilder.h" />
<ClInclude Include="vendor\yaml-cpp\src\nodeevents.h" />
<ClInclude Include="vendor\yaml-cpp\src\ptr_vector.h" />
<ClInclude Include="vendor\yaml-cpp\src\regeximpl.h" />
<ClInclude Include="vendor\yaml-cpp\src\regex_yaml.h" />
<ClInclude Include="vendor\yaml-cpp\src\scanner.h" />
<ClInclude Include="vendor\yaml-cpp\src\scanscalar.h" />
<ClInclude Include="vendor\yaml-cpp\src\scantag.h" />
<ClInclude Include="vendor\yaml-cpp\src\setting.h" />
<ClInclude Include="vendor\yaml-cpp\src\singledocparser.h" />
<ClInclude Include="vendor\yaml-cpp\src\stream.h" />
<ClInclude Include="vendor\yaml-cpp\src\streamcharsource.h" />
<ClInclude Include="vendor\yaml-cpp\src\stringsource.h" />
<ClInclude Include="vendor\yaml-cpp\src\tag.h" />
<ClInclude Include="vendor\yaml-cpp\src\token.h" />
</ItemGroup>
<PropertyGroup Label="Globals">
<VCProjectVersion>16.0</VCProjectVersion>
Expand Down Expand Up @@ -233,7 +320,7 @@
<LanguageStandard>stdcpp17</LanguageStandard>
<AdditionalUsingDirectories>
</AdditionalUsingDirectories>
<AdditionalIncludeDirectories>$(ProjectDir)src;$(ProjectDir)vendor;$(ProjectDir)vendor\libzmq-v142-x64-4_3_4;%(AdditionalUsingDirectories)</AdditionalIncludeDirectories>
<AdditionalIncludeDirectories>$(ProjectDir)src;$(ProjectDir)vendor;$(ProjectDir)vendor\yaml-cpp\include;$(ProjectDir)vendor\libzmq-v142-x64-4_3_4;%(AdditionalUsingDirectories)</AdditionalIncludeDirectories>
</ClCompile>
<Link>
<SubSystem>Console</SubSystem>
Expand All @@ -255,7 +342,7 @@ xcopy /E /Y "$(ProjectDir)Subscriptions.txt" "$(TargetDir)"</Command>
<SDLCheck>true</SDLCheck>
<PreprocessorDefinitions>_WINSOCK_DEPRECATED_NO_WARNINGS;_CRT_SECURE_NO_WARNINGS;_CONSOLE;NDEBUG;%(PreprocessorDefinitions)</PreprocessorDefinitions>
<ConformanceMode>true</ConformanceMode>
<AdditionalIncludeDirectories>$(ProjectDir)src;$(ProjectDir)vendor;$(ProjectDir)vendor\libzmq-v142-x64-4_3_4;%(AdditionalUsingDirectories)</AdditionalIncludeDirectories>
<AdditionalIncludeDirectories>$(ProjectDir)src;$(ProjectDir)vendor;$(ProjectDir)vendor\yaml-cpp\include;$(ProjectDir)vendor\libzmq-v142-x64-4_3_4;%(AdditionalUsingDirectories)</AdditionalIncludeDirectories>
<LanguageStandard>stdcpp17</LanguageStandard>
</ClCompile>
<Link>
Expand Down
91 changes: 43 additions & 48 deletions libXplane-udp-client/src/ClientManager.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,8 @@
#include <future>
#include <iostream>

#include <yaml-cpp/yaml.h>

#include "Log.h"

void ClientManager::receiverCallbackFloat(std::string dataref, float value)
Expand Down Expand Up @@ -61,51 +63,49 @@ void ClientManager::attachToClient(std::string topic, size_t publisher_index, si

std::string topic_found = recv_msgs[0].to_string();
std::string command = recv_msgs[1].to_string();
std::string dref = recv_msgs[2].to_string();
std::string label = recv_msgs[2].to_string();
std::string value = recv_msgs[3].to_string();

if (command == "read")
{
std::string response;
std::chrono::nanoseconds timeElaspedSeconds;
if (m_DataRefs.find(dref) != m_DataRefs.end())
std::chrono::nanoseconds timeElaspedNanoSeconds;
if (m_LabelsToTag.find(label) != m_LabelsToTag.end())
{
response = m_DataRefs[dref].Value;
timeElaspedSeconds = std::chrono::duration_cast<std::chrono::nanoseconds>(std::chrono::steady_clock::now() - m_DataRefs[dref].LastUpdateTime);
response = getDataRef(label).Value;
timeElaspedNanoSeconds = std::chrono::duration_cast<std::chrono::nanoseconds>(std::chrono::steady_clock::now() - getDataRef(label).LastUpdateTime);
}
else response = "Error: Server is currently not subscribed to " + dref;
else response = "Error: Server is currently not subscribed to " + label;

LOG_INFO("READ COMMAND FOUND - {0}: [{1}] {2} VALUE: {3}", topic, recv_msgs[0].to_string(), recv_msgs[1].to_string(), response);

m_Publishers[publisher_index].send(zmq::buffer(topic), zmq::send_flags::sndmore);
m_Publishers[publisher_index].send(zmq::buffer(response), zmq::send_flags::sndmore);
m_Publishers[publisher_index].send(zmq::buffer( std::to_string( timeElaspedSeconds.count() / 1e9 ) ));
m_Publishers[publisher_index].send(zmq::buffer( std::to_string(timeElaspedNanoSeconds.count() / 1e9 ) ));
}

if (command == "set")
{
std::string response = "Received";
if (m_DataRefs.find(dref) != m_DataRefs.end())
if (m_LabelsToTag.find(label) != m_LabelsToTag.end())
{

if (std::regex_search(dref, m_ipcl_labels))
{
m_DataRefs[dref] = DataRef(value, std::chrono::steady_clock::now());
}
if (std::regex_search(label, m_IpclLabels)) m_DataRefs[m_LabelsToTag[label]] = DataRef(value, std::chrono::steady_clock::now());

else
{
if (m_Writer.IsCockpitFree)
{
m_Writer.IsCockpitFree = false;
m_Writer.Topic = topic;
setDataRef(dref, value, response);
setDataRef(m_LabelsToTag[label], value, response);
}
else if (m_Writer.Topic == topic) setDataRef(dref, value, response);
else if (m_Writer.Topic == topic) setDataRef(m_LabelsToTag[label], value, response);
else response = "Error: Cockpit is already in use! Please wait for termination of the current writer";
}

}
else response = "Error: Server is currently not subscribed to " + dref;
else response = "Error: Server is currently not subscribed to " + label;

m_Publishers[publisher_index].send(zmq::buffer(topic), zmq::send_flags::sndmore);
m_Publishers[publisher_index].send(zmq::buffer(response));
Expand All @@ -122,10 +122,7 @@ void ClientManager::attachToClient(std::string topic, size_t publisher_index, si

if (command == "command")
{
if (!std::regex_search(dref, m_ipcl_labels))
{
m_XPlaneClient->sendCommand(dref);
}
if (!std::regex_search(label, m_IpclLabels)) m_XPlaneClient->sendCommand(m_LabelsToTag[label]);

m_Publishers[publisher_index].send(zmq::buffer(topic), zmq::send_flags::sndmore);
m_Publishers[publisher_index].send(zmq::buffer("Received"));
Expand Down Expand Up @@ -165,8 +162,21 @@ void ClientManager::listenForClients()
LOG_INFO("Connect to server by assigning client's publisher port to: {0}", sport);
LOG_INFO("Connect to server by assigning client's subscriber port to: {0}", pport);

for (auto const& [label, tag] : m_LabelsToTag) m_DataRefLogger << label << ", ";
m_DataRefLogger << std::endl;

std::chrono::steady_clock::time_point time = std::chrono::steady_clock::now();
while (m_Running)
{
// Log Data
std::chrono::seconds secondsElasped = std::chrono::duration_cast<std::chrono::seconds>(std::chrono::steady_clock::now() - time);
if (secondsElasped.count() > (long long)m_LoggingFrequency)
{
time = std::chrono::steady_clock::now();
for (auto const& [label, tag] : m_LabelsToTag) m_DataRefLogger << getDataRef(label).Value << ", ";
m_DataRefLogger << std::endl;
}

// Remove topic
// Unbind and diconnect sockets used to communicate to disconnected clients
std::unique_lock lock(m_Mutex);
Expand Down Expand Up @@ -216,7 +226,7 @@ void ClientManager::listenForClients()
}

// Prepare our context and the ClientManager
ClientManager::ClientManager() : m_ClientTerminated(false), m_PortManager(s_StaringPort, 20), m_Context(1)
ClientManager::ClientManager() : m_ClientTerminated(false), m_PortManager(s_StaringPort, 20), m_Context(1), m_DataRefLogger("data.log")
{
LOG_INFO("Initializing Client Manager");
}
Expand All @@ -243,7 +253,7 @@ void ClientManager::run()
LOG_INFO("Found server {0}:{1}", m_Host, m_Port);

// Definitions
std::string dataRefsFileName = "Subscriptions.txt";
std::string dataRefsFileName = "Subscriptions.yaml";
std::unordered_map<std::string, int> dataRefsMap;

// Init the Xplane UDP Client
Expand All @@ -258,13 +268,13 @@ void ClientManager::run()
// Read in the dataref Values
int result = readDataRefsFromFile(dataRefsFileName, dataRefsMap);
if (result != 0) LOG_ERROR("Subscriptions.txt missing or unable to open file");
m_ipcl_labels.assign("ipcl/");
m_IpclLabels.assign("ipcl/");

// Create subscriptions
for (auto const& [key, val] : dataRefsMap)
{
LOG_INFO("Creating subscription for {0} with min frequency of {1}", key, val);
if (!std::regex_search(key, m_ipcl_labels))
if (!std::regex_search(key, m_IpclLabels))
{
m_XPlaneClient->subscribeDataRef(key, val);
}
Expand All @@ -277,6 +287,7 @@ void ClientManager::run()

bool ClientManager::terminate()
{
m_DataRefLogger.close();
for (size_t i = 0; i < m_Publishers.size(); ++i) unbind(i);
for (size_t i = 0; i < m_Subscribers.size(); ++i) disconnect(i);

Expand Down Expand Up @@ -360,35 +371,19 @@ void ClientManager::disconnect(size_t subscriber_index)
m_UnusedSubscribers.emplace_back(subscriber_index);
}


int ClientManager::readDataRefsFromFile(const std::string& fileName, std::unordered_map<std::string, int>& map)
{

std::string line;
std::string segment;
std::vector<std::string> seglist;

std::ifstream myfile(fileName);
if (myfile.is_open())
YAML::Node subscriptions = YAML::LoadFile(fileName);
for (YAML::const_iterator it = subscriptions.begin(); it != subscriptions.end(); ++it)
{
while (getline(myfile, line))
{
if (line[0] == '#') // Enable comments in the subscriptions.txt file
{
continue;
}
std::stringstream ssline(line);
while (getline(ssline, segment, ';')) seglist.push_back(segment);
std::string label = it->first.as<std::string>();
std::string tag = it->second["tag"].as<std::string>();
int frequency = it->second["frequency"].as<int>();
LOG_INFO("Label: {0}, Tag: {1}, Frequency: {2}", label, tag, frequency);

map[seglist[0]] = std::stoi(seglist[1]);
seglist.clear();
}
myfile.close();
}
else
{
LOG_ERROR("Unable to open file");
return 1;
m_LabelsToTag[label] = tag;

map[tag] = frequency;
}

return 0;
Expand Down
7 changes: 6 additions & 1 deletion libXplane-udp-client/src/ClientManager.h
Original file line number Diff line number Diff line change
Expand Up @@ -45,6 +45,7 @@ class ClientManager
DataRef(const std::string& value, const std::chrono::steady_clock::time_point& lastUpdateTime) : Value(value), LastUpdateTime(lastUpdateTime) { }
};

std::unordered_map<std::string, std::string> m_LabelsToTag;
std::unordered_map<std::string, DataRef> m_DataRefs;

XPlaneUDPClient* m_XPlaneClient = nullptr;
Expand Down Expand Up @@ -73,7 +74,7 @@ class ClientManager

const std::string m_Address = "tcp://127.0.0.1:";

std::regex m_ipcl_labels;
std::regex m_IpclLabels;

static constexpr unsigned int s_StaringPort = 5555;

Expand All @@ -88,6 +89,9 @@ class ClientManager

std::stack<Client> m_ClientsToRemove;

unsigned int m_LoggingFrequency = 10;
std::ofstream m_DataRefLogger;

public:
ClientManager();
~ClientManager();
Expand All @@ -104,6 +108,7 @@ class ClientManager
void receiverCallbackString(std::string dataref, std::string value);
void receiverBeaconCallback(XPlaneBeaconListener::XPlaneServer server, bool exists);

inline const DataRef& getDataRef(const std::string& label) { return m_DataRefs[m_LabelsToTag[label]]; }
void setDataRef(const std::string& dataref, const std::string& value, std::string& response);
void terminateWriter(const std::string& topic);
int readDataRefsFromFile(const std::string& fileName, std::unordered_map<std::string, int>& map);
Expand Down
17 changes: 17 additions & 0 deletions libXplane-udp-client/vendor/yaml-cpp/include/yaml-cpp/anchor.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,17 @@
#ifndef ANCHOR_H_62B23520_7C8E_11DE_8A39_0800200C9A66
#define ANCHOR_H_62B23520_7C8E_11DE_8A39_0800200C9A66

#if defined(_MSC_VER) || \
(defined(__GNUC__) && (__GNUC__ == 3 && __GNUC_MINOR__ >= 4) || \
(__GNUC__ >= 4)) // GCC supports "pragma once" correctly since 3.4
#pragma once
#endif

#include <cstddef>

namespace YAML {
using anchor_t = std::size_t;
const anchor_t NullAnchor = 0;
}

#endif // ANCHOR_H_62B23520_7C8E_11DE_8A39_0800200C9A66
Loading

0 comments on commit f070dda

Please sign in to comment.