]> git.mxchange.org Git - flightgear.git/blobdiff - src/Autopilot/xmlauto.hxx
Merge branch 'jmt/gpswidget'
[flightgear.git] / src / Autopilot / xmlauto.hxx
index 31c102900ee63ce3b2a88644228194fbc7b1b347..6d7d3f2aaf2478c6c1318ef105d8536990898523 100644 (file)
 #ifndef _XMLAUTO_HXX
 #define _XMLAUTO_HXX 1
 
-#ifndef __cplusplus
-# error This library requires C++
-#endif
-
-#ifdef HAVE_CONFIG_H
-#  include <config.h>
-#endif
-
 #include <simgear/compiler.h>
 
 #include <string>
 #include <vector>
 #include <deque>
 
-using std::string;
-using std::vector;
-using std::deque;
-
 #include <simgear/props/props.hxx>
 #include <simgear/structure/subsystem_mgr.hxx>
 #include <simgear/props/condition.hxx>
 
-#include <Main/fg_props.hxx>
+typedef SGSharedPtr<class FGXMLAutoInput> FGXMLAutoInput_ptr;
+typedef SGSharedPtr<class FGPeriodicalValue> FGPeriodicalValue_ptr;
 
+class FGPeriodicalValue : public SGReferenced {
+private:
+     FGXMLAutoInput_ptr minPeriod; // The minimum value of the period
+     FGXMLAutoInput_ptr maxPeriod; // The maximum value of the period
+public:
+     FGPeriodicalValue( SGPropertyNode_ptr node );
+     double normalize( double value );
+};
 
-class FGXMLAutoInput {
+class FGXMLAutoInput : public SGReferenced {
 private:
-     SGPropertyNode_ptr property; // The name of the property containing the value
      double             value;    // The value as a constant or initializer for the property
-     double             offset;   // A fixed offset
-     double             scale;    // A constant scaling factor
+     bool               abs;      // return absolute value
+     SGPropertyNode_ptr property; // The name of the property containing the value
+     FGXMLAutoInput_ptr offset;   // A fixed offset, defaults to zero
+     FGXMLAutoInput_ptr scale;    // A constant scaling factor defaults to one
+     FGXMLAutoInput_ptr min;      // A minimum clip defaults to no clipping
+     FGXMLAutoInput_ptr max;      // A maximum clip defaults to no clipping
+     FGPeriodicalValue_ptr  periodical; //
+     SGSharedPtr<const SGCondition> _condition;
 
 public:
-    FGXMLAutoInput() :
-      property(NULL),
-      value(0.0),
-      offset(0.0),
-      scale(1.0) {}
-
-    void   parse( SGPropertyNode_ptr, double value = 0.0, double offset = 0.0, double scale = 1.0 );
-    inline double getValue() {
-      if( property != NULL ) value = property->getDoubleValue();
-      return value * scale + offset;
+    FGXMLAutoInput( SGPropertyNode_ptr node = NULL, double value = 0.0, double offset = 0.0, double scale = 1.0 );
+    
+    void parse( SGPropertyNode_ptr, double value = 0.0, double offset = 0.0, double scale = 1.0 );
+
+    /* get the value of this input, apply scale and offset and clipping */
+    double get_value();
+
+    /* set the input value after applying offset and scale */
+    void set_value( double value );
+
+    inline double get_scale() {
+      return scale == NULL ? 1.0 : scale->get_value();
+    }
+
+    inline double get_offset() {
+      return offset == NULL ? 0.0 : offset->get_value();
+    }
+
+    inline bool is_enabled() {
+      return _condition == NULL ? true : _condition->test();
+    }
+
+};
+
+class FGXMLAutoInputList : public std::vector<FGXMLAutoInput_ptr> {
+  public:
+    FGXMLAutoInput_ptr get_active() {
+      for (iterator it = begin(); it != end(); ++it) {
+        if( (*it)->is_enabled() )
+          return *it;
+      }
+      return NULL;
+    }
+
+    double get_value( double def = 0.0 ) {
+      FGXMLAutoInput_ptr input = get_active();
+      return input == NULL ? def : input->get_value();
     }
+
 };
 
 /**
@@ -77,60 +107,91 @@ public:
 class FGXMLAutoComponent : public SGReferenced {
 
 private:
-    bool clamp;
-    vector <SGPropertyNode_ptr> output_list;
+    std::vector <SGPropertyNode_ptr> output_list;
 
     SGSharedPtr<const SGCondition> _condition;
     SGPropertyNode_ptr enable_prop;
-    string * enable_value;
+    std::string * enable_value;
 
     SGPropertyNode_ptr passive_mode;
     bool honor_passive;
 
-    string name;
-protected:
+    std::string name;
+
+    /* Feed back output property to input property if
+       this filter is disabled. This is for multi-stage
+       filter where one filter sits behind a pid-controller
+       to provide changes of the overall output to the pid-
+       controller.
+       feedback is disabled by default.
+     */
+    bool feedback_if_disabled;
+    void do_feedback_if_disabled();
 
-    FGXMLAutoInput valueInput;
-    FGXMLAutoInput referenceInput;
-    FGXMLAutoInput uminInput;
-    FGXMLAutoInput umaxInput;
+protected:
+    FGXMLAutoComponent();
+    
+    /*
+     * Parse a component specification read from a property-list.
+     * Calls the hook methods below to allow derived classes to
+     * specialise parsing bevaiour.
+     */
+    void parseNode(SGPropertyNode* aNode);
+
+    /**
+     * Helper to parse the config section
+     */
+    void parseConfig(SGPropertyNode* aConfig);
+
+    /*
+     * Over-rideable hook method to allow derived classes to refine top-level
+     * node parsing. Return true if the node was handled, false otherwise.
+     */
+    virtual bool parseNodeHook(const std::string& aName, SGPropertyNode* aNode);
+    
+    /**
+     * Over-rideable hook method to allow derived classes to refine config
+     * node parsing. Return true if the node was handled, false otherwise.
+     */
+    virtual bool parseConfigHook(const std::string& aName, SGPropertyNode* aNode);
+
+    FGXMLAutoInputList valueInput;
+    FGXMLAutoInputList referenceInput;
+    FGXMLAutoInputList uminInput;
+    FGXMLAutoInputList umaxInput;
+    FGPeriodicalValue_ptr periodical;
     // debug flag
     bool debug;
     bool enabled;
 
-public:
+    
+    inline void do_feedback() {
+        if( feedback_if_disabled ) do_feedback_if_disabled();
+    }
 
-    FGXMLAutoComponent( SGPropertyNode *node);
+public:
+    
     virtual ~FGXMLAutoComponent();
 
     virtual void update (double dt)=0;
     
-    inline const string& get_name() { return name; }
-
-    inline double Clamp( double value ) {
-        if( clamp ) {
-            double d = umaxInput.getValue();
-            if( value > d ) value = d;
-            d = uminInput.getValue();
-            if( value < d ) value = d;
-        }
-        return value;
-    }
+    inline const std::string& get_name() { return name; }
 
-    inline void setOutputValue( double value ) {
+    double clamp( double value );
+
+    inline void set_output_value( double value ) {
         // passive_ignore == true means that we go through all the
         // motions, but drive the outputs.  This is analogous to
         // running the autopilot with the "servos" off.  This is
         // helpful for things like flight directors which position
         // their vbars from the autopilot computations.
         if ( honor_passive && passive_mode->getBoolValue() ) return;
-        for ( unsigned i = 0; i < output_list.size(); ++i ) {
-            output_list[i]->setDoubleValue( Clamp(value) );
-        }
+        for( std::vector <SGPropertyNode_ptr>::iterator it = output_list.begin(); it != output_list.end(); ++it)
+          (*it)->setDoubleValue( clamp( value ) );
     }
 
-    inline double getOutputValue() {
-      return output_list.size() == 0 ? 0.0 : Clamp(output_list[0]->getDoubleValue());
+    inline double get_output_value() {
+      return output_list.size() == 0 ? 0.0 : clamp(output_list[0]->getDoubleValue());
     }
 
     /* 
@@ -173,6 +234,8 @@ public:
     bool isPropertyEnabled();
 };
 
+typedef SGSharedPtr<FGXMLAutoComponent> FGXMLAutoComponent_ptr;
+
 
 /**
  * Roy Ovesen's PID controller
@@ -184,9 +247,9 @@ private:
 
 
     // Configuration values
-    FGXMLAutoInput Kp;          // proportional gain
-    FGXMLAutoInput Ti;          // Integrator time (sec)
-    FGXMLAutoInput Td;          // Derivator time (sec)
+    FGXMLAutoInputList Kp;          // proportional gain
+    FGXMLAutoInputList Ti;          // Integrator time (sec)
+    FGXMLAutoInputList Td;          // Derivator time (sec)
 
     double alpha;               // low pass filter weighing factor (usually 0.1)
     double beta;                // process value weighing factor for
@@ -204,7 +267,9 @@ private:
     double desiredTs;            // desired sampling interval (sec)
     double elapsedTime;          // elapsed time (sec)
     
-    
+
+protected:
+  bool parseConfigHook(const std::string& aName, SGPropertyNode* aNode);
     
 public:
 
@@ -212,7 +277,6 @@ public:
     FGPIDController( SGPropertyNode *node, bool old );
     ~FGPIDController() {}
 
-    void update_old( double dt );
     void update( double dt );
 };
 
@@ -226,12 +290,14 @@ class FGPISimpleController : public FGXMLAutoComponent {
 private:
 
     // proportional component data
-    FGXMLAutoInput Kp;
+    FGXMLAutoInputList Kp;
 
     // integral component data
-    FGXMLAutoInput Ki;
+    FGXMLAutoInputList Ki;
     double int_sum;
 
+protected:
+  bool parseConfigHook(const std::string& aName, SGPropertyNode* aNode);
 
 public:
 
@@ -249,18 +315,15 @@ public:
 class FGPredictor : public FGXMLAutoComponent {
 
 private:
-
-    // proportional component data
     double last_value;
     double average;
-    double seconds;
-    double filter_gain;
+    FGXMLAutoInputList seconds;
+    FGXMLAutoInputList filter_gain;
 
-    // Input values
-    double ivalue;                 // input value
-    
-public:
+protected:
+  bool parseNodeHook(const std::string& aName, SGPropertyNode* aNode);
 
+public:
     FGPredictor( SGPropertyNode *node );
     ~FGPredictor() {}
 
@@ -283,17 +346,20 @@ public:
 class FGDigitalFilter : public FGXMLAutoComponent
 {
 private:
-    FGXMLAutoInput samplesInput; // Number of input samples to average
-    FGXMLAutoInput rateOfChangeInput;  // The maximum allowable rate of change [1/s]
-    FGXMLAutoInput gainInput;     // 
-    FGXMLAutoInput TfInput;            // Filter time [s]
+    FGXMLAutoInputList samplesInput; // Number of input samples to average
+    FGXMLAutoInputList rateOfChangeInput;  // The maximum allowable rate of change [1/s]
+    FGXMLAutoInputList gainInput;     // 
+    FGXMLAutoInputList TfInput;            // Filter time [s]
 
-    deque <double> output;
-    deque <double> input;
+    std::deque <double> output;
+    std::deque <double> input;
     enum filterTypes { exponential, doubleExponential, movingAverage,
-                       noiseSpike, gain, reciprocal };
+                       noiseSpike, gain, reciprocal, differential, none };
     filterTypes filterType;
 
+protected:
+  bool parseNodeHook(const std::string& aName, SGPropertyNode* aNode);
+  
 public:
     FGDigitalFilter(SGPropertyNode *node);
     ~FGDigitalFilter() {}
@@ -306,6 +372,42 @@ public:
  * 
  */
 
+class FGXMLAutopilotGroup : public SGSubsystemGroup
+{
+public:
+    FGXMLAutopilotGroup();
+    void init();
+    void reinit();
+    void update( double dt );
+private:
+    std::vector<std::string> _autopilotNames;
+
+    double average;
+    double v_last;
+    double last_static_pressure;
+
+    SGPropertyNode_ptr vel;
+    SGPropertyNode_ptr lookahead5;
+    SGPropertyNode_ptr lookahead10;
+    SGPropertyNode_ptr bug;
+    SGPropertyNode_ptr mag_hdg;
+    SGPropertyNode_ptr bug_error;
+    SGPropertyNode_ptr fdm_bug_error;
+    SGPropertyNode_ptr target_true;
+    SGPropertyNode_ptr true_hdg;
+    SGPropertyNode_ptr true_error;
+    SGPropertyNode_ptr target_nav1;
+    SGPropertyNode_ptr true_nav1;
+    SGPropertyNode_ptr true_track_nav1;
+    SGPropertyNode_ptr nav1_course_error;
+    SGPropertyNode_ptr nav1_selected_course;
+    SGPropertyNode_ptr vs_fps;
+    SGPropertyNode_ptr vs_fpm;
+    SGPropertyNode_ptr static_pressure;
+    SGPropertyNode_ptr pressure_rate;
+    SGPropertyNode_ptr track;
+};
+
 class FGXMLAutopilot : public SGSubsystem
 {
 
@@ -320,17 +422,15 @@ public:
     void unbind();
     void update( double dt );
 
-    bool build();
 
+    bool build( SGPropertyNode_ptr );
 protected:
-
-    typedef vector<SGSharedPtr<FGXMLAutoComponent> > comp_list;
+    typedef std::vector<FGXMLAutoComponent_ptr> comp_list;
 
 private:
-
     bool serviceable;
-    SGPropertyNode_ptr config_props;
     comp_list components;
+    
 };