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:
parent
0f5cd84864
commit
c06bf498a9
2 changed files with 92 additions and 29 deletions
|
@ -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;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
|
@ -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:
|
||||||
|
|
Loading…
Reference in a new issue