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() :
kind(-1),
name(""),
value(0.0)
volts(0.0),
load_amps(0.0)
{
}
@ -117,6 +118,7 @@ FGElectricalBus::FGElectricalBus ( SGPropertyNode *node ) {
FGElectricalOutput::FGElectricalOutput ( SGPropertyNode *node ) {
kind = FG_OUTPUT;
output_amps = 0.1;
name = node->getStringValue("name");
int i;
@ -178,7 +180,10 @@ FGElectricalConnector::FGElectricalConnector ( SGPropertyNode *node,
// set default value of switch to true
// cout << "Switch = " << child->getStringValue() << endl;
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 ) {
// cout << "setting switch state to " << state << endl;
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() {
unsigned int i;
for ( i = 0; i < switches.size(); ++i ) {
if ( ! switches[i]->getBoolValue() ) {
if ( ! switches[i].get_state() ) {
return false;
}
}
@ -293,16 +298,20 @@ void FGElectricalSystem::update (double dt) {
// zero everything out before we start
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 ) {
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 ) {
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 ) {
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
@ -391,52 +400,68 @@ bool FGElectricalSystem::build () {
}
// propagate the electrical current through the network
void FGElectricalSystem::propagate( FGElectricalComponent *node, double val,
// propagate the electrical current through the network, returns the
// total current drawn by the children of this node.
float FGElectricalSystem::propagate( FGElectricalComponent *node, double val,
string s ) {
s += " ";
float current_amps = 0.0;
// determine the current to carry forward
double current = 0.0;
double volts = 0.0;
if ( !fgGetBool("/systems/electrical/serviceable") ) {
current = 0;
volts = 0;
} else if ( node->get_kind() == FG_SUPPLIER ) {
// cout << s << " is a supplier" << endl;
current = ((FGElectricalSupplier *)node)->get_output();
volts = ((FGElectricalSupplier *)node)->get_output();
} else if ( node->get_kind() == FG_BUS ) {
// cout << s << " is a bus" << endl;
current = val;
volts = val;
} else if ( node->get_kind() == FG_OUTPUT ) {
// 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 ) {
// cout << s << " is a connector" << endl;
if ( ((FGElectricalConnector *)node)->get_state() ) {
current = val;
volts = val;
} else {
current = 0.0;
volts = 0.0;
}
// cout << s << " val = " << current << endl;
// cout << s << " val = " << volts << endl;
} else {
SG_LOG( SG_ALL, SG_ALERT, "unkown node type" );
}
if ( current > node->get_value() ) {
node->set_value( current );
if ( volts > node->get_volts() ) {
node->set_volts( volts );
}
int i;
// publish values to specified properties
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;
// propagate to all children
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;
string name;
double value;
float volts;
float load_amps;
comp_list inputs;
comp_list outputs;
@ -76,8 +77,12 @@ public:
inline string get_name() { return name; }
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 FGElectricalComponent *get_input( const int i ) {
@ -146,10 +151,43 @@ public:
// flexibility
class FGElectricalOutput : public FGElectricalComponent {
private:
// number of amps drawn by this output
float output_amps;
public:
FGElectricalOutput ( SGPropertyNode *node );
~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 outputs;
typedef vector<SGPropertyNode *> switch_list;
typedef vector< FGElectricalSwitch> switch_list;
switch_list switches;
public:
@ -167,8 +205,8 @@ public:
FGElectricalConnector ( SGPropertyNode *node, FGElectricalSystem *es );
~FGElectricalConnector () {}
void add_switch( SGPropertyNode *node ) {
switches.push_back( node );
void add_switch( FGElectricalSwitch s ) {
switches.push_back( s );
}
// set all switches to the specified state
@ -197,7 +235,7 @@ public:
virtual void update (double dt);
bool build ();
void propagate( FGElectricalComponent *node, double val, string s = "" );
float propagate( FGElectricalComponent *node, double val, string s = "" );
FGElectricalComponent *find ( const string &name );
protected: