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 != _output_list.end(); ++it)
|
||||||
(*it)->setDoubleValue( value );
|
(*it)->setDoubleValue( value );
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public:
|
||||||
|
const PeriodicalValue * getPeriodicalValue() const { return _periodical; }
|
||||||
};
|
};
|
||||||
|
|
||||||
inline void AnalogComponent::disabled( double dt )
|
inline void AnalogComponent::disabled( double dt )
|
||||||
|
|
|
@ -85,8 +85,10 @@ Autopilot::Autopilot( SGPropertyNode_ptr rootNode, SGPropertyNode_ptr configNode
|
||||||
component->set_name( buf.str() );
|
component->set_name( buf.str() );
|
||||||
}
|
}
|
||||||
|
|
||||||
SG_LOG( SG_AUTOPILOT, SG_INFO, "adding autopilot component \"" << childName << "\" as \"" << component->get_name() << "\"" );
|
double updateInterval = node->getDoubleValue( "update-interval-secs", 0.0 );
|
||||||
add_component(component);
|
|
||||||
|
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" );
|
_rootNode->untie( "serviceable" );
|
||||||
}
|
}
|
||||||
|
|
||||||
void Autopilot::add_component( Component * component )
|
void Autopilot::add_component( Component * component, double updateInterval )
|
||||||
{
|
{
|
||||||
if( component == NULL ) return;
|
if( component == NULL ) return;
|
||||||
|
|
||||||
|
@ -119,7 +121,7 @@ void Autopilot::add_component( Component * component )
|
||||||
if( name != component->get_name() )
|
if( name != component->get_name() )
|
||||||
SG_LOG( SG_ALL, SG_WARN, "Duplicate autopilot component " << component->get_name() << ", renamed to " << 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 )
|
void Autopilot::update( double dt )
|
||||||
|
|
|
@ -54,7 +54,7 @@ public:
|
||||||
std::string get_name() const { return _name; }
|
std::string get_name() const { return _name; }
|
||||||
void set_name( const std::string & name ) { _name = name; }
|
void set_name( const std::string & name ) { _name = name; }
|
||||||
|
|
||||||
void add_component( Component * component );
|
void add_component( Component * component, double updateInterval );
|
||||||
|
|
||||||
protected:
|
protected:
|
||||||
|
|
||||||
|
|
|
@ -32,6 +32,25 @@ using std::cout;
|
||||||
|
|
||||||
namespace FGXMLAutopilot {
|
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 {
|
class GainFilterImplementation : public DigitalFilterImplementation {
|
||||||
|
@ -101,6 +120,10 @@ using namespace FGXMLAutopilot;
|
||||||
|
|
||||||
/* --------------------------------------------------------------------------------- */
|
/* --------------------------------------------------------------------------------- */
|
||||||
/* --------------------------------------------------------------------------------- */
|
/* --------------------------------------------------------------------------------- */
|
||||||
|
DigitalFilterImplementation::DigitalFilterImplementation() :
|
||||||
|
_digitalFilter(NULL)
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
bool DigitalFilterImplementation::configure( SGPropertyNode_ptr configNode )
|
bool DigitalFilterImplementation::configure( SGPropertyNode_ptr configNode )
|
||||||
{
|
{
|
||||||
|
@ -227,19 +250,17 @@ void NoiseSpikeFilterImplementation::initialize( double output )
|
||||||
|
|
||||||
double NoiseSpikeFilterImplementation::compute( double dt, double input )
|
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;
|
double maxChange = _rateOfChangeInput.get_value() * dt;
|
||||||
|
const PeriodicalValue * periodical = _digitalFilter->getPeriodicalValue();
|
||||||
|
if( periodical ) delta = periodical->normalizeSymmetric( delta );
|
||||||
|
|
||||||
double output_0 = _output_1;
|
if( fabs(delta) <= maxChange )
|
||||||
|
return (_output_1 = input);
|
||||||
if (_output_1 - input > maxChange) {
|
else
|
||||||
output_0 = _output_1 - maxChange;
|
return (_output_1 = _output_1 + copysign( maxChange, delta ));
|
||||||
} 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;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
bool NoiseSpikeFilterImplementation::configure( const std::string & nodeName, SGPropertyNode_ptr configNode )
|
bool NoiseSpikeFilterImplementation::configure( const std::string & nodeName, SGPropertyNode_ptr configNode )
|
||||||
|
@ -318,6 +339,11 @@ DigitalFilter::DigitalFilter() :
|
||||||
{
|
{
|
||||||
}
|
}
|
||||||
|
|
||||||
|
DigitalFilter::~DigitalFilter()
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
static map<string,FunctorBase<DigitalFilterImplementation> *> componentForge;
|
static map<string,FunctorBase<DigitalFilterImplementation> *> componentForge;
|
||||||
|
|
||||||
bool DigitalFilter::configure(const string& nodeName, SGPropertyNode_ptr configNode)
|
bool DigitalFilter::configure(const string& nodeName, SGPropertyNode_ptr configNode)
|
||||||
|
@ -343,6 +369,7 @@ bool DigitalFilter::configure(const string& nodeName, SGPropertyNode_ptr configN
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
_implementation = (*componentForge[type])( configNode->getParent() );
|
_implementation = (*componentForge[type])( configNode->getParent() );
|
||||||
|
_implementation->setDigitalFilter( this );
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -31,19 +31,6 @@
|
||||||
|
|
||||||
namespace FGXMLAutopilot {
|
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
|
* brief@ DigitalFilter - a selection of digital filters
|
||||||
*
|
*
|
||||||
|
@ -51,7 +38,7 @@ public:
|
||||||
class DigitalFilter : public AnalogComponent
|
class DigitalFilter : public AnalogComponent
|
||||||
{
|
{
|
||||||
private:
|
private:
|
||||||
SGSharedPtr<DigitalFilterImplementation> _implementation;
|
SGSharedPtr<class DigitalFilterImplementation> _implementation;
|
||||||
|
|
||||||
enum InitializeTo {
|
enum InitializeTo {
|
||||||
INITIALIZE_OUTPUT,
|
INITIALIZE_OUTPUT,
|
||||||
|
@ -71,7 +58,7 @@ protected:
|
||||||
|
|
||||||
public:
|
public:
|
||||||
DigitalFilter();
|
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 );
|
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) :
|
InputValue::InputValue( SGPropertyNode_ptr node, double value, double offset, double scale) :
|
||||||
_value(0.0),
|
_value(0.0),
|
||||||
_abs(false)
|
_abs(false)
|
||||||
|
|
|
@ -45,7 +45,8 @@ private:
|
||||||
InputValue_ptr maxPeriod; // The maximum value of the period
|
InputValue_ptr maxPeriod; // The maximum value of the period
|
||||||
public:
|
public:
|
||||||
PeriodicalValue( SGPropertyNode_ptr node );
|
PeriodicalValue( SGPropertyNode_ptr node );
|
||||||
double normalize( double value );
|
double normalize( double value ) const;
|
||||||
|
double normalizeSymmetric( double value ) const;
|
||||||
};
|
};
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
|
Loading…
Reference in a new issue