- 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::cout;
|
||||||
using std::endl;
|
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) :
|
FGXMLAutoInput::FGXMLAutoInput( SGPropertyNode_ptr node, double value, double offset, double scale) :
|
||||||
value(0.0),
|
value(0.0),
|
||||||
abs(false),
|
abs(false),
|
||||||
property(NULL),
|
|
||||||
offset(NULL),
|
|
||||||
scale(NULL),
|
|
||||||
min(NULL),
|
|
||||||
max(NULL),
|
|
||||||
_condition(NULL)
|
_condition(NULL)
|
||||||
{
|
{
|
||||||
parse( node, value, offset, scale );
|
parse( node, value, offset, scale );
|
||||||
|
@ -62,6 +90,7 @@ void FGXMLAutoInput::parse( SGPropertyNode_ptr node, double aValue, double aOffs
|
||||||
scale = NULL;
|
scale = NULL;
|
||||||
min = NULL;
|
min = NULL;
|
||||||
max = NULL;
|
max = NULL;
|
||||||
|
periodical = NULL;
|
||||||
|
|
||||||
if( node == NULL )
|
if( node == NULL )
|
||||||
return;
|
return;
|
||||||
|
@ -92,6 +121,10 @@ void FGXMLAutoInput::parse( SGPropertyNode_ptr node, double aValue, double aOffs
|
||||||
abs = n->getBoolValue();
|
abs = n->getBoolValue();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if( (n = node->getChild( "period" )) != NULL ) {
|
||||||
|
periodical = new FGPeriodicalValue( n );
|
||||||
|
}
|
||||||
|
|
||||||
SGPropertyNode *valueNode = node->getChild( "value" );
|
SGPropertyNode *valueNode = node->getChild( "value" );
|
||||||
if ( valueNode != NULL ) {
|
if ( valueNode != NULL ) {
|
||||||
value = valueNode->getDoubleValue();
|
value = valueNode->getDoubleValue();
|
||||||
|
@ -161,6 +194,10 @@ double FGXMLAutoInput::get_value()
|
||||||
if( value > m )
|
if( value > m )
|
||||||
value = m;
|
value = m;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if( periodical ) {
|
||||||
|
value = periodical->normalize( value );
|
||||||
|
}
|
||||||
|
|
||||||
return abs ? fabs(value) : value;
|
return abs ? fabs(value) : value;
|
||||||
}
|
}
|
||||||
|
@ -246,6 +283,8 @@ void FGXMLAutoComponent::parseNode(SGPropertyNode* aNode)
|
||||||
umaxInput.push_back( new FGXMLAutoInput( child ) );
|
umaxInput.push_back( new FGXMLAutoInput( child ) );
|
||||||
} else if ( cname == "u_max" ) {
|
} else if ( cname == "u_max" ) {
|
||||||
umaxInput.push_back( new FGXMLAutoInput( child ) );
|
umaxInput.push_back( new FGXMLAutoInput( child ) );
|
||||||
|
} else if ( cname == "period" ) {
|
||||||
|
periodical = new FGPeriodicalValue( child );
|
||||||
} else {
|
} else {
|
||||||
SG_LOG(SG_AUTOPILOT, SG_ALERT, "malformed autopilot definition - unrecognized node:"
|
SG_LOG(SG_AUTOPILOT, SG_ALERT, "malformed autopilot definition - unrecognized node:"
|
||||||
<< cname << " in section " << name);
|
<< cname << " in section " << name);
|
||||||
|
@ -314,6 +353,11 @@ void FGXMLAutoComponent::do_feedback_if_disabled()
|
||||||
|
|
||||||
double FGXMLAutoComponent::clamp( double value )
|
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
|
// clamp, if either min or max is defined
|
||||||
if( uminInput.size() + umaxInput.size() > 0 ) {
|
if( uminInput.size() + umaxInput.size() > 0 ) {
|
||||||
double d = umaxInput.get_value( 0.0 );
|
double d = umaxInput.get_value( 0.0 );
|
||||||
|
|
|
@ -34,16 +34,28 @@
|
||||||
#include <simgear/structure/subsystem_mgr.hxx>
|
#include <simgear/structure/subsystem_mgr.hxx>
|
||||||
#include <simgear/props/condition.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 {
|
class FGXMLAutoInput : public SGReferenced {
|
||||||
private:
|
private:
|
||||||
double value; // The value as a constant or initializer for the property
|
double value; // The value as a constant or initializer for the property
|
||||||
bool abs; // return absolute value
|
bool abs; // return absolute value
|
||||||
SGPropertyNode_ptr property; // The name of the property containing the value
|
SGPropertyNode_ptr property; // The name of the property containing the value
|
||||||
SGSharedPtr<FGXMLAutoInput> offset; // A fixed offset, defaults to zero
|
FGXMLAutoInput_ptr offset; // A fixed offset, defaults to zero
|
||||||
SGSharedPtr<FGXMLAutoInput> scale; // A constant scaling factor defaults to one
|
FGXMLAutoInput_ptr scale; // A constant scaling factor defaults to one
|
||||||
SGSharedPtr<FGXMLAutoInput> min; // A minimum clip defaults to no clipping
|
FGXMLAutoInput_ptr min; // A minimum clip defaults to no clipping
|
||||||
SGSharedPtr<FGXMLAutoInput> max; // A maximum clip defaults to no clipping
|
FGXMLAutoInput_ptr max; // A maximum clip defaults to no clipping
|
||||||
|
FGPeriodicalValue_ptr periodical; //
|
||||||
SGSharedPtr<const SGCondition> _condition;
|
SGSharedPtr<const SGCondition> _condition;
|
||||||
|
|
||||||
public:
|
public:
|
||||||
|
@ -71,9 +83,9 @@ public:
|
||||||
|
|
||||||
};
|
};
|
||||||
|
|
||||||
class FGXMLAutoInputList : public std::vector<SGSharedPtr<FGXMLAutoInput> > {
|
class FGXMLAutoInputList : public std::vector<FGXMLAutoInput_ptr> {
|
||||||
public:
|
public:
|
||||||
FGXMLAutoInput * get_active() {
|
FGXMLAutoInput_ptr get_active() {
|
||||||
for (iterator it = begin(); it != end(); ++it) {
|
for (iterator it = begin(); it != end(); ++it) {
|
||||||
if( (*it)->is_enabled() )
|
if( (*it)->is_enabled() )
|
||||||
return *it;
|
return *it;
|
||||||
|
@ -82,7 +94,7 @@ class FGXMLAutoInputList : public std::vector<SGSharedPtr<FGXMLAutoInput> > {
|
||||||
}
|
}
|
||||||
|
|
||||||
double get_value( double def = 0.0 ) {
|
double get_value( double def = 0.0 ) {
|
||||||
FGXMLAutoInput * input = get_active();
|
FGXMLAutoInput_ptr input = get_active();
|
||||||
return input == NULL ? def : input->get_value();
|
return input == NULL ? def : input->get_value();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -147,6 +159,7 @@ protected:
|
||||||
FGXMLAutoInputList referenceInput;
|
FGXMLAutoInputList referenceInput;
|
||||||
FGXMLAutoInputList uminInput;
|
FGXMLAutoInputList uminInput;
|
||||||
FGXMLAutoInputList umaxInput;
|
FGXMLAutoInputList umaxInput;
|
||||||
|
FGPeriodicalValue_ptr periodical;
|
||||||
// debug flag
|
// debug flag
|
||||||
bool debug;
|
bool debug;
|
||||||
bool enabled;
|
bool enabled;
|
||||||
|
@ -221,6 +234,8 @@ public:
|
||||||
bool isPropertyEnabled();
|
bool isPropertyEnabled();
|
||||||
};
|
};
|
||||||
|
|
||||||
|
typedef SGSharedPtr<FGXMLAutoComponent> FGXMLAutoComponent_ptr;
|
||||||
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Roy Ovesen's PID controller
|
* Roy Ovesen's PID controller
|
||||||
|
@ -384,7 +399,7 @@ public:
|
||||||
|
|
||||||
bool build( SGPropertyNode_ptr );
|
bool build( SGPropertyNode_ptr );
|
||||||
protected:
|
protected:
|
||||||
typedef std::vector<SGSharedPtr<FGXMLAutoComponent> > comp_list;
|
typedef std::vector<FGXMLAutoComponent_ptr> comp_list;
|
||||||
|
|
||||||
private:
|
private:
|
||||||
|
|
||||||
|
|
Loading…
Add table
Reference in a new issue