Commit d543aa88 authored by Alexander Morozov's avatar Alexander Morozov

add new filters, use filters before calibration

parent 1e140fc7
......@@ -17,11 +17,14 @@
class DigitalFilter
{
public:
DigitalFilter ( unsigned int bufsize=5, double T=0 );
DigitalFilter ( unsigned int bufsize=5, double T=0, double lsq=0.2,
int iir_thr=10000, double iir_coeff_prev=0.5,
double iir_coeff_new=0.5 );
~DigitalFilter ();
// T <=0 -
void setSettings( unsigned int bufsize, double T );
void setSettings( unsigned int bufsize, double T, double lsq,
int iir_thr, double iir_coeff_prev, double iir_coeff_new );
// ޣ
//
......@@ -35,10 +38,18 @@ class DigitalFilter
//
int median( int newval );
//
int leastsqr( int newval );
//
int filterIIR( int newval );
//
int current1();
int currentRC();
int currentMedian();
int currentLS();
int currentIIR();
//
void add( int newValue );
......@@ -74,6 +85,19 @@ class DigitalFilter
typedef std::vector<int> MedianVector;
MedianVector mvec;
typedef std::vector<double> Coeff;
Coeff w; // filterIIR
double lsparam; // filterIIR
double ls; // , ݣ filterIIR
int thr; // ,
int prev; // , ݣ
//
double coeff_prev;
double coeff_new;
};
//--------------------------------------------------------------------------
#endif // DigitalFilter_H_
......
......@@ -29,6 +29,8 @@ static const int NoSafety = -1;
df(1),
nofilter(false),
f_median(false),
f_ls(false),
f_filter_iir(false),
ignore(false),
invert(false),
noprecision(false),
......@@ -60,6 +62,8 @@ static const int NoSafety = -1;
DigitalFilter df; /*!< */
bool nofilter; /*!< */
bool f_median; /*!< */
bool f_ls; /*!< */
bool f_filter_iir; /*!< */
bool ignore; /*!< */
bool invert; /*!< */
......@@ -103,7 +107,9 @@ static const int NoSafety = -1;
static void processingThreshold( IOBase* it, SMInterface* shm, bool force );
static bool initItem( IOBase* b, UniXML_iterator& it, SMInterface* shm,
DebugStream* dlog=0, std::string myname="",
int def_filtersize=0, float def_filterT=0.0 );
int def_filtersize=0, float def_filterT=0.0,
float def_lsparam=0.2, float def_iir_coeff_prev=0.5,
float def_iir_coeff_new=0.5 );
};
......
......@@ -11,14 +11,23 @@
using namespace UniSetTypes;
using namespace std;
//--------------------------------------------------------------------------
DigitalFilter::DigitalFilter( unsigned int bufsize, double T ):
DigitalFilter::DigitalFilter( unsigned int bufsize, double T, double lsq,
int iir_thr, double iir_coeff_prev,
double iir_coeff_new ):
Ti(T),
val(0),
M(0),
S(0),
tmr(UniSetTimer::WaitUpTime),
maxsize(bufsize),
mvec(bufsize)
mvec(bufsize),
w(bufsize),
lsparam(lsq),
ls(0),
thr(iir_thr),
prev(0),
coeff_prev(iir_coeff_prev),
coeff_new(iir_coeff_new)
{
}
//--------------------------------------------------------------------------
......@@ -26,13 +35,20 @@ DigitalFilter::~DigitalFilter()
{
}
//--------------------------------------------------------------------------
void DigitalFilter::setSettings( unsigned int bufsize, double T )
void DigitalFilter::setSettings( unsigned int bufsize, double T, double lsq,
int iir_thr, double iir_coeff_prev,
double iir_coeff_new )
{
Ti = T;
maxsize = bufsize;
if( maxsize < 1 )
maxsize = 1;
coeff_prev = iir_coeff_prev;
coeff_new = iir_coeff_new;
if( iir_thr > 0 )
thr = iir_thr;
if( buf.size() > maxsize )
{
// ()
......@@ -40,6 +56,10 @@ void DigitalFilter::setSettings( unsigned int bufsize, double T )
for( int i=0; i<sub; i++ )
buf.erase( buf.begin() );
}
if( w.size() != maxsize || lsq != lsparam )
w.assign(maxsize, 1.0/maxsize);
lsparam = lsq;
}
//--------------------------------------------------------------------------
void DigitalFilter::init( int val )
......@@ -48,6 +68,8 @@ void DigitalFilter::init( int val )
for( unsigned int i=0; i<maxsize; i++ )
buf.push_back(val);
w.assign(maxsize, 1.0/maxsize);
tmr.reset();
this->val = val;
}
......@@ -188,3 +210,57 @@ int DigitalFilter::currentMedian()
return mvec[maxsize/2];
}
//--------------------------------------------------------------------------
int DigitalFilter::leastsqr( int newval )
{
ls = 0;
add(newval);
//
FIFOBuffer::const_iterator it = buf.begin();
for( unsigned int i=0; i<maxsize; i++,it++ )
ls += *it * w[i];
//
double er = newval - ls;
//
double u = 2 * (lsparam/maxsize) * er;
it = buf.begin();
for( unsigned int i=0; i<maxsize; i++,it++ )
w[i] = w[i] + *it * u;
return lroundf(ls);
}
//--------------------------------------------------------------------------
int DigitalFilter::currentLS()
{
return lroundf(ls);
}
//--------------------------------------------------------------------------
int DigitalFilter::filterIIR( int newval )
{
if( newval > prev + thr || newval < prev - thr || maxsize < 1 )
{
if( maxsize > 0 )
init(newval);
prev = newval;
}
else
{
double aver;
add(newval);
for( FIFOBuffer::iterator i = buf.begin(); i != buf.end(); ++i )
aver += *i;
aver /= maxsize;
prev = lroundf((coeff_prev * prev + coeff_new * aver)/(coeff_prev + coeff_new));
}
return prev;
}
//--------------------------------------------------------------------------
int DigitalFilter::currentIIR()
{
return prev;
}
//--------------------------------------------------------------------------
......@@ -105,18 +105,20 @@ void IOBase::processingAsAI( IOBase* it, long val, SMInterface* shm, bool force
return;
}
if( it->cdiagram ) //
{
// ,
// ,
if( !it->nofilter && it->df.size() > 1 )
{
if( it->f_median )
val = it->df.median(val);
else if( it->f_filter_iir )
val = it->df.filterIIR(val);
else if( it->f_ls )
val = it->df.leastsqr(val);
else
val = it->df.filterRC(val);
}
if( it->cdiagram ) //
{
if( it->craw != val )
{
it->craw = val;
......@@ -131,16 +133,6 @@ void IOBase::processingAsAI( IOBase* it, long val, SMInterface* shm, bool force
IOController_i::CalibrateInfo* cal( &(it->cal) );
if( cal->maxRaw!=cal->minRaw ) //
val = UniSetTypes::lcalibrate(val,cal->minRaw,cal->maxRaw,cal->minCal,cal->maxCal,true);
// ,
// ,
if( !it->nofilter && it->df.size() > 1 )
{
if( it->f_median )
val = it->df.median(val);
else
val = it->df.filterRC(val);
}
}
if( !it->noprecision && it->cal.precision > 0 )
......@@ -389,7 +381,8 @@ void IOBase::processingThreshold( IOBase* it, SMInterface* shm, bool force )
bool IOBase::initItem( IOBase* b, UniXML_iterator& it, SMInterface* shm,
DebugStream* dlog, std::string myname,
int def_filtersize, float def_filterT )
int def_filtersize, float def_filterT, float def_lsparam,
float def_iir_coeff_prev, float def_iir_coeff_new )
{
string sname( it.getProp("name") );
......@@ -448,6 +441,8 @@ bool IOBase::initItem( IOBase* b, UniXML_iterator& it, SMInterface* shm,
b->cal.precision = 0;
b->cdiagram = 0;
b->f_median = false;
b->f_ls = false;
b->f_filter_iir = false;
shm->initAIterator(b->ait);
shm->initDIterator(b->dit);
......@@ -463,7 +458,11 @@ bool IOBase::initItem( IOBase* b, UniXML_iterator& it, SMInterface* shm,
int f_size = def_filtersize;
float f_T = def_filterT;
float f_lsparam = def_lsparam;
int f_median = it.getIntProp("filtermedian");
int f_iir = it.getIntProp("iir_thr");
float f_iir_coeff_prev = def_iir_coeff_prev;
float f_iir_coeff_new = def_iir_coeff_new;
if( f_median > 0 )
{
......@@ -472,6 +471,8 @@ bool IOBase::initItem( IOBase* b, UniXML_iterator& it, SMInterface* shm,
}
else
{
if( f_iir > 0 )
b->f_filter_iir = true;
if( !it.getProp("filtersize").empty() )
{
#warning " 0, f_size def_filtersize?"
......@@ -486,8 +487,22 @@ bool IOBase::initItem( IOBase* b, UniXML_iterator& it, SMInterface* shm,
f_T = 0.0;
}
if( !it.getProp("leastsqr").empty() )
{
b->f_ls = true;
f_lsparam = atof(it.getProp("leastsqr").c_str());
if( f_lsparam < 0 )
f_lsparam = def_lsparam;
}
if( !it.getProp("iir_coeff_prev").empty() )
f_iir_coeff_prev = atof(it.getProp("iir_coeff_prev").c_str());
if( !it.getProp("iir_coeff_new").empty() )
f_iir_coeff_new = atof(it.getProp("iir_coeff_new").c_str());
if( b->stype == UniversalIO::AnalogInput )
b->df.setSettings( f_size, f_T );
b->df.setSettings( f_size, f_T, f_lsparam, f_iir,
f_iir_coeff_prev, f_iir_coeff_new );
b->df.init(b->defval);
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment