A new type of anti-slip controller based on TS fuzzy models

Revision:
0:bfcd2371f3dc
Child:
1:773d8ae11c1a
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/ANTI_SLIP_FUZZY_CONTROL.cpp	Thu Feb 23 11:12:35 2017 +0000
@@ -0,0 +1,346 @@
+#include "ANTI_SLIP_FUZZY_CONTROL.h"
+
+//------------------------------------------//
+// The template for building a library
+//   for control system apllication
+//------------------------------------------//
+
+// The plant is a (p, n, q) system
+// Dimensions:
+//
+// Inputs, u   |   States, x    |   outputs, y
+//     p     -->      n        -->      q
+//
+
+//
+// The number of vertex systems is m_vertex.
+//
+
+ANTI_SLIP_FUZZY_CONTROL::ANTI_SLIP_FUZZY_CONTROL(size_t num_state, size_t num_in, size_t num_out, size_t num_vertex, float samplingTime):
+        n(num_state), p(num_in), q(num_out), m_vertex(num_vertex), Ts(samplingTime),
+        E_out(num_out, vector<float>(num_state,0.0)),
+        ver_K_matrix(num_vertex ,vector<vector<float> >(num_in, vector<float>( (num_state + num_out), 0.0)) ),
+        SA_r(1.0, 0.0),
+        SA_l(1.0, 0.0)
+{
+    // Normally, q = p
+    if (q > p)
+        q = p;
+    //
+    zeros_n.assign(n, 0.0);
+    zeros_p.assign(p, 0.0);
+    zeros_q.assign(q, 0.0);
+    zeros_nPq.assign((n+q), 0.0); // (n+q)
+    zeros_m_vertex.assign(m_vertex, 0.0);
+    //
+    ones_p.assign(p, 1.0);
+
+    // States
+    // Input signal ---
+    states = zeros_n;
+    command = zeros_q; // r, commands, q = p
+    // Output signal ---
+    sys_inputs = zeros_p;
+
+    // Internal states ---
+    ver_u.assign(m_vertex, zeros_p);
+    sys_outputs = zeros_q;
+    // Integral state
+    state_int = zeros_q;
+    // Total states, [states; state_int]
+    state_total = zeros_nPq;
+
+
+    // The composition ratio of each vertex system
+    ver_ratio = zeros_m_vertex; // ver_ratio \in R^m_vertex, its values are in [0, 1]
+    ver_ratio[3] = 1.0; // Vertex of no-slip system
+
+}
+// Assign Parameters
+void ANTI_SLIP_FUZZY_CONTROL::assign_E_out(float* E_out_in){
+    // E_out_in is the pointer of a mutidimentional array with size q by n
+    E_out.assign(q, zeros_n);
+    //
+    for (size_t i = 0; i < q; ++i){
+        for (size_t j = 0; j < n; ++j){
+            // E_out[i][j] = E_out_in[i][j];
+            E_out[i][j] = *E_out_in;
+            E_out_in++;
+        }
+    }
+}
+// 1st controller Parameters (no-slip plant, sys_dVs)
+void ANTI_SLIP_FUZZY_CONTROL::assign_ver_K_matrix(float* ver_K_matrix_in){
+    // ver_K_matrix_in is the pointer of a list of mutidimentional array with size p by (n+q)
+    ver_K_matrix.assign(m_vertex, vector<vector<float> >(p, zeros_nPq) );
+    //
+    for (size_t k = 0; k < m_vertex; ++k){
+        // For each vertex
+        for (size_t i = 0; i < p; ++i){
+            for (size_t j = 0; j < (n+q); ++j){
+                // (ver_K_matrix[k])[i][j] = ver_K_matrix_in[i][j];
+                (ver_K_matrix[k])[i][j] = *ver_K_matrix_in;
+                ver_K_matrix_in++;
+            }
+        }
+        //
+    }
+    //
+}
+
+
+//
+void ANTI_SLIP_FUZZY_CONTROL::set_ver_ratio(float ratio_ft_right, float ratio_ft_left){
+    float one_ratio_ft_right;
+    float one_ratio_ft_left;
+    // Input Saturation
+    ratio_ft_right = SA_r.filter(ratio_ft_right);
+    ratio_ft_left = SA_l.filter(ratio_ft_left);
+    //
+    one_ratio_ft_right = 1.0 - ratio_ft_right;
+    one_ratio_ft_left = 1.0 - ratio_ft_left;
+    //
+    ver_ratio[0] = one_ratio_ft_right   * one_ratio_ft_left;
+    ver_ratio[1] = ratio_ft_right       * one_ratio_ft_left;
+    ver_ratio[2] = one_ratio_ft_right   * ratio_ft_left;
+    ver_ratio[3] = ratio_ft_right       * ratio_ft_left;
+}
+//
+void ANTI_SLIP_FUZZY_CONTROL::fullStateFeedBack_calc(bool enable){
+
+    // Control law
+    if (enable){
+        // Get the state_total
+        get_state_total();
+
+
+        /*
+        // Slower solution, record the outout of each vertex controller
+        sys_inputs = zeros_p;
+        //
+        for (size_t k = 0; k < m_vertex; ++k){
+            ver_u[k] = Get_VectorScalarMultiply( Mat_multiply_Vec(ver_K_matrix[k], state_total), -1.0 );
+            Get_VectorIncrement(sys_inputs, Get_VectorScalarMultiply( ver_u[k], ver_ratio[k]), false); // +=
+        }
+        */
+
+
+
+        // Faster solution, no recording the output of each vertex controller
+        sys_inputs = zeros_p;
+        //
+
+        for (size_t k = 0; k < m_vertex; ++k){
+            // sys_inputs -= ver_ratio[k]*(ver_K_matrix[k]*state_total);
+            Get_VectorIncrement(sys_inputs, Get_VectorScalarMultiply( Mat_multiply_Vec(ver_K_matrix[k], state_total), ver_ratio[k] ), true); // -=
+        }
+
+
+
+        /*
+        for (size_t k = 3; k < 4; ++k){
+            // sys_inputs -= ver_ratio[k]*(ver_K_matrix[k]*state_total);
+            Get_VectorIncrement(sys_inputs, Get_VectorScalarMultiply( Mat_multiply_Vec(ver_K_matrix[k], state_total), ver_ratio[k] ), true); // -=
+        }
+        */
+
+
+
+        //
+    }else{
+        state_total = zeros_nPq;
+        sys_inputs = zeros_p;
+    }
+
+    // Integral action
+    get_integral(enable);
+}
+
+// Private functions
+// Calculate the sys_outputs
+void ANTI_SLIP_FUZZY_CONTROL::get_sys_outputs(void){ // Calculate the sys_outputs from states, by mutiplying E_out
+    // sys_outputs = E_out*states
+    // Mat_multiply_Vec(sys_outputs, E_out, states);
+    sys_outputs = Mat_multiply_Vec(E_out, states);
+}
+// Calculate the Integral
+void ANTI_SLIP_FUZZY_CONTROL::get_integral(bool enable){ // Calculate the state_int
+    //
+    // Calculate the sys_outputs
+    get_sys_outputs();
+
+    // Integral action
+    // state_int += sys_outputs - command
+    if (enable){
+        Get_VectorIncrement(state_int, Get_VectorScalarMultiply(Get_VectorPlus(sys_outputs,command,true),Ts) ,false); // +=
+    }else{
+        state_int = zeros_q;
+    }
+}
+// Concatenate the state and state_int
+void ANTI_SLIP_FUZZY_CONTROL::get_state_total(void){ // Total states, [states; state_int]
+    //
+    size_t idx = 0;
+    // states
+    for (size_t i = 0; i < n; ++i){
+        state_total[idx] = states[i];
+        idx++;
+    }
+    // state_int
+    for (size_t i = 0; i < q; ++i){
+        state_total[idx] = state_int[i];
+        idx++;
+    }
+}
+
+// Utilities
+void ANTI_SLIP_FUZZY_CONTROL::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> ANTI_SLIP_FUZZY_CONTROL::Mat_multiply_Vec(const vector<vector<float> > &m_left, const vector<float> &v_right){ // v_out = m_left*v_right
+    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<const float>::iterator it_m_row;
+    static vector<const 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 = m_left[i].begin();
+        it_v = 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> ANTI_SLIP_FUZZY_CONTROL::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> ANTI_SLIP_FUZZY_CONTROL::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 ANTI_SLIP_FUZZY_CONTROL::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];
+        }
+    }
+
+}