An observer for estimating the friction-force ratio
Observer_ftRatio.cpp
- Committer:
- benson516
- Date:
- 2017-02-26
- Revision:
- 1:fbae330f0e71
- Parent:
- 0:a936477fcd4a
File content as of revision 1:fbae330f0e71:
#include "Observer_ftRatio.h" // float Dimension_ftOb[] = { #include "Dimensions_ftOb.txt" // Load the parameter Dimensions_ftOb }; // Observer_ftRatio::Observer_ftRatio(float samplingTime): Ts(samplingTime), OB(Dimension_ftOb[3], Dimension_ftOb[4], Dimension_ftOb[5], 0, samplingTime), KFID_ratio_ft_right(samplingTime, 1.0, 0.0, 1.0, 1.0, 1.0, false), // For identifing the ratio_ft of the right wheel KFID_ratio_ft_left(samplingTime, 1.0, 0.0, 1.0, 1.0, 1.0, false), // For identifing the ratio_ft of the left wheel SAT_ratio_ft(Dimension_ftOb[1], 1.0, 0.0), LPF_ratio_ft(Dimension_ftOb[1], samplingTime, 10.0, 1) // fc = 10 Hz { // To enble, run *.start() function enable = false; // Dimensions of the original system n = Dimension_ftOb[0]; p = Dimension_ftOb[1]; q = Dimension_ftOb[2]; // Dimensions of the observer n_OB = Dimension_ftOb[3]; p_OB = Dimension_ftOb[4]; q_OB = Dimension_ftOb[5]; n_ME_OB = Dimension_ftOb[6]; // Number of the measurement errors in the PI observer // zeros_n.assign(n, 0.0); zeros_p.assign(p, 0.0); zeros_q.assign(q, 0.0); zeros_n_ME_OB.assign(n_ME_OB, 0.0); // ones_p.assign(p, 1.0); // Assign parameters // init(); // Indexes // idx_x_real = 0; // Index for x_real_est idx_x_ns = n; idx_ft_error_est = 2*n; // Index for ft_error_est // Input signals yc = zeros_p; // States ft_est = zeros_p; ft_error_est = zeros_p; ft_ideal_est = zeros_p; // x_real_est = zeros_n; // Estimation of the real states // x_ns_est = zeros_n; // Estimation of the states of the no-slip system // The estimation of measurement errors in PI observer Measurement_error_est = zeros_n_ME_OB; // The degree of no-slip // ratio_ft = zeros_p; ratio_ft = ones_p; // No slip ratio_ft_filtered = ones_p; // No slip } void Observer_ftRatio::start(){ enable = true; // OB.start(); } void Observer_ftRatio::pause(){ enable = false; // OB.enable = false; } void Observer_ftRatio::stop(){ if (!enable){ return; } enable = false; // Reset reset(); // OB.stop(); } void Observer_ftRatio::reset(){ // // Input signals yc = zeros_p; // States ft_est = zeros_p; ft_error_est = zeros_p; ft_ideal_est = zeros_p; // x_real_est = zeros_n; // Estimation of the real states // x_ns_est = zeros_n; // Estimation of the states of the no-slip system // The estimation of measurement errors in PI observer Measurement_error_est.assign(2, 0.0); // Reset the identifier for ratio_ft(s) KFID_ratio_ft_right.reset(1.0); // 1.0 for no-slip (full friction-force) KFID_ratio_ft_left.reset(1.0); // 1.0 for no-slip (full friction-force) // The degree of no-slip // ratio_ft = zeros_p; ratio_ft = ones_p; // No slip ratio_ft_filtered = ones_p;// No slip // Reset the low-pass filter for ratio_ft LPF_ratio_ft.reset(ratio_ft); // OB.reset(); } // void Observer_ftRatio::init(void){ // float _A_ftOb[] = { #include "A_ftOb.txt" // Load the parameter A_ftOb }; float _By_ftOb[] = { #include "By_ftOb.txt" // Load the parameter By_ftOb }; /* float _Bv1_ftOb[] = { #include "Bv1_ftOb.txt" // Load the parameter Bv1_ftOb }; */ float _C_ftOb[] = { #include "C_ftOb.txt" // Load the parameter C_ftOb }; // float _F1_ftOb[] = { #include "F1_ftOb.txt" // Load the parameter F1_ftOb }; float _F2_ftOb[] = { #include "F2_ftOb.txt" // Load the parameter F2_ftOb }; // float _L_ftOb[] = { #include "L_ftOb.txt" // Load the parameter L_ftOb }; // OB.assign_At(_A_ftOb, n_OB); OB.assign_Bt(_By_ftOb, n_OB, p_OB); OB.assign_Cd(_C_ftOb, q_OB, n_OB); // OB.assign_Lt(_L_ftOb, n_OB, 0, q_OB); //-------------------------// // assign_Matrix(Bv1_ftOb, _Bv1_ftOb, n_OB, p_OB); // assign_Matrix(F1_ftOb, _F1_ftOb, p, n); assign_Matrix(F2_ftOb, _F2_ftOb, p, p); } // void Observer_ftRatio::iterateOnce(const vector<float> &yc_in, const vector<float> &x_real_in){ if(!enable){ return; } // Insert values insertSignals(yc_in, x_real_in); // Progress one time slot OB.iterateOnce(); // Clean up the estimation of w_ideal_avg and w_ideal_delta /* // for test return; // */ // Get the results //--------------------------// size_t idx = 0; // x_real_est for (size_t i = 0; i < n; ++i){ x_real_est[i] = OB.state_est[idx]; // idx++; } // ft_est for (size_t i = 0; i < p; ++i){ ft_est[i] = OB.state_est[idx]; // idx++; } // Measurement_error_est for (size_t i = 0; i < n_ME_OB; ++i){ Measurement_error_est[i] = OB.state_est[idx]; // idx++; } //--------------------------// // ft_ideal_est // ft_ideal_est = F1_ftOb*x_real_est + F2_ftOb*yc ft_ideal_est = Mat_multiply_Vec(F1_ftOb, x_real_est); Get_VectorIncrement(ft_ideal_est, Mat_multiply_Vec(F2_ftOb, yc), false); // += // ft_error_est = ft_est - ft_ideal_est; ft_error_est = Get_VectorPlus(ft_est, ft_ideal_est, true); // minus /* // The ratio_ft for (size_t i = 0; i < p; ++i){ // if (ft_ideal_est[i] < NUM_THRESHOLD && (-ft_ideal_est[i]) < NUM_THRESHOLD){ ratio_ft[i] = 1.0; // no-slip }else{ ratio_ft[i] = ft_est[i]/ft_ideal_est[i]; } // Saturation if (ratio_ft[i] > 1.0){ ratio_ft[i] = 1.0; }else if (ratio_ft[i] < 0.0){ ratio_ft[i] = 0.0; } // } */ // Identify the ratio_ft //----------------------------------------------------// /* // Transform from (rifht, left) to (average, delta) T_ft_est.assign_R_L(ft_est); T_ft_ideal_est.assign_R_L(ft_ideal_est); // ratio_ft_avg KFID_ratio_ft_avg.C = T_ft_ideal_est.get_avg(); ratio_ft[0] = KFID_ratio_ft_avg.filter(0.0, T_ft_est.get_avg()); // ratio_ft_delta KFID_ratio_ft_delta.C = T_ft_ideal_est.get_delta(); ratio_ft[1] = KFID_ratio_ft_delta.filter(0.0, T_ft_est.get_delta()); */ // Right-side ratio KFID_ratio_ft_right.C = ft_ideal_est[0]; ratio_ft[0] = KFID_ratio_ft_right.filter(0.0, ft_est[0] ); // Left-side ratio KFID_ratio_ft_left.C = ft_ideal_est[1]; ratio_ft[1] = KFID_ratio_ft_left.filter(0.0, ft_est[1] ); // Saturation ratio_ft = SAT_ratio_ft.filter(ratio_ft); //----------------------------------------------------// // Filtering ratio_ft_filtered = LPF_ratio_ft.filter(ratio_ft); } // Private methods // void Observer_ftRatio::insertSignals(const vector<float> &yc_in, const vector<float> &x_real_in){ // yc = yc_in; // Insert values OB.sys_inputs = yc_in; OB.sys_outputs = x_real_in; // // OB.sys_extraDisturbance = Mat_multiply_Vec(Bv1_ftOb, v1_in); } // Utilities void Observer_ftRatio::Mat_multiply_Vec(vector<float> &v_out, const vector<vector<float> > &m_left, const vector<float> &v_right){ // v_out = m_left*v_right // Size check if (v_out.size() != m_left.size()){ v_out.resize(m_left.size()); } /* // Iterators static vector<float>::iterator it_out; static vector<float>::iterator it_m_row; static vector<float>::iterator it_v; // it_out = v_out.begin(); for (size_t i = 0; i < m_left.size(); ++i){ *it_out = 0.0; it_m_row = vector<vector<float> >(m_left)[i].begin(); it_v = vector<float>(v_right).begin(); for (size_t j = 0; j < m_left[i].size(); ++j){ // *it_out += m_left[i][j] * v_right[j]; if (*it_m_row != 0.0 && *it_v != 0.0){ (*it_out) += (*it_m_row) * (*it_v); }else{ // (*it_out) += 0.0 } // (*it_out) += (*it_m_row) * (*it_v); // it_m_row++; it_v++; } it_out++; } */ // Indexing for (size_t i = 0; i < m_left.size(); ++i){ // v_out[i] = 0.0; // for (size_t j = 0; j < v_right.size(); ++j){ if (m_left[i][j] != 0.0 && v_right[j] != 0.0) v_out[i] += m_left[i][j]*v_right[j]; } } } vector<float> Observer_ftRatio::Mat_multiply_Vec(const vector<vector<float> > &m_left, const vector<float> &v_right){ // v_out = m_left*v_right static vector<float> v_out; // Size check if (v_out.size() != m_left.size()){ v_out.resize(m_left.size()); } /* // Iterators static vector<float>::iterator it_out; static vector<float>::iterator it_m_row; static vector<float>::iterator it_v; // it_out = v_out.begin(); for (size_t i = 0; i < m_left.size(); ++i){ *it_out = 0.0; it_m_row = vector<vector<float> >(m_left)[i].begin(); it_v = vector<float>(v_right).begin(); for (size_t j = 0; j < m_left[i].size(); ++j){ // *it_out += m_left[i][j] * v_right[j]; if (*it_m_row != 0.0 && *it_v != 0.0){ (*it_out) += (*it_m_row) * (*it_v); }else{ // (*it_out) += 0.0 } // (*it_out) += (*it_m_row) * (*it_v); // it_m_row++; it_v++; } it_out++; } */ // Indexing for (size_t i = 0; i < m_left.size(); ++i){ // v_out[i] = 0.0; // for (size_t j = 0; j < v_right.size(); ++j){ if (m_left[i][j] != 0.0 && v_right[j] != 0.0) v_out[i] += m_left[i][j]*v_right[j]; } } return v_out; } vector<float> Observer_ftRatio::Get_VectorPlus(const vector<float> &v_a, const vector<float> &v_b, bool is_minus) // v_a + (or -) v_b { static vector<float> v_c; // Size check if (v_c.size() != v_a.size()){ v_c.resize(v_a.size()); } // for (size_t i = 0; i < v_a.size(); ++i){ if (is_minus){ v_c[i] = v_a[i] - v_b[i]; }else{ v_c[i] = v_a[i] + v_b[i]; } } return v_c; } vector<float> Observer_ftRatio::Get_VectorScalarMultiply(const vector<float> &v_a, float scale) // scale*v_a { static vector<float> v_c; // Size check if (v_c.size() != v_a.size()){ v_c.resize(v_a.size()); } // for pure negative if (scale == -1.0){ for (size_t i = 0; i < v_a.size(); ++i){ v_c[i] = -v_a[i]; } return v_c; } // else for (size_t i = 0; i < v_a.size(); ++i){ v_c[i] = scale*v_a[i]; } return v_c; } // Increment void Observer_ftRatio::Get_VectorIncrement(vector<float> &v_a, const vector<float> &v_b, bool is_minus){ // v_a += (or -=) v_b // Size check if (v_a.size() != v_b.size()){ v_a.resize(v_b.size()); } // if (is_minus){ // -= for (size_t i = 0; i < v_b.size(); ++i){ v_a[i] -= v_b[i]; } }else{ // += for (size_t i = 0; i < v_b.size(); ++i){ v_a[i] += v_b[i]; } } } // void Observer_ftRatio::assign_Matrix(vector<vector<float> > &M, float* M_in, size_t m_in, size_t n_in){ // M_in is a m_in by n_in array // M_in is the pointer of a mutidimentional array with size m_in by n_in M.resize(m_in, vector<float>(n_in, 0.0)); // for (size_t i = 0; i < m_in; ++i){ for (size_t j = 0; j < n_in; ++j){ // M[i][j] = M_in[i][j]; M[i][j] = *M_in; M_in++; } } }