#include "electrical.hxx"
-ElectricalSystem::ElectricalSystem ()
+
+FGElectricalSupplier::FGElectricalSupplier ( string _name, string _model,
+ double _volts, double _amps )
{
-}
+ kind = FG_SUPPLIER;
+
+ name = _name;
+ if ( _model == "battery" ) {
+ model = FG_BATTERY;
+ } else if ( _model == "alternator" ) {
+ model = FG_ALTERNATOR;
+ } else if ( _model == "external" ) {
+ model = FG_EXTERNAL;
+ } else {
+ model = FG_UNKNOWN;
+ }
+ volts = _volts;
+ amps = _amps;
+}
+
-ElectricalSystem::~ElectricalSystem ()
+FGElectricalBus::FGElectricalBus ( string _name )
{
-}
+ kind = FG_BUS;
+
+ name = _name;
+}
+
+
+FGElectricalOutput::FGElectricalOutput ( string _name )
+{
+ kind = FG_OUTPUT;
+
+ name = _name;
+}
-void
-ElectricalSystem::init ()
+
+FGElectricalConnector::FGElectricalConnector ()
+{
+ kind = FG_CONNECTOR;
+}
+
+
+FGElectricalSystem::FGElectricalSystem () :
+ enabled(false)
{
+}
+
+
+FGElectricalSystem::~FGElectricalSystem () {
+}
+
+
+void FGElectricalSystem::init () {
config_props = new SGPropertyNode;
SGPath config( globals->get_fg_root() );
<< config.str() );
try {
readProperties( config.str(), config_props );
+
+ if ( build() ) {
+ enabled = true;
+ } else {
+ SG_LOG( SG_ALL, SG_ALERT,
+ "Detected an internal inconsistancy in the electrical" );
+ SG_LOG( SG_ALL, SG_ALERT,
+ " system specification file. See earlier errors for" );
+ SG_LOG( SG_ALL, SG_ALERT,
+ " details.");
+ exit(-1);
+ }
} catch (const sg_exception& exc) {
SG_LOG( SG_ALL, SG_ALERT, "Failed to load electrical system model: "
<< config.str() );
delete config_props;
}
-void
-ElectricalSystem::bind ()
-{
+
+void FGElectricalSystem::bind () {
}
-void
-ElectricalSystem::unbind ()
-{
+
+void FGElectricalSystem::unbind () {
}
-void
-ElectricalSystem::update (double dt)
-{
+
+void FGElectricalSystem::update (double dt) {
+}
+
+
+bool FGElectricalSystem::build () {
+ SGPropertyNode *node;
+ int i, j;
+
+ int count = config_props->nChildren();
+ for ( i = 0; i < count; ++i ) {
+ node = config_props->getChild(i);
+ string name = node->getName();
+ // cout << name << endl;
+ if ( name == "supplier" ) {
+ FGElectricalSupplier *s =
+ new FGElectricalSupplier( node->getStringValue("name"),
+ node->getStringValue("kind"),
+ node->getDoubleValue("volts"),
+ node->getDoubleValue("amps") );
+ suppliers.push_back( s );
+ } else if ( name == "bus" ) {
+ FGElectricalBus *b =
+ new FGElectricalBus( node->getStringValue("name") );
+ buses.push_back( b );
+ } else if ( name == "output" ) {
+ FGElectricalOutput *o =
+ new FGElectricalOutput( node->getStringValue("name") );
+ outputs.push_back( o );
+ } else if ( name == "connector" ) {
+ FGElectricalConnector *c =
+ new FGElectricalConnector();
+ connectors.push_back( c );
+ SGPropertyNode *child;
+ int ccount = node->nChildren();
+ for ( j = 0; j < ccount; ++j ) {
+ child = node->getChild(j);
+ string cname = child->getName();
+ string cval = child->getStringValue();
+ // cout << " " << cname << " = " << cval << endl;
+ if ( cname == "input" ) {
+ FGElectricalComponent *s = find( child->getStringValue() );
+ if ( s != NULL ) {
+ c->add_input( s );
+ if ( s->get_kind() == FG_SUPPLIER ) {
+ ((FGElectricalSupplier *)s)->add_output( c );
+ } else if ( s->get_kind() == FG_BUS ) {
+ ((FGElectricalBus *)s)->add_output( c );
+ } else {
+ SG_LOG( SG_ALL, SG_ALERT,
+ "Attempt to connect to something that can't provide an output: "
+ << child->getStringValue() );
+ return false;
+ }
+ } else {
+ SG_LOG( SG_ALL, SG_ALERT,
+ "Can't find named source: "
+ << child->getStringValue() );
+ return false;
+ }
+ } else if ( cname == "output" ) {
+ FGElectricalComponent *s = find( child->getStringValue() );
+ if ( s != NULL ) {
+ c->add_output( s );
+ if ( s->get_kind() == FG_BUS ) {
+ ((FGElectricalBus *)s)->add_input( c );
+ } else if ( s->get_kind() == FG_OUTPUT ) {
+ ((FGElectricalOutput *)s)->add_input( c );
+ } else {
+ SG_LOG( SG_ALL, SG_ALERT,
+ "Attempt to connect to something that can't provide an input: "
+ << child->getStringValue() );
+ return false;
+ }
+ } else {
+ SG_LOG( SG_ALL, SG_ALERT,
+ "Can't find named source: "
+ << child->getStringValue() );
+ return false;
+ }
+ } else if ( cname == "switch" ) {
+ c->add_switch( child->getStringValue() );
+ }
+ }
+ } else {
+ SG_LOG( SG_ALL, SG_ALERT, "Unknown component type specified: "
+ << name );
+ return false;
+ }
+ }
+
+ return true;
+}
+
+
+// search for the named component and return a pointer to it, NULL otherwise
+FGElectricalComponent *FGElectricalSystem::find ( const string &name ) {
+ unsigned int i;
+ string s;
+
+ // search suppliers
+ for ( i = 0; i < suppliers.size(); ++i ) {
+ s = ((FGElectricalSupplier *)suppliers[i])->get_name();
+ // cout << " " << s << endl;
+ if ( s == name ) {
+ return suppliers[i];
+ }
+ }
+
+ // then search buses
+ for ( i = 0; i < buses.size(); ++i ) {
+ s = ((FGElectricalBus *)buses[i])->get_name();
+ // cout << " " << s << endl;
+ if ( s == name ) {
+ return buses[i];
+ }
+ }
+
+ // then search outputs
+ for ( i = 0; i < outputs.size(); ++i ) {
+ s = ((FGElectricalOutput *)outputs[i])->get_name();
+ // cout << " " << s << endl;
+ if ( s == name ) {
+ return outputs[i];
+ }
+ }
+
+ // nothing found
+ return NULL;
}
# error This library requires C++
#endif
+#ifdef HAVE_CONFIG_H
+# include <config.h>
+#endif
+
+#include STL_STRING
+#include <vector>
+
+SG_USING_STD(string);
+SG_USING_STD(vector);
+
#include <simgear/misc/props.hxx>
#include <Main/fgfs.hxx>
+#define FG_UNKNOWN -1
+#define FG_SUPPLIER 0
+#define FG_BUS 1
+#define FG_OUTPUT 2
+#define FG_CONNECTOR 3
+
+// Base class for other electrical components
+class FGElectricalComponent {
+
+ typedef vector<FGElectricalComponent *> comp_list;
+ typedef vector<string> string_list;
+
+public:
+
+ FGElectricalComponent() {}
+ virtual ~FGElectricalComponent() {}
+
+ virtual string get_name() { return ""; }
+
+ int kind;
+ inline int get_kind() { return kind; }
+};
+
+
+// Electrical supplier
+class FGElectricalSupplier : public FGElectricalComponent {
+
+ enum FGSupplierType {
+ FG_BATTERY = 0,
+ FG_ALTERNATOR = 1,
+ FG_EXTERNAL = 2
+ };
+
+ string name;
+ int model;
+ double volts;
+ double amps;
+
+ comp_list outputs;
+
+public:
+
+ FGElectricalSupplier ( string _name, string _model,
+ double _volts, double _amps );
+ ~FGElectricalSupplier () {}
+
+ void add_output( FGElectricalComponent *c ) {
+ outputs.push_back( c );
+ }
+
+ string get_name() const { return name; }
+};
+
+
+// Electrical bus (can take multiple inputs and provide multiple
+// outputs)
+class FGElectricalBus : public FGElectricalComponent {
+
+ string name;
+ comp_list inputs;
+ comp_list outputs;
+
+public:
+
+ FGElectricalBus ( string _name );
+ ~FGElectricalBus () {}
+
+ void add_input( FGElectricalComponent *c ) {
+ inputs.push_back( c );
+ }
+
+ void add_output( FGElectricalComponent *c ) {
+ outputs.push_back( c );
+ }
+
+ string get_name() const { return name; }
+};
+
+
+// A lot like an FGElectricalBus, but here for convenience and future
+// flexibility
+class FGElectricalOutput : public FGElectricalComponent {
+
+ string name;
+ comp_list inputs;
+
+public:
+
+ FGElectricalOutput ( string _name );
+ ~FGElectricalOutput () {}
+
+ void add_input( FGElectricalComponent *c ) {
+ inputs.push_back( c );
+ }
+
+ string get_name() const { return name; }
+};
+
+
+// Connects multiple sources to multiple destinations with optional
+// switches/fuses/circuit breakers inline
+class FGElectricalConnector : public FGElectricalComponent {
+
+ comp_list inputs;
+ comp_list outputs;
+ string_list switches;
+
+public:
+
+ FGElectricalConnector ();
+ ~FGElectricalConnector () {}
+
+ void add_input( FGElectricalComponent *c ) {
+ inputs.push_back( c );
+ }
+
+ void add_output( FGElectricalComponent *c ) {
+ outputs.push_back( c );
+ }
+
+ void add_switch( const string &s ) {
+ switches.push_back( s );
+ }
+
+ string get_name() const { return ""; }
+};
+
+
/**
* Model an electrical system. This is a simple system with the
* alternator hardwired to engine[0]/rpm
*
*/
-class ElectricalSystem : public FGSubsystem
+class FGElectricalSystem : public FGSubsystem
{
public:
- ElectricalSystem ();
- virtual ~ElectricalSystem ();
+ FGElectricalSystem ();
+ virtual ~FGElectricalSystem ();
virtual void init ();
virtual void bind ();
virtual void unbind ();
virtual void update (double dt);
+ bool build ();
+ FGElectricalComponent *find ( const string &name );
+
private:
SGPropertyNode *config_props;
// SGPropertyNode_ptr _serviceable_node;
-
+
+ bool enabled;
+
+ typedef vector<FGElectricalComponent *> comp_list;
+
+ comp_list suppliers;
+ comp_list buses;
+ comp_list outputs;
+ comp_list connectors;
};
+
#endif // _SYSTEMS_ELECTRICAL_HXX