- introduce some typedefs for SGSharedPtr<>
- add a <period> element to input and output of each filter to support periodical values like headings. See README.digitalfilters for details.
This commit is contained in:
parent
179a799333
commit
506f6894e4
2 changed files with 72 additions and 13 deletions
|
@ -40,14 +40,42 @@
|
|||
using std::cout;
|
||||
using std::endl;
|
||||
|
||||
FGPeriodicalValue::FGPeriodicalValue( SGPropertyNode_ptr root )
|
||||
{
|
||||
SGPropertyNode_ptr minNode = root->getChild( "min" );
|
||||
SGPropertyNode_ptr maxNode = root->getChild( "max" );
|
||||
if( minNode == NULL || maxNode == NULL ) {
|
||||
SG_LOG(SG_AUTOPILOT, SG_ALERT, "periodical defined, but no <min> and/or <max> tag. Period ignored." );
|
||||
} else {
|
||||
minPeriod = new FGXMLAutoInput( minNode );
|
||||
maxPeriod = new FGXMLAutoInput( maxNode );
|
||||
}
|
||||
}
|
||||
|
||||
double FGPeriodicalValue::normalize( double value )
|
||||
{
|
||||
if( !(minPeriod && maxPeriod )) return value;
|
||||
|
||||
double p1 = minPeriod->get_value();
|
||||
double p2 = maxPeriod->get_value();
|
||||
|
||||
double min = std::min<double>(p1,p2);
|
||||
double max = std::max<double>(p1,p2);
|
||||
double phase = fabs(max - min);
|
||||
|
||||
if( phase > SGLimitsd::min() ) {
|
||||
while( value < min ) value += phase;
|
||||
while( value > max ) value -= phase;
|
||||
} else {
|
||||
value = min; // phase is zero
|
||||
}
|
||||
|
||||
return value;
|
||||
}
|
||||
|
||||
FGXMLAutoInput::FGXMLAutoInput( SGPropertyNode_ptr node, double value, double offset, double scale) :
|
||||
value(0.0),
|
||||
abs(false),
|
||||
property(NULL),
|
||||
offset(NULL),
|
||||
scale(NULL),
|
||||
min(NULL),
|
||||
max(NULL),
|
||||
_condition(NULL)
|
||||
{
|
||||
parse( node, value, offset, scale );
|
||||
|
@ -62,6 +90,7 @@ void FGXMLAutoInput::parse( SGPropertyNode_ptr node, double aValue, double aOffs
|
|||
scale = NULL;
|
||||
min = NULL;
|
||||
max = NULL;
|
||||
periodical = NULL;
|
||||
|
||||
if( node == NULL )
|
||||
return;
|
||||
|
@ -92,6 +121,10 @@ void FGXMLAutoInput::parse( SGPropertyNode_ptr node, double aValue, double aOffs
|
|||
abs = n->getBoolValue();
|
||||
}
|
||||
|
||||
if( (n = node->getChild( "period" )) != NULL ) {
|
||||
periodical = new FGPeriodicalValue( n );
|
||||
}
|
||||
|
||||
SGPropertyNode *valueNode = node->getChild( "value" );
|
||||
if ( valueNode != NULL ) {
|
||||
value = valueNode->getDoubleValue();
|
||||
|
@ -161,6 +194,10 @@ double FGXMLAutoInput::get_value()
|
|||
if( value > m )
|
||||
value = m;
|
||||
}
|
||||
|
||||
if( periodical ) {
|
||||
value = periodical->normalize( value );
|
||||
}
|
||||
|
||||
return abs ? fabs(value) : value;
|
||||
}
|
||||
|
@ -246,6 +283,8 @@ void FGXMLAutoComponent::parseNode(SGPropertyNode* aNode)
|
|||
umaxInput.push_back( new FGXMLAutoInput( child ) );
|
||||
} else if ( cname == "u_max" ) {
|
||||
umaxInput.push_back( new FGXMLAutoInput( child ) );
|
||||
} else if ( cname == "period" ) {
|
||||
periodical = new FGPeriodicalValue( child );
|
||||
} else {
|
||||
SG_LOG(SG_AUTOPILOT, SG_ALERT, "malformed autopilot definition - unrecognized node:"
|
||||
<< cname << " in section " << name);
|
||||
|
@ -314,6 +353,11 @@ void FGXMLAutoComponent::do_feedback_if_disabled()
|
|||
|
||||
double FGXMLAutoComponent::clamp( double value )
|
||||
{
|
||||
//If this is a periodical value, normalize it into our domain
|
||||
// before clamping
|
||||
if( periodical )
|
||||
value = periodical->normalize( value );
|
||||
|
||||
// clamp, if either min or max is defined
|
||||
if( uminInput.size() + umaxInput.size() > 0 ) {
|
||||
double d = umaxInput.get_value( 0.0 );
|
||||
|
|
|
@ -34,16 +34,28 @@
|
|||
#include <simgear/structure/subsystem_mgr.hxx>
|
||||
#include <simgear/props/condition.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 : public SGReferenced {
|
||||
private:
|
||||
double value; // The value as a constant or initializer for the property
|
||||
bool abs; // return absolute value
|
||||
SGPropertyNode_ptr property; // The name of the property containing the value
|
||||
SGSharedPtr<FGXMLAutoInput> offset; // A fixed offset, defaults to zero
|
||||
SGSharedPtr<FGXMLAutoInput> scale; // A constant scaling factor defaults to one
|
||||
SGSharedPtr<FGXMLAutoInput> min; // A minimum clip defaults to no clipping
|
||||
SGSharedPtr<FGXMLAutoInput> max; // A maximum clip defaults to no clipping
|
||||
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:
|
||||
|
@ -71,9 +83,9 @@ public:
|
|||
|
||||
};
|
||||
|
||||
class FGXMLAutoInputList : public std::vector<SGSharedPtr<FGXMLAutoInput> > {
|
||||
class FGXMLAutoInputList : public std::vector<FGXMLAutoInput_ptr> {
|
||||
public:
|
||||
FGXMLAutoInput * get_active() {
|
||||
FGXMLAutoInput_ptr get_active() {
|
||||
for (iterator it = begin(); it != end(); ++it) {
|
||||
if( (*it)->is_enabled() )
|
||||
return *it;
|
||||
|
@ -82,7 +94,7 @@ class FGXMLAutoInputList : public std::vector<SGSharedPtr<FGXMLAutoInput> > {
|
|||
}
|
||||
|
||||
double get_value( double def = 0.0 ) {
|
||||
FGXMLAutoInput * input = get_active();
|
||||
FGXMLAutoInput_ptr input = get_active();
|
||||
return input == NULL ? def : input->get_value();
|
||||
}
|
||||
|
||||
|
@ -147,6 +159,7 @@ protected:
|
|||
FGXMLAutoInputList referenceInput;
|
||||
FGXMLAutoInputList uminInput;
|
||||
FGXMLAutoInputList umaxInput;
|
||||
FGPeriodicalValue_ptr periodical;
|
||||
// debug flag
|
||||
bool debug;
|
||||
bool enabled;
|
||||
|
@ -221,6 +234,8 @@ public:
|
|||
bool isPropertyEnabled();
|
||||
};
|
||||
|
||||
typedef SGSharedPtr<FGXMLAutoComponent> FGXMLAutoComponent_ptr;
|
||||
|
||||
|
||||
/**
|
||||
* Roy Ovesen's PID controller
|
||||
|
@ -384,7 +399,7 @@ public:
|
|||
|
||||
bool build( SGPropertyNode_ptr );
|
||||
protected:
|
||||
typedef std::vector<SGSharedPtr<FGXMLAutoComponent> > comp_list;
|
||||
typedef std::vector<FGXMLAutoComponent_ptr> comp_list;
|
||||
|
||||
private:
|
||||
|
||||
|
|
Loading…
Reference in a new issue