FlightGear next
TankProperties.cxx
Go to the documentation of this file.
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
32static const double LBS_PER_KG = 2.20462262;
33static const double KG_PER_LBS = 1.0/LBS_PER_KG;
34static const double USGAL_PER_M3 = 1000.0/3.785411784;
35static const double M3_PER_USGAL = 1.0/USGAL_PER_M3;
36static const double IMPGAL_PER_M3 = 1000.0/4.54609;
37static const double M3_PER_IMPGAL = 1.0/IMPGAL_PER_M3;
38
39TankProperties::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
49{
56
61
64
67
68 _tiedProperties.Tie("empty", this, &TankProperties::getEmpty );
69}
70
74
76{
77 _tiedProperties.Untie();
78}
79
81{
82 return _content_kg;
83}
84
86{
87 _content_kg = SG_MAX2<double>(value, 0.0);
88}
89
91{
92 return _density_kgpm3;
93}
94
96{
97 _density_kgpm3 = SG_MAX2<double>(value, 0.0);
98}
99
104
106{
107 _density_kgpm3 = SG_MAX2<double>(value * KG_PER_LBS / M3_PER_USGAL, 0.0);
108}
109
111{
112 return _content_kg * LBS_PER_KG;
113}
114
116{
117 _content_kg = SG_MAX2<double>(value * KG_PER_LBS, 0.0);
118}
119
121{
122 return _density_kgpm3 > SGLimitsd::min() ? _content_kg / _density_kgpm3 : 0.0;
123}
124
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
132{
133 return getContent_m3() * USGAL_PER_M3;
134}
135
137{
138 setContent_m3( value * M3_PER_USGAL );
139}
140
142{
143 return getContent_m3() * IMPGAL_PER_M3;
144}
145
147{
148 setContent_m3( value * M3_PER_IMPGAL );
149}
150
152{
153 return _capacity_m3;
154}
155
157{
158 _capacity_m3 = SG_MAX2<double>(value, 0.0);
159}
160
162{
163 return _capacity_m3 * USGAL_PER_M3;
164}
165
167{
168 _capacity_m3 = SG_MAX2<double>(value * M3_PER_USGAL, 0.0);
169}
170
175
177{
178 _capacity_m3 = SG_MAX2<double>(value * M3_PER_IMPGAL, 0.0);
179}
180
182{
183 return _unusable_m3;
184}
185
187{
188 _unusable_m3 = SG_MAX2<double>(value, 0.0);
189}
190
192{
193 return _unusable_m3 * USGAL_PER_M3;
194}
195
197{
198 _unusable_m3 = SG_MAX2<double>(value * M3_PER_USGAL, 0.0);
199}
200
201
206
208{
209 _unusable_m3 = SG_MAX2<double>(value * M3_PER_IMPGAL, 0.0);
210}
211
213{
214 return _capacity_m3 > SGLimitsd::min() ? getContent_m3() / _capacity_m3 : 0.0;
215}
216
218{
220}
221
223{
224 return getContent_m3() <= _unusable_m3;
225}
226
227TankPropertiesList::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}
240
242{
243 double value = 0.0;
244 for( const_iterator it = begin(); it != end(); ++it )
245 value += (*it)->getContent_lbs();
246 return value;
247}
248
250{
251 double value = 0.0;
252 for( const_iterator it = begin(); it != end(); ++it )
253 value += (*it)->getContent_kg();
254 return value;
255}
256
258{
259 double value = 0.0;
260 for( const_iterator it = begin(); it != end(); ++it )
261 value += (*it)->getContent_gal_us();
262 return value;
263}
264
266{
267 double value = 0.0;
268 for( const_iterator it = begin(); it != end(); ++it )
269 value += (*it)->getContent_gal_imp();
270 return value;
271}
272
274{
275 double value = 0.0;
276 for( const_iterator it = begin(); it != end(); ++it )
277 value += (*it)->getContent_m3();
278 return value;
279}
280
282{
283 double content = 0.0;
284 double capacity = 0.0;
285 for( const_iterator it = begin(); it != end(); ++it ) {
286 content += (*it)->getContent_m3();
287 capacity += (*it)->getCapacity_m3();
288 }
289 return capacity > SGLimitsd::min() ? content / capacity : 0.0;
290}
291
293{
294 _tiedProperties.Tie("total-fuel-m3", this, &TankPropertiesList::getTotalContent_m3 );
295 _tiedProperties.Tie("total-fuel-kg", this, &TankPropertiesList::getTotalContent_kg );
296 _tiedProperties.Tie("total-fuel-lbs", this, &TankPropertiesList::getTotalContent_lbs );
297 _tiedProperties.Tie("total-fuel-gal_us", this, &TankPropertiesList::getTotalContent_gal_us );
298 _tiedProperties.Tie("total-fuel-gals", this, &TankPropertiesList::getTotalContent_gal_us );
299 _tiedProperties.Tie("total-fuel-gal_imp", this, &TankPropertiesList::getTotalContent_gal_imp );
300 _tiedProperties.Tie("total-fuel-norm", this, &TankPropertiesList::getTotalContent_norm );
301 for( const_iterator it = begin(); it != end(); ++it ) {
302 (*it)->bind();
303 }
304}
305
307{
308 for( const_iterator it = begin(); it != end(); ++it ) {
309 (*it)->unbind();
310 }
311 _tiedProperties.Untie();
312}
#define i(x)
static const double M3_PER_USGAL
static const double M3_PER_IMPGAL
static const double KG_PER_LBS
static const double IMPGAL_PER_M3
static const double LBS_PER_KG
static const double USGAL_PER_M3
double getTotalContent_gal_imp() const
double getTotalContent_lbs() const
double getTotalContent_m3() const
TankPropertiesList(SGPropertyNode_ptr rootNode)
double getTotalContent_gal_us() const
double getTotalContent_norm() const
double getTotalContent_kg() const
void setUnusable_gal_us(double value)
double getDensity_kgpm3() const
virtual ~TankProperties()
void setContent_kg(double value)
double getUnusable_m3() const
TankProperties(SGPropertyNode_ptr rootNode)
void setDensity_ppg(double value)
void setUnusable_m3(double value)
double getContent_gal_us() const
void setContent_gal_us(double value)
double getContent_kg() const
double getContent_norm() const
double getContent_lbs() const
double getContent_gal_imp() const
void setCapacity_gal_imp(double value)
void setContent_norm(double value)
double getCapacity_gal_imp() const
void setCapacity_m3(double value)
void setCapacity_gal_us(double value)
double getCapacity_gal_us() const
double getUnusable_gal_us() const
double getDensity_ppg() const
void setDensity_kgpm3(double value)
double getContent_m3() const
void setContent_m3(double value)
double getUnusable_gal_imp() const
simgear::TiedPropertyList _tiedProperties
void setContent_gal_imp(double value)
void setUnusable_gal_imp(double value)
bool getEmpty() const
void setContent_lbs(double value)
double getCapacity_m3() const