/*%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% Module: FGOutputSocket.cpp Author: Bertrand Coconnier Date started: 09/10/11 Purpose: Manage output of sim parameters to a socket Called by: FGOutput ------------- Copyright (C) 2011 Bertrand Coconnier ------------- This program is free software; you can redistribute it and/or modify it under the terms of the GNU Lesser 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 Lesser General Public License for more details. You should have received a copy of the GNU Lesser 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 Lesser 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 -------------------------------------------------------------------------------- 09/10/11 BC Created %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% INCLUDES %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%*/ #include #include #include "FGOutputSocket.h" #include "FGFDMExec.h" #include "models/FGAerodynamics.h" #include "models/FGAccelerations.h" #include "models/FGAircraft.h" #include "models/FGAtmosphere.h" #include "models/FGAuxiliary.h" #include "models/FGPropulsion.h" #include "models/FGMassBalance.h" #include "models/FGPropagate.h" #include "models/FGGroundReactions.h" #include "models/FGFCS.h" #include "models/atmosphere/FGWinds.h" #include "input_output/FGXMLElement.h" using namespace std; namespace JSBSim { IDENT(IdSrc,"$Id: FGOutputSocket.cpp,v 1.8 2014/01/13 10:46:00 ehofman Exp $"); IDENT(IdHdr,ID_OUTPUTSOCKET); /*%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% CLASS IMPLEMENTATION %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%*/ FGOutputSocket::FGOutputSocket(FGFDMExec* fdmex) : FGOutputType(fdmex), socket(0) { } //%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% FGOutputSocket::~FGOutputSocket() { delete socket; } //%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% void FGOutputSocket::SetOutputName(const string& fname) { // tokenize the output name size_t dot_pos = fname.find(':', 0); size_t slash_pos = fname.find('/', 0); string name = fname.substr(0, dot_pos); string proto = "TCP"; if(dot_pos + 1 < slash_pos) proto = fname.substr(dot_pos + 1, slash_pos - dot_pos - 1); string port = "1138"; if(slash_pos < string::npos) port = fname.substr(slash_pos + 1, string::npos); // set the model name Name = name + ":" + port + "/" + proto; // set the socket params SockName = name; SockPort = atoi(port.c_str()); if (proto == "UDP") SockProtocol = FGfdmSocket::ptUDP; else // Default to TCP SockProtocol = FGfdmSocket::ptTCP; } //%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% bool FGOutputSocket::Load(Element* el) { if (!FGOutputType::Load(el)) return false; SetOutputName(el->GetAttributeValue("name") + ":" + el->GetAttributeValue("protocol") + "/" + el->GetAttributeValue("port")); return true; } //%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% bool FGOutputSocket::InitModel(void) { if (FGOutputType::InitModel()) { delete socket; socket = new FGfdmSocket(SockName, SockPort, SockProtocol); if (socket == 0) return false; if (!socket->GetConnectStatus()) return false; PrintHeaders(); return true; } return false; } //%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% void FGOutputSocket::PrintHeaders(void) { string scratch; socket->Clear(); socket->Clear(""); socket->Append("Time"); if (SubSystems & ssAerosurfaces) { socket->Append("Aileron Command"); socket->Append("Elevator Command"); socket->Append("Rudder Command"); socket->Append("Flap Command"); socket->Append("Left Aileron Position"); socket->Append("Right Aileron Position"); socket->Append("Elevator Position"); socket->Append("Rudder Position"); socket->Append("Flap Position"); } if (SubSystems & ssRates) { socket->Append("P"); socket->Append("Q"); socket->Append("R"); socket->Append("PDot"); socket->Append("QDot"); socket->Append("RDot"); } if (SubSystems & ssVelocities) { socket->Append("QBar"); 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"); } if (SubSystems & ssForces) { socket->Append("F_Drag"); socket->Append("F_Side"); socket->Append("F_Lift"); socket->Append("LoD"); socket->Append("Fx"); socket->Append("Fy"); socket->Append("Fz"); } if (SubSystems & ssMoments) { socket->Append("L"); socket->Append("M"); socket->Append("N"); } if (SubSystems & ssAtmosphere) { socket->Append("Rho"); socket->Append("SL pressure"); socket->Append("Ambient pressure"); socket->Append("Turbulence Magnitude"); socket->Append("Turbulence Direction X"); socket->Append("Turbulence Direction Y"); socket->Append("Turbulence Direction Z"); socket->Append("NWind"); socket->Append("EWind"); socket->Append("DWind"); } if (SubSystems & ssMassProps) { socket->Append("Ixx"); socket->Append("Ixy"); socket->Append("Ixz"); socket->Append("Iyx"); socket->Append("Iyy"); socket->Append("Iyz"); socket->Append("Izx"); socket->Append("Izy"); socket->Append("Izz"); socket->Append("Mass"); socket->Append("Xcg"); socket->Append("Ycg"); socket->Append("Zcg"); } if (SubSystems & ssPropagate) { socket->Append("Altitude"); socket->Append("Phi (deg)"); socket->Append("Tht (deg)"); socket->Append("Psi (deg)"); socket->Append("Alpha (deg)"); socket->Append("Beta (deg)"); socket->Append("Latitude (deg)"); socket->Append("Longitude (deg)"); } if (SubSystems & ssAeroFunctions) { scratch = Aerodynamics->GetAeroFunctionStrings(","); if (scratch.length() != 0) socket->Append(scratch); } if (SubSystems & ssFCS) { scratch = FCS->GetComponentStrings(","); if (scratch.length() != 0) socket->Append(scratch); } if (SubSystems & ssGroundReactions) socket->Append(GroundReactions->GetGroundReactionStrings(",")); if (SubSystems & ssPropulsion && Propulsion->GetNumEngines() > 0) socket->Append(Propulsion->GetPropulsionStrings(",")); if (OutputProperties.size() > 0) { for (unsigned int i=0;i 0) { socket->Append(OutputCaptions[i]); } else { socket->Append(OutputProperties[i]->GetPrintableName()); } } socket->Send(); } //%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% void FGOutputSocket::Print(void) { string asciiData, scratch; if (socket == 0) return; if (!socket->GetConnectStatus()) return; socket->Clear(); socket->Append(FDMExec->GetSimTime()); if (SubSystems & ssAerosurfaces) { socket->Append(FCS->GetDaCmd()); socket->Append(FCS->GetDeCmd()); socket->Append(FCS->GetDrCmd()); socket->Append(FCS->GetDfCmd()); socket->Append(FCS->GetDaLPos()); socket->Append(FCS->GetDaRPos()); socket->Append(FCS->GetDePos()); socket->Append(FCS->GetDrPos()); socket->Append(FCS->GetDfPos()); } if (SubSystems & ssRates) { socket->Append(radtodeg*Propagate->GetPQR(eP)); socket->Append(radtodeg*Propagate->GetPQR(eQ)); socket->Append(radtodeg*Propagate->GetPQR(eR)); socket->Append(radtodeg*Accelerations->GetPQRdot(eP)); socket->Append(radtodeg*Accelerations->GetPQRdot(eQ)); socket->Append(radtodeg*Accelerations->GetPQRdot(eR)); } if (SubSystems & ssVelocities) { socket->Append(Auxiliary->Getqbar()); 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)); } if (SubSystems & ssForces) { socket->Append(Aerodynamics->GetvFw()(eDrag)); socket->Append(Aerodynamics->GetvFw()(eSide)); socket->Append(Aerodynamics->GetvFw()(eLift)); socket->Append(Aerodynamics->GetLoD()); socket->Append(Aircraft->GetForces(eX)); socket->Append(Aircraft->GetForces(eY)); socket->Append(Aircraft->GetForces(eZ)); } if (SubSystems & ssMoments) { socket->Append(Aircraft->GetMoments(eL)); socket->Append(Aircraft->GetMoments(eM)); socket->Append(Aircraft->GetMoments(eN)); } if (SubSystems & ssAtmosphere) { socket->Append(Atmosphere->GetDensity()); socket->Append(Atmosphere->GetPressureSL()); socket->Append(Atmosphere->GetPressure()); socket->Append(Winds->GetTurbMagnitude()); socket->Append(Winds->GetTurbDirection().Dump(",")); socket->Append(Winds->GetTotalWindNED().Dump(",")); } if (SubSystems & ssMassProps) { socket->Append(MassBalance->GetJ()(1,1)); socket->Append(MassBalance->GetJ()(1,2)); socket->Append(MassBalance->GetJ()(1,3)); socket->Append(MassBalance->GetJ()(2,1)); socket->Append(MassBalance->GetJ()(2,2)); socket->Append(MassBalance->GetJ()(2,3)); socket->Append(MassBalance->GetJ()(3,1)); socket->Append(MassBalance->GetJ()(3,2)); socket->Append(MassBalance->GetJ()(3,3)); socket->Append(MassBalance->GetMass()); socket->Append(MassBalance->GetXYZcg()(eX)); socket->Append(MassBalance->GetXYZcg()(eY)); socket->Append(MassBalance->GetXYZcg()(eZ)); } if (SubSystems & ssPropagate) { socket->Append(Propagate->GetAltitudeASL()); socket->Append(radtodeg*Propagate->GetEuler(ePhi)); socket->Append(radtodeg*Propagate->GetEuler(eTht)); socket->Append(radtodeg*Propagate->GetEuler(ePsi)); socket->Append(Auxiliary->Getalpha(inDegrees)); socket->Append(Auxiliary->Getbeta(inDegrees)); socket->Append(Propagate->GetLocation().GetLatitudeDeg()); socket->Append(Propagate->GetLocation().GetLongitudeDeg()); } if (SubSystems & ssAeroFunctions) { scratch = Aerodynamics->GetAeroFunctionValues(","); if (scratch.length() != 0) socket->Append(scratch); } if (SubSystems & ssFCS) { scratch = FCS->GetComponentValues(","); if (scratch.length() != 0) socket->Append(scratch); } if (SubSystems & ssGroundReactions) { socket->Append(GroundReactions->GetGroundReactionValues(",")); } if (SubSystems & ssPropulsion && Propulsion->GetNumEngines() > 0) { socket->Append(Propulsion->GetPropulsionValues(",")); } for (unsigned int i=0;iAppend(OutputProperties[i]->getDoubleValue()); } socket->Send(); } //%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% void FGOutputSocket::SocketStatusOutput(const string& out_str) { string asciiData; if (socket == 0) return; socket->Clear(); asciiData = string("") + out_str; socket->Append(asciiData.c_str()); socket->Send(); } }