}
}
+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 )),
static_pressure(fgGetNode( "/systems/static[0]/pressure-inhg", true )),
pressure_rate(fgGetNode( "/autopilot/internal/pressure-rate", true )),
track(fgGetNode( "/orientation/track-deg", true ))
+#endif
{
}
{
// update all configured autopilots
SGSubsystemGroup::update( dt );
-
+#ifdef XMLAUTO_USEHELPER
// update helper values
double v = vel->getDoubleValue();
double a = 0.0;
pressure_rate->setDoubleValue(current_pressure_rate);
last_static_pressure = current_static_pressure;
}
+#endif
}
void FGXMLAutopilotGroup::reinit()
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;
#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>
(*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());
}
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.
*
private:
std::vector<std::string> _autopilotNames;
+#ifdef XMLAUTO_USEHELPER
double average;
double v_last;
double last_static_pressure;
SGPropertyNode_ptr static_pressure;
SGPropertyNode_ptr pressure_rate;
SGPropertyNode_ptr track;
+#endif
};
class FGXMLAutopilot : public SGSubsystem