35#include <simgear/misc/strutils.hxx>
51 virtual double compute(
double dt,
double input ) = 0;
53 const std::string& cfg_name,
54 SGPropertyNode& prop_root ) = 0;
68 const std::string& cfg_name,
69 SGPropertyNode& prop_root);
72 double compute(
double dt,
double input );
81 double compute(
double dt,
double input );
85 simgear::ValueList _TfInput;
87 bool configure( SGPropertyNode& cfg_node,
88 const std::string& cfg_name,
89 SGPropertyNode& prop_root );
92 double compute(
double dt,
double input );
97 _TfInput.collectDependentProperties(props);
105 const std::string& cfg_name,
106 SGPropertyNode& prop_root);
111 double compute(
double dt,
double input );
116 _TfInput.collectDependentProperties(props);
126 const std::string& cfg_name,
127 SGPropertyNode& prop_root);
130 double compute(
double dt,
double input );
142 bool configure( SGPropertyNode& cfg_node,
143 const std::string& cfg_name,
144 SGPropertyNode& prop_root );
147 double compute(
double dt,
double input );
160 bool configure( SGPropertyNode& cfg_node,
161 const std::string& cfg_name,
162 SGPropertyNode& prop_root );
165 double compute(
double dt,
double input );
182 const std::string& cfg_name,
183 SGPropertyNode& prop_root);
186 double compute(
double dt,
double input );
191 _TfInput.collectDependentProperties(props);
192 _minInput.collectDependentProperties(props);
193 _maxInput.collectDependentProperties(props);
207 const std::string& cfg_name,
208 SGPropertyNode& prop_root);
211 double compute(
double dt,
double input );
216 _aInput.collectDependentProperties(props);
217 _bInput.collectDependentProperties(props);
218 _cInput.collectDependentProperties(props);
228 const std::string& cfg_name,
229 SGPropertyNode& prop_root);
232 double compute(
double dt,
double input );
237 _TfInput.collectDependentProperties(props);
247 const std::string& cfg_name,
248 SGPropertyNode& prop_root);
251 double compute(
double dt,
double input );
256 _TfaInput.collectDependentProperties(props);
257 _TfbInput.collectDependentProperties(props);
271 const std::string& cfg_name,
272 SGPropertyNode& prop_root)
override;
276 double compute(
double dt,
double input)
override;
305 const std::string& cfg_name,
306 SGPropertyNode& prop_root )
308 if (cfg_name ==
"gain" ) {
309 _gainInput.push_back(
new simgear::Value(prop_root, cfg_node, 1));
321 if( input >= -SGLimitsd::min() && input <= SGLimitsd::min() )
322 return SGLimitsd::max();
338 _input_1 = initvalue;
342bool DerivativeFilterImplementation::configure( SGPropertyNode& cfg_node,
343 const std::string& cfg_name,
344 SGPropertyNode& prop_root )
349 if (cfg_name ==
"filter-time" ) {
350 _TfInput.push_back(
new simgear::Value(prop_root, cfg_node, 1));
359 double output = (input - _input_1) * _TfInput.get_value() *
_gainInput.get_value() / dt;
380 typedef std::deque<double>::size_type size_type;
389 for (size_type ii = 0; ii < samples; ii++)
404 const std::string& cfg_name,
405 SGPropertyNode& prop_root )
407 if (cfg_name ==
"samples" ) {
408 _samplesInput.push_back(
new simgear::Value(prop_root, cfg_node, 1));
431 if( fabs(delta) <= SGLimitsd::min() )
return input;
435 if( periodical ) delta = periodical->normalizeSymmetric( delta );
437 if( fabs(delta) <= maxChange )
445 const std::string& cfg_name,
446 SGPropertyNode& prop_root )
448 if (cfg_name ==
"max-rate-of-change" ) {
473 if( fabs(delta) <= SGLimitsd::min() )
return input;
481 if(delta >= maxChange ) output =
_output_1 + maxChange;
482 if(delta <= minChange ) output =
_output_1 + minChange;
489 const std::string& cfg_name,
490 SGPropertyNode& prop_root )
493 if (cfg_name ==
"max-rate-of-change" ) {
497 if (cfg_name ==
"min-rate-of-change" ) {
530 double alpha = tf > 0.0 ? 1 / ((tf/dt) + 1) : 1.0;
533 output_0 = alpha * alpha * input +
537 output_0 = alpha * input + (1 - alpha) *
_output_1;
545 const std::string& cfg_name,
546 SGPropertyNode& prop_root )
551 if (cfg_name ==
"filter-time" ) {
552 _TfInput.push_back(
new simgear::Value(prop_root, cfg_node, 1));
556 if (cfg_name ==
"type" ) {
557 std::string type = simgear::strutils::strip(cfg_node.getStringValue());
579 const std::string& cfg_name,
580 SGPropertyNode& prop_root )
585 if (cfg_name ==
"u_min" ) {
586 _minInput.push_back(
new simgear::Value(prop_root, cfg_node, 1));
589 if (cfg_name ==
"u_max" ) {
590 _maxInput.push_back(
new simgear::Value(prop_root, cfg_node, 1));
601 if (output >= u_max) output = u_max;
602 if (output <= u_min) output = u_min;
621 const std::string& cfg_name,
622 SGPropertyNode& prop_root )
627 if (cfg_name ==
"a" ) {
628 _aInput.push_back(
new simgear::Value(prop_root, cfg_node, 1));
631 if (cfg_name ==
"b" ) {
632 _bInput.push_back(
new simgear::Value(prop_root, cfg_node, 1));
635 if (cfg_name ==
"c" ) {
636 _cInput.push_back(
new simgear::Value(prop_root, cfg_node, 1));
644 if (fabs(input) > 1e-15) {
645 double dz = dt * input;
649 double a =
_aInput.get_value();
650 double b =
_bInput.get_value();
651 double c =
_cInput.get_value();
652 _x0 = (
_x1 * (2. + dt * (a - b * dt)) -
_x2 - c * dt * dt) / (1. + a * dt);
693 if (SGMiscd::isNaN(input))
694 SG_LOG(SG_AUTOPILOT, SG_ALERT,
"High pass filter output is NaN.");
705 double alpha = tf > 0.0 ? 1 / ((tf / dt) + 1) : 1.0;
711 if (output != output) {
712 SG_LOG(SG_AUTOPILOT, SG_ALERT,
"High pass filter output is NaN.");
720 const std::string& cfg_name,
721 SGPropertyNode& prop_root )
726 if (cfg_name ==
"filter-time" ) {
727 _TfInput.push_back(
new simgear::Value(prop_root, cfg_node, 1));
760 double alpha = tfa > 0.0 ? 1 / ((tfa/dt) + 1) : 1.0;
761 double beta = tfb > 0.0 ? 1 / ((tfb/dt) + 1) : 1.0;
770 const std::string& cfg_name,
771 SGPropertyNode& prop_root )
776 if (cfg_name ==
"filter-time-a" ) {
777 _TfaInput.push_back(
new simgear::Value(prop_root, cfg_node, 1));
780 if (cfg_name ==
"filter-time-b" ) {
781 _TfbInput.push_back(
new simgear::Value(prop_root, cfg_node, 1));
801 return (sg_random() * 2.0) - 1.0;
805static double lerp(
double a,
double b,
double t)
807 return (a * (1.0 - t)) + (b * t);
819 const auto weight = t - floor(t);
820 const double output =
lerp(v0, v1, weight);
827 const std::string& cfg_name,
828 SGPropertyNode& prop_root)
830 if (cfg_name ==
"discrete-resolution") {
835 if (cfg_name ==
"amplitude") {
836 _amplitude.push_back(
new simgear::Value(prop_root, cfg_node, 1.0));
840 if (cfg_name ==
"absolute") {
862template<
class DigitalFilterType>
865 return new DigitalFilterType();
874 SGPropertyNode& cfg )
893 const auto type = simgear::strutils::strip(cfg.getStringValue(
"type"));
894 DigitalFilterMap::iterator component_factory =
componentForge.find(type);
897 SG_LOG(SG_AUTOPILOT, SG_WARN,
"unhandled filter type '" << type <<
"'");
901 _implementation = (*component_factory->second)();
902 _implementation->setDigitalFilter(
this );
904 for(
int i = 0;
i < cfg.nChildren(); ++
i )
906 SGPropertyNode_ptr child = cfg.getChild(
i);
907 std::string cname(child->getNameString());
909 if (!ok) ok = _implementation->configure(*child, cname, prop_root);
910 if (!ok) ok =
configure(*child, cname, prop_root);
911 if (!ok) ok = (cname ==
"type");
912 if (!ok) ok = (cname ==
"params");
918 "DigitalFilter: unknown config node: " << cname
925 std::set<const SGPropertyNode*> inputs;
926 _implementation->collectDependentProperties(inputs);
931 for (
auto in: inputs) {
933 highlight->addPropertyProperty(
946 const std::string& cfg_name,
947 SGPropertyNode& prop_root )
949 if( cfg_name ==
"initialize-to" )
951 const auto s = simgear::strutils::strip(cfg_node.getStringValue());
954 else if( s ==
"output" )
956 else if( s ==
"none" )
962 SG_WARN,
"DigitalFilter: initialize-to (" << s <<
") ignored"
974 if( _implementation == NULL )
return;
979 case INITIALIZE_INPUT:
980 SG_LOG(SG_AUTOPILOT,SG_DEBUG,
"First time initialization of " << subsystemId() <<
" to " <<
_valueInput.get_value() );
981 _implementation->initialize(
_valueInput.get_value() );
984 case INITIALIZE_OUTPUT:
985 SG_LOG(SG_AUTOPILOT,SG_DEBUG,
"First time initialization of " << subsystemId() <<
" to " <<
get_output_value() );
990 SG_LOG(SG_AUTOPILOT,SG_DEBUG,
"First time initialization of " << subsystemId() <<
" to (uninitialized)" );
996 if (SGMiscd::isNaN(input))
998 double output = _implementation->compute( dt, input );
1003 std::cout << subsystemId() <<
": input=" << input
1004 <<
"\toutput=" << output << std::endl;
static ComponentForge componentForge
simgear::PropertyList _output_list
void set_output_value(double value)
simgear::ValueList _valueInput
the value input
bool configure(SGPropertyNode &cfg_node, const std::string &cfg_name, SGPropertyNode &prop_root) override
This method configures this analog component from a property node.
AnalogComponent()
A constructor for an analog component.
simgear::ValueList _referenceInput
the reference input
void collectDependentProperties(std::set< const SGPropertyNode * > &props) const
Add to <props> all properties that are used by this component.
double get_output_value() const
return the current double value of the output property
void initialize(double initvalue) override
std::vector< double > _discreteValues
size_t _numDiscreteValues
CoherentNoiseFilterImplementation()
double compute(double dt, double input) override
simgear::ValueList _amplitude
bool configure(SGPropertyNode &cfg_node, const std::string &cfg_name, SGPropertyNode &prop_root) override
virtual void collectDependentProperties(std::set< const SGPropertyNode * > &props) const
bool _debug
debug flag, true if this component should generate some useful output on every iteration
virtual void initialize(double initvalue)
simgear::ValueList _bInput
bool configure(SGPropertyNode &cfg_node, const std::string &cfg_name, SGPropertyNode &prop_root)
simgear::ValueList _aInput
simgear::ValueList _cInput
virtual void collectDependentProperties(std::set< const SGPropertyNode * > &props) const
DampedOscillationFilterImplementation()
double compute(double dt, double input)
virtual void collectDependentProperties(std::set< const SGPropertyNode * > &props) const
virtual void initialize(double initvalue)
DerivativeFilterImplementation()
double compute(double dt, double input)
virtual ~DigitalFilterImplementation()
virtual void collectDependentProperties(std::set< const SGPropertyNode * > &props) const =0
virtual double compute(double dt, double input)=0
DigitalFilterImplementation()
void setDigitalFilter(DigitalFilter *digitalFilter)
virtual bool configure(SGPropertyNode &cfg_node, const std::string &cfg_name, SGPropertyNode &prop_root)=0
DigitalFilter * _digitalFilter
virtual void initialize(double initvalue)
brief@ DigitalFilter - a selection of digital filters
bool configure(SGPropertyNode &cfg_node, const std::string &cfg_name, SGPropertyNode &prop_root) override
This method configures this analog component from a property node.
void update(bool firstTime, double dt) override
pure virtual function to be implemented by the derived classes.
InitializeTo _initializeTo
simgear::ValueList _TfInput
double compute(double dt, double input)
virtual void collectDependentProperties(std::set< const SGPropertyNode * > &props) const
ExponentialFilterImplementation()
bool configure(SGPropertyNode &cfg_node, const std::string &cfg_name, SGPropertyNode &prop_root)
virtual void initialize(double initvalue)
virtual void collectDependentProperties(std::set< const SGPropertyNode * > &props) const
GainFilterImplementation()
double compute(double dt, double input)
bool configure(SGPropertyNode &cfg_node, const std::string &cfg_name, SGPropertyNode &prop_root)
simgear::ValueList _gainInput
double compute(double dt, double input)
bool configure(SGPropertyNode &cfg_node, const std::string &cfg_name, SGPropertyNode &prop_root)
virtual void initialize(double initvalue)
virtual void collectDependentProperties(std::set< const SGPropertyNode * > &props) const
simgear::ValueList _TfInput
HighPassFilterImplementation()
virtual void initialize(double initvalue)
simgear::ValueList _minInput
bool configure(SGPropertyNode &cfg_node, const std::string &cfg_name, SGPropertyNode &prop_root)
IntegratorFilterImplementation()
double compute(double dt, double input)
virtual void collectDependentProperties(std::set< const SGPropertyNode * > &props) const
simgear::ValueList _maxInput
simgear::ValueList _TfInput
bool configure(SGPropertyNode &cfg_node, const std::string &cfg_name, SGPropertyNode &prop_root)
simgear::ValueList _TfaInput
virtual void collectDependentProperties(std::set< const SGPropertyNode * > &props) const
virtual void initialize(double initvalue)
LeadLagFilterImplementation()
double compute(double dt, double input)
simgear::ValueList _TfbInput
double compute(double dt, double input)
bool configure(SGPropertyNode &cfg_node, const std::string &cfg_name, SGPropertyNode &prop_root)
virtual void collectDependentProperties(std::set< const SGPropertyNode * > &props) const
MovingAverageFilterImplementation()
std::deque< double > _inputQueue
simgear::ValueList _samplesInput
virtual void initialize(double initvalue)
double compute(double dt, double input)
bool configure(SGPropertyNode &cfg_node, const std::string &cfg_name, SGPropertyNode &prop_root)
virtual void collectDependentProperties(std::set< const SGPropertyNode * > &props) const
NoiseSpikeFilterImplementation()
simgear::ValueList _rateOfChangeInput
virtual void initialize(double initvalue)
double compute(double dt, double input)
virtual void collectDependentProperties(std::set< const SGPropertyNode * > &props) const
simgear::ValueList _rateOfChangeMin
bool configure(SGPropertyNode &cfg_node, const std::string &cfg_name, SGPropertyNode &prop_root)
virtual void initialize(double initvalue)
simgear::ValueList _rateOfChangeMax
RateLimitFilterImplementation()
double compute(double dt, double input)
SGSubsystemMgr::Registrant< DigitalFilter > registrantDigitalFilter
static double lerp(double a, double b, double t)
std::map< std::string, DigitalFilterImplementation *(*)()> DigitalFilterMap
DigitalFilterImplementation * digitalFilterFactory()