JSBSim Flight Dynamics Model  1.0 (02 March 2017)
An Open Source Flight Dynamics and Control Software Library in C++
FGUDPInputSocket.cpp
1 /*%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
2 
3  Module: FGUDPInputSocket.cpp
4  Author: Dave Culp
5  Date started: 02/19/15
6  Purpose: Manage input of data from a UDP socket
7  Called by: FGInput
8 
9  ------------- Copyright (C) 2015 Dave Culp --------------
10 
11  This program is free software; you can redistribute it and/or modify it under
12  the terms of the GNU Lesser General Public License as published by the Free Software
13  Foundation; either version 2 of the License, or (at your option) any later
14  version.
15 
16  This program is distributed in the hope that it will be useful, but WITHOUT
17  ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
18  FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License for more
19  details.
20 
21  You should have received a copy of the GNU Lesser General Public License along with
22  this program; if not, write to the Free Software Foundation, Inc., 59 Temple
23  Place - Suite 330, Boston, MA 02111-1307, USA.
24 
25  Further information about the GNU Lesser General Public License can also be found on
26  the world wide web at http://www.gnu.org.
27 
28 FUNCTIONAL DESCRIPTION
29 --------------------------------------------------------------------------------
30 This class establishes a UDP socket and reads data from it.
31 
32 HISTORY
33 --------------------------------------------------------------------------------
34 02/19/15 DC Created
35 
36 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
37 INCLUDES
38 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%*/
39 
40 #include <cstring>
41 #include <cstdlib>
42 #include <sstream>
43 
44 #include "FGUDPInputSocket.h"
45 #include "FGFDMExec.h"
46 #include "input_output/FGXMLElement.h"
47 
48 using namespace std;
49 
50 namespace JSBSim {
51 
52 IDENT(IdSrc,"$Id");
53 IDENT(IdHdr,ID_UDPINPUTSOCKET);
54 
55 /*%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
56 CLASS IMPLEMENTATION
57 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%*/
58 
59 FGUDPInputSocket::FGUDPInputSocket(FGFDMExec* fdmex) :
60  FGInputType(fdmex),
61  socket(0)
62 {
63  rate = 20;
64  SockPort = 5139;
65  oldTimeStamp = 0.0;
66 }
67 
68 //%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
69 
71 {
72  delete socket;
73 }
74 
75 //%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
76 
78 {
79  if (!FGInputType::Load(el))
80  return false;
81 
82  rate = atoi(el->GetAttributeValue("rate").c_str());
83  SetRate(0.5 + 1.0/(FDMExec->GetDeltaT()*rate));
84 
85  SockPort = atoi(el->GetAttributeValue("port").c_str());
86  if (SockPort == 0) {
87  cerr << endl << "No port assigned in input element" << endl;
88  return false;
89  }
90 
91  Element *property_element = el->FindElement("property");
92 
93  while (property_element) {
94  string property_str = property_element->GetDataLine();
95  FGPropertyNode* node = PropertyManager->GetNode(property_str);
96  if (!node) {
97  cerr << fgred << highint << endl << " No property by the name "
98  << property_str << " can be found." << reset << endl;
99  } else {
100  InputProperties.push_back(node);
101  }
102  property_element = el->FindNextElement("property");
103  }
104 
105  return true;
106 }
107 
108 //%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
109 
111 {
112  if (FGInputType::InitModel()) {
113  delete socket;
114  socket = new FGfdmSocket(SockPort, FGfdmSocket::ptUDP, FGfdmSocket::dIN);
115 
116  if (socket == 0) return false;
117  cout << "UDP input socket established on port " << SockPort << endl;
118  return true;
119  }
120 
121  return false;
122 }
123 
124 //%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
125 
126 void FGUDPInputSocket::Read(bool Holding)
127 {
128 
129  if (socket == 0) return;
130 
131  data = socket->Receive();
132 
133  if (data.size() > 0) {
134 
135  vector<string> tokens;
136  stringstream ss(data);
137  string temp;
138  while (getline(ss, temp, ',')) {
139  tokens.push_back(temp);
140  }
141 
142  vector<double> values;
143 
144  for (unsigned int i=0; i<tokens.size(); i++) {
145  values.push_back( atof(tokens[i].c_str()) );
146  }
147 
148  if (values[0] < oldTimeStamp) {
149  return;
150  } else {
151  oldTimeStamp = values[0];
152  }
153 
154  // the zeroeth value is the time stamp
155  if ((values.size() - 1) != InputProperties.size()) {
156  cerr << endl << "Mismatch between UDP input property and value counts." << endl;
157  return;
158  }
159 
160  for (unsigned int i=1; i<values.size(); i++) {
161  InputProperties[i-1]->setDoubleValue(values[i]);
162  }
163 
164  }
165 
166 }
167 
168 }
bool InitModel(void)
Initializes the instance.
std::string GetAttributeValue(const std::string &key)
Retrieves an attribute.
void Read(bool Holding)
Reads the socket and updates properties accordingly.
virtual bool Load(Element *el)
Init the input directives from an XML file (implement the FGModel interface).
Definition: FGInputType.cpp:81
Class wrapper for property handling.
static char reset[5]
resets text properties
Definition: FGJSBBase.h:131
STL namespace.
Element * FindElement(const std::string &el="")
Searches for a specified element.
bool Load(Element *el)
Reads the property names from an XML file.
static char fgred[6]
red text
Definition: FGJSBBase.h:141
Abstract class to provide functions generic to all the input directives.
Definition: FGInputType.h:79
void SetRate(unsigned int tt)
Set the ouput rate for the model in frames.
Definition: FGModel.h:98
std::string GetDataLine(unsigned int i=0)
Gets a line of data belonging to an element.
Element * FindNextElement(const std::string &el="")
Searches for the next element as specified.
static char highint[5]
highlights text
Definition: FGJSBBase.h:125
double GetDeltaT(void) const
Returns the simulation delta T.
Definition: FGFDMExec.h:536
virtual bool InitModel(void)
Init the input model according to its configitation.
Definition: FGInputType.cpp:97
Encapsulates the JSBSim simulation executive.
Definition: FGFDMExec.h:189
Encapsulates an object that enables JSBSim to communicate via socket (input and/or output)...
Definition: FGfdmSocket.h:89