Commit 67510a6d authored by Pavel Vainerman's avatar Pavel Vainerman

(Calibration): исправлена ошибка с поиском значения (!),

заодно небольшой рефакторинг
parent fbe21930
...@@ -77,8 +77,8 @@ class Calibration ...@@ -77,8 +77,8 @@ class Calibration
{ {
public: public:
Calibration(); Calibration();
Calibration( const std::string& name, const std::string& confile = "calibration.xml" ); Calibration( const std::string& name, const std::string& confile = "calibration.xml", size_t reserv=50 );
Calibration( xmlNode* node ); Calibration( xmlNode* node, size_t reserv=50 );
~Calibration(); ~Calibration();
/*! Тип для хранения значения */ /*! Тип для хранения значения */
...@@ -96,26 +96,26 @@ class Calibration ...@@ -96,26 +96,26 @@ class Calibration
\param crop_raw - обрезать переданное значение по крайним точкам \param crop_raw - обрезать переданное значение по крайним точкам
\return Возвращает калиброванное или outOfRange \return Возвращает калиброванное или outOfRange
*/ */
long getValue( long raw, bool crop_raw = false ); long getValue( const long raw, bool crop_raw = false );
/*! Возвращает минимальное значение 'x' встретившееся в диаграмме */ /*! Возвращает минимальное значение 'x' встретившееся в диаграмме */
inline long getMinValue() inline long getMinValue() const noexcept
{ {
return minVal; return minVal;
} }
/*! Возвращает максимальное значение 'x' втретившееся в диаграмме */ /*! Возвращает максимальное значение 'x' втретившееся в диаграмме */
inline long getMaxValue() inline long getMaxValue() const noexcept
{ {
return maxVal; return maxVal;
} }
/*! Возвращает крайнее левое значение 'x' встретившееся в диаграмме (ПОСЛЕ СОРТИРОВКИ ПО ВОЗРАСТАНИЮ 'x'!) */ /*! Возвращает крайнее левое значение 'x' встретившееся в диаграмме (ПОСЛЕ СОРТИРОВКИ ПО ВОЗРАСТАНИЮ 'x'!) */
inline long getLeftValue() inline long getLeftValue() const noexcept
{ {
return leftVal; return leftVal;
} }
/*! Возвращает крайнее правое значение 'x' встретившееся в диаграмме (ПОСЛЕ СОРТИРОВКИ ПО ВОЗРАСТАНИЮ 'x'!) */ /*! Возвращает крайнее правое значение 'x' встретившееся в диаграмме (ПОСЛЕ СОРТИРОВКИ ПО ВОЗРАСТАНИЮ 'x'!) */
inline long getRightValue() inline long getRightValue() const noexcept
{ {
return rightVal; return rightVal;
} }
...@@ -127,26 +127,26 @@ class Calibration ...@@ -127,26 +127,26 @@ class Calibration
Если range=false, то может быть возвращено значение outOfRange. Если range=false, то может быть возвращено значение outOfRange.
*/ */
long getRawValue( long cal, bool range = false ); long getRawValue( const long cal, bool range = false );
/*! Возвращает минимальное значение 'y' встретившееся в диаграмме */ /*! Возвращает минимальное значение 'y' встретившееся в диаграмме */
inline long getMinRaw() inline long getMinRaw() const noexcept
{ {
return minRaw; return minRaw;
} }
/*! Возвращает максимальное значение 'y' встретившееся в диаграмме */ /*! Возвращает максимальное значение 'y' встретившееся в диаграмме */
inline long getMaxRaw() inline long getMaxRaw() const noexcept
{ {
return maxRaw; return maxRaw;
} }
/*! Возвращает крайнее левое значение 'y' встретившееся в диаграмме (ПОСЛЕ СОРТИРОВКИ ПО ВОЗРАСТАНИЮ 'x'!) */ /*! Возвращает крайнее левое значение 'y' встретившееся в диаграмме (ПОСЛЕ СОРТИРОВКИ ПО ВОЗРАСТАНИЮ 'x'!) */
inline long getLeftRaw() inline long getLeftRaw() const noexcept
{ {
return leftRaw; return leftRaw;
} }
/*! Возвращает крайнее правое значение 'y' встретившееся в диаграмме (ПОСЛЕ СОРТИРОВКИ ПО ВОЗРАСТАНИЮ 'x'!) */ /*! Возвращает крайнее правое значение 'y' встретившееся в диаграмме (ПОСЛЕ СОРТИРОВКИ ПО ВОЗРАСТАНИЮ 'x'!) */
inline long getRightRaw() inline long getRightRaw() const noexcept
{ {
return rightRaw; return rightRaw;
} }
...@@ -166,14 +166,15 @@ class Calibration ...@@ -166,14 +166,15 @@ class Calibration
return lround(val); return lround(val);
} }
void setCacheSize( unsigned int sz ); void setCacheSize( size_t sz );
inline unsigned int getCacheSize()
inline size_t getCacheSize() const
{ {
return cache.size(); return cache.size();
} }
void setCacheResortCycle( unsigned int n ); void setCacheResortCycle( size_t n );
inline unsigned int getCacheResotrCycle() inline size_t getCacheResotrCycle() const noexcept
{ {
return numCacheResort; return numCacheResort;
} }
...@@ -204,64 +205,64 @@ class Calibration ...@@ -204,64 +205,64 @@ class Calibration
class Part class Part
{ {
public: public:
Part(); Part() noexcept;
Part( const Point& pleft, const Point& pright ); Part( const Point& pleft, const Point& pright ) noexcept;
~Part() {}; ~Part() {};
/*! находится ли точка на данном участке */ /*! находится ли точка на данном участке */
bool check( const Point& p ) const; bool check( const Point& p ) const noexcept;
/*! находится ли точка на данном участке по X */ /*! находится ли точка на данном участке по X */
bool checkX( const TypeOfValue& x ) const; bool checkX( const TypeOfValue& x ) const noexcept;
/*! находится ли точка на данном участке по Y */ /*! находится ли точка на данном участке по Y */
bool checkY( const TypeOfValue& y ) const; bool checkY( const TypeOfValue& y ) const noexcept;
// функции могут вернуть OutOfRange // функции могут вернуть OutOfRange
TypeOfValue getY( const TypeOfValue& x ) const; /*!< получить значение Y */ TypeOfValue getY( const TypeOfValue& x ) const noexcept; /*!< получить значение Y */
TypeOfValue getX( const TypeOfValue& y ) const; /*!< получить значение X */ TypeOfValue getX( const TypeOfValue& y ) const noexcept; /*!< получить значение X */
TypeOfValue calcY( const TypeOfValue& x ) const; /*!< расчитать значение для x */ TypeOfValue calcY( const TypeOfValue& x ) const noexcept; /*!< расчитать значение для x */
TypeOfValue calcX( const TypeOfValue& y ) const; /*!< расчитать значение для y */ TypeOfValue calcX( const TypeOfValue& y ) const noexcept; /*!< расчитать значение для y */
inline bool operator < ( const Part& p ) const inline bool operator < ( const Part& p ) const noexcept
{ {
return (p_right < p.p_right); return (p_right < p.p_right);
} }
inline Point leftPoint() const inline Point leftPoint() const noexcept
{ {
return p_left; return p_left;
} }
inline Point rightPoint() const inline Point rightPoint() const noexcept
{ {
return p_right; return p_right;
} }
inline TypeOfValue getK() const inline TypeOfValue getK() const noexcept
{ {
return k; /*!< получить коэффициент наклона */ return k; /*!< получить коэффициент наклона */
} }
inline TypeOfValue left_x() const inline TypeOfValue left_x() const noexcept
{ {
return p_left.x; return p_left.x;
} }
inline TypeOfValue left_y() const inline TypeOfValue left_y() const noexcept
{ {
return p_left.y; return p_left.y;
} }
inline TypeOfValue right_x() const inline TypeOfValue right_x() const noexcept
{ {
return p_right.x; return p_right.x;
} }
inline TypeOfValue right_y() const inline TypeOfValue right_y() const noexcept
{ {
return p_right.y; return p_right.y;
} }
protected: protected:
Point p_left; /*!< левый предел участка */ Point p_left; /*!< левый предел участка */
Point p_right; /*!< правый предел участка */ Point p_right; /*!< правый предел участка */
TypeOfValue k; /*!< коэффициент наклона */ TypeOfValue k; /*!< коэффициент наклона */
}; };
// список надо отсортировать по x! // список надо отсортировать по x!
...@@ -283,19 +284,19 @@ class Calibration ...@@ -283,19 +284,19 @@ class Calibration
std::string myname; std::string myname;
// Cache // Cache
unsigned int szCache; size_t szCache;
struct CacheInfo struct CacheInfo
{ {
CacheInfo(): val(0), raw(outOfRange), cnt(0) {} CacheInfo() noexcept: val(0), raw(outOfRange), cnt(0) {}
CacheInfo( const long r, const long v ): val(v), raw(r), cnt(0) {} CacheInfo( const long r, const long v ) noexcept: val(v), raw(r), cnt(0) {}
long val; long val;
long raw; long raw;
unsigned long cnt; // счётчик обращений size_t cnt; // счётчик обращений
// сортируем в порядке убывания(!) обращений // сортируем в порядке убывания(!) обращений
// т.е. наиболее часто используемые (впереди) // т.е. наиболее часто используемые (впереди)
inline bool operator<( const CacheInfo& r ) const inline bool operator<( const CacheInfo& r ) const noexcept
{ {
if( r.raw == outOfRange ) if( r.raw == outOfRange )
return true; return true;
...@@ -310,8 +311,8 @@ class Calibration ...@@ -310,8 +311,8 @@ class Calibration
typedef std::deque<CacheInfo> ValueCache; typedef std::deque<CacheInfo> ValueCache;
ValueCache cache; ValueCache cache;
unsigned long numCacheResort; // количество обращений, при которых происходит перестроение (сортировка) кэша.. size_t numCacheResort; // количество обращений, при которых происходит перестроение (сортировка) кэша..
unsigned long numCallToCache; // текущий счётчик обращений к кэшу size_t numCallToCache; // текущий счётчик обращений к кэшу
}; };
// ----------------------------------------------------------------------------- // -----------------------------------------------------------------------------
#endif // Calibration_H_ #endif // Calibration_H_
......
...@@ -29,23 +29,19 @@ using namespace UniSetTypes; ...@@ -29,23 +29,19 @@ using namespace UniSetTypes;
const Calibration::TypeOfValue Calibration::ValueOutOfRange = std::numeric_limits<Calibration::TypeOfValue>::max(); const Calibration::TypeOfValue Calibration::ValueOutOfRange = std::numeric_limits<Calibration::TypeOfValue>::max();
const long Calibration::outOfRange = std::numeric_limits<long>::max(); const long Calibration::outOfRange = std::numeric_limits<long>::max();
// ---------------------------------------------------------------------------- // ----------------------------------------------------------------------------
Calibration::Part::Part(): Calibration::Part::Part() noexcept:
k(0) k(0)
{ {
} }
Calibration::Part::Part( const Point& pleft, const Point& pright ): Calibration::Part::Part( const Point& pleft, const Point& pright ) noexcept:
p_left(pleft), p_left(pleft),
p_right(pright), p_right(pright),
k(0) k(0)
{ {
if( p_right.x < p_left.x ) if( p_right.x < p_left.x )
{ std::swap(p_right,p_left);
Point t(p_right);
p_right = p_left;
p_left = t;
}
// вычисление коэффициента наклона (один раз в конструкторе) // вычисление коэффициента наклона (один раз в конструкторе)
// k = (y2-y1)/(x2-x1) // k = (y2-y1)/(x2-x1)
...@@ -55,29 +51,28 @@ Calibration::Part::Part( const Point& pleft, const Point& pright ): ...@@ -55,29 +51,28 @@ Calibration::Part::Part( const Point& pleft, const Point& pright ):
k = ( p_right.y - p_left.y ) / ( p_right.x - p_left.x ); k = ( p_right.y - p_left.y ) / ( p_right.x - p_left.x );
} }
// ---------------------------------------------------------------------------- // ----------------------------------------------------------------------------
bool Calibration::Part::check( const Point& p ) const bool Calibration::Part::check( const Point& p ) const noexcept
{ {
return ( checkX(p.x) && checkY(p.y) ); return ( checkX(p.x) && checkY(p.y) );
} }
// ----------------------------------------------------------------------------
bool Calibration::Part::checkX( const TypeOfValue& x ) const bool Calibration::Part::checkX( const TypeOfValue& x ) const noexcept
{ {
if( x < p_left.x || x > p_right.x ) if( x < p_left.x || x > p_right.x )
return false; return false;
return true; return true;
} }
// ----------------------------------------------------------------------------
bool Calibration::Part::checkY( const TypeOfValue& y ) const bool Calibration::Part::checkY( const TypeOfValue& y ) const noexcept
{ {
if( y < p_left.y || y > p_right.y ) if( y < p_left.y || y > p_right.y )
return false; return false;
return true; return true;
} }
// ---------------------------------------------------------------------------- // ----------------------------------------------------------------------------
Calibration::TypeOfValue Calibration::Part::getY( const TypeOfValue& x ) const Calibration::TypeOfValue Calibration::Part::getY( const TypeOfValue& x ) const noexcept
{ {
if( !checkX(x) ) if( !checkX(x) )
return Calibration::ValueOutOfRange; return Calibration::ValueOutOfRange;
...@@ -91,7 +86,7 @@ Calibration::TypeOfValue Calibration::Part::getY( const TypeOfValue& x ) const ...@@ -91,7 +86,7 @@ Calibration::TypeOfValue Calibration::Part::getY( const TypeOfValue& x ) const
return calcY(x); return calcY(x);
} }
// ---------------------------------------------------------------------------- // ----------------------------------------------------------------------------
Calibration::TypeOfValue Calibration::Part::getX( const TypeOfValue& y ) const Calibration::TypeOfValue Calibration::Part::getX( const TypeOfValue& y ) const noexcept
{ {
if( !checkY(y) ) if( !checkY(y) )
return Calibration::ValueOutOfRange; return Calibration::ValueOutOfRange;
...@@ -105,13 +100,13 @@ Calibration::TypeOfValue Calibration::Part::getX( const TypeOfValue& y ) const ...@@ -105,13 +100,13 @@ Calibration::TypeOfValue Calibration::Part::getX( const TypeOfValue& y ) const
return calcX(y); return calcX(y);
} }
// ---------------------------------------------------------------------------- // ----------------------------------------------------------------------------
Calibration::TypeOfValue Calibration::Part::calcY( const TypeOfValue& x ) const Calibration::TypeOfValue Calibration::Part::calcY( const TypeOfValue& x ) const noexcept
{ {
// y = y0 + kx // y = y0 + kx
return k * (x - p_left.x) + p_left.y; return k * (x - p_left.x) + p_left.y;
} }
// ---------------------------------------------------------------------------- // ----------------------------------------------------------------------------
Calibration::TypeOfValue Calibration::Part::calcX( const TypeOfValue& y ) const Calibration::TypeOfValue Calibration::Part::calcX( const TypeOfValue& y ) const noexcept
{ {
// x = (y - y0) / k // x = (y - y0) / k
if( k == 0 ) if( k == 0 )
...@@ -123,7 +118,6 @@ Calibration::TypeOfValue Calibration::Part::calcX( const TypeOfValue& y ) const ...@@ -123,7 +118,6 @@ Calibration::TypeOfValue Calibration::Part::calcX( const TypeOfValue& y ) const
Calibration::Calibration(): Calibration::Calibration():
minRaw(0), maxRaw(0), minVal(0), maxVal(0), rightVal(0), leftVal(0), rightRaw(0), leftRaw(0), minRaw(0), maxRaw(0), minVal(0), maxVal(0), rightVal(0), leftVal(0), rightRaw(0), leftRaw(0),
pvec(50),
myname(""), myname(""),
szCache(5), szCache(5),
numCacheResort(20), numCacheResort(20),
...@@ -134,25 +128,26 @@ Calibration::Calibration(): ...@@ -134,25 +128,26 @@ Calibration::Calibration():
// ---------------------------------------------------------------------------- // ----------------------------------------------------------------------------
Calibration::Calibration( const string& name, const string& confile ): Calibration::Calibration( const string& name, const string& confile, size_t reserv ):
minRaw(0), maxRaw(0), minVal(0), maxVal(0), rightVal(0), leftVal(0), rightRaw(0), leftRaw(0), minRaw(0), maxRaw(0), minVal(0), maxVal(0), rightVal(0), leftVal(0), rightRaw(0), leftRaw(0),
pvec(50),
myname(name), myname(name),
szCache(5), szCache(5),
numCacheResort(20), numCacheResort(20),
numCallToCache(5) numCallToCache(5)
{ {
pvec.reserve(reserv);
cache.assign(szCache, CacheInfo()); cache.assign(szCache, CacheInfo());
build(name, confile, 0); build(name, confile, 0);
} }
// ---------------------------------------------------------------------------- // ----------------------------------------------------------------------------
Calibration::Calibration( xmlNode* node ): Calibration::Calibration(xmlNode* node , size_t reserv ):
minRaw(0), maxRaw(0), minVal(0), maxVal(0), rightVal(0), leftVal(0), rightRaw(0), leftRaw(0), pvec(100), minRaw(0), maxRaw(0), minVal(0), maxVal(0), rightVal(0), leftVal(0), rightRaw(0), leftRaw(0),
szCache(5), szCache(5),
numCacheResort(20), numCacheResort(20),
numCallToCache(5) numCallToCache(5)
{ {
pvec.reserve(reserv);
cache.assign(szCache, CacheInfo()); cache.assign(szCache, CacheInfo());
UniXML::iterator it(node); UniXML::iterator it(node);
myname = it.getProp("name"); myname = it.getProp("name");
...@@ -199,14 +194,13 @@ void Calibration::build( const string& name, const string& confile, xmlNode* roo ...@@ -199,14 +194,13 @@ void Calibration::build( const string& name, const string& confile, xmlNode* roo
} }
bool prev = false; bool prev = false;
Point prev_point(0, 0); Point prev_point;
unsigned int i = 0;
for(; it; it.goNext()) for(; it; it++ )
{ {
Point p(prev_point); Point p(prev_point);
p.x = atof(it.getProp("x").c_str()); p.x = std::atof(it.getProp("x").c_str());
p.y = atof(it.getProp("y").c_str()); p.y = std::atof(it.getProp("y").c_str());
if( p.x == 0 || p.y == 0 ) if( p.x == 0 || p.y == 0 )
{ {
...@@ -225,36 +219,28 @@ void Calibration::build( const string& name, const string& confile, xmlNode* roo ...@@ -225,36 +219,28 @@ void Calibration::build( const string& name, const string& confile, xmlNode* roo
minVal = p.y; minVal = p.y;
if( prev ) if( prev )
{ pvec.emplace_back(prev_point, p);
Part pt(prev_point, p);
pvec[i++] = pt;
if( i >= pvec.size() )
pvec.resize(pvec.size() + 20);
}
else else
prev = true; prev = true;
prev_point = p; prev_point = p;
} }
pvec.resize(i); // приводим размер к фактическому.. pvec.shrink_to_fit();
std::sort(pvec.begin(), pvec.end()); std::sort(pvec.begin(), pvec.end());
auto beg = pvec.begin(); if( !pvec.empty() )
auto end = pvec.end();
if( pvec.size() > 0 )
{ {
auto beg = pvec.begin();
auto end = --pvec.end();
leftRaw = beg->left_x(); leftRaw = beg->left_x();
leftVal = beg->left_y(); leftVal = beg->left_y();
--end;
rightRaw = end->right_x(); rightRaw = end->right_x();
rightVal = end->right_y(); rightVal = end->right_y();
} }
} }
catch( const Exception& ex ) catch( const UniSetTypes::Exception& ex )
{ {
dcrit << myname << "(Calibration::build): Failed open " << confile << endl; dcrit << myname << "(Calibration::build): Failed open " << confile << endl;
throw; throw;
...@@ -262,7 +248,7 @@ void Calibration::build( const string& name, const string& confile, xmlNode* roo ...@@ -262,7 +248,7 @@ void Calibration::build( const string& name, const string& confile, xmlNode* roo
} }
// ---------------------------------------------------------------------------- // ----------------------------------------------------------------------------
// рекурсивная функция поиска методом "половинного деления" // рекурсивная функция поиска методом "половинного деления"
static Calibration::PartsVec::iterator find_range( long raw, Calibration::PartsVec::iterator beg, static Calibration::PartsVec::iterator find_range( const long raw, Calibration::PartsVec::iterator beg,
Calibration::PartsVec::iterator end ) Calibration::PartsVec::iterator end )
{ {
if( beg->checkX(raw) ) if( beg->checkX(raw) )
...@@ -282,7 +268,7 @@ static Calibration::PartsVec::iterator find_range( long raw, Calibration::PartsV ...@@ -282,7 +268,7 @@ static Calibration::PartsVec::iterator find_range( long raw, Calibration::PartsV
return it; return it;
} }
// ---------------------------------------------------------------------------- // ----------------------------------------------------------------------------
long Calibration::getValue( long raw, bool crop_raw ) long Calibration::getValue( const long raw, bool crop_raw )
{ {
// если x левее первого отрезка то берём первую точку... // если x левее первого отрезка то берём первую точку...
if( raw < leftRaw ) if( raw < leftRaw )
...@@ -312,7 +298,7 @@ long Calibration::getValue( long raw, bool crop_raw ) ...@@ -312,7 +298,7 @@ long Calibration::getValue( long raw, bool crop_raw )
} }
} }
auto fit = find_range(raw, pvec.begin(), pvec.end()); auto fit = find_range(raw, pvec.begin(), --pvec.end() );
if( fit == pvec.end() ) if( fit == pvec.end() )
{ {
...@@ -338,13 +324,13 @@ long Calibration::getValue( long raw, bool crop_raw ) ...@@ -338,13 +324,13 @@ long Calibration::getValue( long raw, bool crop_raw )
return outOfRange; return outOfRange;
} }
// ---------------------------------------------------------------------------- // ----------------------------------------------------------------------------
void Calibration::setCacheResortCycle( unsigned int n ) void Calibration::setCacheResortCycle( size_t n )
{ {
numCacheResort = n; numCacheResort = n;
numCallToCache = n; numCallToCache = n;
} }
// ---------------------------------------------------------------------------- // ----------------------------------------------------------------------------
void Calibration::setCacheSize( unsigned int sz ) void Calibration::setCacheSize( size_t sz )
{ {
sort(cache.begin(), cache.end()); // в порядке уменьшения обращений (см. CacheInfo::operator< ) sort(cache.begin(), cache.end()); // в порядке уменьшения обращений (см. CacheInfo::operator< )
cache.resize(sz); cache.resize(sz);
...@@ -358,7 +344,7 @@ void Calibration::insertToCache( const long raw, const long val ) ...@@ -358,7 +344,7 @@ void Calibration::insertToCache( const long raw, const long val )
sort(cache.begin(), cache.end()); // пересортируем в порядке уменьшения обращений (см. CacheInfo::operator< ) sort(cache.begin(), cache.end()); // пересортируем в порядке уменьшения обращений (см. CacheInfo::operator< )
} }
// ---------------------------------------------------------------------------- // ----------------------------------------------------------------------------
long Calibration::getRawValue( long cal, bool range ) long Calibration::getRawValue( const long cal, bool range )
{ {
for( auto& it : pvec ) for( auto& it : pvec )
{ {
......
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