]> git.mxchange.org Git - flightgear.git/blob - src/FDM/JSBSim/input_output/FGOutputSocket.cpp
sync with JSBSim
[flightgear.git] / src / FDM / JSBSim / input_output / FGOutputSocket.cpp
1 /*%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
2
3  Module:       FGOutputSocket.cpp
4  Author:       Bertrand Coconnier
5  Date started: 09/10/11
6  Purpose:      Manage output of sim parameters to a socket
7  Called by:    FGOutput
8
9  ------------- Copyright (C) 2011 Bertrand Coconnier -------------
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 is the place where you create output routines to dump data for perusal
31 later.
32
33 HISTORY
34 --------------------------------------------------------------------------------
35 09/10/11   BC    Created
36
37 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
38 INCLUDES
39 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%*/
40
41 #include <cstring>
42 #include <cstdlib>
43
44 #include "FGOutputSocket.h"
45 #include "FGFDMExec.h"
46 #include "models/FGAerodynamics.h"
47 #include "models/FGAccelerations.h"
48 #include "models/FGAircraft.h"
49 #include "models/FGAtmosphere.h"
50 #include "models/FGAuxiliary.h"
51 #include "models/FGPropulsion.h"
52 #include "models/FGMassBalance.h"
53 #include "models/FGPropagate.h"
54 #include "models/FGGroundReactions.h"
55 #include "models/FGFCS.h"
56 #include "models/atmosphere/FGWinds.h"
57
58 using namespace std;
59
60 namespace JSBSim {
61
62 static const char *IdSrc = "$Id: FGOutputSocket.cpp,v 1.5 2013/01/12 21:14:46 bcoconni Exp $";
63 static const char *IdHdr = ID_OUTPUTSOCKET;
64
65 /*%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
66 CLASS IMPLEMENTATION
67 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%*/
68
69 FGOutputSocket::FGOutputSocket(FGFDMExec* fdmex) :
70   FGOutputType(fdmex),
71   socket(0)
72 {
73 }
74
75 //%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
76
77 FGOutputSocket::~FGOutputSocket()
78 {
79   delete socket;
80 }
81
82 //%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
83
84 void FGOutputSocket::SetOutputName(const string& fname)
85 {
86   // tokenize the output name
87   size_t dot_pos = fname.find(':', 0);
88   size_t slash_pos = fname.find('/', 0);
89   
90   string name = fname.substr(0, dot_pos);
91   
92   string proto = "TCP";
93   if(dot_pos + 1 < slash_pos)
94     proto = fname.substr(dot_pos + 1, slash_pos - dot_pos - 1);
95   
96   string port = "1138";
97   if(slash_pos < string::npos)
98     port = fname.substr(slash_pos + 1, string::npos);
99   
100   // set the model name
101   Name = name + ":" + port + "/" + proto;
102   
103   // set the socket params
104   SockName = name;
105   
106   SockPort = atoi(port.c_str());
107   
108   if (proto == "UDP")
109     SockProtocol = FGfdmSocket::ptUDP;
110   else // Default to TCP
111     SockProtocol = FGfdmSocket::ptTCP;
112 }
113
114 //%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
115
116 bool FGOutputSocket::Load(Element* el)
117 {
118   if (!FGOutputType::Load(el))
119     return false;
120
121   SetOutputName(el->GetAttributeValue("name") + ":" +
122                 el->GetAttributeValue("protocol") + "/" +
123                 el->GetAttributeValue("port"));
124
125   return true;
126 }
127
128 //%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
129
130 bool FGOutputSocket::InitModel(void)
131 {
132   if (FGOutputType::InitModel()) {
133     delete socket;
134     socket = new FGfdmSocket(SockName, SockPort, SockProtocol);
135
136     if (socket == 0) return false;
137     if (!socket->GetConnectStatus()) return false;
138
139     PrintHeaders();
140
141     return true;
142   }
143
144   return false;
145 }
146
147 //%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
148
149 void FGOutputSocket::PrintHeaders(void)
150 {
151   string scratch;
152
153   socket->Clear();
154   socket->Clear("<LABELS>");
155   socket->Append("Time");
156
157   if (SubSystems & ssAerosurfaces) {
158     socket->Append("Aileron Command");
159     socket->Append("Elevator Command");
160     socket->Append("Rudder Command");
161     socket->Append("Flap Command");
162     socket->Append("Left Aileron Position");
163     socket->Append("Right Aileron Position");
164     socket->Append("Elevator Position");
165     socket->Append("Rudder Position");
166     socket->Append("Flap Position");
167   }
168
169   if (SubSystems & ssRates) {
170     socket->Append("P");
171     socket->Append("Q");
172     socket->Append("R");
173     socket->Append("PDot");
174     socket->Append("QDot");
175     socket->Append("RDot");
176   }
177
178   if (SubSystems & ssVelocities) {
179     socket->Append("QBar");
180     socket->Append("Vtotal");
181     socket->Append("UBody");
182     socket->Append("VBody");
183     socket->Append("WBody");
184     socket->Append("UAero");
185     socket->Append("VAero");
186     socket->Append("WAero");
187     socket->Append("Vn");
188     socket->Append("Ve");
189     socket->Append("Vd");
190   }
191
192   if (SubSystems & ssForces) {
193     socket->Append("F_Drag");
194     socket->Append("F_Side");
195     socket->Append("F_Lift");
196     socket->Append("LoD");
197     socket->Append("Fx");
198     socket->Append("Fy");
199     socket->Append("Fz");
200   }
201
202   if (SubSystems & ssMoments) {
203     socket->Append("L");
204     socket->Append("M");
205     socket->Append("N");
206   }
207
208   if (SubSystems & ssAtmosphere) {
209     socket->Append("Rho");
210     socket->Append("SL pressure");
211     socket->Append("Ambient pressure");
212     socket->Append("Turbulence Magnitude");
213     socket->Append("Turbulence Direction X");
214     socket->Append("Turbulence Direction Y");
215     socket->Append("Turbulence Direction Z");
216     socket->Append("NWind");
217     socket->Append("EWind");
218     socket->Append("DWind");
219   }
220
221   if (SubSystems & ssMassProps) {
222     socket->Append("Ixx");
223     socket->Append("Ixy");
224     socket->Append("Ixz");
225     socket->Append("Iyx");
226     socket->Append("Iyy");
227     socket->Append("Iyz");
228     socket->Append("Izx");
229     socket->Append("Izy");
230     socket->Append("Izz");
231     socket->Append("Mass");
232     socket->Append("Xcg");
233     socket->Append("Ycg");
234     socket->Append("Zcg");
235   }
236
237   if (SubSystems & ssPropagate) {
238     socket->Append("Altitude");
239     socket->Append("Phi (deg)");
240     socket->Append("Tht (deg)");
241     socket->Append("Psi (deg)");
242     socket->Append("Alpha (deg)");
243     socket->Append("Beta (deg)");
244     socket->Append("Latitude (deg)");
245     socket->Append("Longitude (deg)");
246   }
247
248   if (SubSystems & ssAeroFunctions) {
249     scratch = Aerodynamics->GetAeroFunctionStrings(",");
250     if (scratch.length() != 0) socket->Append(scratch);
251   }
252
253   if (SubSystems & ssFCS) {
254     scratch = FCS->GetComponentStrings(",");
255     if (scratch.length() != 0) socket->Append(scratch);
256   }
257
258   if (SubSystems & ssGroundReactions)
259     socket->Append(GroundReactions->GetGroundReactionStrings(","));
260
261   if (SubSystems & ssPropulsion && Propulsion->GetNumEngines() > 0)
262     socket->Append(Propulsion->GetPropulsionStrings(","));
263
264   if (OutputProperties.size() > 0) {
265     for (unsigned int i=0;i<OutputProperties.size();i++)
266       if (OutputCaptions[i].size() > 0) {
267         socket->Append(OutputCaptions[i]);
268       } else {
269         socket->Append(OutputProperties[i]->GetPrintableName());
270       }
271   }
272
273   socket->Send();
274 }
275
276 //%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
277
278 void FGOutputSocket::Print(void)
279 {
280   string asciiData, scratch;
281
282   if (socket == 0) return;
283   if (!socket->GetConnectStatus()) return;
284
285   socket->Clear();
286   socket->Append(FDMExec->GetSimTime());
287
288   if (SubSystems & ssAerosurfaces) {
289     socket->Append(FCS->GetDaCmd());
290     socket->Append(FCS->GetDeCmd());
291     socket->Append(FCS->GetDrCmd());
292     socket->Append(FCS->GetDfCmd());
293     socket->Append(FCS->GetDaLPos());
294     socket->Append(FCS->GetDaRPos());
295     socket->Append(FCS->GetDePos());
296     socket->Append(FCS->GetDrPos());
297     socket->Append(FCS->GetDfPos());
298   }
299   if (SubSystems & ssRates) {
300     socket->Append(radtodeg*Propagate->GetPQR(eP));
301     socket->Append(radtodeg*Propagate->GetPQR(eQ));
302     socket->Append(radtodeg*Propagate->GetPQR(eR));
303     socket->Append(radtodeg*Accelerations->GetPQRdot(eP));
304     socket->Append(radtodeg*Accelerations->GetPQRdot(eQ));
305     socket->Append(radtodeg*Accelerations->GetPQRdot(eR));
306   }
307   if (SubSystems & ssVelocities) {
308     socket->Append(Auxiliary->Getqbar());
309     socket->Append(Auxiliary->GetVt());
310     socket->Append(Propagate->GetUVW(eU));
311     socket->Append(Propagate->GetUVW(eV));
312     socket->Append(Propagate->GetUVW(eW));
313     socket->Append(Auxiliary->GetAeroUVW(eU));
314     socket->Append(Auxiliary->GetAeroUVW(eV));
315     socket->Append(Auxiliary->GetAeroUVW(eW));
316     socket->Append(Propagate->GetVel(eNorth));
317     socket->Append(Propagate->GetVel(eEast));
318     socket->Append(Propagate->GetVel(eDown));
319   }
320   if (SubSystems & ssForces) {
321     socket->Append(Aerodynamics->GetvFw()(eDrag));
322     socket->Append(Aerodynamics->GetvFw()(eSide));
323     socket->Append(Aerodynamics->GetvFw()(eLift));
324     socket->Append(Aerodynamics->GetLoD());
325     socket->Append(Aircraft->GetForces(eX));
326     socket->Append(Aircraft->GetForces(eY));
327     socket->Append(Aircraft->GetForces(eZ));
328   }
329   if (SubSystems & ssMoments) {
330     socket->Append(Aircraft->GetMoments(eL));
331     socket->Append(Aircraft->GetMoments(eM));
332     socket->Append(Aircraft->GetMoments(eN));
333   }
334   if (SubSystems & ssAtmosphere) {
335     socket->Append(Atmosphere->GetDensity());
336     socket->Append(Atmosphere->GetPressureSL());
337     socket->Append(Atmosphere->GetPressure());
338     socket->Append(Winds->GetTurbMagnitude());
339     socket->Append(Winds->GetTurbDirection().Dump(","));
340     socket->Append(Winds->GetTotalWindNED().Dump(","));
341   }
342   if (SubSystems & ssMassProps) {
343     socket->Append(MassBalance->GetJ()(1,1));
344     socket->Append(MassBalance->GetJ()(1,2));
345     socket->Append(MassBalance->GetJ()(1,3));
346     socket->Append(MassBalance->GetJ()(2,1));
347     socket->Append(MassBalance->GetJ()(2,2));
348     socket->Append(MassBalance->GetJ()(2,3));
349     socket->Append(MassBalance->GetJ()(3,1));
350     socket->Append(MassBalance->GetJ()(3,2));
351     socket->Append(MassBalance->GetJ()(3,3));
352     socket->Append(MassBalance->GetMass());
353     socket->Append(MassBalance->GetXYZcg()(eX));
354     socket->Append(MassBalance->GetXYZcg()(eY));
355     socket->Append(MassBalance->GetXYZcg()(eZ));
356   }
357   if (SubSystems & ssPropagate) {
358     socket->Append(Propagate->GetAltitudeASL());
359     socket->Append(radtodeg*Propagate->GetEuler(ePhi));
360     socket->Append(radtodeg*Propagate->GetEuler(eTht));
361     socket->Append(radtodeg*Propagate->GetEuler(ePsi));
362     socket->Append(Auxiliary->Getalpha(inDegrees));
363     socket->Append(Auxiliary->Getbeta(inDegrees));
364     socket->Append(Propagate->GetLocation().GetLatitudeDeg());
365     socket->Append(Propagate->GetLocation().GetLongitudeDeg());
366   }
367   if (SubSystems & ssAeroFunctions) {
368     scratch = Aerodynamics->GetAeroFunctionValues(",");
369     if (scratch.length() != 0) socket->Append(scratch);
370   }
371   if (SubSystems & ssFCS) {
372     scratch = FCS->GetComponentValues(",");
373     if (scratch.length() != 0) socket->Append(scratch);
374   }
375   if (SubSystems & ssGroundReactions) {
376     socket->Append(GroundReactions->GetGroundReactionValues(","));
377   }
378   if (SubSystems & ssPropulsion && Propulsion->GetNumEngines() > 0) {
379     socket->Append(Propulsion->GetPropulsionValues(","));
380   }
381
382   for (unsigned int i=0;i<OutputProperties.size();i++) {
383     socket->Append(OutputProperties[i]->getDoubleValue());
384   }
385
386   socket->Send();
387 }
388
389 //%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
390
391 void FGOutputSocket::SocketStatusOutput(const string& out_str)
392 {
393   string asciiData;
394
395   if (socket == 0) return;
396
397   socket->Clear();
398   asciiData = string("<STATUS>") + out_str;
399   socket->Append(asciiData.c_str());
400   socket->Send();
401 }
402 }