176 lines
4.0 KiB
C++
176 lines
4.0 KiB
C++
#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();
|
|
}
|
|
|
|
|
|
}
|
|
}
|