- 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
it != _output_list.end(); ++it)
(*it)->setDoubleValue( value );
}
+
+public:
+ const PeriodicalValue * getPeriodicalValue() const { return _periodical; }
};
inline void AnalogComponent::disabled( double dt )
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);
}
}
_rootNode->untie( "serviceable" );
}
-void Autopilot::add_component( Component * component )
+void Autopilot::add_component( Component * component, double updateInterval )
{
if( component == NULL ) return;
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 )
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:
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 {
/* --------------------------------------------------------------------------------- */
/* --------------------------------------------------------------------------------- */
+DigitalFilterImplementation::DigitalFilterImplementation() :
+ _digitalFilter(NULL)
+{
+}
bool DigitalFilterImplementation::configure( SGPropertyNode_ptr configNode )
{
double NoiseSpikeFilterImplementation::compute( double dt, double input )
{
- double maxChange = _rateOfChangeInput.get_value() * dt;
+ double delta = input - _output_1;
+ if( delta == 0.0 ) return input; // trivial
- double output_0 = _output_1;
+ double maxChange = _rateOfChangeInput.get_value() * dt;
+ const PeriodicalValue * periodical = _digitalFilter->getPeriodicalValue();
+ if( periodical ) delta = periodical->normalizeSymmetric( delta );
- 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 )
{
}
+DigitalFilter::~DigitalFilter()
+{
+}
+
+
static map<string,FunctorBase<DigitalFilterImplementation> *> componentForge;
bool DigitalFilter::configure(const string& nodeName, SGPropertyNode_ptr configNode)
return true;
}
_implementation = (*componentForge[type])( configNode->getParent() );
+ _implementation->setDigitalFilter( this );
return true;
}
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
*
class DigitalFilter : public AnalogComponent
{
private:
- SGSharedPtr<DigitalFilterImplementation> _implementation;
+ SGSharedPtr<class DigitalFilterImplementation> _implementation;
enum InitializeTo {
INITIALIZE_OUTPUT,
public:
DigitalFilter();
- ~DigitalFilter() {}
+ ~DigitalFilter();
};
}
}
-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)
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;
};
/**