Commit d543aa88 authored by Alexander Morozov's avatar Alexander Morozov

add new filters, use filters before calibration

parent 1e140fc7
...@@ -17,11 +17,14 @@ ...@@ -17,11 +17,14 @@
class DigitalFilter class DigitalFilter
{ {
public: 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 (); ~DigitalFilter ();
// T <=0 - // 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 ...@@ -35,10 +38,18 @@ class DigitalFilter
// //
int median( int newval ); int median( int newval );
//
int leastsqr( int newval );
//
int filterIIR( int newval );
// //
int current1(); int current1();
int currentRC(); int currentRC();
int currentMedian(); int currentMedian();
int currentLS();
int currentIIR();
// //
void add( int newValue ); void add( int newValue );
...@@ -74,6 +85,19 @@ class DigitalFilter ...@@ -74,6 +85,19 @@ class DigitalFilter
typedef std::vector<int> MedianVector; typedef std::vector<int> MedianVector;
MedianVector mvec; 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_ #endif // DigitalFilter_H_
......
...@@ -29,6 +29,8 @@ static const int NoSafety = -1; ...@@ -29,6 +29,8 @@ static const int NoSafety = -1;
df(1), df(1),
nofilter(false), nofilter(false),
f_median(false), f_median(false),
f_ls(false),
f_filter_iir(false),
ignore(false), ignore(false),
invert(false), invert(false),
noprecision(false), noprecision(false),
...@@ -60,6 +62,8 @@ static const int NoSafety = -1; ...@@ -60,6 +62,8 @@ static const int NoSafety = -1;
DigitalFilter df; /*!< */ DigitalFilter df; /*!< */
bool nofilter; /*!< */ bool nofilter; /*!< */
bool f_median; /*!< */ bool f_median; /*!< */
bool f_ls; /*!< */
bool f_filter_iir; /*!< */
bool ignore; /*!< */ bool ignore; /*!< */
bool invert; /*!< */ bool invert; /*!< */
...@@ -103,7 +107,9 @@ static const int NoSafety = -1; ...@@ -103,7 +107,9 @@ static const int NoSafety = -1;
static void processingThreshold( IOBase* it, SMInterface* shm, bool force ); static void processingThreshold( IOBase* it, SMInterface* shm, bool force );
static bool initItem( IOBase* b, UniXML_iterator& it, SMInterface* shm, static bool initItem( IOBase* b, UniXML_iterator& it, SMInterface* shm,
DebugStream* dlog=0, std::string myname="", 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 @@ ...@@ -11,14 +11,23 @@
using namespace UniSetTypes; using namespace UniSetTypes;
using namespace std; 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), Ti(T),
val(0), val(0),
M(0), M(0),
S(0), S(0),
tmr(UniSetTimer::WaitUpTime), tmr(UniSetTimer::WaitUpTime),
maxsize(bufsize), 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() ...@@ -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; Ti = T;
maxsize = bufsize; maxsize = bufsize;
if( maxsize < 1 ) if( maxsize < 1 )
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 ) if( buf.size() > maxsize )
{ {
// () // ()
...@@ -40,6 +56,10 @@ void DigitalFilter::setSettings( unsigned int bufsize, double T ) ...@@ -40,6 +56,10 @@ void DigitalFilter::setSettings( unsigned int bufsize, double T )
for( int i=0; i<sub; i++ ) for( int i=0; i<sub; i++ )
buf.erase( buf.begin() ); buf.erase( buf.begin() );
} }
if( w.size() != maxsize || lsq != lsparam )
w.assign(maxsize, 1.0/maxsize);
lsparam = lsq;
} }
//-------------------------------------------------------------------------- //--------------------------------------------------------------------------
void DigitalFilter::init( int val ) void DigitalFilter::init( int val )
...@@ -48,6 +68,8 @@ void DigitalFilter::init( int val ) ...@@ -48,6 +68,8 @@ void DigitalFilter::init( int val )
for( unsigned int i=0; i<maxsize; i++ ) for( unsigned int i=0; i<maxsize; i++ )
buf.push_back(val); buf.push_back(val);
w.assign(maxsize, 1.0/maxsize);
tmr.reset(); tmr.reset();
this->val = val; this->val = val;
} }
...@@ -188,3 +210,57 @@ int DigitalFilter::currentMedian() ...@@ -188,3 +210,57 @@ int DigitalFilter::currentMedian()
return mvec[maxsize/2]; 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 ...@@ -105,18 +105,20 @@ void IOBase::processingAsAI( IOBase* it, long val, SMInterface* shm, bool force
return; return;
} }
if( it->cdiagram ) // if( !it->nofilter && it->df.size() > 1 )
{ {
// , if( it->f_median )
// , val = it->df.median(val);
if( !it->nofilter && it->df.size() > 1 ) else if( it->f_filter_iir )
{ val = it->df.filterIIR(val);
if( it->f_median ) else if( it->f_ls )
val = it->df.median(val); val = it->df.leastsqr(val);
else else
val = it->df.filterRC(val); val = it->df.filterRC(val);
} }
if( it->cdiagram ) //
{
if( it->craw != val ) if( it->craw != val )
{ {
it->craw = val; it->craw = val;
...@@ -131,16 +133,6 @@ void IOBase::processingAsAI( IOBase* it, long val, SMInterface* shm, bool force ...@@ -131,16 +133,6 @@ void IOBase::processingAsAI( IOBase* it, long val, SMInterface* shm, bool force
IOController_i::CalibrateInfo* cal( &(it->cal) ); IOController_i::CalibrateInfo* cal( &(it->cal) );
if( cal->maxRaw!=cal->minRaw ) // if( cal->maxRaw!=cal->minRaw ) //
val = UniSetTypes::lcalibrate(val,cal->minRaw,cal->maxRaw,cal->minCal,cal->maxCal,true); 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 ) if( !it->noprecision && it->cal.precision > 0 )
...@@ -389,7 +381,8 @@ void IOBase::processingThreshold( IOBase* it, SMInterface* shm, bool force ) ...@@ -389,7 +381,8 @@ void IOBase::processingThreshold( IOBase* it, SMInterface* shm, bool force )
bool IOBase::initItem( IOBase* b, UniXML_iterator& it, SMInterface* shm, bool IOBase::initItem( IOBase* b, UniXML_iterator& it, SMInterface* shm,
DebugStream* dlog, std::string myname, 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") ); string sname( it.getProp("name") );
...@@ -448,6 +441,8 @@ bool IOBase::initItem( IOBase* b, UniXML_iterator& it, SMInterface* shm, ...@@ -448,6 +441,8 @@ bool IOBase::initItem( IOBase* b, UniXML_iterator& it, SMInterface* shm,
b->cal.precision = 0; b->cal.precision = 0;
b->cdiagram = 0; b->cdiagram = 0;
b->f_median = false; b->f_median = false;
b->f_ls = false;
b->f_filter_iir = false;
shm->initAIterator(b->ait); shm->initAIterator(b->ait);
shm->initDIterator(b->dit); shm->initDIterator(b->dit);
...@@ -463,7 +458,11 @@ bool IOBase::initItem( IOBase* b, UniXML_iterator& it, SMInterface* shm, ...@@ -463,7 +458,11 @@ bool IOBase::initItem( IOBase* b, UniXML_iterator& it, SMInterface* shm,
int f_size = def_filtersize; int f_size = def_filtersize;
float f_T = def_filterT; float f_T = def_filterT;
float f_lsparam = def_lsparam;
int f_median = it.getIntProp("filtermedian"); 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 ) if( f_median > 0 )
{ {
...@@ -472,6 +471,8 @@ bool IOBase::initItem( IOBase* b, UniXML_iterator& it, SMInterface* shm, ...@@ -472,6 +471,8 @@ bool IOBase::initItem( IOBase* b, UniXML_iterator& it, SMInterface* shm,
} }
else else
{ {
if( f_iir > 0 )
b->f_filter_iir = true;
if( !it.getProp("filtersize").empty() ) if( !it.getProp("filtersize").empty() )
{ {
#warning " 0, f_size def_filtersize?" #warning " 0, f_size def_filtersize?"
...@@ -486,8 +487,22 @@ bool IOBase::initItem( IOBase* b, UniXML_iterator& it, SMInterface* shm, ...@@ -486,8 +487,22 @@ bool IOBase::initItem( IOBase* b, UniXML_iterator& it, SMInterface* shm,
f_T = 0.0; 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 ) 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); 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