Commit 65566188 authored by Pavel Vainerman's avatar Pavel Vainerman

(Calibration): перешёл на использование vector вместо list, переписал функцию…

(Calibration): перешёл на использование vector вместо list, переписал функцию поиска (сделал поиск методом половинного деления).
parent d4980d69
......@@ -275,6 +275,12 @@
<!-- <xi:include href="testIDnon-exist.xml"/> -->
<Calibrations name="Calibrations">
<diagram name="testcal">
<point x="-1000" y="-300"/>
<point x="-900" y="-250"/>
<point x="-800" y="-200"/>
<point x="-700" y="-150"/>
<point x="-600" y="-100"/>
<point x="-500" y="-80"/>
<point x="-200" y="-60"/>
<point x="-100" y="-60"/>
<point x="-50" y="-20"/>
......@@ -282,6 +288,14 @@
<point x="50" y="20"/>
<point x="100" y="60"/>
<point x="200" y="60"/>
<point x="300" y="80"/>
<point x="400" y="100"/>
<point x="500" y="150"/>
<point x="600" y="200"/>
<point x="700" y="250"/>
<point x="800" y="300"/>
<point x="900" y="400"/>
<point x="1000" y="600"/>
</diagram>
</Calibrations>
</UNISETPLC>
......@@ -3,7 +3,7 @@
// -----------------------------------------------------------------------------
#include <cmath>
#include <string>
#include <list>
#include <vector>
#include <ostream>
// -----------------------------------------------------------------------------
/*!
......@@ -55,8 +55,11 @@ class Calibration
Calibration( xmlNode* node );
~Calibration();
/*! Тип для хранения значения */
typedef float TypeOfValue;
/*! выход за границы диапазона */
static const int outOfRange=-1;
static const TypeOfValue outOfRange;
/*!
Получение калиброванного значения
......@@ -103,10 +106,6 @@ class Calibration
*/
void build( const std::string& name, const std::string& confile, xmlNode* node=0 );
/*! Тип для хранения текущего значения */
typedef float TypeOfValue;
/*! преобразование типа для хранения
в тип для аналоговых датчиков
*/
......@@ -121,6 +120,8 @@ class Calibration
/*! точка характеристики */
struct Point
{
Point():x(outOfRange),y(outOfRange){}
Point( TypeOfValue _x, TypeOfValue _y ):
x(_x),y(_y){}
......@@ -137,6 +138,7 @@ class Calibration
class Part
{
public:
Part();
Part( const Point& pleft, const Point& pright );
~Part(){};
......@@ -175,15 +177,15 @@ class Calibration
TypeOfValue k; /*!< коэффициент наклона */
};
protected:
// список надо отсортировать по x!
typedef std::list<Part> PartsList;
typedef std::vector<Part> PartsVec;
protected:
long minRaw, maxRaw, minVal, maxVal, rightVal, leftVal, rightRaw, leftRaw;
private:
PartsList plist;
PartsVec pvec;
std::string myname;
};
// -----------------------------------------------------------------------------
......
#include <sstream>
#include <iostream>
#include <limits>
#include <algorithm>
#include "UniXML.h"
#include "Exceptions.h"
......@@ -8,6 +9,13 @@
using namespace std;
using namespace UniSetTypes;
// ----------------------------------------------------------------------------
const Calibration::TypeOfValue Calibration::outOfRange = std::numeric_limits<Calibration::TypeOfValue>::max();
// ----------------------------------------------------------------------------
Calibration::Part::Part():
k(0)
{
}
Calibration::Part::Part( const Point& pleft, const Point& pright ):
p_left(pleft),
......@@ -96,6 +104,7 @@ Calibration::TypeOfValue Calibration::Part::calcX( const TypeOfValue& y ) const
Calibration::Calibration():
minRaw(0),maxRaw(0),minVal(0),maxVal(0),rightVal(0),leftVal(0),rightRaw(0),leftRaw(0),
pvec(50),
myname("")
{
}
......@@ -104,6 +113,7 @@ myname("")
Calibration::Calibration( const string& name, const string& confile ):
minRaw(0),maxRaw(0),minVal(0),maxVal(0),rightVal(0),leftVal(0),rightRaw(0),leftRaw(0),
pvec(50),
myname(name)
{
build(name,confile,0);
......@@ -111,7 +121,7 @@ myname(name)
// ----------------------------------------------------------------------------
Calibration::Calibration( xmlNode* node ):
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(100)
{
UniXML_iterator it(node);
myname = it.getProp("name");
......@@ -157,6 +167,7 @@ void Calibration::build( const string& name, const string& confile, xmlNode* roo
bool prev = false;
Point prev_point(0,0);
unsigned int i=0;
for(;it;it.goNext())
{
Point p(prev_point);
......@@ -169,9 +180,6 @@ void Calibration::build( const string& name, const string& confile, xmlNode* roo
<< p.x << " y=" << p.y << endl;
}
// cout << myname << "(Calibration::build):"
// << "\tadd x=" << p.x << " y=" << p.y << endl;
if( p.x > maxRaw )
maxRaw = p.x;
else if( p.x < minRaw )
......@@ -184,13 +192,10 @@ void Calibration::build( const string& name, const string& confile, xmlNode* roo
if( prev )
{
// cout << myname << "(Calibration::build):"
// << "\tadd x=" << p.x << " y=" << p.y
// << " prev.x=" << prev_point.x
// << " prev.y=" << prev_point.y
// << endl;
Part pt(prev_point,p);
plist.push_back(pt);
pvec[i++] = pt;
if( i >= pvec.size() )
pvec.resize(pvec.size()+20);
}
else
prev = true;
......@@ -198,12 +203,14 @@ void Calibration::build( const string& name, const string& confile, xmlNode* roo
prev_point = p;
}
plist.sort();
pvec.resize(i); // приводим размер к фактическому..
PartsList::iterator beg = plist.begin();
PartsList::iterator end = plist.end();
std::sort(pvec.begin(),pvec.end());
if( plist.size() > 0 )
PartsVec::iterator beg = pvec.begin();
PartsVec::iterator end = pvec.end();
if( pvec.size() > 0 )
{
leftRaw = beg->left_x();
leftVal = beg->left_y();
......@@ -219,6 +226,27 @@ void Calibration::build( const string& name, const string& confile, xmlNode* roo
}
}
// ----------------------------------------------------------------------------
// рекурсивная функция поиска методом "половинного деления"
static Calibration::PartsVec::iterator find_range( long raw, Calibration::PartsVec::iterator beg,
Calibration::PartsVec::iterator end )
{
if( beg->checkX(raw) )
return beg;
if( end->checkX(raw) )
return end;
Calibration::PartsVec::iterator it = beg + std::distance(beg,end)/2;
if( raw < it->left_x() )
return find_range(raw,beg,it);
if( raw > it->right_x() )
return find_range(raw,it,end);
return it;
}
// ----------------------------------------------------------------------------
long Calibration::getValue( long raw, bool crop_raw )
{
// если x левее первого отрезка то берём первую точку...
......@@ -229,19 +257,21 @@ long Calibration::getValue( long raw, bool crop_raw )
if( raw > rightRaw )
return (crop_raw ? rightVal : outOfRange);
for( PartsList::iterator it=plist.begin(); it!=plist.end(); ++it )
{
TypeOfValue q = it->getY(raw);
PartsVec::iterator fit = find_range(raw, pvec.begin(), pvec.end());
if( fit == pvec.end() )
return outOfRange;
TypeOfValue q = fit->getY(raw);
if( q != outOfRange )
return tRound(q);
}
return outOfRange;
}
// ----------------------------------------------------------------------------
long Calibration::getRawValue( long cal, bool range )
{
for( PartsList::iterator it=plist.begin(); it!=plist.end(); ++it )
for( PartsVec::iterator it=pvec.begin(); it!=pvec.end(); ++it )
{
TypeOfValue q = it->getX(cal);
if( q != outOfRange )
......@@ -263,7 +293,7 @@ long Calibration::getRawValue( long cal, bool range )
std::ostream& operator<<( std::ostream& os, Calibration& c )
{
os << "*******************" << endl;
for( Calibration::PartsList::iterator it=c.plist.begin(); it!=c.plist.end(); ++it )
for( Calibration::PartsVec::iterator it=c.pvec.begin(); it!=c.pvec.end(); ++it )
{
os << "[" << it->leftPoint().x << " : " << it->rightPoint().x << " ] --> ["
<< it->leftPoint().y << " : " << it->rightPoint().y << " ]"
......@@ -276,7 +306,7 @@ std::ostream& operator<<( std::ostream& os, Calibration& c )
std::ostream& operator<<( std::ostream& os, Calibration* c )
{
os << "*******************" << endl;
for( Calibration::PartsList::iterator it=c->plist.begin(); it!=c->plist.end(); ++it )
for( Calibration::PartsVec::iterator it=c->pvec.begin(); it!=c->pvec.end(); ++it )
{
os << "[" << it->leftPoint().x << " : " << it->rightPoint().x << " ] --> ["
<< it->leftPoint().y << " : " << it->rightPoint().y << " ]"
......
......@@ -19,6 +19,12 @@ int main( int argc, const char** argv )
cout << "diagram: " << cal << endl;
cout << "-1500 --> " << cal->getValue(-1500) << endl;
cout << "-933 --> " << cal->getValue(-933) << endl;
cout << "-844 --> " << cal->getValue(-844) << endl;
cout << "-540 --> " << cal->getValue(-540) << endl;
cout << "-320 --> " << cal->getValue(-320) << endl;
cout << "-200 --> " << cal->getValue(-200) << endl;
cout << "-100 --> " << cal->getValue(-100) << endl;
cout << "-200 --> " << cal->getValue(-200) << endl;
cout << "-100 --> " << cal->getValue(-100) << endl;
cout << " -75 --> " << cal->getValue(-75) << endl;
......@@ -30,6 +36,10 @@ int main( int argc, const char** argv )
cout << " 75 --> " << cal->getValue(75) << endl;
cout << " 100 --> " << cal->getValue(100) << endl;
cout << " 200 --> " << cal->getValue(200) << endl;
cout << " 310 --> " << cal->getValue(310) << endl;
cout << " 415 --> " << cal->getValue(415) << endl;
cout << " 556 --> " << cal->getValue(556) << endl;
cout << " 873 --> " << cal->getValue(873) << endl;
cout << " 1500 --> " << cal->getValue(1500) << endl;
cout << endl << " RAW VALUE.." << endl;
......
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