X-Git-Url: https://git.mxchange.org/?a=blobdiff_plain;f=src%2FFDM%2FJSBSim%2FFGOutput.cpp;h=b3b3858088f2c6d0986a541acef77d82397ac8e3;hb=b5d116dad7816125dbaf94989aba774349f01017;hp=3d501834a09e19bbbce3b5020b0c1cd9f00cb397;hpb=6eaf06957d9c49a84accf2d52903f38f33aaba48;p=flightgear.git diff --git a/src/FDM/JSBSim/FGOutput.cpp b/src/FDM/JSBSim/FGOutput.cpp index 3d501834a..b3b385808 100644 --- a/src/FDM/JSBSim/FGOutput.cpp +++ b/src/FDM/JSBSim/FGOutput.cpp @@ -1,4 +1,4 @@ -/******************************************************************************* +/*%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% Module: FGOutput.cpp Author: Jon Berndt @@ -28,203 +28,533 @@ FUNCTIONAL DESCRIPTION -------------------------------------------------------------------------------- This is the place where you create output routines to dump data for perusal -later. Some machines may not support the ncurses console output. Borland is one -of those environments which does not, so the ncurses stuff is commented out. +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 "FGTranslation.h" #include "FGRotation.h" #include "FGPosition.h" #include "FGAuxiliary.h" -/******************************************************************************* -************************************ CODE ************************************** -*******************************************************************************/ +static const char *IdSrc = "$Id$"; +static const char *IdHdr = ID_OUTPUT; + +/*%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% +CLASS IMPLEMENTATION +%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%*/ FGOutput::FGOutput(FGFDMExec* fdmex) : FGModel(fdmex) { Name = "FGOutput"; - FirstPass = true; + sFirstPass = dFirstPass = true; + socket = 0; + Type = otNone; + Filename = "JSBSim.out"; + SubSystems = 0; + enabled = true; + + Debug(0); } +//%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% -FGOutput::~FGOutput(void) +FGOutput::~FGOutput() { + if (socket) delete socket; + Debug(1); } +//%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% bool FGOutput::Run(void) { - if (!FGModel::Run()) { - DelimitedOutput("JSBSimData.csv"); - } else { + if (enabled) { + if (!FGModel::Run()) { + + if (Type == otSocket) { + SocketOutput(); + } else if (Type == otCSV) { + DelimitedOutput(Filename); + } else if (Type == otTerminal) { + // Not done yet + } else if (Type == otNone) { + // Do nothing + } else { + // Not a valid type of output + } + return false; + } else { + return true; + } } return false; } +//%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% -void FGOutput::DelimitedOutput(void) +void FGOutput::SetType(string type) { - if (FirstPass) { - cout << "Time,"; - cout << "Altitude,"; - cout << "Phi,"; - cout << "Tht,"; - cout << "Psi,"; - cout << "Rho,"; - cout << "Vtotal,"; - cout << "U,"; - cout << "V,"; - cout << "W,"; - cout << "Vn,"; - cout << "Ve,"; - cout << "Vd,"; - cout << "Udot,"; - cout << "Vdot,"; - cout << "Wdot,"; - cout << "P,"; - cout << "Q,"; - cout << "R,"; - cout << "PDot,"; - cout << "QDot,"; - cout << "RDot,"; - cout << "Fx,"; - cout << "Fy,"; - cout << "Fz,"; - cout << "Latitude,"; - cout << "Longitude,"; - cout << "QBar,"; - cout << "Alpha,"; - cout << "L,"; - cout << "M,"; - cout << "N"; - cout << endl; - FirstPass = false; - } - - cout << State->Getsim_time() << ","; - cout << State->Geth() << ","; - cout << Rotation->Getphi() << ","; - cout << Rotation->Gettht() << ","; - cout << Rotation->Getpsi() << ","; - cout << Atmosphere->GetDensity() << ","; - cout << State->GetVt() << ","; - cout << Translation->GetU() << ","; - cout << Translation->GetV() << ","; - cout << Translation->GetW() << ","; - cout << Position->GetVn() << ","; - cout << Position->GetVe() << ","; - cout << Position->GetVd() << ","; - cout << Translation->GetUdot() << ","; - cout << Translation->GetVdot() << ","; - cout << Translation->GetWdot() << ","; - cout << Rotation->GetP() << ","; - cout << Rotation->GetQ() << ","; - cout << Rotation->GetR() << ","; - cout << Rotation->GetPdot() << ","; - cout << Rotation->GetQdot() << ","; - cout << Rotation->GetRdot() << ","; - cout << Aircraft->GetFx() << ","; - cout << Aircraft->GetFy() << ","; - cout << Aircraft->GetFz() << ","; - cout << State->Getlatitude() << ","; - cout << State->Getlongitude() << ","; - cout << State->Getqbar() << ","; - cout << Translation->Getalpha() << ","; - cout << Aircraft->GetL() << ","; - cout << Aircraft->GetM() << ","; - cout << Aircraft->GetN() << ""; - cout << endl; - + if (type == "CSV") { + Type = otCSV; + } else if (type == "TABULAR") { + Type = otTab; + } else if (type == "SOCKET") { + Type = otSocket; + } else if (type == "TERMINAL") { + Type = otTerminal; + } else if (type != string("NONE")) { + Type = otUnknown; + cerr << "Unknown type of output specified in config file" << endl; + } } +//%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% void FGOutput::DelimitedOutput(string fname) { - if (FirstPass) { + streambuf* buffer; + + if (fname == "COUT" || fname == "cout") { + buffer = cout.rdbuf(); + } else { datafile.open(fname.c_str()); - datafile << "Time,"; - datafile << "Altitude,"; - datafile << "Phi,"; - datafile << "Tht,"; - datafile << "Psi,"; - datafile << "Rho,"; - datafile << "Vtotal,"; - datafile << "U,"; - datafile << "V,"; - datafile << "W,"; - datafile << "Vn,"; - datafile << "Ve,"; - datafile << "Vd,"; - datafile << "Udot,"; - datafile << "Vdot,"; - datafile << "Wdot,"; - datafile << "P,"; - datafile << "Q,"; - datafile << "R,"; - datafile << "PDot,"; - datafile << "QDot,"; - datafile << "RDot,"; - datafile << "Fx,"; - datafile << "Fy,"; - datafile << "Fz,"; - datafile << "Latitude,"; - datafile << "Longitude,"; - datafile << "QBar,"; - datafile << "Alpha,"; - datafile << "L,"; - datafile << "M,"; - datafile << "N"; - datafile << endl; - FirstPass = false; - } - - datafile << State->Getsim_time() << ","; - datafile << State->Geth() << ","; - datafile << Rotation->Getphi() << ","; - datafile << Rotation->Gettht() << ","; - datafile << Rotation->Getpsi() << ","; - datafile << Atmosphere->GetDensity() << ","; - datafile << State->GetVt() << ","; - datafile << Translation->GetU() << ","; - datafile << Translation->GetV() << ","; - datafile << Translation->GetW() << ","; - datafile << Position->GetVn() << ","; - datafile << Position->GetVe() << ","; - datafile << Position->GetVd() << ","; - datafile << Translation->GetUdot() << ","; - datafile << Translation->GetVdot() << ","; - datafile << Translation->GetWdot() << ","; - datafile << Rotation->GetP() << ","; - datafile << Rotation->GetQ() << ","; - datafile << Rotation->GetR() << ","; - datafile << Rotation->GetPdot() << ","; - datafile << Rotation->GetQdot() << ","; - datafile << Rotation->GetRdot() << ","; - datafile << Aircraft->GetFx() << ","; - datafile << Aircraft->GetFy() << ","; - datafile << Aircraft->GetFz() << ","; - datafile << State->Getlatitude() << ","; - datafile << State->Getlongitude() << ","; - datafile << State->Getqbar() << ","; - datafile << Translation->Getalpha() << ","; - datafile << Aircraft->GetL() << ","; - datafile << Aircraft->GetM() << ","; - datafile << Aircraft->GetN() << ""; - datafile << endl; - datafile.flush(); + buffer = datafile.rdbuf(); + } + + ostream outstream(buffer); + + if (dFirstPass) { + outstream << "Time"; + if (SubSystems & ssSimulation) { + // Nothing here, yet + } + if (SubSystems & ssAerosurfaces) { + outstream << ", "; + outstream << "Aileron Cmd, "; + outstream << "Elevator Cmd, "; + outstream << "Rudder Cmd, "; + outstream << "Flap Cmd, "; + outstream << "Left Aileron Pos, "; + outstream << "Right Aileron Pos, "; + outstream << "Elevator Pos, "; + outstream << "Rudder Pos, "; + outstream << "Flap Pos"; + } + if (SubSystems & ssRates) { + outstream << ", "; + outstream << "P, Q, R, "; + outstream << "Pdot, Qdot, Rdot"; + } + if (SubSystems & ssVelocities) { + outstream << ", "; + outstream << "QBar, "; + outstream << "Vtotal, "; + outstream << "UBody, VBody, WBody, "; + outstream << "UAero, VAero, WAero, "; + outstream << "Vn, Ve, Vd"; + } + if (SubSystems & ssForces) { + outstream << ", "; + outstream << "Drag, Side, Lift, "; + outstream << "L/D, "; + outstream << "Xforce, Yforce, Zforce, "; + outstream << "xGravity, yGravity, zGravity, "; + outstream << "xCoriolis, yCoriolis, zCoriolis, "; + outstream << "xCentrifugal, yCentrifugal, zCentrifugal"; + } + if (SubSystems & ssMoments) { + outstream << ", "; + outstream << "L, M, N"; + } + if (SubSystems & ssAtmosphere) { + outstream << ", "; + outstream << "Rho, "; + outstream << "NWind, EWind, DWind"; + } + if (SubSystems & ssMassProps) { + outstream << ", "; + outstream << "Ixx, "; + outstream << "Iyy, "; + outstream << "Izz, "; + outstream << "Ixz, "; + outstream << "Mass, "; + outstream << "Xcg, Ycg, Zcg"; + } + if (SubSystems & ssPosition) { + outstream << ", "; + outstream << "Altitude, "; + outstream << "Phi, Tht, Psi, "; + outstream << "Alpha, "; + outstream << "Beta, "; + outstream << "Latitude, "; + outstream << "Longitude, "; + outstream << "Distance AGL, "; + outstream << "Runway Radius"; + } + if (SubSystems & ssCoefficients) { + outstream << ", "; + outstream << Aerodynamics->GetCoefficientStrings(); + } + if (SubSystems & ssFCS) { + outstream << ", "; + outstream << FCS->GetComponentStrings(); + } + if (SubSystems & ssGroundReactions) { + outstream << ", "; + outstream << GroundReactions->GetGroundReactionStrings(); + } + if (SubSystems & ssPropulsion && Propulsion->GetNumEngines() > 0) { + outstream << ", "; + outstream << Propulsion->GetPropulsionStrings(); + } + + 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 << Rotation->GetPQR() << ", "; + outstream << Rotation->GetPQRdot(); + } + if (SubSystems & ssVelocities) { + outstream << ", "; + outstream << Translation->Getqbar() << ", "; + outstream << Translation->GetVt() << ", "; + outstream << Translation->GetUVW() << ", "; + outstream << Translation->GetAeroUVW() << ", "; + outstream << Position->GetVel(); + } + if (SubSystems & ssForces) { + outstream << ", "; + outstream << Aerodynamics->GetvFs() << ", "; + outstream << Aerodynamics->GetLoD() << ", "; + outstream << Aircraft->GetForces() << ", "; + outstream << Inertial->GetGravity() << ", "; + outstream << Inertial->GetCoriolis() << ", "; + outstream << Inertial->GetCentrifugal(); + } + if (SubSystems & ssMoments) { + outstream << ", "; + outstream << Aircraft->GetMoments(); + } + if (SubSystems & ssAtmosphere) { + outstream << ", "; + outstream << Atmosphere->GetDensity() << ", "; + outstream << Atmosphere->GetWindNED(); + } + if (SubSystems & ssMassProps) { + outstream << ", "; + outstream << MassBalance->GetIxx() << ", "; + outstream << MassBalance->GetIyy() << ", "; + outstream << MassBalance->GetIzz() << ", "; + outstream << MassBalance->GetIxz() << ", "; + outstream << MassBalance->GetMass() << ", "; + outstream << MassBalance->GetXYZcg(); + } + if (SubSystems & ssPosition) { + outstream << ", "; + outstream << Position->Geth() << ", "; + outstream << Rotation->GetEuler() << ", "; + outstream << Translation->Getalpha() << ", "; + outstream << Translation->Getbeta() << ", "; + outstream << Position->GetLatitude() << ", "; + outstream << Position->GetLongitude() << ", "; + outstream << Position->GetDistanceAGL() << ", "; + outstream << Position->GetRunwayRadius(); + } + if (SubSystems & ssCoefficients) { + outstream << ", "; + outstream << Aerodynamics->GetCoefficientValues(); + } + if (SubSystems & ssFCS) { + outstream << ", "; + outstream << FCS->GetComponentValues(); + } + if (SubSystems & ssGroundReactions) { + outstream << ", "; + outstream << GroundReactions->GetGroundReactionValues(); + } + if (SubSystems & ssPropulsion && Propulsion->GetNumEngines() > 0) { + outstream << ", "; + outstream << Propulsion->GetPropulsionValues(); + } + + 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"); + socket->Append("Longitude"); + 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(Position->Geth()); + socket->Append(Rotation->Getphi()); + socket->Append(Rotation->Gettht()); + socket->Append(Rotation->Getpsi()); + socket->Append(Atmosphere->GetDensity()); + socket->Append(Translation->GetVt()); + socket->Append(Translation->GetUVW(eU)); + socket->Append(Translation->GetUVW(eV)); + socket->Append(Translation->GetUVW(eW)); + socket->Append(Translation->GetAeroUVW(eU)); + socket->Append(Translation->GetAeroUVW(eV)); + socket->Append(Translation->GetAeroUVW(eW)); + socket->Append(Position->GetVn()); + socket->Append(Position->GetVe()); + socket->Append(Position->GetVd()); + socket->Append(Translation->GetUVWdot(eU)); + socket->Append(Translation->GetUVWdot(eV)); + socket->Append(Translation->GetUVWdot(eW)); + socket->Append(Rotation->GetPQR(eP)); + socket->Append(Rotation->GetPQR(eQ)); + socket->Append(Rotation->GetPQR(eR)); + socket->Append(Rotation->GetPQRdot(eP)); + socket->Append(Rotation->GetPQRdot(eQ)); + socket->Append(Rotation->GetPQRdot(eR)); + socket->Append(Aircraft->GetForces(eX)); + socket->Append(Aircraft->GetForces(eY)); + socket->Append(Aircraft->GetForces(eZ)); + socket->Append(Position->GetLatitude()); + socket->Append(Position->GetLongitude()); + socket->Append(Translation->Getqbar()); + socket->Append(Translation->Getalpha()); + 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; + int OutRate = 0; + + token = AC_cfg->GetValue("NAME"); + Output->SetFilename(token); + token = AC_cfg->GetValue("TYPE"); + Output->SetType(token); + +#if defined( FG_WITH_JSBSIM_SOCKET ) || !defined( FGFS ) + if (token == "SOCKET") { + socket = new FGfdmSocket("localhost",1138); + } +#endif + + AC_cfg->GetNextConfigLine(); + + while ((token = AC_cfg->GetValue()) != string("/OUTPUT")) { + *AC_cfg >> parameter; + if (parameter == "RATE_IN_HZ") *AC_cfg >> OutRate; + if (parameter == "SIMULATION") { + *AC_cfg >> parameter; + if (parameter == "ON") SubSystems += ssSimulation; + } + if (parameter == "AEROSURFACES") { + *AC_cfg >> parameter; + if (parameter == "ON") SubSystems += ssAerosurfaces; + } + if (parameter == "RATES") { + *AC_cfg >> parameter; + if (parameter == "ON") SubSystems += ssRates; + } + if (parameter == "VELOCITIES") { + *AC_cfg >> parameter; + if (parameter == "ON") SubSystems += ssVelocities; + } + if (parameter == "FORCES") { + *AC_cfg >> parameter; + if (parameter == "ON") SubSystems += ssForces; + } + if (parameter == "MOMENTS") { + *AC_cfg >> parameter; + if (parameter == "ON") SubSystems += ssMoments; + } + if (parameter == "ATMOSPHERE") { + *AC_cfg >> parameter; + if (parameter == "ON") SubSystems += ssAtmosphere; + } + if (parameter == "MASSPROPS") { + *AC_cfg >> parameter; + if (parameter == "ON") SubSystems += ssMassProps; + } + if (parameter == "POSITION") { + *AC_cfg >> parameter; + if (parameter == "ON") SubSystems += ssPosition; + } + if (parameter == "COEFFICIENTS") { + *AC_cfg >> parameter; + if (parameter == "ON") SubSystems += ssCoefficients; + } + if (parameter == "GROUND_REACTIONS") { + *AC_cfg >> parameter; + if (parameter == "ON") SubSystems += ssGroundReactions; + } + if (parameter == "FCS") { + *AC_cfg >> parameter; + if (parameter == "ON") SubSystems += ssFCS; + } + if (parameter == "PROPULSION") { + *AC_cfg >> parameter; + if (parameter == "ON") SubSystems += ssPropulsion; + } + } + + OutRate = OutRate>120?120:(OutRate<0?0:OutRate); + rate = (int)(0.5 + 1.0/(State->Getdt()*OutRate)); + + 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) +{ + if (debug_lvl <= 0) return; + + if (debug_lvl & 1) { // Standard console startup message output + if (from == 0) { // Constructor + + } + } + 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; + } + } }