1
0
Fork 0

Additions to the electrical system model to allow it to back propagate

current draw.  This is only one piece of the puzzle, but as we move forward,
the idea is better modeling of the ammeter, and we could automatically pop
circuit breakers if the current gets too high.
This commit is contained in:
curt 2003-11-15 05:18:55 +00:00
parent 0f5cd84864
commit c06bf498a9
2 changed files with 92 additions and 29 deletions

View file

@ -33,7 +33,8 @@
FGElectricalComponent::FGElectricalComponent() : FGElectricalComponent::FGElectricalComponent() :
kind(-1), kind(-1),
name(""), name(""),
value(0.0) volts(0.0),
load_amps(0.0)
{ {
} }
@ -117,6 +118,7 @@ FGElectricalBus::FGElectricalBus ( SGPropertyNode *node ) {
FGElectricalOutput::FGElectricalOutput ( SGPropertyNode *node ) { FGElectricalOutput::FGElectricalOutput ( SGPropertyNode *node ) {
kind = FG_OUTPUT; kind = FG_OUTPUT;
output_amps = 0.1;
name = node->getStringValue("name"); name = node->getStringValue("name");
int i; int i;
@ -178,7 +180,10 @@ FGElectricalConnector::FGElectricalConnector ( SGPropertyNode *node,
// set default value of switch to true // set default value of switch to true
// cout << "Switch = " << child->getStringValue() << endl; // cout << "Switch = " << child->getStringValue() << endl;
fgSetBool( child->getStringValue(), true ); fgSetBool( child->getStringValue(), true );
add_switch( fgGetNode( child->getStringValue(), true ) ); FGElectricalSwitch s( fgGetNode(child->getStringValue(), true),
100.0f,
false );
add_switch( s );
} }
} }
@ -203,7 +208,7 @@ FGElectricalConnector::FGElectricalConnector ( SGPropertyNode *node,
void FGElectricalConnector::set_switches( bool state ) { void FGElectricalConnector::set_switches( bool state ) {
// cout << "setting switch state to " << state << endl; // cout << "setting switch state to " << state << endl;
for ( unsigned int i = 0; i < switches.size(); ++i ) { for ( unsigned int i = 0; i < switches.size(); ++i ) {
switches[i]->setBoolValue( state ); switches[i].set_state( state );
} }
} }
@ -214,7 +219,7 @@ void FGElectricalConnector::set_switches( bool state ) {
bool FGElectricalConnector::get_state() { bool FGElectricalConnector::get_state() {
unsigned int i; unsigned int i;
for ( i = 0; i < switches.size(); ++i ) { for ( i = 0; i < switches.size(); ++i ) {
if ( ! switches[i]->getBoolValue() ) { if ( ! switches[i].get_state() ) {
return false; return false;
} }
} }
@ -293,16 +298,20 @@ void FGElectricalSystem::update (double dt) {
// zero everything out before we start // zero everything out before we start
for ( i = 0; i < suppliers.size(); ++i ) { for ( i = 0; i < suppliers.size(); ++i ) {
suppliers[i]->set_value( 0.0 ); suppliers[i]->set_volts( 0.0 );
suppliers[i]->set_load_amps( 0.0 );
} }
for ( i = 0; i < buses.size(); ++i ) { for ( i = 0; i < buses.size(); ++i ) {
buses[i]->set_value( 0.0 ); buses[i]->set_volts( 0.0 );
buses[i]->set_load_amps( 0.0 );
} }
for ( i = 0; i < outputs.size(); ++i ) { for ( i = 0; i < outputs.size(); ++i ) {
outputs[i]->set_value( 0.0 ); outputs[i]->set_volts( 0.0 );
outputs[i]->set_load_amps( 0.0 );
} }
for ( i = 0; i < connectors.size(); ++i ) { for ( i = 0; i < connectors.size(); ++i ) {
connectors[i]->set_value( 0.0 ); connectors[i]->set_volts( 0.0 );
connectors[i]->set_load_amps( 0.0 );
} }
// for each supplier, propagate the electrical current // for each supplier, propagate the electrical current
@ -391,52 +400,68 @@ bool FGElectricalSystem::build () {
} }
// propagate the electrical current through the network // propagate the electrical current through the network, returns the
void FGElectricalSystem::propagate( FGElectricalComponent *node, double val, // total current drawn by the children of this node.
float FGElectricalSystem::propagate( FGElectricalComponent *node, double val,
string s ) { string s ) {
s += " "; s += " ";
float current_amps = 0.0;
// determine the current to carry forward // determine the current to carry forward
double current = 0.0; double volts = 0.0;
if ( !fgGetBool("/systems/electrical/serviceable") ) { if ( !fgGetBool("/systems/electrical/serviceable") ) {
current = 0; volts = 0;
} else if ( node->get_kind() == FG_SUPPLIER ) { } else if ( node->get_kind() == FG_SUPPLIER ) {
// cout << s << " is a supplier" << endl; // cout << s << " is a supplier" << endl;
current = ((FGElectricalSupplier *)node)->get_output(); volts = ((FGElectricalSupplier *)node)->get_output();
} else if ( node->get_kind() == FG_BUS ) { } else if ( node->get_kind() == FG_BUS ) {
// cout << s << " is a bus" << endl; // cout << s << " is a bus" << endl;
current = val; volts = val;
} else if ( node->get_kind() == FG_OUTPUT ) { } else if ( node->get_kind() == FG_OUTPUT ) {
// cout << s << " is an output" << endl; // cout << s << " is an output" << endl;
current = val; volts = val;
if ( volts > 1.0 ) {
// draw current if we have voltage
current_amps = ((FGElectricalOutput *)node)->get_output_amps();
}
} else if ( node->get_kind() == FG_CONNECTOR ) { } else if ( node->get_kind() == FG_CONNECTOR ) {
// cout << s << " is a connector" << endl; // cout << s << " is a connector" << endl;
if ( ((FGElectricalConnector *)node)->get_state() ) { if ( ((FGElectricalConnector *)node)->get_state() ) {
current = val; volts = val;
} else { } else {
current = 0.0; volts = 0.0;
} }
// cout << s << " val = " << current << endl; // cout << s << " val = " << volts << endl;
} else { } else {
SG_LOG( SG_ALL, SG_ALERT, "unkown node type" ); SG_LOG( SG_ALL, SG_ALERT, "unkown node type" );
} }
if ( current > node->get_value() ) { if ( volts > node->get_volts() ) {
node->set_value( current ); node->set_volts( volts );
} }
int i; int i;
// publish values to specified properties // publish values to specified properties
for ( i = 0; i < node->get_num_props(); ++i ) { for ( i = 0; i < node->get_num_props(); ++i ) {
fgSetDouble( node->get_prop(i).c_str(), node->get_value() ); fgSetDouble( node->get_prop(i).c_str(), node->get_volts() );
} }
// cout << s << node->get_name() << " -> " << node->get_value() << endl; // cout << s << node->get_name() << " -> " << node->get_value() << endl;
// propagate to all children // propagate to all children
for ( i = 0; i < node->get_num_outputs(); ++i ) { for ( i = 0; i < node->get_num_outputs(); ++i ) {
propagate( node->get_output(i), current, s ); current_amps += propagate( node->get_output(i), volts, s );
} }
// if not an output node, register the downstream current draw
// with this node. If volts are zero, current draw should be zero.
if ( node->get_kind() != FG_OUTPUT ) {
node->set_load_amps( current_amps );
}
// cout << s << node->get_name() << " -> " << current_amps << endl;
return current_amps;
} }

View file

@ -62,7 +62,8 @@ protected:
int kind; int kind;
string name; string name;
double value; float volts;
float load_amps;
comp_list inputs; comp_list inputs;
comp_list outputs; comp_list outputs;
@ -76,8 +77,12 @@ public:
inline string get_name() { return name; } inline string get_name() { return name; }
inline int get_kind() const { return kind; } inline int get_kind() const { return kind; }
inline double get_value() const { return value; }
inline void set_value( double val ) { value = val; } inline float get_volts() const { return volts; }
inline void set_volts( float val ) { volts = val; }
inline float get_load_amps() const { return load_amps; }
inline void set_load_amps( float val ) { load_amps = val; }
inline int get_num_inputs() const { return outputs.size(); } inline int get_num_inputs() const { return outputs.size(); }
inline FGElectricalComponent *get_input( const int i ) { inline FGElectricalComponent *get_input( const int i ) {
@ -146,10 +151,43 @@ public:
// flexibility // flexibility
class FGElectricalOutput : public FGElectricalComponent { class FGElectricalOutput : public FGElectricalComponent {
private:
// number of amps drawn by this output
float output_amps;
public: public:
FGElectricalOutput ( SGPropertyNode *node ); FGElectricalOutput ( SGPropertyNode *node );
~FGElectricalOutput () {} ~FGElectricalOutput () {}
inline float get_output_amps() const { return output_amps; }
inline void set_output_amps( float val ) { output_amps = val; }
};
// Model an electrical switch. If the rating_amps > 0 then this
// becomes a circuit breaker type switch that can trip
class FGElectricalSwitch {
private:
SGPropertyNode *switch_node;
float rating_amps;
bool circuit_breaker;
public:
FGElectricalSwitch( SGPropertyNode *node, float rate, bool cb ) {
switch_node = node;
rating_amps = rate;
circuit_breaker = cb;
}
~FGElectricalSwitch() { };
inline bool get_state() const { return switch_node->getBoolValue(); }
void set_state( bool val ) { switch_node->setBoolValue( val ); }
}; };
@ -159,7 +197,7 @@ class FGElectricalConnector : public FGElectricalComponent {
comp_list inputs; comp_list inputs;
comp_list outputs; comp_list outputs;
typedef vector<SGPropertyNode *> switch_list; typedef vector< FGElectricalSwitch> switch_list;
switch_list switches; switch_list switches;
public: public:
@ -167,8 +205,8 @@ public:
FGElectricalConnector ( SGPropertyNode *node, FGElectricalSystem *es ); FGElectricalConnector ( SGPropertyNode *node, FGElectricalSystem *es );
~FGElectricalConnector () {} ~FGElectricalConnector () {}
void add_switch( SGPropertyNode *node ) { void add_switch( FGElectricalSwitch s ) {
switches.push_back( node ); switches.push_back( s );
} }
// set all switches to the specified state // set all switches to the specified state
@ -197,7 +235,7 @@ public:
virtual void update (double dt); virtual void update (double dt);
bool build (); bool build ();
void propagate( FGElectricalComponent *node, double val, string s = "" ); float propagate( FGElectricalComponent *node, double val, string s = "" );
FGElectricalComponent *find ( const string &name ); FGElectricalComponent *find ( const string &name );
protected: protected: