JSBSim Flight Dynamics Model  1.2.0 (05 Nov 2023)
An Open Source Flight Dynamics and Control Software Library in C++
FGModelFunctions.cpp
1 /*%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
2 
3  Module: FGModelFunctions.cpp
4  Author: Jon S. Berndt
5  Date started: August 2010
6 
7  ------- Copyright (C) 2010 Jon S. Berndt (jon@jsbsim.org) ------------------
8 
9  This program is free software; you can redistribute it and/or modify it under
10  the terms of the GNU Lesser General Public License as published by the Free
11  Software Foundation; either version 2 of the License, or (at your option) any
12  later version.
13 
14  This program is distributed in the hope that it will be useful, but WITHOUT
15  ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
16  FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License for more
17  details.
18 
19  You should have received a copy of the GNU Lesser General Public License along
20  with this program; if not, write to the Free Software Foundation, Inc., 59
21  Temple Place - Suite 330, Boston, MA 02111-1307, USA.
22 
23  Further information about the GNU Lesser General Public License can also be
24  found on the world wide web at http://www.gnu.org.
25 
26 FUNCTIONAL DESCRIPTION
27 --------------------------------------------------------------------------------
28 
29 HISTORY
30 --------------------------------------------------------------------------------
31 
32 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
33 COMMENTS, REFERENCES, and NOTES
34 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
35 
36 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
37 INCLUDES
38 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%*/
39 
40 #include "FGFDMExec.h"
41 #include "FGModelFunctions.h"
42 #include "input_output/FGXMLElement.h"
43 
44 using namespace std;
45 
46 namespace JSBSim {
47 
48 /*%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
49 CLASS IMPLEMENTATION
50 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%*/
51 
52 bool FGModelFunctions::InitModel(void)
53 {
54  LocalProperties.ResetToIC();
55 
56  return true;
57 }
58 
59 //%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
60 
61 bool FGModelFunctions::Load(Element* el, FGFDMExec* fdmex, string prefix)
62 {
63  LocalProperties.Load(el, fdmex->GetPropertyManager().get(), false);
64  PreLoad(el, fdmex, prefix);
65 
66  return true; // TODO: Need to make this value mean something.
67 }
68 
69 //%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
70 
71 void FGModelFunctions::PreLoad(Element* el, FGFDMExec* fdmex, string prefix)
72 {
73  // Load model post-functions, if any
74 
75  Element *function = el->FindElement("function");
76 
77  while (function) {
78  string fType = function->GetAttributeValue("type");
79  if (fType.empty() || fType == "pre")
80  PreFunctions.push_back(std::make_shared<FGFunction>(fdmex, function, prefix));
81  else if (fType == "template") {
82  string name = function->GetAttributeValue("name");
83  fdmex->AddTemplateFunc(name, function);
84  }
85 
86  function = el->FindNextElement("function");
87  }
88 }
89 
90 //%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
91 
92 void FGModelFunctions::PostLoad(Element* el, FGFDMExec* fdmex, string prefix)
93 {
94  // Load model post-functions, if any
95 
96  Element *function = el->FindElement("function");
97  while (function) {
98  if (function->GetAttributeValue("type") == "post") {
99  PostFunctions.push_back(std::make_shared<FGFunction>(fdmex, function, prefix));
100  }
101  function = el->FindNextElement("function");
102  }
103 }
104 
105 //%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
106 // Tell the Functions to cache values, so when the function values
107 // are being used in the model, the functions do not get
108 // calculated each time, but instead use the values that have already
109 // been calculated for this frame.
110 
111 void FGModelFunctions::RunPreFunctions(void)
112 {
113  for (auto& prefunc: PreFunctions)
114  prefunc->cacheValue(true);
115 }
116 
117 //%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
118 // Tell the Functions to cache values, so when the function values
119 // are being used in the model, the functions do not get
120 // calculated each time, but instead use the values that have already
121 // been calculated for this frame.
122 
123 void FGModelFunctions::RunPostFunctions(void)
124 {
125  for (auto& postfunc: PostFunctions)
126  postfunc->cacheValue(true);
127 }
128 
129 //%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
130 
131 std::shared_ptr<FGFunction> FGModelFunctions::GetPreFunction(const std::string& name)
132 {
133  for (auto& prefunc: PreFunctions) {
134  if (prefunc->GetName() == name)
135  return prefunc;
136  }
137 
138  return nullptr;
139 }
140 
141 //%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
142 
143 string FGModelFunctions::GetFunctionStrings(const string& delimeter) const
144 {
145  string FunctionStrings;
146 
147  for (auto& prefunc: PreFunctions) {
148  if (!FunctionStrings.empty())
149  FunctionStrings += delimeter;
150 
151  FunctionStrings += prefunc->GetName();
152  }
153 
154  for (auto& postfunc: PostFunctions) {
155  if (!FunctionStrings.empty())
156  FunctionStrings += delimeter;
157 
158  FunctionStrings += postfunc->GetName();
159  }
160 
161  return FunctionStrings;
162 }
163 
164 //%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
165 
166 string FGModelFunctions::GetFunctionValues(const string& delimeter) const
167 {
168  ostringstream buf;
169 
170  for (auto& prefunc: PreFunctions) {
171  if (buf.tellp() > 0) buf << delimeter;
172  buf << prefunc->GetValue();
173  }
174 
175  for (auto& postfunc: PostFunctions) {
176  if (buf.tellp() > 0) buf << delimeter;
177  buf << postfunc->GetValue();
178  }
179 
180  return buf.str();
181 }
182 
183 //%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
184 
185 }