/*%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% Module: FGOutput.cpp Author: Jon Berndt Date started: 12/02/98 Purpose: Manage output of sim parameters to file or stdout Called by: FGSimExec ------------- Copyright (C) 1999 Jon S. Berndt (jsb@hal-pc.org) ------------- This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 2 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. Further information about the GNU General Public License can also be found on the world wide web at http://www.gnu.org. FUNCTIONAL DESCRIPTION -------------------------------------------------------------------------------- This is the place where you create output routines to dump data for perusal later. HISTORY -------------------------------------------------------------------------------- 12/02/98 JSB Created %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% INCLUDES %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%*/ #include "FGOutput.h" #include "FGState.h" #include "FGFDMExec.h" #include "FGAtmosphere.h" #include "FGFCS.h" #include "FGAerodynamics.h" #include "FGGroundReactions.h" #include "FGAircraft.h" #include "FGMassBalance.h" #include "FGPropagate.h" #include "FGAuxiliary.h" #include "FGInertial.h" #include namespace JSBSim { static const char *IdSrc = "$Id$"; static const char *IdHdr = ID_OUTPUT; /*%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% CLASS IMPLEMENTATION %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%*/ FGOutput::FGOutput(FGFDMExec* fdmex) : FGModel(fdmex) { Name = "FGOutput"; sFirstPass = dFirstPass = true; socket = 0; Type = otNone; Filename = ""; SubSystems = 0; enabled = true; outputInFileName = ""; Debug(0); } //%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% FGOutput::~FGOutput() { if (socket) delete socket; for (unsigned int i=0; iGetCoefficientStrings(); if (scratch.length() != 0) outstream << ", " << scratch; } if (SubSystems & ssFCS) { scratch = FCS->GetComponentStrings(); if (scratch.length() != 0) outstream << ", " << scratch; } if (SubSystems & ssGroundReactions) { outstream << ", "; outstream << GroundReactions->GetGroundReactionStrings(); } if (SubSystems & ssPropulsion && Propulsion->GetNumEngines() > 0) { outstream << ", "; outstream << Propulsion->GetPropulsionStrings(); } if (OutputProperties.size() > 0) { for (unsigned int i=0;iGetName(); } } outstream << endl; dFirstPass = false; } outstream << State->Getsim_time(); if (SubSystems & ssSimulation) { } if (SubSystems & ssAerosurfaces) { outstream << ", "; outstream << FCS->GetDaCmd() << ", "; outstream << FCS->GetDeCmd() << ", "; outstream << FCS->GetDrCmd() << ", "; outstream << FCS->GetDfCmd() << ", "; outstream << FCS->GetDaLPos() << ", "; outstream << FCS->GetDaRPos() << ", "; outstream << FCS->GetDePos() << ", "; outstream << FCS->GetDrPos() << ", "; outstream << FCS->GetDfPos(); } if (SubSystems & ssRates) { outstream << ", "; outstream << Propagate->GetPQR() << ", "; outstream << Propagate->GetPQRdot(); } if (SubSystems & ssVelocities) { outstream << ", "; outstream << Auxiliary->Getqbar() << ", "; outstream << setprecision(12) << Auxiliary->GetVt() << ", "; outstream << setprecision(12) << Propagate->GetUVW() << ", "; outstream << Auxiliary->GetAeroUVW() << ", "; outstream << Propagate->GetVel(); } if (SubSystems & ssForces) { outstream << ", "; outstream << Aerodynamics->GetvFs() << ", "; outstream << Aerodynamics->GetLoD() << ", "; outstream << Aircraft->GetForces(); } if (SubSystems & ssMoments) { outstream << ", "; outstream << Aircraft->GetMoments(); } if (SubSystems & ssAtmosphere) { outstream << ", "; outstream << Atmosphere->GetDensity() << ", "; outstream << Atmosphere->GetWindNED(); } if (SubSystems & ssMassProps) { outstream << ", "; outstream << MassBalance->GetJ() << ", "; outstream << MassBalance->GetMass() << ", "; outstream << MassBalance->GetXYZcg(); } if (SubSystems & ssPropagate) { outstream << ", "; outstream << Propagate->Geth() << ", "; outstream << Propagate->GetEuler() << ", "; outstream << Auxiliary->Getalpha(inDegrees) << ", "; outstream << Auxiliary->Getbeta(inDegrees) << ", "; outstream << Propagate->GetLocation().GetLatitudeDeg() << ", "; outstream << Propagate->GetLocation().GetLongitudeDeg() << ", "; outstream << Propagate->GetDistanceAGL() << ", "; outstream << Propagate->GetRunwayRadius(); } if (SubSystems & ssCoefficients) { scratch = Aerodynamics->GetCoefficientValues(); if (scratch.length() != 0) outstream << ", " << scratch; } if (SubSystems & ssFCS) { scratch = FCS->GetComponentValues(); if (scratch.length() != 0) outstream << ", " << scratch; } if (SubSystems & ssGroundReactions) { outstream << ", "; outstream << GroundReactions->GetGroundReactionValues(); } if (SubSystems & ssPropulsion && Propulsion->GetNumEngines() > 0) { outstream << ", "; outstream << Propulsion->GetPropulsionValues(); } for (unsigned int i=0;igetDoubleValue(); } outstream << endl; outstream.flush(); } //%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% void FGOutput::SocketOutput(void) { string asciiData; if (socket == NULL) return; if (!socket->GetConnectStatus()) return; socket->Clear(); if (sFirstPass) { socket->Append(""); socket->Append("Time"); socket->Append("Altitude"); socket->Append("Phi"); socket->Append("Tht"); socket->Append("Psi"); socket->Append("Rho"); socket->Append("Vtotal"); socket->Append("UBody"); socket->Append("VBody"); socket->Append("WBody"); socket->Append("UAero"); socket->Append("VAero"); socket->Append("WAero"); socket->Append("Vn"); socket->Append("Ve"); socket->Append("Vd"); socket->Append("Udot"); socket->Append("Vdot"); socket->Append("Wdot"); socket->Append("P"); socket->Append("Q"); socket->Append("R"); socket->Append("PDot"); socket->Append("QDot"); socket->Append("RDot"); socket->Append("Fx"); socket->Append("Fy"); socket->Append("Fz"); socket->Append("Latitude (Deg)"); socket->Append("Longitude (Deg)"); socket->Append("QBar"); socket->Append("Alpha"); socket->Append("L"); socket->Append("M"); socket->Append("N"); socket->Append("Throttle Position"); socket->Append("Left Aileron Position"); socket->Append("Right Aileron Position"); socket->Append("Elevator Position"); socket->Append("Rudder Position"); sFirstPass = false; socket->Send(); } socket->Clear(); socket->Append(State->Getsim_time()); socket->Append(Propagate->Geth()); socket->Append(Propagate->Getphi()); socket->Append(Propagate->Gettht()); socket->Append(Propagate->Getpsi()); socket->Append(Atmosphere->GetDensity()); socket->Append(Auxiliary->GetVt()); socket->Append(Propagate->GetUVW(eU)); socket->Append(Propagate->GetUVW(eV)); socket->Append(Propagate->GetUVW(eW)); socket->Append(Auxiliary->GetAeroUVW(eU)); socket->Append(Auxiliary->GetAeroUVW(eV)); socket->Append(Auxiliary->GetAeroUVW(eW)); socket->Append(Propagate->GetVel(eNorth)); socket->Append(Propagate->GetVel(eEast)); socket->Append(Propagate->GetVel(eDown)); socket->Append(Propagate->GetUVWdot(eU)); socket->Append(Propagate->GetUVWdot(eV)); socket->Append(Propagate->GetUVWdot(eW)); socket->Append(Propagate->GetPQR(eP)); socket->Append(Propagate->GetPQR(eQ)); socket->Append(Propagate->GetPQR(eR)); socket->Append(Propagate->GetPQRdot(eP)); socket->Append(Propagate->GetPQRdot(eQ)); socket->Append(Propagate->GetPQRdot(eR)); socket->Append(Aircraft->GetForces(eX)); socket->Append(Aircraft->GetForces(eY)); socket->Append(Aircraft->GetForces(eZ)); socket->Append(Propagate->GetLocation().GetLatitudeDeg()); socket->Append(Propagate->GetLocation().GetLongitudeDeg()); socket->Append(Auxiliary->Getqbar()); socket->Append(Auxiliary->Getalpha(inDegrees)); socket->Append(Aircraft->GetMoments(eL)); socket->Append(Aircraft->GetMoments(eM)); socket->Append(Aircraft->GetMoments(eN)); socket->Append(FCS->GetThrottlePos(0)); socket->Append(FCS->GetDaLPos()); socket->Append(FCS->GetDaRPos()); socket->Append(FCS->GetDePos()); socket->Append(FCS->GetDrPos()); socket->Send(); } //%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% void FGOutput::SocketStatusOutput(string out_str) { string asciiData; if (socket == NULL) return; socket->Clear(); asciiData = string("") + out_str; socket->Append(asciiData.c_str()); socket->Send(); } //%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% bool FGOutput::Load(FGConfigFile* AC_cfg) { string token="", parameter="", separator=""; string name="", fname=""; int OutRate = 0; FGConfigFile* Output_cfg; string property; unsigned int port; # ifndef macintosh separator = "/"; # else separator = ";"; # endif name = AC_cfg->GetValue("NAME"); fname = AC_cfg->GetValue("FILE"); token = AC_cfg->GetValue("TYPE"); port = atoi(AC_cfg->GetValue("PORT").c_str()); Output->SetType(token); if (token == "SOCKET") { socket = new FGfdmSocket(name,port); } if (!fname.empty()) { outputInFileName = FDMExec->GetAircraftPath() + separator + FDMExec->GetModelName() + separator + fname + ".xml"; Output_cfg = new FGConfigFile(outputInFileName); if (!Output_cfg->IsOpen()) { cerr << "Could not open file: " << outputInFileName << endl; return false; } } else { Output_cfg = AC_cfg; } Output->SetFilename(name); while ((token = Output_cfg->GetValue()) != string("/OUTPUT")) { *Output_cfg >> parameter; if (parameter == "RATE_IN_HZ") { *Output_cfg >> OutRate; } if (parameter == "SIMULATION") { *Output_cfg >> parameter; if (parameter == "ON") SubSystems += ssSimulation; } if (parameter == "AEROSURFACES") { *Output_cfg >> parameter; if (parameter == "ON") SubSystems += ssAerosurfaces; } if (parameter == "RATES") { *Output_cfg >> parameter; if (parameter == "ON") SubSystems += ssRates; } if (parameter == "VELOCITIES") { *Output_cfg >> parameter; if (parameter == "ON") SubSystems += ssVelocities; } if (parameter == "FORCES") { *Output_cfg >> parameter; if (parameter == "ON") SubSystems += ssForces; } if (parameter == "MOMENTS") { *Output_cfg >> parameter; if (parameter == "ON") SubSystems += ssMoments; } if (parameter == "ATMOSPHERE") { *Output_cfg >> parameter; if (parameter == "ON") SubSystems += ssAtmosphere; } if (parameter == "MASSPROPS") { *Output_cfg >> parameter; if (parameter == "ON") SubSystems += ssMassProps; } if (parameter == "POSITION") { *Output_cfg >> parameter; if (parameter == "ON") SubSystems += ssPropagate; } if (parameter == "COEFFICIENTS") { *Output_cfg >> parameter; if (parameter == "ON") SubSystems += ssCoefficients; } if (parameter == "GROUND_REACTIONS") { *Output_cfg >> parameter; if (parameter == "ON") SubSystems += ssGroundReactions; } if (parameter == "FCS") { *Output_cfg >> parameter; if (parameter == "ON") SubSystems += ssFCS; } if (parameter == "PROPULSION") { *Output_cfg >> parameter; if (parameter == "ON") SubSystems += ssPropulsion; } if (parameter == "PROPERTY") { *Output_cfg >> property; OutputProperties.push_back(PropertyManager->GetNode(property)); } if (parameter == "EOF") break; } OutRate = OutRate>120?120:(OutRate<0?0:OutRate); rate = (int)(0.5 + 1.0/(State->Getdt()*OutRate)); Debug(2); return true; } //%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% // The bitmasked value choices are as follows: // unset: In this case (the default) JSBSim would only print // out the normally expected messages, essentially echoing // the config files as they are read. If the environment // variable is not set, debug_lvl is set to 1 internally // 0: This requests JSBSim not to output any messages // whatsoever. // 1: This value explicity requests the normal JSBSim // startup messages // 2: This value asks for a message to be printed out when // a class is instantiated // 4: When this value is set, a message is displayed when a // FGModel object executes its Run() method // 8: When this value is set, various runtime state variables // are printed out periodically // 16: When set various parameters are sanity checked and // a message is printed out when they go out of bounds void FGOutput::Debug(int from) { string scratch=""; if (debug_lvl <= 0) return; if (debug_lvl & 1) { // Standard console startup message output if (from == 0) { // Constructor } if (from == 2) { if (outputInFileName.empty()) cout << " " << "Output parameters read inline" << endl; else cout << " Output parameters read from file: " << outputInFileName << endl; if (Filename == "cout" || Filename == "COUT") { scratch = " Log output goes to screen console"; } else if (!Filename.empty()) { scratch = " Log output goes to file: " + Filename; } switch (Type) { case otCSV: cout << scratch << " in CSV format output at rate " << 120/rate << " Hz" << endl; break; case otNone: cout << " No log output" << endl; break; } if (SubSystems & ssSimulation) cout << " Simulation parameters logged" << endl; if (SubSystems & ssAerosurfaces) cout << " Aerosurface parameters logged" << endl; if (SubSystems & ssRates) cout << " Rate parameters logged" << endl; if (SubSystems & ssVelocities) cout << " Velocity parameters logged" << endl; if (SubSystems & ssForces) cout << " Force parameters logged" << endl; if (SubSystems & ssMoments) cout << " Moments parameters logged" << endl; if (SubSystems & ssAtmosphere) cout << " Atmosphere parameters logged" << endl; if (SubSystems & ssMassProps) cout << " Mass parameters logged" << endl; if (SubSystems & ssCoefficients) cout << " Coefficient parameters logged" << endl; if (SubSystems & ssPropagate) cout << " Propagate parameters logged" << endl; if (SubSystems & ssGroundReactions) cout << " Ground parameters logged" << endl; if (SubSystems & ssFCS) cout << " FCS parameters logged" << endl; if (SubSystems & ssPropulsion) cout << " Propulsion parameters logged" << endl; if (OutputProperties.size() > 0) cout << " Properties logged:" << endl; for (unsigned int i=0;iGetName() << endl; } } } if (debug_lvl & 2 ) { // Instantiation/Destruction notification if (from == 0) cout << "Instantiated: FGOutput" << endl; if (from == 1) cout << "Destroyed: FGOutput" << endl; } if (debug_lvl & 4 ) { // Run() method entry print for FGModel-derived objects } if (debug_lvl & 8 ) { // Runtime state variables } if (debug_lvl & 16) { // Sanity checking } if (debug_lvl & 64) { if (from == 0) { // Constructor cout << IdSrc << endl; cout << IdHdr << endl; } } } }