JSBSim Flight Dynamics Model  1.2.0 (05 Nov 2023)
An Open Source Flight Dynamics and Control Software Library in C++
FGInput.cpp
1 /*%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
2 
3  Module: FGInput.cpp
4  Author: Jon Berndt
5  Date started: 12/02/98
6  Purpose: Manage input of sim parameters from socket
7  Called by: FGSimExec
8 
9  ------------- Copyright (C) 1999 Jon S. Berndt (jon@jsbsim.org) -------------
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
13  Software Foundation; either version 2 of the License, or (at your option) any
14  later 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
22  with this program; if not, write to the Free Software Foundation, Inc., 59
23  Temple Place - Suite 330, Boston, MA 02111-1307, USA.
24 
25  Further information about the GNU Lesser General Public License can also be
26  found on the world wide web at http://www.gnu.org.
27 
28 FUNCTIONAL DESCRIPTION
29 --------------------------------------------------------------------------------
30 This is the place where you create output routines to dump data for perusal
31 later.
32 
33 HISTORY
34 --------------------------------------------------------------------------------
35 12/02/98 JSB Created
36 
37 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
38 INCLUDES
39 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%*/
40 
41 #include "FGInput.h"
42 #include "FGFDMExec.h"
43 #include "input_output/FGUDPInputSocket.h"
44 #include "input_output/FGXMLFileRead.h"
45 #include "input_output/FGModelLoader.h"
46 
47 using namespace std;
48 
49 namespace JSBSim {
50 
51 /*%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
52 CLASS IMPLEMENTATION
53 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%*/
54 
55 FGInput::FGInput(FGFDMExec* fdmex) : FGModel(fdmex)
56 {
57  Name = "FGInput";
58  enabled = true;
59 
60  Debug(0);
61 }
62 
63 //%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
64 
65 FGInput::~FGInput()
66 {
67  vector<FGInputType*>::iterator it;
68  for (it = InputTypes.begin(); it != InputTypes.end(); ++it)
69  delete (*it);
70 
71  Debug(1);
72 }
73 
74 //%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
75 
76 bool FGInput::Load(Element* el)
77 {
78  // Unlike the other FGModel classes, properties listed in the <input> section
79  // are not intended to create new properties. For that reason, FGInput
80  // cannot load its XML directives with FGModel::Load().
81  // Instead FGModelLoader::Open() and FGModel::PreLoad() must be explicitely
82  // called.
83  FGModelLoader ModelLoader(this);
84  Element* element = ModelLoader.Open(el);
85 
86  if (!element) return false;
87 
88  FGModel::PreLoad(element, FDMExec);
89 
90  size_t idx = InputTypes.size();
91  string type = element->GetAttributeValue("type");
92  FGInputType* Input = 0;
93 
94  if (debug_lvl > 0) cout << endl << " Input data set: " << idx << " " << endl;
95 
96  type = to_upper(type);
97 
98  if (type.empty() || type == "SOCKET") {
99  Input = new FGInputSocket(FDMExec);
100  } else if (type == "QTJSBSIM") {
101  Input = new FGUDPInputSocket(FDMExec);
102  } else if (type != string("NONE")) {
103  cerr << element->ReadFrom()
104  << "Unknown type of input specified in config file" << endl;
105  }
106 
107  if (!Input) return false;
108 
109  Input->SetIdx(idx);
110  Input->Load(element);
111  PostLoad(element, FDMExec);
112 
113  InputTypes.push_back(Input);
114 
115  Debug(2);
116  return true;
117 }
118 
119 //%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
120 
121 bool FGInput::InitModel(void)
122 {
123  bool ret = false;
124 
125  if (!FGModel::InitModel()) return false;
126 
127  vector<FGInputType*>::iterator it;
128  for (it = InputTypes.begin(); it != InputTypes.end(); ++it)
129  ret &= (*it)->InitModel();
130 
131  return ret;
132 }
133 
134 //%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
135 
136 bool FGInput::Run(bool Holding)
137 {
138  if (FDMExec->GetTrimStatus()) return true;
139  if (FGModel::Run(Holding)) return true;
140  if (!enabled) return true;
141 
142  vector<FGInputType*>::iterator it;
143  for (it = InputTypes.begin(); it != InputTypes.end(); ++it)
144  (*it)->Run(Holding);
145 
146  return false;
147 }
148 
149 //%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
150 
151 bool FGInput::SetDirectivesFile(const SGPath& fname)
152 {
154  Element* document = XMLFile.LoadXMLDocument(fname);
155  if (!document) {
156  stringstream s;
157  s << "Could not read directive file: " << fname;
158  throw BaseException(s.str());
159  }
160  bool result = Load(document);
161 
162  if (!result)
163  cerr << endl << "Aircraft input element has problems in file " << fname << endl;
164 
165  return result;
166 }
167 
168 //%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
169 
170 bool FGInput::Toggle(int idx)
171 {
172  if (idx >= (int)0 && idx < (int)InputTypes.size())
173  return InputTypes[idx]->Toggle();
174 
175  return false;
176 }
177 
178 //%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
179 
180 bool FGInput::SetInputName(unsigned int idx, const std::string& name)
181 {
182  if (idx >= InputTypes.size()) return false;
183 
184  InputTypes[idx]->SetInputName(name);
185  return true;
186 }
187 
188 //%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
189 
190 string FGInput::GetInputName(unsigned int idx) const
191 {
192  string name;
193 
194  if (idx < InputTypes.size())
195  name = InputTypes[idx]->GetInputName();
196  return name;
197 }
198 
199 
200 //%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
201 // The bitmasked value choices are as follows:
202 // unset: In this case (the default) JSBSim would only print
203 // out the normally expected messages, essentially echoing
204 // the config files as they are read. If the environment
205 // variable is not set, debug_lvl is set to 1 internally
206 // 0: This requests JSBSim not to output any messages
207 // whatsoever.
208 // 1: This value explicity requests the normal JSBSim
209 // startup messages
210 // 2: This value asks for a message to be printed out when
211 // a class is instantiated
212 // 4: When this value is set, a message is displayed when a
213 // FGModel object executes its Run() method
214 // 8: When this value is set, various runtime state variables
215 // are printed out periodically
216 // 16: When set various parameters are sanity checked and
217 // a message is printed out when they go out of bounds
218 
219 void FGInput::Debug(int from)
220 {
221  string scratch="";
222 
223  if (debug_lvl <= 0) return;
224 
225  if (debug_lvl & 1) { // Standard console startup message output
226  if (from == 0) { // Constructor
227  }
228  if (from == 2) {
229  }
230  }
231  if (debug_lvl & 2 ) { // Instantiation/Destruction notification
232  if (from == 0) cout << "Instantiated: FGInput" << endl;
233  if (from == 1) cout << "Destroyed: FGInput" << endl;
234  }
235  if (debug_lvl & 4 ) { // Run() method entry print for FGModel-derived objects
236  }
237  if (debug_lvl & 8 ) { // Runtime state variables
238  }
239  if (debug_lvl & 16) { // Sanity checking
240  }
241  if (debug_lvl & 64) {
242  if (from == 0) { // Constructor
243  }
244  }
245 }
246 }
std::string GetAttributeValue(const std::string &key)
Retrieves an attribute.
std::string ReadFrom(void) const
Return a string that contains a description of the location where the current XML element was read fr...
Implements the input from a socket.
Definition: FGInputSocket.h:63
Abstract class to provide functions generic to all the input directives.
Definition: FGInputType.h:74
bool Load(Element *el) override
Init the input directives from an XML file (implement the FGModel interface).
Definition: FGInputType.cpp:72
void SetIdx(unsigned int idx)
Set the idx for this input instance.
Definition: FGInputType.cpp:65
Implements a UDP input socket.
This class is solely for the purpose of determining what type of file is given on the command line.
Definition: JSBSim.cpp:149