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