PageRenderTime 6ms CodeModel.GetById 4ms app.highlight 38ms RepoModel.GetById 1ms app.codeStats 0ms

/src/input_output/FGOutputSocket.cpp

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