00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024
00025
00026
00027
00028
00029
00030
00031
00032
00033
00034 #include <labust/control/SOIdentification.hpp>
00035 #include <labust/math/NumberManipulation.hpp>
00036
00037 #include <boost/numeric/ublas/matrix_proxy.hpp>
00038
00039 using namespace labust::control;
00040
00041 SOIdentification::SOIdentification(
00042 double C, double X, double R, double E, double identLen):
00043 finished(false),
00044 relay(C,X),
00045 params(numParams,0),
00046 tSum(0),
00047 maxOsc(-std::numeric_limits<double>::max()),
00048 minOsc(std::numeric_limits<double>::max()),
00049 counterHigh(0),
00050 counterLow(0),
00051 eMaxError(E),
00052 eMinError(E),
00053 ref(0),
00054 identLen(identLen),
00055 xa_high(identLen,0),
00056 xa_low(identLen,0),
00057 e_min(identLen,0),
00058 e_max(identLen,0),
00059 t_min(identLen,0),
00060 t_max(identLen,0)
00061 {this->reset();};
00062
00063 SOIdentification::~SOIdentification(){};
00064
00065 double SOIdentification::step(double error, double dT)
00066 {
00067
00068 double retVal = relay.step(error);
00069
00070 tSum += dT;
00071
00072
00073 if (error > maxOsc) maxOsc=error;
00074 if (error < minOsc) minOsc=error;
00075
00076 if (int sw = relay.hasSwitched())
00077 {
00078
00079
00080
00081 if (sw == 1)
00082 {
00083 xa_high[counterHigh] = error;
00084 e_min[counterLow] = minOsc;
00085 t_min[counterLow] = tSum;
00086 tSum = 0;
00087 counterLow=(counterLow+1)%identLen;
00088 }
00089 else
00090 {
00091 xa_low[counterLow] = error;
00092 e_max[counterHigh] = maxOsc;
00093 t_max[counterHigh] = tSum;
00094 tSum = 0;
00095 counterHigh=(counterHigh+1)%identLen;
00096 }
00097
00098
00099 maxOsc=-std::numeric_limits<double>::max();
00100 minOsc=std::numeric_limits<double>::max();
00101
00102
00103 calculateParameters();
00104 }
00105
00106 return retVal;
00107 }
00108
00109 void SOIdentification::calculateParameters()
00110 {
00111 using boost::numeric::ublas::row;
00112
00113 double meanEMax(labust::math::mean(e_max)),
00114 stdEMax(labust::math::std2(e_max)),
00115
00116 meanEMin(labust::math::mean(e_min)),
00117 stdEMin(labust::math::std2(e_min)),
00118
00119 meanTMax(labust::math::mean(t_max)),
00120 meanTMin(labust::math::mean(t_min)),
00121
00122 meanXaLow(labust::math::mean(xa_low)),
00123 meanXaHigh(labust::math::mean(xa_high));
00124
00125 double T(meanTMax+meanTMin),
00126 Xm(0.5*(meanEMax-meanEMin)),
00127 X0(0.5*(meanEMax+meanEMin)),
00128 xa_star(0.5*(meanXaHigh-meanXaLow));
00129
00130 double omega(2*M_PI/T),
00131 C(relay.getAmplitude());
00132
00133 double sq1((xa_star+X0)/Xm);
00134 sq1 = sqrt(1-sq1*sq1);
00135 double sq2((xa_star-X0)/Xm);
00136 sq2 = sqrt(1-sq2*sq2);
00137
00138 params[alpha] = 2*C*(sq1+sq2)/(M_PI*omega*omega*Xm);
00139 params[kx]=(4.0*C*xa_star)/(omega*M_PI*Xm*Xm);
00140 params[kxx]=(3.0*C*xa_star)/(2*omega*omega*Xm*Xm*Xm);
00141 params[delta] = C*(meanTMax - meanTMin)/(meanTMax + meanTMin);
00142 params[wn] = omega;
00143
00144
00145
00146
00147 finished = ((std::fabs(stdEMax/meanEMax)<eMaxError) && (std::fabs(stdEMin/meanEMin)<eMinError));
00148 minMaxError = (std::fabs(stdEMax/meanEMax) + std::fabs(stdEMin/meanEMin))/2;
00149 }
00150
00151 void SOIdentification::reset()
00152 {
00153 finished = false;
00154 xa_high = std::vector<double>(identLen,0);
00155 xa_low = std::vector<double>(identLen,0);
00156 e_min = std::vector<double>(identLen,0);
00157 e_max = std::vector<double>(identLen,0);
00158 t_min = std::vector<double>(identLen,0);
00159 t_max = std::vector<double>(identLen,0);
00160 tSum = 0;
00161 maxOsc = -std::numeric_limits<double>::max();
00162 minOsc = std::numeric_limits<double>::max();
00163 counterHigh = 0;
00164 counterLow = 0;
00165 relay.setAmplitude(relay.getAmplitude());
00166 }