]> git.mxchange.org Git - flightgear.git/blob - src/FDM/TankProperties.cxx
Improve timing statistics
[flightgear.git] / src / FDM / TankProperties.cxx
1 // TankProperties.cxx -- expose (fuel)-tank properties 
2 //
3 // Written by Torsten Dreyer, started January 2011.
4 //
5 // Copyright (C) 2011  Torsten Dreyer - Torsten (at) t3r _dot_ de
6 //
7 // This program is free software; you can redistribute it and/or
8 // modify it under the terms of the GNU General Public License as
9 // published by the Free Software Foundation; either version 2 of the
10 // License, or (at your option) any later version.
11 //
12 // This program is distributed in the hope that it will be useful, but
13 // WITHOUT ANY WARRANTY; without even the implied warranty of
14 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
15 // General Public License for more details.
16 //
17 // You should have received a copy of the GNU General Public License
18 // along with this program; if not, write to the Free Software
19 // Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA.
20 //
21
22 #ifdef HAVE_CONFIG_H
23 #  include <config.h>
24 #endif
25
26 #include "TankProperties.hxx"
27
28 #include <simgear/math/SGMath.hxx>
29 #include <simgear/sg_inlines.h>
30 #include <Main/fg_props.hxx>
31
32 static const double LBS_PER_KG = 2.20462262;
33 static const double KG_PER_LBS = 1.0/LBS_PER_KG;
34 static const double USGAL_PER_M3 = 1000.0/3.785411784;
35 static const double M3_PER_USGAL = 1.0/USGAL_PER_M3;
36 static const double IMPGAL_PER_M3 = 1000.0/4.54609;
37 static const double M3_PER_IMPGAL = 1.0/IMPGAL_PER_M3;
38
39 TankProperties::TankProperties(SGPropertyNode_ptr rootNode ) :
40   _content_kg(0.0),
41   _density_kgpm3(0.0),
42   _capacity_m3(0.0),
43   _unusable_m3(0.0)
44 {
45   _tiedProperties.setRoot( rootNode );
46 }
47
48 void TankProperties::bind()
49 {
50   _tiedProperties.Tie("level-kg", this, &TankProperties::getContent_kg, &TankProperties::setContent_kg );
51   _tiedProperties.Tie("density-kgpm3", this, &TankProperties::getDensity_kgpm3, &TankProperties::setDensity_kgpm3 );
52   _tiedProperties.Tie("capacity-m3", this, &TankProperties::getCapacity_m3, &TankProperties::setCapacity_m3 );
53   _tiedProperties.Tie("unusable-m3", this, &TankProperties::getUnusable_m3, &TankProperties::setUnusable_m3 );
54   _tiedProperties.Tie("level-m3", this, &TankProperties::getContent_m3, &TankProperties::setContent_m3 );
55   _tiedProperties.Tie("level-norm", this, &TankProperties::getContent_norm, &TankProperties::setContent_norm );
56
57   _tiedProperties.Tie("density-ppg", this, &TankProperties::getDensity_ppg, &TankProperties::setDensity_ppg );
58   _tiedProperties.Tie("level-lbs", this, &TankProperties::getContent_lbs, &TankProperties::setContent_lbs );
59   _tiedProperties.Tie("level-gal_us", this, &TankProperties::getContent_gal_us, &TankProperties::setContent_gal_us );
60   _tiedProperties.Tie("level-gal_imp", this, &TankProperties::getContent_gal_imp, &TankProperties::setContent_gal_imp );
61
62   _tiedProperties.Tie("capacity-gal_us", this, &TankProperties::getCapacity_gal_us, &TankProperties::setCapacity_gal_us );
63   _tiedProperties.Tie("unusable-gal_us", this, &TankProperties::getUnusable_gal_us, &TankProperties::setUnusable_gal_us );
64
65   _tiedProperties.Tie("capacity-gal_imp", this, &TankProperties::getCapacity_gal_imp, &TankProperties::setCapacity_gal_imp );
66   _tiedProperties.Tie("unusable-gal_imp", this, &TankProperties::getUnusable_gal_imp, &TankProperties::setUnusable_gal_imp );
67
68   _tiedProperties.Tie("empty", this, &TankProperties::getEmpty );
69 }
70
71 TankProperties::~TankProperties()
72 {
73 }
74
75 void TankProperties::unbind()
76 {
77     _tiedProperties.Untie();
78 }
79
80 double TankProperties::getContent_kg() const
81 {
82   return _content_kg;
83 }
84
85 void TankProperties::setContent_kg( double value )
86 {
87   _content_kg = SG_MAX2<double>(value, 0.0);
88 }
89
90 double TankProperties::getDensity_kgpm3() const
91 {
92   return _density_kgpm3;
93 }
94
95 void TankProperties::setDensity_kgpm3( double value )
96 {
97   _density_kgpm3 = SG_MAX2<double>(value, 0.0);
98 }
99
100 double TankProperties::getDensity_ppg() const
101 {
102   return _density_kgpm3 * LBS_PER_KG / USGAL_PER_M3;
103 }
104
105 void TankProperties::setDensity_ppg( double value )
106 {
107   _density_kgpm3 = SG_MAX2<double>(value * KG_PER_LBS / M3_PER_USGAL, 0.0);
108 }
109
110 double TankProperties::getContent_lbs() const
111 {
112   return _content_kg * LBS_PER_KG;
113 }
114
115 void TankProperties::setContent_lbs( double value )
116 {
117   _content_kg = SG_MAX2<double>(value * KG_PER_LBS, 0.0);
118 }
119
120 double TankProperties::getContent_m3() const
121 {
122   return _density_kgpm3 > SGLimitsd::min() ? _content_kg / _density_kgpm3 : 0.0;
123 }
124
125 void TankProperties::setContent_m3( double value )
126 {
127   // ugly hack to allow setting of a volumetric content without having the density
128   _content_kg = SG_MAX2<double>(value * (_density_kgpm3>0.0?_density_kgpm3:755.0), 0.0);
129 }
130
131 double TankProperties::getContent_gal_us() const
132 {
133   return getContent_m3() * USGAL_PER_M3;
134 }
135
136 void TankProperties::setContent_gal_us( double value )
137 {
138   setContent_m3( value * M3_PER_USGAL );
139 }
140
141 double TankProperties::getContent_gal_imp() const
142 {
143   return getContent_m3() * IMPGAL_PER_M3;
144 }
145
146 void TankProperties::setContent_gal_imp( double value )
147 {
148   setContent_m3( value * M3_PER_IMPGAL );
149 }
150
151 double TankProperties::getCapacity_m3() const
152 {
153   return _capacity_m3;
154 }
155
156 void TankProperties::setCapacity_m3( double value )
157 {
158   _capacity_m3 = SG_MAX2<double>(value, 0.0);
159 }
160
161 double TankProperties::getCapacity_gal_us() const
162 {
163   return _capacity_m3 * USGAL_PER_M3;
164 }
165
166 void TankProperties::setCapacity_gal_us( double value )
167 {
168   _capacity_m3 = SG_MAX2<double>(value * M3_PER_USGAL, 0.0);
169 }
170
171 double TankProperties::getCapacity_gal_imp() const
172 {
173   return _capacity_m3 * IMPGAL_PER_M3;
174 }
175
176 void TankProperties::setCapacity_gal_imp( double value )
177 {
178   _capacity_m3 = SG_MAX2<double>(value * M3_PER_IMPGAL, 0.0);
179 }
180
181 double TankProperties::getUnusable_m3() const
182 {
183   return _unusable_m3;
184 }
185
186 void TankProperties::setUnusable_m3( double value )
187 {
188   _unusable_m3 = SG_MAX2<double>(value, 0.0);
189 }
190
191 double TankProperties::getUnusable_gal_us() const
192 {
193   return _unusable_m3 * USGAL_PER_M3;
194 }
195
196 void TankProperties::setUnusable_gal_us( double value )
197 {
198   _unusable_m3 = SG_MAX2<double>(value * M3_PER_USGAL, 0.0);
199 }
200
201
202 double TankProperties::getUnusable_gal_imp() const
203 {
204   return _unusable_m3 * IMPGAL_PER_M3;
205 }
206
207 void TankProperties::setUnusable_gal_imp( double value )
208 {
209   _unusable_m3 = SG_MAX2<double>(value * M3_PER_IMPGAL, 0.0);
210 }
211
212 double TankProperties::getContent_norm() const
213 {
214   return  _capacity_m3 > SGLimitsd::min() ? getContent_m3() / _capacity_m3 : 0.0;
215 }
216
217 void TankProperties::setContent_norm( double value )
218 {
219   setContent_m3(_capacity_m3 * value);
220 }
221
222 bool TankProperties::getEmpty() const
223 {
224   return getContent_m3() <= _unusable_m3;
225 }
226
227 TankPropertiesList::TankPropertiesList( SGPropertyNode_ptr rootNode )
228 {
229   // we don't have a global rule how many tanks we support, so I assume eight.
230   // Because hard coded values suck, make it settable by a property.
231   // If tanks were configured, use that number
232   int n = rootNode->getChildren("tank").size();
233   if( n == 0 ) n = rootNode->getIntValue( "numtanks", 8 );
234   for( int i = 0; i < n; i++ ) {
235     push_back( new TankProperties( rootNode->getChild( "tank", i, true ) ) );
236   }
237
238   _tiedProperties.setRoot( rootNode );
239   _tiedProperties.Tie("total-fuel-kg", this, &TankPropertiesList::getTotalContent_kg );
240   _tiedProperties.Tie("total-fuel-lbs", this, &TankPropertiesList::getTotalContent_lbs );
241   _tiedProperties.Tie("total-fuel-gal_us", this, &TankPropertiesList::getTotalContent_gal_us );
242   _tiedProperties.Tie("total-fuel-gals", this, &TankPropertiesList::getTotalContent_gal_us );
243   _tiedProperties.Tie("total-fuel-gal_imp", this, &TankPropertiesList::getTotalContent_gal_imp );
244   _tiedProperties.Tie("total-fuel-norm", this, &TankPropertiesList::getTotalContent_norm );
245 }
246
247 double TankPropertiesList::getTotalContent_lbs() const
248 {
249   double value = 0.0;
250   for( const_iterator it = begin(); it != end(); ++it )
251     value += (*it)->getContent_lbs();
252   return value;
253 }
254
255 double TankPropertiesList::getTotalContent_kg() const
256 {
257   double value = 0.0;
258   for( const_iterator it = begin(); it != end(); ++it )
259     value += (*it)->getContent_kg();
260   return value;
261 }
262
263 double TankPropertiesList::getTotalContent_gal_us() const
264 {
265   double value = 0.0;
266   for( const_iterator it = begin(); it != end(); ++it )
267     value += (*it)->getContent_gal_us();
268   return value;
269 }
270
271 double TankPropertiesList::getTotalContent_gal_imp() const
272 {
273   double value = 0.0;
274   for( const_iterator it = begin(); it != end(); ++it )
275     value += (*it)->getContent_gal_imp();
276   return value;
277 }
278
279 double TankPropertiesList::getTotalContent_m3() const
280 {
281   double value = 0.0;
282   for( const_iterator it = begin(); it != end(); ++it )
283     value += (*it)->getContent_m3();
284   return value;
285 }
286
287 double TankPropertiesList::getTotalContent_norm() const
288 {
289   double content = 0.0;
290   double capacity = 0.0;
291   for( const_iterator it = begin(); it != end(); ++it ) {
292     content += (*it)->getContent_m3();
293     capacity += (*it)->getCapacity_m3();
294   }
295   return capacity > SGLimitsd::min() ? content / capacity : 0.0;
296 }
297
298 void TankPropertiesList::bind()
299 {
300     for( const_iterator it = begin(); it != end(); ++it ) {
301       (*it)->bind();
302     }
303 }
304
305 void TankPropertiesList::unbind()
306 {
307     for( const_iterator it = begin(); it != end(); ++it ) {
308       (*it)->unbind();
309     }
310     _tiedProperties.Untie();
311 }