New feature: added <logic> "filters"
"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>
This commit is contained in:
parent
4ae8c90f76
commit
90e313a8dd
2 changed files with 100 additions and 3 deletions
src/Autopilot
|
@ -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() :
|
FGXMLAutopilotGroup::FGXMLAutopilotGroup() :
|
||||||
SGSubsystemGroup(),
|
SGSubsystemGroup()
|
||||||
average(0.0), // average/filtered prediction
|
#ifdef XMLAUTO_USEHELPER
|
||||||
|
,average(0.0), // average/filtered prediction
|
||||||
v_last(0.0), // last velocity
|
v_last(0.0), // last velocity
|
||||||
last_static_pressure(0.0),
|
last_static_pressure(0.0),
|
||||||
vel(fgGetNode( "/velocities/airspeed-kt", true )),
|
vel(fgGetNode( "/velocities/airspeed-kt", true )),
|
||||||
|
@ -874,6 +923,7 @@ FGXMLAutopilotGroup::FGXMLAutopilotGroup() :
|
||||||
static_pressure(fgGetNode( "/systems/static[0]/pressure-inhg", true )),
|
static_pressure(fgGetNode( "/systems/static[0]/pressure-inhg", true )),
|
||||||
pressure_rate(fgGetNode( "/autopilot/internal/pressure-rate", true )),
|
pressure_rate(fgGetNode( "/autopilot/internal/pressure-rate", true )),
|
||||||
track(fgGetNode( "/orientation/track-deg", true ))
|
track(fgGetNode( "/orientation/track-deg", true ))
|
||||||
|
#endif
|
||||||
{
|
{
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -881,7 +931,7 @@ void FGXMLAutopilotGroup::update( double dt )
|
||||||
{
|
{
|
||||||
// update all configured autopilots
|
// update all configured autopilots
|
||||||
SGSubsystemGroup::update( dt );
|
SGSubsystemGroup::update( dt );
|
||||||
|
#ifdef XMLAUTO_USEHELPER
|
||||||
// update helper values
|
// update helper values
|
||||||
double v = vel->getDoubleValue();
|
double v = vel->getDoubleValue();
|
||||||
double a = 0.0;
|
double a = 0.0;
|
||||||
|
@ -940,6 +990,7 @@ void FGXMLAutopilotGroup::update( double dt )
|
||||||
pressure_rate->setDoubleValue(current_pressure_rate);
|
pressure_rate->setDoubleValue(current_pressure_rate);
|
||||||
last_static_pressure = current_static_pressure;
|
last_static_pressure = current_static_pressure;
|
||||||
}
|
}
|
||||||
|
#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
void FGXMLAutopilotGroup::reinit()
|
void FGXMLAutopilotGroup::reinit()
|
||||||
|
@ -1062,6 +1113,8 @@ bool FGXMLAutopilot::build( SGPropertyNode_ptr config_props ) {
|
||||||
components.push_back( new FGPredictor( node ) );
|
components.push_back( new FGPredictor( node ) );
|
||||||
} else if ( name == "filter" ) {
|
} else if ( name == "filter" ) {
|
||||||
components.push_back( new FGDigitalFilter( node ) );
|
components.push_back( new FGDigitalFilter( node ) );
|
||||||
|
} else if ( name == "logic" ) {
|
||||||
|
components.push_back( new FGXMLAutoLogic( node ) );
|
||||||
} else {
|
} else {
|
||||||
SG_LOG( SG_AUTOPILOT, SG_WARN, "Unknown top level autopilot section: " << name );
|
SG_LOG( SG_AUTOPILOT, SG_WARN, "Unknown top level autopilot section: " << name );
|
||||||
// return false;
|
// return false;
|
||||||
|
|
|
@ -24,6 +24,21 @@
|
||||||
#ifndef _XMLAUTO_HXX
|
#ifndef _XMLAUTO_HXX
|
||||||
#define _XMLAUTO_HXX 1
|
#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 <simgear/compiler.h>
|
||||||
|
|
||||||
#include <string>
|
#include <string>
|
||||||
|
@ -190,6 +205,17 @@ public:
|
||||||
(*it)->setDoubleValue( clamp( value ) );
|
(*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() {
|
inline double get_output_value() {
|
||||||
return output_list.size() == 0 ? 0.0 : clamp(output_list[0]->getDoubleValue());
|
return output_list.size() == 0 ? 0.0 : clamp(output_list[0]->getDoubleValue());
|
||||||
}
|
}
|
||||||
|
@ -367,6 +393,22 @@ public:
|
||||||
void update(double dt);
|
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.
|
* Model an autopilot system.
|
||||||
*
|
*
|
||||||
|
@ -382,6 +424,7 @@ public:
|
||||||
private:
|
private:
|
||||||
std::vector<std::string> _autopilotNames;
|
std::vector<std::string> _autopilotNames;
|
||||||
|
|
||||||
|
#ifdef XMLAUTO_USEHELPER
|
||||||
double average;
|
double average;
|
||||||
double v_last;
|
double v_last;
|
||||||
double last_static_pressure;
|
double last_static_pressure;
|
||||||
|
@ -406,6 +449,7 @@ private:
|
||||||
SGPropertyNode_ptr static_pressure;
|
SGPropertyNode_ptr static_pressure;
|
||||||
SGPropertyNode_ptr pressure_rate;
|
SGPropertyNode_ptr pressure_rate;
|
||||||
SGPropertyNode_ptr track;
|
SGPropertyNode_ptr track;
|
||||||
|
#endif
|
||||||
};
|
};
|
||||||
|
|
||||||
class FGXMLAutopilot : public SGSubsystem
|
class FGXMLAutopilot : public SGSubsystem
|
||||||
|
|
Loading…
Add table
Reference in a new issue