]> git.mxchange.org Git - flightgear.git/blob - src/FDM/JSBSim/input_output/FGOutputTextFile.cpp
Fix for bug 1304 - crash loading XML route
[flightgear.git] / src / FDM / JSBSim / input_output / FGOutputTextFile.cpp
1 /*%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
2
3  Module:       FGOutputTextFile.cpp
4  Author:       Bertrand Coconnier
5  Date started: 09/17/11
6  Purpose:      Manage output of sim parameters to a text file
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/17/11   BC    Created
36
37 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
38 INCLUDES
39 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%*/
40
41 #include <cstring>
42 #include <cstdlib>
43 #include <iomanip>
44 #include <sstream>
45
46 #include "FGOutputTextFile.h"
47 #include "FGFDMExec.h"
48 #include "models/FGAerodynamics.h"
49 #include "models/FGAccelerations.h"
50 #include "models/FGAircraft.h"
51 #include "models/FGAtmosphere.h"
52 #include "models/FGAuxiliary.h"
53 #include "models/FGPropulsion.h"
54 #include "models/FGMassBalance.h"
55 #include "models/FGPropagate.h"
56 #include "models/FGGroundReactions.h"
57 #include "models/FGExternalReactions.h"
58 #include "models/FGBuoyantForces.h"
59 #include "models/FGFCS.h"
60 #include "models/atmosphere/FGWinds.h"
61 #include "input_output/FGXMLElement.h"
62
63 using namespace std;
64
65 namespace JSBSim {
66
67 IDENT(IdSrc,"$Id: FGOutputTextFile.cpp,v 1.10 2014/01/13 10:46:00 ehofman Exp $");
68 IDENT(IdHdr,ID_OUTPUTTEXTFILE);
69
70 /*%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
71 CLASS IMPLEMENTATION
72 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%*/
73
74 bool FGOutputTextFile::Load(Element* el)
75 {
76   if(!FGOutputFile::Load(el))
77     return false;
78
79 //  PreLoad(el, PropertyManager);
80
81   string type = el->GetAttributeValue("type");
82   string delim;
83   if (type == "TABULAR") {
84     delim = "\t";
85   } else {
86     delim = ",";
87   }
88
89   SetDelimiter(delim);
90
91   return true;
92 }
93
94 //%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
95
96 bool FGOutputTextFile::OpenFile(void)
97 {
98   datafile.clear();
99   datafile.open(Filename.c_str());
100   if (!datafile) {
101     cerr << endl << fgred << highint << "ERROR: unable to open the file "
102          << reset << Filename.c_str() << endl
103          << fgred << highint << "       => Output to this file is disabled."
104          << reset << endl << endl;
105     Disable();
106     return false;
107   }
108
109   string scratch = "";
110   streambuf* buffer = datafile.rdbuf();
111   ostream outstream(buffer);
112
113   outstream.precision(10);
114
115   outstream << "Time";
116   if (SubSystems & ssSimulation) {
117     // Nothing here, yet
118   }
119   if (SubSystems & ssAerosurfaces) {
120     outstream << delimeter;
121     outstream << "Aileron Command (norm)" + delimeter;
122     outstream << "Elevator Command (norm)" + delimeter;
123     outstream << "Rudder Command (norm)" + delimeter;
124     outstream << "Flap Command (norm)" + delimeter;
125     outstream << "Left Aileron Position (deg)" + delimeter;
126     outstream << "Right Aileron Position (deg)" + delimeter;
127     outstream << "Elevator Position (deg)" + delimeter;
128     outstream << "Rudder Position (deg)" + delimeter;
129     outstream << "Flap Position (deg)";
130   }
131   if (SubSystems & ssRates) {
132     outstream << delimeter;
133     outstream << "P (deg/s)" + delimeter + "Q (deg/s)" + delimeter + "R (deg/s)" + delimeter;
134     outstream << "P dot (deg/s^2)" + delimeter + "Q dot (deg/s^2)" + delimeter + "R dot (deg/s^2)" + delimeter;
135     outstream << "P_{inertial} (deg/s)" + delimeter + "Q_{inertial} (deg/s)" + delimeter + "R_{inertial} (deg/s)";
136   }
137   if (SubSystems & ssVelocities) {
138     outstream << delimeter;
139     outstream << "q bar (psf)" + delimeter;
140     outstream << "Reynolds Number" + delimeter;
141     outstream << "V_{Total} (ft/s)" + delimeter;
142     outstream << "V_{Inertial} (ft/s)" + delimeter;
143     outstream << "UBody" + delimeter + "VBody" + delimeter + "WBody" + delimeter;
144     outstream << "UdotBody" + delimeter + "VdotBody" + delimeter + "WdotBody" + delimeter;
145     outstream << "UdotBody_i" + delimeter + "VdotBody_i" + delimeter + "WdotBody_i" + delimeter;
146     outstream << "BodyAccel_X" + delimeter + "BodyAccel_Y" + delimeter + "BodyAccel_Z" + delimeter;
147     outstream << "Aero V_{X Body} (ft/s)" + delimeter + "Aero V_{Y Body} (ft/s)" + delimeter + "Aero V_{Z Body} (ft/s)" + delimeter;
148     outstream << "V_{X_{inertial}} (ft/s)" + delimeter + "V_{Y_{inertial}} (ft/s)" + delimeter + "V_{Z_{inertial}} (ft/s)" + delimeter;
149     outstream << "V_{X_{ecef}} (ft/s)" + delimeter + "V_{Y_{ecef}} (ft/s)" + delimeter + "V_{Z_{ecef}} (ft/s)" + delimeter;
150     outstream << "V_{North} (ft/s)" + delimeter + "V_{East} (ft/s)" + delimeter + "V_{Down} (ft/s)";
151   }
152   if (SubSystems & ssForces) {
153     outstream << delimeter;
154     outstream << "F_{Drag} (lbs)" + delimeter + "F_{Side} (lbs)" + delimeter + "F_{Lift} (lbs)" + delimeter;
155     outstream << "L/D" + delimeter;
156     outstream << "F_{Aero x} (lbs)" + delimeter + "F_{Aero y} (lbs)" + delimeter + "F_{Aero z} (lbs)" + delimeter;
157     outstream << "F_{Prop x} (lbs)" + delimeter + "F_{Prop y} (lbs)" + delimeter + "F_{Prop z} (lbs)" + delimeter;
158     outstream << "F_{Gear x} (lbs)" + delimeter + "F_{Gear y} (lbs)" + delimeter + "F_{Gear z} (lbs)" + delimeter;
159     outstream << "F_{Ext x} (lbs)" + delimeter + "F_{Ext y} (lbs)" + delimeter + "F_{Ext z} (lbs)" + delimeter;
160     outstream << "F_{Buoyant x} (lbs)" + delimeter + "F_{Buoyant y} (lbs)" + delimeter + "F_{Buoyant z} (lbs)" + delimeter;
161     outstream << "F_{Total x} (lbs)" + delimeter + "F_{Total y} (lbs)" + delimeter + "F_{Total z} (lbs)";
162   }
163   if (SubSystems & ssMoments) {
164     outstream << delimeter;
165     outstream << "L_{Aero} (ft-lbs)" + delimeter + "M_{Aero} (ft-lbs)" + delimeter + "N_{Aero} (ft-lbs)" + delimeter;
166     outstream << "L_{Aero MRC} (ft-lbs)" + delimeter + "M_{Aero MRC} (ft-lbs)" + delimeter + "N_{Aero MRC} (ft-lbs)" + delimeter;
167     outstream << "L_{Prop} (ft-lbs)" + delimeter + "M_{Prop} (ft-lbs)" + delimeter + "N_{Prop} (ft-lbs)" + delimeter;
168     outstream << "L_{Gear} (ft-lbs)" + delimeter + "M_{Gear} (ft-lbs)" + delimeter + "N_{Gear} (ft-lbs)" + delimeter;
169     outstream << "L_{ext} (ft-lbs)" + delimeter + "M_{ext} (ft-lbs)" + delimeter + "N_{ext} (ft-lbs)" + delimeter;
170     outstream << "L_{Buoyant} (ft-lbs)" + delimeter + "M_{Buoyant} (ft-lbs)" + delimeter + "N_{Buoyant} (ft-lbs)" + delimeter;
171     outstream << "L_{Total} (ft-lbs)" + delimeter + "M_{Total} (ft-lbs)" + delimeter + "N_{Total} (ft-lbs)";
172   }
173   if (SubSystems & ssAtmosphere) {
174     outstream << delimeter;
175     outstream << "Rho (slugs/ft^3)" + delimeter;
176     outstream << "Absolute Viscosity" + delimeter;
177     outstream << "Kinematic Viscosity" + delimeter;
178     outstream << "Temperature (R)" + delimeter;
179     outstream << "P_{SL} (psf)" + delimeter;
180     outstream << "P_{Ambient} (psf)" + delimeter;
181     outstream << "Turbulence Magnitude (ft/sec)" + delimeter;
182     outstream << "Turbulence X Direction (rad)" + delimeter + "Turbulence Y Direction (rad)" + delimeter + "Turbulence Z Direction (rad)" + delimeter;
183     outstream << "Wind V_{North} (ft/s)" + delimeter + "Wind V_{East} (ft/s)" + delimeter + "Wind V_{Down} (ft/s)";
184   }
185   if (SubSystems & ssMassProps) {
186     outstream << delimeter;
187     outstream << "I_{xx}" + delimeter;
188     outstream << "I_{xy}" + delimeter;
189     outstream << "I_{xz}" + delimeter;
190     outstream << "I_{yx}" + delimeter;
191     outstream << "I_{yy}" + delimeter;
192     outstream << "I_{yz}" + delimeter;
193     outstream << "I_{zx}" + delimeter;
194     outstream << "I_{zy}" + delimeter;
195     outstream << "I_{zz}" + delimeter;
196     outstream << "Mass" + delimeter;
197     outstream << "X_{cg}" + delimeter + "Y_{cg}" + delimeter + "Z_{cg}";
198   }
199   if (SubSystems & ssPropagate) {
200     outstream << delimeter;
201     outstream << "Altitude ASL (ft)" + delimeter;
202     outstream << "Altitude AGL (ft)" + delimeter;
203     outstream << "Phi (deg)" + delimeter + "Theta (deg)" + delimeter + "Psi (deg)" + delimeter;
204     outstream << "Q(1)_{LOCAL}" + delimeter + "Q(2)_{LOCAL}" + delimeter + "Q(3)_{LOCAL}" + delimeter + "Q(4)_{LOCAL}" +  delimeter;
205     outstream << "Q(1)_{ECEF}" + delimeter + "Q(2)_{ECEF}" + delimeter + "Q(3)_{ECEF}" + delimeter + "Q(4)_{ECEF}" +  delimeter;
206     outstream << "Q(1)_{ECI}" + delimeter + "Q(2)_{ECI}" + delimeter + "Q(3)_{ECI}" + delimeter + "Q(4)_{ECI}" +  delimeter;
207     outstream << "Alpha (deg)" + delimeter;
208     outstream << "Beta (deg)" + delimeter;
209     outstream << "Latitude (deg)" + delimeter;
210     outstream << "Latitude Geodetic (deg)" + delimeter;
211     outstream << "Longitude (deg)" + delimeter;
212     outstream << "X_{ECI} (ft)" + delimeter + "Y_{ECI} (ft)" + delimeter + "Z_{ECI} (ft)" + delimeter;
213     outstream << "X_{ECEF} (ft)" + delimeter + "Y_{ECEF} (ft)" + delimeter + "Z_{ECEF} (ft)" + delimeter;
214     outstream << "Earth Position Angle (deg)" + delimeter;
215     outstream << "Distance AGL (ft)" + delimeter;
216     outstream << "Terrain Elevation (ft)";
217   }
218   if (SubSystems & ssAeroFunctions) {
219     scratch = Aerodynamics->GetAeroFunctionStrings(delimeter);
220     if (scratch.length() != 0) outstream << delimeter << scratch;
221   }
222   if (SubSystems & ssFCS) {
223     scratch = FCS->GetComponentStrings(delimeter);
224     if (scratch.length() != 0) outstream << delimeter << scratch;
225   }
226   if (SubSystems & ssGroundReactions) {
227     outstream << delimeter;
228     outstream << GroundReactions->GetGroundReactionStrings(delimeter);
229   }
230   if (SubSystems & ssPropulsion && Propulsion->GetNumEngines() > 0) {
231     outstream << delimeter;
232     outstream << Propulsion->GetPropulsionStrings(delimeter);
233   }
234   if (OutputProperties.size() > 0) {
235     for (unsigned int i=0;i<OutputProperties.size();i++) {
236       if (OutputCaptions[i].size() > 0) {
237         outstream << delimeter << OutputCaptions[i];
238       } else {
239         outstream << delimeter << OutputProperties[i]->GetFullyQualifiedName();
240       }
241     }
242   }
243
244   if (PreFunctions.size() > 0) {
245     for (unsigned int i=0;i<PreFunctions.size();i++) {
246       outstream << delimeter << PreFunctions[i]->GetName();
247     }
248   }
249
250   outstream << endl;
251   outstream.flush();
252
253   return true;
254 }
255
256 //%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
257
258 void FGOutputTextFile::Print(void)
259 {
260   streambuf* buffer;
261   string scratch = "";
262
263   if (Filename == "COUT" || Filename == "cout") {
264     buffer = cout.rdbuf();
265   } else {
266     buffer = datafile.rdbuf();
267   }
268
269   ostream outstream(buffer);
270
271   outstream.precision(10);
272
273   outstream << FDMExec->GetSimTime();
274   if (SubSystems & ssSimulation) {
275   }
276   if (SubSystems & ssAerosurfaces) {
277     outstream << delimeter;
278     outstream << FCS->GetDaCmd() << delimeter;
279     outstream << FCS->GetDeCmd() << delimeter;
280     outstream << FCS->GetDrCmd() << delimeter;
281     outstream << FCS->GetDfCmd() << delimeter;
282     outstream << FCS->GetDaLPos(ofDeg) << delimeter;
283     outstream << FCS->GetDaRPos(ofDeg) << delimeter;
284     outstream << FCS->GetDePos(ofDeg) << delimeter;
285     outstream << FCS->GetDrPos(ofDeg) << delimeter;
286     outstream << FCS->GetDfPos(ofDeg);
287   }
288   if (SubSystems & ssRates) {
289     outstream << delimeter;
290     outstream << (radtodeg*Propagate->GetPQR()).Dump(delimeter) << delimeter;
291     outstream << (radtodeg*Accelerations->GetPQRdot()).Dump(delimeter) << delimeter;
292     outstream << (radtodeg*Propagate->GetPQRi()).Dump(delimeter);
293   }
294   if (SubSystems & ssVelocities) {
295     outstream << delimeter;
296     outstream << Auxiliary->Getqbar() << delimeter;
297     outstream << Auxiliary->GetReynoldsNumber() << delimeter;
298     outstream << setprecision(12) << Auxiliary->GetVt() << delimeter;
299     outstream << Propagate->GetInertialVelocityMagnitude() << delimeter;
300     outstream << setprecision(12) << Propagate->GetUVW().Dump(delimeter) << delimeter;
301     outstream << setprecision(12) << Accelerations->GetUVWdot().Dump(delimeter) << delimeter;
302     outstream << setprecision(12) << Accelerations->GetUVWidot().Dump(delimeter) << delimeter;
303     outstream << setprecision(12) << Accelerations->GetBodyAccel().Dump(delimeter) << delimeter;
304     outstream << Auxiliary->GetAeroUVW().Dump(delimeter) << delimeter;
305     outstream << Propagate->GetInertialVelocity().Dump(delimeter) << delimeter;
306     outstream << Propagate->GetECEFVelocity().Dump(delimeter) << delimeter;
307     outstream << Propagate->GetVel().Dump(delimeter);
308     outstream.precision(10);
309   }
310   if (SubSystems & ssForces) {
311     outstream << delimeter;
312     outstream << Aerodynamics->GetvFw().Dump(delimeter) << delimeter;
313     outstream << Aerodynamics->GetLoD() << delimeter;
314     outstream << Aerodynamics->GetForces().Dump(delimeter) << delimeter;
315     outstream << Propulsion->GetForces().Dump(delimeter) << delimeter;
316     outstream << GroundReactions->GetForces().Dump(delimeter) << delimeter;
317     outstream << ExternalReactions->GetForces().Dump(delimeter) << delimeter;
318     outstream << BuoyantForces->GetForces().Dump(delimeter) << delimeter;
319     outstream << Aircraft->GetForces().Dump(delimeter);
320   }
321   if (SubSystems & ssMoments) {
322     outstream << delimeter;
323     outstream << Aerodynamics->GetMoments().Dump(delimeter) << delimeter;
324     outstream << Aerodynamics->GetMomentsMRC().Dump(delimeter) << delimeter;
325     outstream << Propulsion->GetMoments().Dump(delimeter) << delimeter;
326     outstream << GroundReactions->GetMoments().Dump(delimeter) << delimeter;
327     outstream << ExternalReactions->GetMoments().Dump(delimeter) << delimeter;
328     outstream << BuoyantForces->GetMoments().Dump(delimeter) << delimeter;
329     outstream << Aircraft->GetMoments().Dump(delimeter);
330   }
331   if (SubSystems & ssAtmosphere) {
332     outstream << delimeter;
333     outstream << Atmosphere->GetDensity() << delimeter;
334     outstream << Atmosphere->GetAbsoluteViscosity() << delimeter;
335     outstream << Atmosphere->GetKinematicViscosity() << delimeter;
336     outstream << Atmosphere->GetTemperature() << delimeter;
337     outstream << Atmosphere->GetPressureSL() << delimeter;
338     outstream << Atmosphere->GetPressure() << delimeter;
339     outstream << Winds->GetTurbMagnitude() << delimeter;
340     outstream << Winds->GetTurbDirection().Dump(delimeter) << delimeter;
341     outstream << Winds->GetTotalWindNED().Dump(delimeter);
342   }
343   if (SubSystems & ssMassProps) {
344     outstream << delimeter;
345     outstream << MassBalance->GetJ().Dump(delimeter) << delimeter;
346     outstream << MassBalance->GetMass() << delimeter;
347     outstream << MassBalance->GetXYZcg().Dump(delimeter);
348   }
349   if (SubSystems & ssPropagate) {
350     outstream.precision(14);
351     outstream << delimeter;
352     outstream << Propagate->GetAltitudeASL() << delimeter;
353     outstream << Propagate->GetDistanceAGL() << delimeter;
354     outstream << (radtodeg*Propagate->GetEuler()).Dump(delimeter) << delimeter;
355     outstream << Propagate->GetQuaternion().Dump(delimeter) << delimeter;
356     FGQuaternion Qec = Propagate->GetQuaternionECEF();
357     outstream << Qec.Dump(delimeter) << delimeter;
358     outstream << Propagate->GetQuaternionECI().Dump(delimeter) << delimeter;
359     outstream << Auxiliary->Getalpha(inDegrees) << delimeter;
360     outstream << Auxiliary->Getbeta(inDegrees) << delimeter;
361     outstream << Propagate->GetLocation().GetLatitudeDeg() << delimeter;
362     outstream << Propagate->GetLocation().GetGeodLatitudeDeg() << delimeter;
363     outstream << Propagate->GetLocation().GetLongitudeDeg() << delimeter;
364     outstream.precision(18);
365     outstream << ((FGColumnVector3)Propagate->GetInertialPosition()).Dump(delimeter) << delimeter;
366     outstream << ((FGColumnVector3)Propagate->GetLocation()).Dump(delimeter) << delimeter;
367     outstream.precision(14);
368     outstream << Propagate->GetEarthPositionAngleDeg() << delimeter;
369     outstream << Propagate->GetDistanceAGL() << delimeter;
370     outstream << Propagate->GetTerrainElevation();
371     outstream.precision(10);
372   }
373   if (SubSystems & ssAeroFunctions) {
374     scratch = Aerodynamics->GetAeroFunctionValues(delimeter);
375     if (scratch.length() != 0) outstream << delimeter << scratch;
376   }
377   if (SubSystems & ssFCS) {
378     scratch = FCS->GetComponentValues(delimeter);
379     if (scratch.length() != 0) outstream << delimeter << scratch;
380   }
381   if (SubSystems & ssGroundReactions) {
382     outstream << delimeter;
383     outstream << GroundReactions->GetGroundReactionValues(delimeter);
384   }
385   if (SubSystems & ssPropulsion && Propulsion->GetNumEngines() > 0) {
386     outstream << delimeter;
387     outstream << Propulsion->GetPropulsionValues(delimeter);
388   }
389
390   outstream.precision(18);
391   for (unsigned int i=0;i<OutputProperties.size();i++) {
392     outstream << delimeter << OutputProperties[i]->getDoubleValue();
393   }
394   for (unsigned int i=0;i<PreFunctions.size();i++) {
395     outstream << delimeter << PreFunctions[i]->getDoubleValue();
396   }
397   outstream.precision(10);
398
399   outstream << endl;
400   outstream.flush();
401 }
402 }