Some autopilot works
- add new <update-interval-secs> for autopilot components. This does what it says. - add new method to PeriodicalValue to normalize symmetric around zero - move the DigitalFilterImplementation out of the header file - refactor NoiseSpikeFilter: spare some cpu-cycles and respect periodical output
This commit is contained in:
parent
a8d5ac90c6
commit
5ebdcdc3d5
7 changed files with 60 additions and 33 deletions
|
@ -133,6 +133,9 @@ protected:
|
|||
it != _output_list.end(); ++it)
|
||||
(*it)->setDoubleValue( value );
|
||||
}
|
||||
|
||||
public:
|
||||
const PeriodicalValue * getPeriodicalValue() const { return _periodical; }
|
||||
};
|
||||
|
||||
inline void AnalogComponent::disabled( double dt )
|
||||
|
|
|
@ -85,8 +85,10 @@ Autopilot::Autopilot( SGPropertyNode_ptr rootNode, SGPropertyNode_ptr configNode
|
|||
component->set_name( buf.str() );
|
||||
}
|
||||
|
||||
SG_LOG( SG_AUTOPILOT, SG_INFO, "adding autopilot component \"" << childName << "\" as \"" << component->get_name() << "\"" );
|
||||
add_component(component);
|
||||
double updateInterval = node->getDoubleValue( "update-interval-secs", 0.0 );
|
||||
|
||||
SG_LOG( SG_AUTOPILOT, SG_INFO, "adding autopilot component \"" << childName << "\" as \"" << component->get_name() << "\" with interval=" << updateInterval );
|
||||
add_component(component,updateInterval);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -105,7 +107,7 @@ void Autopilot::unbind()
|
|||
_rootNode->untie( "serviceable" );
|
||||
}
|
||||
|
||||
void Autopilot::add_component( Component * component )
|
||||
void Autopilot::add_component( Component * component, double updateInterval )
|
||||
{
|
||||
if( component == NULL ) return;
|
||||
|
||||
|
@ -119,7 +121,7 @@ void Autopilot::add_component( Component * component )
|
|||
if( name != component->get_name() )
|
||||
SG_LOG( SG_ALL, SG_WARN, "Duplicate autopilot component " << component->get_name() << ", renamed to " << name );
|
||||
|
||||
set_subsystem( name.c_str(), component );
|
||||
set_subsystem( name.c_str(), component, updateInterval );
|
||||
}
|
||||
|
||||
void Autopilot::update( double dt )
|
||||
|
|
|
@ -54,7 +54,7 @@ public:
|
|||
std::string get_name() const { return _name; }
|
||||
void set_name( const std::string & name ) { _name = name; }
|
||||
|
||||
void add_component( Component * component );
|
||||
void add_component( Component * component, double updateInterval );
|
||||
|
||||
protected:
|
||||
|
||||
|
|
|
@ -32,6 +32,25 @@ using std::cout;
|
|||
|
||||
namespace FGXMLAutopilot {
|
||||
|
||||
/**
|
||||
*
|
||||
*
|
||||
*/
|
||||
class DigitalFilterImplementation : public SGReferenced {
|
||||
protected:
|
||||
virtual bool configure( const std::string & nodeName, SGPropertyNode_ptr configNode) = 0;
|
||||
public:
|
||||
DigitalFilterImplementation();
|
||||
virtual void initialize( double output ) {}
|
||||
virtual double compute( double dt, double input ) = 0;
|
||||
bool configure( SGPropertyNode_ptr configNode );
|
||||
|
||||
void setDigitalFilter( DigitalFilter * digitalFilter ) { _digitalFilter = digitalFilter; }
|
||||
|
||||
protected:
|
||||
DigitalFilter * _digitalFilter;
|
||||
};
|
||||
|
||||
/* --------------------------------------------------------------------------------- */
|
||||
/* --------------------------------------------------------------------------------- */
|
||||
class GainFilterImplementation : public DigitalFilterImplementation {
|
||||
|
@ -101,6 +120,10 @@ using namespace FGXMLAutopilot;
|
|||
|
||||
/* --------------------------------------------------------------------------------- */
|
||||
/* --------------------------------------------------------------------------------- */
|
||||
DigitalFilterImplementation::DigitalFilterImplementation() :
|
||||
_digitalFilter(NULL)
|
||||
{
|
||||
}
|
||||
|
||||
bool DigitalFilterImplementation::configure( SGPropertyNode_ptr configNode )
|
||||
{
|
||||
|
@ -227,19 +250,17 @@ void NoiseSpikeFilterImplementation::initialize( double output )
|
|||
|
||||
double NoiseSpikeFilterImplementation::compute( double dt, double input )
|
||||
{
|
||||
double delta = input - _output_1;
|
||||
if( delta == 0.0 ) return input; // trivial
|
||||
|
||||
double maxChange = _rateOfChangeInput.get_value() * dt;
|
||||
const PeriodicalValue * periodical = _digitalFilter->getPeriodicalValue();
|
||||
if( periodical ) delta = periodical->normalizeSymmetric( delta );
|
||||
|
||||
double output_0 = _output_1;
|
||||
|
||||
if (_output_1 - input > maxChange) {
|
||||
output_0 = _output_1 - maxChange;
|
||||
} else if( _output_1 - input < -maxChange ) {
|
||||
output_0 = _output_1 + maxChange;
|
||||
} else if (fabs(input - _output_1) <= maxChange) {
|
||||
output_0 = input;
|
||||
}
|
||||
_output_1 = output_0;
|
||||
return output_0;
|
||||
if( fabs(delta) <= maxChange )
|
||||
return (_output_1 = input);
|
||||
else
|
||||
return (_output_1 = _output_1 + copysign( maxChange, delta ));
|
||||
}
|
||||
|
||||
bool NoiseSpikeFilterImplementation::configure( const std::string & nodeName, SGPropertyNode_ptr configNode )
|
||||
|
@ -318,6 +339,11 @@ DigitalFilter::DigitalFilter() :
|
|||
{
|
||||
}
|
||||
|
||||
DigitalFilter::~DigitalFilter()
|
||||
{
|
||||
}
|
||||
|
||||
|
||||
static map<string,FunctorBase<DigitalFilterImplementation> *> componentForge;
|
||||
|
||||
bool DigitalFilter::configure(const string& nodeName, SGPropertyNode_ptr configNode)
|
||||
|
@ -343,6 +369,7 @@ bool DigitalFilter::configure(const string& nodeName, SGPropertyNode_ptr configN
|
|||
return true;
|
||||
}
|
||||
_implementation = (*componentForge[type])( configNode->getParent() );
|
||||
_implementation->setDigitalFilter( this );
|
||||
return true;
|
||||
}
|
||||
|
||||
|
|
|
@ -31,19 +31,6 @@
|
|||
|
||||
namespace FGXMLAutopilot {
|
||||
|
||||
/**
|
||||
*
|
||||
*
|
||||
*/
|
||||
class DigitalFilterImplementation : public SGReferenced {
|
||||
protected:
|
||||
virtual bool configure( const std::string & nodeName, SGPropertyNode_ptr configNode) = 0;
|
||||
public:
|
||||
virtual void initialize( double output ) {}
|
||||
virtual double compute( double dt, double input ) = 0;
|
||||
bool configure( SGPropertyNode_ptr configNode );
|
||||
};
|
||||
|
||||
/**
|
||||
* brief@ DigitalFilter - a selection of digital filters
|
||||
*
|
||||
|
@ -51,7 +38,7 @@ public:
|
|||
class DigitalFilter : public AnalogComponent
|
||||
{
|
||||
private:
|
||||
SGSharedPtr<DigitalFilterImplementation> _implementation;
|
||||
SGSharedPtr<class DigitalFilterImplementation> _implementation;
|
||||
|
||||
enum InitializeTo {
|
||||
INITIALIZE_OUTPUT,
|
||||
|
@ -71,7 +58,7 @@ protected:
|
|||
|
||||
public:
|
||||
DigitalFilter();
|
||||
~DigitalFilter() {}
|
||||
~DigitalFilter();
|
||||
|
||||
};
|
||||
|
||||
|
|
|
@ -34,11 +34,18 @@ PeriodicalValue::PeriodicalValue( SGPropertyNode_ptr root )
|
|||
}
|
||||
}
|
||||
|
||||
double PeriodicalValue::normalize( double value )
|
||||
double PeriodicalValue::normalize( double value ) const
|
||||
{
|
||||
return SGMiscd::normalizePeriodic( minPeriod->get_value(), maxPeriod->get_value(), value );
|
||||
}
|
||||
|
||||
double PeriodicalValue::normalizeSymmetric( double value ) const
|
||||
{
|
||||
value = SGMiscd::normalizePeriodic( minPeriod->get_value(), maxPeriod->get_value(), value );
|
||||
double width_2 = (maxPeriod->get_value() - minPeriod->get_value())/2;
|
||||
return value > width_2 ? width_2 - value : value;
|
||||
}
|
||||
|
||||
InputValue::InputValue( SGPropertyNode_ptr node, double value, double offset, double scale) :
|
||||
_value(0.0),
|
||||
_abs(false)
|
||||
|
|
|
@ -45,7 +45,8 @@ private:
|
|||
InputValue_ptr maxPeriod; // The maximum value of the period
|
||||
public:
|
||||
PeriodicalValue( SGPropertyNode_ptr node );
|
||||
double normalize( double value );
|
||||
double normalize( double value ) const;
|
||||
double normalizeSymmetric( double value ) const;
|
||||
};
|
||||
|
||||
/**
|
||||
|
|
Loading…
Reference in a new issue