pitot system stalls at high angles, using /system/pitot[x]/stall-deg
[fg:hoorays-flightgear.git] / src / Systems / electrical.hxx
1 // electrical.hxx - a flexible, generic electrical system model.
2 //
3 // Written by Curtis Olson, started September 2002.
4 //
5 // Copyright (C) 2002  Curtis L. Olson  - http://www.flightgear.org/~curt
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 // $Id$
22
23
24 #ifndef _SYSTEMS_ELECTRICAL_HXX
25 #define _SYSTEMS_ELECTRICAL_HXX 1
26
27 #ifndef __cplusplus
28 # error This library requires C++
29 #endif
30
31 #ifdef HAVE_CONFIG_H
32 #  include <config.h>
33 #endif
34
35 #include <string>
36 #include <vector>
37
38 using std::string;
39 using std::vector;
40
41 #include <simgear/props/props.hxx>
42 #include <simgear/structure/subsystem_mgr.hxx>
43
44
45 // Forward declaration
46 class FGElectricalSystem;
47
48
49 // Base class for other electrical components
50 class FGElectricalComponent {
51
52 public:
53
54 enum FGElectricalComponentType {
55     FG_UNKNOWN,
56     FG_SUPPLIER,
57     FG_BUS,
58     FG_OUTPUT,
59     FG_CONNECTOR
60 };
61
62 protected:
63
64     typedef vector<FGElectricalComponent *> comp_list;
65     typedef vector<string> string_list;
66
67     int kind;
68     string name;
69     float volts;
70     float load_amps;            // sum of current draw (load) due to
71                                 // this node and all it's children
72     float available_amps;       // available current (after the load
73                                 // is subtracted)
74
75     comp_list inputs;
76     comp_list outputs;
77     string_list props;
78
79 public:
80
81     FGElectricalComponent();
82     virtual ~FGElectricalComponent() {}
83
84     inline const string& get_name() { return name; }
85
86     inline int get_kind() const { return kind; }
87
88     inline float get_volts() const { return volts; }
89     inline void set_volts( float val ) { volts = val; }
90
91     inline float get_load_amps() const { return load_amps; }
92     inline void set_load_amps( float val ) { load_amps = val; }
93
94     inline float get_available_amps() const { return available_amps; }
95     inline void set_available_amps( float val ) { available_amps = val; }
96
97     inline int get_num_inputs() const { return outputs.size(); }
98     inline FGElectricalComponent *get_input( const int i ) {
99         return inputs[i];
100     }
101     inline void add_input( FGElectricalComponent *c ) {
102         inputs.push_back( c );
103     }
104
105     inline int get_num_outputs() const { return outputs.size(); }
106     inline FGElectricalComponent *get_output( const int i ) {
107         return outputs[i];
108     }
109     inline void add_output( FGElectricalComponent *c ) {
110         outputs.push_back( c );
111     }
112
113     inline int get_num_props() const { return props.size(); }
114     inline const string& get_prop( const int i ) {
115         return props[i];
116     }
117     inline void add_prop( const string &s ) {
118         props.push_back( s );
119     }
120
121 };
122
123
124 // Electrical supplier
125 class FGElectricalSupplier : public FGElectricalComponent {
126
127 public:
128
129     enum FGSupplierType {
130         FG_BATTERY,
131         FG_ALTERNATOR,
132         FG_EXTERNAL,
133         FG_UNKNOWN
134     };
135
136 private:
137
138     SGPropertyNode_ptr _rpm_node;
139
140     FGSupplierType model;       // store supplier type
141     float ideal_volts;          // ideal volts
142
143     // alternator fields
144     string rpm_src;             // property name of alternator power source
145     float rpm_threshold;        // minimal rpm to generate full power
146
147     // alt & ext supplier fields
148     float ideal_amps;           // total amps produced (above rpm threshold).
149
150     // battery fields
151     float amp_hours;            // fully charged battery capacity
152     float percent_remaining;    // percent of charge remaining
153     float charge_amps;          // maximum charge load battery can draw
154
155 public:
156
157     FGElectricalSupplier ( SGPropertyNode *node );
158     ~FGElectricalSupplier () {}
159
160     inline FGSupplierType get_model() const { return model; }
161     float apply_load( float amps, float dt );
162     float get_output_volts();
163     float get_output_amps();
164     float get_charge_amps() const { return charge_amps; }
165 };
166
167
168 // Electrical bus (can take multiple inputs and provide multiple
169 // outputs)
170 class FGElectricalBus : public FGElectricalComponent {
171
172 public:
173
174     FGElectricalBus ( SGPropertyNode *node );
175     ~FGElectricalBus () {}
176 };
177
178
179 // A lot like an FGElectricalBus, but here for convenience and future
180 // flexibility
181 class FGElectricalOutput : public FGElectricalComponent {
182
183 public:
184
185     FGElectricalOutput ( SGPropertyNode *node );
186     ~FGElectricalOutput () {}
187 };
188
189
190 // Model an electrical switch.  If the rating_amps > 0 then this
191 // becomes a circuit breaker type switch that can trip
192 class FGElectricalSwitch {
193
194 private:
195
196     SGPropertyNode_ptr switch_node;
197     float rating_amps;
198     bool circuit_breaker;
199
200 public:
201
202     FGElectricalSwitch( SGPropertyNode *node );
203
204     ~FGElectricalSwitch() { };
205
206     inline bool get_state() const { return switch_node->getBoolValue(); }
207     void set_state( bool val ) { switch_node->setBoolValue( val ); }
208 };
209
210
211 // Connects multiple sources to multiple destinations with optional
212 // switches/fuses/circuit breakers inline
213 class FGElectricalConnector : public FGElectricalComponent {
214
215     comp_list inputs;
216     comp_list outputs;
217     typedef vector< FGElectricalSwitch> switch_list;
218     switch_list switches;
219
220 public:
221
222     FGElectricalConnector ( SGPropertyNode *node, FGElectricalSystem *es );
223     ~FGElectricalConnector () {}
224
225     void add_switch( FGElectricalSwitch s ) {
226         switches.push_back( s );
227     }
228
229     // set all switches to the specified state
230     void set_switches( bool state );
231
232     bool get_state();
233 };
234
235
236 /**
237  * Model an electrical system.  This is a fairly simplistic system
238  * 
239  */
240
241 class FGElectricalSystem : public SGSubsystem
242 {
243
244 public:
245
246     FGElectricalSystem ( SGPropertyNode *node );
247     virtual ~FGElectricalSystem ();
248
249     virtual void init ();
250     virtual void bind ();
251     virtual void unbind ();
252     virtual void update (double dt);
253
254     bool build (SGPropertyNode* config_props);
255     float propagate( FGElectricalComponent *node, double dt,
256                      float input_volts, float input_amps,
257                      string s = "" );
258     FGElectricalComponent *find ( const string &name );
259
260 protected:
261
262     typedef vector<FGElectricalComponent *> comp_list;
263
264 private:
265
266     string name;
267     int num;
268     string path;
269
270     bool enabled;
271
272     comp_list suppliers;
273     comp_list buses;
274     comp_list outputs;
275     comp_list connectors;
276
277     SGPropertyNode_ptr _volts_out;
278     SGPropertyNode_ptr _amps_out;
279 };
280
281
282 #endif // _SYSTEMS_ELECTRICAL_HXX