]> git.mxchange.org Git - flightgear.git/commitdiff
New feature: added <logic> "filters"
authortorsten <torsten>
Wed, 24 Feb 2010 22:15:48 +0000 (22:15 +0000)
committerTim Moore <timoore33@gmail.com>
Thu, 25 Feb 2010 22:21:41 +0000 (23:21 +0100)
"logic filters" use well known conditions to drive output properties. Example for bax = baz & (foo | bar).

 <logic>
    <name>my first logic element</name>
    <input>
      <or>
        <property>foo</property>
        <property>bar</property>
      </or>
      <property>baz</property>
    </input>
    <output>bax</output>
  </logic>

src/Autopilot/xmlauto.cxx
src/Autopilot/xmlauto.hxx

index 119083f66c7738b29b9a38d3ff8df91c5bb7939a..136ea647d3a0c889415d7b84e00a21e2f62cfe56 100644 (file)
@@ -848,9 +848,58 @@ void FGDigitalFilter::update(double dt)
     }
 }
 
+FGXMLAutoLogic::FGXMLAutoLogic(SGPropertyNode * node ) :
+    FGXMLAutoComponent(),
+    inverted(false)
+{
+    parseNode(node);
+}
+
+bool FGXMLAutoLogic::parseNodeHook(const std::string& aName, SGPropertyNode* aNode)
+{
+    if (aName == "input") {
+        input = sgReadCondition( fgGetNode("/"), aNode );
+    } else if (aName == "inverted") {
+        inverted = aNode->getBoolValue();
+    } else {
+        return false;
+    }
+  
+    return true;
+}
+
+void FGXMLAutoLogic::update(double dt)
+{
+    if ( isPropertyEnabled() ) {
+        if ( !enabled ) {
+            // we have just been enabled
+        }
+        enabled = true;
+    } else {
+        enabled = false;
+        do_feedback();
+    }
+
+    if ( !enabled || dt < SGLimitsd::min() ) 
+        return;
+
+    if( input == NULL ) {
+        if ( debug ) cout << "No input for " << get_name() << endl;
+        return;
+    }
+
+    bool i = input->test();
+
+    if ( debug ) cout << "Updating " << get_name() << ": " << (inverted ? !i : i) << endl;
+
+    set_output_value( i );
+}
+
+
 FGXMLAutopilotGroup::FGXMLAutopilotGroup() :
-  SGSubsystemGroup(),
-  average(0.0), // average/filtered prediction
+  SGSubsystemGroup()
+#ifdef XMLAUTO_USEHELPER
+  ,average(0.0), // average/filtered prediction
   v_last(0.0),  // last velocity
   last_static_pressure(0.0),
   vel(fgGetNode( "/velocities/airspeed-kt", true )),
@@ -874,6 +923,7 @@ FGXMLAutopilotGroup::FGXMLAutopilotGroup() :
   static_pressure(fgGetNode( "/systems/static[0]/pressure-inhg", true )),
   pressure_rate(fgGetNode( "/autopilot/internal/pressure-rate", true )),
   track(fgGetNode( "/orientation/track-deg", true ))
+#endif
 {
 }
 
@@ -881,7 +931,7 @@ void FGXMLAutopilotGroup::update( double dt )
 {
     // update all configured autopilots
     SGSubsystemGroup::update( dt );
-
+#ifdef XMLAUTO_USEHELPER
     // update helper values
     double v = vel->getDoubleValue();
     double a = 0.0;
@@ -940,6 +990,7 @@ void FGXMLAutopilotGroup::update( double dt )
         pressure_rate->setDoubleValue(current_pressure_rate);
         last_static_pressure = current_static_pressure;
     }
+#endif
 }
 
 void FGXMLAutopilotGroup::reinit()
@@ -1062,6 +1113,8 @@ bool FGXMLAutopilot::build( SGPropertyNode_ptr config_props ) {
             components.push_back( new FGPredictor( node ) );
         } else if ( name == "filter" ) {
             components.push_back( new FGDigitalFilter( node ) );
+        } else if ( name == "logic" ) {
+            components.push_back( new FGXMLAutoLogic( node ) );
         } else {
             SG_LOG( SG_AUTOPILOT, SG_WARN, "Unknown top level autopilot section: " << name );
 //            return false;
index 6d7d3f2aaf2478c6c1318ef105d8536990898523..d3b5fa34ea2daf32bd83c181d389c68cb1141bb7 100644 (file)
 #ifndef _XMLAUTO_HXX
 #define _XMLAUTO_HXX 1
 
+/* 
+Torsten Dreyer:
+I'd like to deprecate the so called autopilot helper function
+(which is now part of the AutopilotGroup::update() method).
+Every property calculated within this helper can be calculated
+using filters defined in an external autopilot definition file.
+The complete set of calculations may be extracted into a separate
+configuration file. The current implementation is able to hande 
+multiple config files and autopilots. The helper doubles code
+and writes properties used only by a few aircraft.
+*/
+// FIXME: this should go into config.h and/or configure
+// or removed along with the "helper" one day.
+#define XMLAUTO_USEHELPER
+
 #include <simgear/compiler.h>
 
 #include <string>
@@ -190,6 +205,17 @@ public:
           (*it)->setDoubleValue( clamp( value ) );
     }
 
+    inline void set_output_value( bool 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( std::vector <SGPropertyNode_ptr>::iterator it = output_list.begin(); it != output_list.end(); ++it)
+          (*it)->setBoolValue( value ); // don't use clamp here, bool is clamped anyway
+    }
+
     inline double get_output_value() {
       return output_list.size() == 0 ? 0.0 : clamp(output_list[0]->getDoubleValue());
     }
@@ -367,6 +393,22 @@ public:
     void update(double dt);
 };
 
+class FGXMLAutoLogic : public FGXMLAutoComponent
+{
+private:
+    SGSharedPtr<SGCondition> input;
+    bool inverted;
+
+protected:
+    bool parseNodeHook(const std::string& aName, SGPropertyNode* aNode);
+
+public:
+    FGXMLAutoLogic(SGPropertyNode * node );
+    ~FGXMLAutoLogic() {}
+
+    void update(double dt);
+};
+
 /**
  * Model an autopilot system.
  * 
@@ -382,6 +424,7 @@ public:
 private:
     std::vector<std::string> _autopilotNames;
 
+#ifdef XMLAUTO_USEHELPER
     double average;
     double v_last;
     double last_static_pressure;
@@ -406,6 +449,7 @@ private:
     SGPropertyNode_ptr static_pressure;
     SGPropertyNode_ptr pressure_rate;
     SGPropertyNode_ptr track;
+#endif
 };
 
 class FGXMLAutopilot : public SGSubsystem