From c06bf498a9f1ca405a5a1785ccf27d0f2d6d1f74 Mon Sep 17 00:00:00 2001 From: curt Date: Sat, 15 Nov 2003 05:18:55 +0000 Subject: [PATCH] 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. --- src/Systems/electrical.cxx | 69 ++++++++++++++++++++++++++------------ src/Systems/electrical.hxx | 52 ++++++++++++++++++++++++---- 2 files changed, 92 insertions(+), 29 deletions(-) diff --git a/src/Systems/electrical.cxx b/src/Systems/electrical.cxx index d2bb01c59..8e6cbc2b9 100644 --- a/src/Systems/electrical.cxx +++ b/src/Systems/electrical.cxx @@ -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; } diff --git a/src/Systems/electrical.hxx b/src/Systems/electrical.hxx index fee71cf0b..16a86ba8e 100644 --- a/src/Systems/electrical.hxx +++ b/src/Systems/electrical.hxx @@ -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 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: