PageRenderTime 153ms CodeModel.GetById 46ms 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
Possible License(s): LGPL-3.0
  1. /*%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
  2. Module: FGOutputSocket.cpp
  3. Author: Bertrand Coconnier
  4. Date started: 09/10/11
  5. Purpose: Manage output of sim parameters to a socket
  6. Called by: FGOutput
  7. ------------- Copyright (C) 2011 Bertrand Coconnier -------------
  8. This program is free software; you can redistribute it and/or modify it under
  9. the terms of the GNU Lesser General Public License as published by the Free Software
  10. Foundation; either version 2 of the License, or (at your option) any later
  11. version.
  12. This program is distributed in the hope that it will be useful, but WITHOUT
  13. ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
  14. FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License for more
  15. details.
  16. You should have received a copy of the GNU Lesser General Public License along with
  17. this program; if not, write to the Free Software Foundation, Inc., 59 Temple
  18. Place - Suite 330, Boston, MA 02111-1307, USA.
  19. Further information about the GNU Lesser General Public License can also be found on
  20. the world wide web at http://www.gnu.org.
  21. FUNCTIONAL DESCRIPTION
  22. --------------------------------------------------------------------------------
  23. This is the place where you create output routines to dump data for perusal
  24. later.
  25. HISTORY
  26. --------------------------------------------------------------------------------
  27. 09/10/11 BC Created
  28. %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
  29. INCLUDES
  30. %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%*/
  31. #include <cstring>
  32. #include <cstdlib>
  33. #include "FGOutputSocket.h"
  34. #include "FGFDMExec.h"
  35. #include "models/FGAerodynamics.h"
  36. #include "models/FGAccelerations.h"
  37. #include "models/FGAircraft.h"
  38. #include "models/FGAtmosphere.h"
  39. #include "models/FGAuxiliary.h"
  40. #include "models/FGPropulsion.h"
  41. #include "models/FGMassBalance.h"
  42. #include "models/FGPropagate.h"
  43. #include "models/FGGroundReactions.h"
  44. #include "models/FGFCS.h"
  45. #include "models/atmosphere/FGWinds.h"
  46. using namespace std;
  47. namespace JSBSim {
  48. static const char *IdSrc = "$Id: FGOutputSocket.cpp,v 1.1 2012/09/05 21:49:19 bcoconni Exp $";
  49. static const char *IdHdr = ID_OUTPUTSOCKET;
  50. /*%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
  51. CLASS IMPLEMENTATION
  52. %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%*/
  53. FGOutputSocket::FGOutputSocket(FGFDMExec* fdmex, Element* element, int idx) :
  54. FGOutputType(fdmex, element, idx),
  55. socket(0)
  56. {
  57. Name = element->GetAttributeValue("name");
  58. string Port = element->GetAttributeValue("port");
  59. if (!Port.empty()) {
  60. port = atoi(Port.c_str());
  61. SetProtocol(element->GetAttributeValue("protocol"));
  62. socket = new FGfdmSocket(Name, port, Protocol);
  63. }
  64. }
  65. //%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
  66. FGOutputSocket::FGOutputSocket(FGFDMExec* fdmex, int idx, int subSystems,
  67. std::string protocol, std::string Port,
  68. std::string name, double outRate,
  69. std::vector<FGPropertyManager *> & outputProperties) :
  70. FGOutputType(fdmex, idx, subSystems, outRate, outputProperties),
  71. Name(name),
  72. socket(0)
  73. {
  74. if (!Port.empty()) {
  75. port = atoi(Port.c_str());
  76. SetProtocol(protocol);
  77. socket = new FGfdmSocket(Name, port, Protocol);
  78. }
  79. }
  80. //%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
  81. FGOutputSocket::~FGOutputSocket()
  82. {
  83. delete socket;
  84. }
  85. //%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
  86. bool FGOutputSocket::InitModel(void)
  87. {
  88. if (FGOutputType::InitModel()) {
  89. string scratch;
  90. if (socket == 0) return false;
  91. if (!socket->GetConnectStatus()) return false;
  92. socket->Clear();
  93. socket->Clear("<LABELS>");
  94. socket->Append("Time");
  95. if (SubSystems & ssAerosurfaces) {
  96. socket->Append("Aileron Command");
  97. socket->Append("Elevator Command");
  98. socket->Append("Rudder Command");
  99. socket->Append("Flap Command");
  100. socket->Append("Left Aileron Position");
  101. socket->Append("Right Aileron Position");
  102. socket->Append("Elevator Position");
  103. socket->Append("Rudder Position");
  104. socket->Append("Flap Position");
  105. }
  106. if (SubSystems & ssRates) {
  107. socket->Append("P");
  108. socket->Append("Q");
  109. socket->Append("R");
  110. socket->Append("PDot");
  111. socket->Append("QDot");
  112. socket->Append("RDot");
  113. }
  114. if (SubSystems & ssVelocities) {
  115. socket->Append("QBar");
  116. socket->Append("Vtotal");
  117. socket->Append("UBody");
  118. socket->Append("VBody");
  119. socket->Append("WBody");
  120. socket->Append("UAero");
  121. socket->Append("VAero");
  122. socket->Append("WAero");
  123. socket->Append("Vn");
  124. socket->Append("Ve");
  125. socket->Append("Vd");
  126. }
  127. if (SubSystems & ssForces) {
  128. socket->Append("F_Drag");
  129. socket->Append("F_Side");
  130. socket->Append("F_Lift");
  131. socket->Append("LoD");
  132. socket->Append("Fx");
  133. socket->Append("Fy");
  134. socket->Append("Fz");
  135. }
  136. if (SubSystems & ssMoments) {
  137. socket->Append("L");
  138. socket->Append("M");
  139. socket->Append("N");
  140. }
  141. if (SubSystems & ssAtmosphere) {
  142. socket->Append("Rho");
  143. socket->Append("SL pressure");
  144. socket->Append("Ambient pressure");
  145. socket->Append("Turbulence Magnitude");
  146. socket->Append("Turbulence Direction X");
  147. socket->Append("Turbulence Direction Y");
  148. socket->Append("Turbulence Direction Z");
  149. socket->Append("NWind");
  150. socket->Append("EWind");
  151. socket->Append("DWind");
  152. }
  153. if (SubSystems & ssMassProps) {
  154. socket->Append("Ixx");
  155. socket->Append("Ixy");
  156. socket->Append("Ixz");
  157. socket->Append("Iyx");
  158. socket->Append("Iyy");
  159. socket->Append("Iyz");
  160. socket->Append("Izx");
  161. socket->Append("Izy");
  162. socket->Append("Izz");
  163. socket->Append("Mass");
  164. socket->Append("Xcg");
  165. socket->Append("Ycg");
  166. socket->Append("Zcg");
  167. }
  168. if (SubSystems & ssPropagate) {
  169. socket->Append("Altitude");
  170. socket->Append("Phi (deg)");
  171. socket->Append("Tht (deg)");
  172. socket->Append("Psi (deg)");
  173. socket->Append("Alpha (deg)");
  174. socket->Append("Beta (deg)");
  175. socket->Append("Latitude (deg)");
  176. socket->Append("Longitude (deg)");
  177. }
  178. if (SubSystems & ssAeroFunctions) {
  179. scratch = Aerodynamics->GetAeroFunctionStrings(",");
  180. if (scratch.length() != 0) socket->Append(scratch);
  181. }
  182. if (SubSystems & ssFCS) {
  183. scratch = FCS->GetComponentStrings(",");
  184. if (scratch.length() != 0) socket->Append(scratch);
  185. }
  186. if (SubSystems & ssGroundReactions)
  187. socket->Append(GroundReactions->GetGroundReactionStrings(","));
  188. if (SubSystems & ssPropulsion && Propulsion->GetNumEngines() > 0)
  189. socket->Append(Propulsion->GetPropulsionStrings(","));
  190. if (OutputProperties.size() > 0) {
  191. for (unsigned int i=0;i<OutputProperties.size();i++)
  192. socket->Append(OutputProperties[i]->GetPrintableName());
  193. }
  194. socket->Send();
  195. return true;
  196. }
  197. return false;
  198. }
  199. //%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
  200. void FGOutputSocket::SetProtocol(const string& protocol)
  201. {
  202. if (protocol == "UDP") Protocol = FGfdmSocket::ptUDP;
  203. else if (protocol == "TCP") Protocol = FGfdmSocket::ptTCP;
  204. else Protocol = FGfdmSocket::ptTCP; // Default to TCP
  205. if (socket != 0) {
  206. delete socket;
  207. socket = new FGfdmSocket(Name, port, Protocol);
  208. InitModel();
  209. }
  210. }
  211. //%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
  212. void FGOutputSocket::SetPort(const std::string& Port)
  213. {
  214. delete socket;
  215. port = atoi(Port.c_str());
  216. socket = new FGfdmSocket(Name, port, Protocol);
  217. InitModel();
  218. }
  219. //%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
  220. void FGOutputSocket::Print(void)
  221. {
  222. string asciiData, scratch;
  223. if (socket == 0) return;
  224. if (!socket->GetConnectStatus()) return;
  225. socket->Clear();
  226. socket->Append(FDMExec->GetSimTime());
  227. if (SubSystems & ssAerosurfaces) {
  228. socket->Append(FCS->GetDaCmd());
  229. socket->Append(FCS->GetDeCmd());
  230. socket->Append(FCS->GetDrCmd());
  231. socket->Append(FCS->GetDfCmd());
  232. socket->Append(FCS->GetDaLPos());
  233. socket->Append(FCS->GetDaRPos());
  234. socket->Append(FCS->GetDePos());
  235. socket->Append(FCS->GetDrPos());
  236. socket->Append(FCS->GetDfPos());
  237. }
  238. if (SubSystems & ssRates) {
  239. socket->Append(radtodeg*Propagate->GetPQR(eP));
  240. socket->Append(radtodeg*Propagate->GetPQR(eQ));
  241. socket->Append(radtodeg*Propagate->GetPQR(eR));
  242. socket->Append(radtodeg*Accelerations->GetPQRdot(eP));
  243. socket->Append(radtodeg*Accelerations->GetPQRdot(eQ));
  244. socket->Append(radtodeg*Accelerations->GetPQRdot(eR));
  245. }
  246. if (SubSystems & ssVelocities) {
  247. socket->Append(Auxiliary->Getqbar());
  248. socket->Append(Auxiliary->GetVt());
  249. socket->Append(Propagate->GetUVW(eU));
  250. socket->Append(Propagate->GetUVW(eV));
  251. socket->Append(Propagate->GetUVW(eW));
  252. socket->Append(Auxiliary->GetAeroUVW(eU));
  253. socket->Append(Auxiliary->GetAeroUVW(eV));
  254. socket->Append(Auxiliary->GetAeroUVW(eW));
  255. socket->Append(Propagate->GetVel(eNorth));
  256. socket->Append(Propagate->GetVel(eEast));
  257. socket->Append(Propagate->GetVel(eDown));
  258. }
  259. if (SubSystems & ssForces) {
  260. socket->Append(Aerodynamics->GetvFw()(eDrag));
  261. socket->Append(Aerodynamics->GetvFw()(eSide));
  262. socket->Append(Aerodynamics->GetvFw()(eLift));
  263. socket->Append(Aerodynamics->GetLoD());
  264. socket->Append(Aircraft->GetForces(eX));
  265. socket->Append(Aircraft->GetForces(eY));
  266. socket->Append(Aircraft->GetForces(eZ));
  267. }
  268. if (SubSystems & ssMoments) {
  269. socket->Append(Aircraft->GetMoments(eL));
  270. socket->Append(Aircraft->GetMoments(eM));
  271. socket->Append(Aircraft->GetMoments(eN));
  272. }
  273. if (SubSystems & ssAtmosphere) {
  274. socket->Append(Atmosphere->GetDensity());
  275. socket->Append(Atmosphere->GetPressureSL());
  276. socket->Append(Atmosphere->GetPressure());
  277. socket->Append(Winds->GetTurbMagnitude());
  278. socket->Append(Winds->GetTurbDirection().Dump(","));
  279. socket->Append(Winds->GetTotalWindNED().Dump(","));
  280. }
  281. if (SubSystems & ssMassProps) {
  282. socket->Append(MassBalance->GetJ()(1,1));
  283. socket->Append(MassBalance->GetJ()(1,2));
  284. socket->Append(MassBalance->GetJ()(1,3));
  285. socket->Append(MassBalance->GetJ()(2,1));
  286. socket->Append(MassBalance->GetJ()(2,2));
  287. socket->Append(MassBalance->GetJ()(2,3));
  288. socket->Append(MassBalance->GetJ()(3,1));
  289. socket->Append(MassBalance->GetJ()(3,2));
  290. socket->Append(MassBalance->GetJ()(3,3));
  291. socket->Append(MassBalance->GetMass());
  292. socket->Append(MassBalance->GetXYZcg()(eX));
  293. socket->Append(MassBalance->GetXYZcg()(eY));
  294. socket->Append(MassBalance->GetXYZcg()(eZ));
  295. }
  296. if (SubSystems & ssPropagate) {
  297. socket->Append(Propagate->GetAltitudeASL());
  298. socket->Append(radtodeg*Propagate->GetEuler(ePhi));
  299. socket->Append(radtodeg*Propagate->GetEuler(eTht));
  300. socket->Append(radtodeg*Propagate->GetEuler(ePsi));
  301. socket->Append(Auxiliary->Getalpha(inDegrees));
  302. socket->Append(Auxiliary->Getbeta(inDegrees));
  303. socket->Append(Propagate->GetLocation().GetLatitudeDeg());
  304. socket->Append(Propagate->GetLocation().GetLongitudeDeg());
  305. }
  306. if (SubSystems & ssAeroFunctions) {
  307. scratch = Aerodynamics->GetAeroFunctionValues(",");
  308. if (scratch.length() != 0) socket->Append(scratch);
  309. }
  310. if (SubSystems & ssFCS) {
  311. scratch = FCS->GetComponentValues(",");
  312. if (scratch.length() != 0) socket->Append(scratch);
  313. }
  314. if (SubSystems & ssGroundReactions) {
  315. socket->Append(GroundReactions->GetGroundReactionValues(","));
  316. }
  317. if (SubSystems & ssPropulsion && Propulsion->GetNumEngines() > 0) {
  318. socket->Append(Propulsion->GetPropulsionValues(","));
  319. }
  320. for (unsigned int i=0;i<OutputProperties.size();i++) {
  321. socket->Append(OutputProperties[i]->getDoubleValue());
  322. }
  323. socket->Send();
  324. }
  325. //%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
  326. void FGOutputSocket::SocketStatusOutput(const string& out_str)
  327. {
  328. string asciiData;
  329. if (socket == 0) return;
  330. socket->Clear();
  331. asciiData = string("<STATUS>") + out_str;
  332. socket->Append(asciiData.c_str());
  333. socket->Send();
  334. }
  335. }