test_sdk/math/gtl_math_intg.cpp

176 lines
4.0 KiB
C++
Raw Permalink Normal View History

#include "gtl_math_intg.h"
namespace gtl
{
namespace math
{
intg::intg(gtl::analog_data* parent, bool is_hidden)
: gtl::analog_data(parent, is_hidden)
, _taps(1)
// , _delay(1)
, _threshold(1e+10)
, _autonorm(false)
, _autoreset(false)
{
if(parent == NULL)
return;
_device = static_cast<gtl::device*>(analog_data::root());
if(_device)
_device->lock_ai();
QString name_base = tr("integrator");
QString name = name_base;
int idx = 0;
while(parent->is_child_name_exist(name))
{
idx++;
name = name_base + "_" + QString::number(idx);
}
set_name(name);
init();
if(_device)
_device->unlock_ai();
}
intg::~intg()
{
delete _delays;
}
int intg::taps() const
{
return _taps;
}
void intg::reset()
{
if(_device)
_device->lock_ai();
for( int i = 0; i < _taps; i++)
_delays->at(i) = 0;
if(_device)
_device->unlock_ai();
}
void intg::set_taps(int value)
{
if( value > 0 && value != _taps)
{
_taps = value;
init();
}
}
// int intg::delay() const
// {
// return _delay;
// }
// void intg::set_delay(int value)
// {
// if( value > 0 && value != _delay)
// {
// _delay = value;
// init();
// }
// }
void intg::set_data(iterator begin, iterator end)
{
clear();
std::copy(begin, end, std::back_inserter(*this)); //to do...
process(this->begin(), this->end());
gtl::analog_data::set_data(this->begin(), this->end());
}
void intg::init()
{
if(_device)
_device->lock_ai();
if(_delays)
delete _delays;
_delays = new std::vector<qreal>(_taps);
if(_device)
_device->unlock_ai();
}
void intg::process(iterator begin, iterator end)
{
if(_autoreset && (abs(_delays->back()) > _threshold))
reset();
int size = std::distance(begin, end);
qreal dt = 1./get_rate();
for( int i = 0; i < size; i++)
{
// Обратный метод Эйлера : https://docs.exponenta.ru/simulink/slref/discretetimeintegrator.html
qreal value = *(begin + i)*dt;
for(int t = 0; t < _taps; t++)
{
value += _delays->at(t);
_delays->at(t) = value;
}
*(begin + i) = value;
}
return;
}
qreal intg::threshold() const
{
return _threshold;
}
void intg::set_threshold(qreal newThreshold)
{
if (qFuzzyCompare(_threshold, newThreshold))
return;
_threshold = newThreshold;
emit threshold_changed();
}
bool intg::autonorm() const
{
return _autonorm;
}
void intg::set_autonorm(bool newAuto_norm)
{
if (_autonorm == newAuto_norm)
return;
_autonorm = newAuto_norm;
emit autonorm_changed();
}
bool intg::autoreset() const
{
return _autoreset;
}
void intg::set_autoreset(bool newAuto_reset)
{
if (_autoreset == newAuto_reset)
return;
_autoreset = newAuto_reset;
emit autoreset_changed();
}
}
}