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() :
|
||||
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;
|
||||
}
|
||||
|
||||
|
||||
|
|
|
@ -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:
|
||||
|
|
Loading…
Reference in a new issue