An state-observer that deals with delay in measurements, also compatible with the standard state-observer

Files at this revision

API Documentation at this revision

Comitter:
benson516
Date:
Fri Feb 10 18:27:14 2017 +0000
Parent:
0:0699f8e638ca
Commit message:
Fix some serious bugs

Changed in this revision

STATES_OBSERVER_DELAY.cpp Show annotated file Show diff for this revision Revisions of this file
STATES_OBSERVER_DELAY.h Show annotated file Show diff for this revision Revisions of this file
diff -r 0699f8e638ca -r 085d41355949 STATES_OBSERVER_DELAY.cpp
--- a/STATES_OBSERVER_DELAY.cpp	Wed Jan 11 09:30:18 2017 +0000
+++ b/STATES_OBSERVER_DELAY.cpp	Fri Feb 10 18:27:14 2017 +0000
@@ -18,6 +18,7 @@
         enable_Cd = false; // Default: not using Cd
         q = n;
         zeros_q.resize(q, 0.0);
+        Cd.assign(q,zeros_n);
     }else{
         enable_Cd = true; // using Cd
         Cd.assign(q,zeros_n);
@@ -101,6 +102,29 @@
         }
     }
 }
+void STATES_OBSERVER_DELAY::assign_Lt(float* Lt_in, size_t n_in, size_t d_in, size_t q_in){ // Continuous-time version
+    // Lt_in is the pointer of a mutidimentional array with size n_in*(d_in+1) by q_in
+    if (n != n_in || d != d_in || q != q_in){
+        n = n_in;
+        q = q_in;
+        zeros_n.resize(n, 0.0);
+        zeros_q.resize(q, 0.0);
+        //
+        if (d != d_in){
+            d = d_in;
+            states_est_buffer.Init((d+1), zeros_n);
+        }
+        Ld.assign(n*(d+1), zeros_q);
+    }
+    //
+    for (size_t i = 0; i < n*(d+1); ++i){
+        for (size_t j = 0; j < q; ++j){
+            // Ld[i][j] = Lt_in[i][j];
+            Ld[i][j] = (*Lt_in)*Ts;
+            Lt_in++;
+        }
+    }
+}
 // ** Assign the continuous-time version of system matrices by matrices
 void STATES_OBSERVER_DELAY::assign_At(const vector<vector<float> > &At_in){
     size_t n_in = At_in.size();
@@ -139,6 +163,25 @@
         }
     }
 }
+void STATES_OBSERVER_DELAY::assign_Lt(const vector<vector<float> > &Lt_in){
+    size_t ndp1_in = Lt_in.size();
+    size_t q_in = Lt_in[0].size();
+    //
+    if ( n*(d+1) != ndp1_in || q != q_in){
+        n = ndp1_in/(d+1);
+        q = q_in;
+        zeros_n.resize(n, 0.0);
+        zeros_q.resize(q, 0.0);
+        Ld.assign(n*(d+1), zeros_q);
+    }
+    // Ld
+    for (size_t i = 0; i < n*(d+1); ++i){
+        for (size_t j = 0; j < q; ++j){
+            //
+            Ld[i][j] = Ts*Lt_in[i][j];
+        }
+    }
+}
 // Assign discrete-time version of system matrices directly
 void STATES_OBSERVER_DELAY::assign_Ad(float* Ad_in, size_t n_in){ // Discrete-time version
     // Ad_in is the pointer of a mutidimentional array with size n_in by n_in
@@ -177,6 +220,23 @@
 //
 void STATES_OBSERVER_DELAY::assign_Cd(float* Cd_in, size_t q_in, size_t n_in){
     // Cd_in is the pointer of a mutidimentional array with size q_in by n_in
+    // q = n if not using Cd
+    if (q_in == 0){
+        enable_Cd = false; // Default: not using Cd
+        q_in = n_in;
+        //
+        q = q_in;
+        n = n_in;
+        zeros_n.resize(n,0.0);
+        zeros_q.resize(q, 0.0);
+        Cd.assign(q,zeros_n);
+        //
+        return;
+    }else{
+        enable_Cd = true; // using Cd
+        // Cd.assign(q,zeros_n);
+    }
+
     if (n != n_in || q != q_in){
         n = n_in;
         q = q_in;
@@ -192,15 +252,7 @@
             Cd_in++;
         }
     }
-    // q = n if not using Cd
-    if (q == 0){
-        enable_Cd = false; // Default: not using Cd
-        q = n;
-        zeros_q.resize(q, 0.0);
-    }else{
-        enable_Cd = true; // using Cd
-        Cd.assign(q,zeros_n);
-    }
+
 }
 // Assignment for observer Gain
 void STATES_OBSERVER_DELAY::assign_Ld(float* Ld_in, size_t n_in, size_t d_in, size_t q_in){
@@ -237,6 +289,7 @@
         return;
     }
 
+
     // Inputs of the observer:  sys_inputs, sys_outputs
     //
     // Get the delayed estimation of states
@@ -252,6 +305,7 @@
         est_error = Get_VectorPlus(states_est_buffer.Get(d), sys_outputs,true); // minus
     }
 
+
     // Get estimation
     state_est = states_est_buffer.Get(0);
 
@@ -276,23 +330,46 @@
 
     // Rotate the buffer
     states_est_buffer.Insert(states_new);
+    
+
+    /*
+    // No-delay version
+    //----------------------------------------//
+    if (enable_Cd){
+        // y_est = Cd*states_est_delay_d
+        y_est = Mat_multiply_Vec(Cd, state_est);
+        // est_error = y_est - sys_outputs
+        est_error = Get_VectorPlus(y_est,sys_outputs, true); // minus
+    }else{
+        // est_error = y_est - sys_outputs
+        est_error = Get_VectorPlus(state_est, sys_outputs, true); // minus
+    }
+    //
+    state_est = Get_VectorPlus(Mat_multiply_Vec(Ad,state_est), Mat_multiply_Vec(Bd,sys_inputs), false); // plus
+    // Get_VectorIncrement(state_est, sys_extraDisturbance, false); // +=, extra disturbances
+    Get_VectorIncrement(state_est, Mat_multiply_Vec(Ld, est_error), true); // -=
+    */
 }
 
 // Utilities
 void STATES_OBSERVER_DELAY::Mat_multiply_Vec(vector<float> &v_out, const vector<vector<float> > &m_left, const vector<float> &v_right){ // v_out = m_left*v_right
-    static vector<float>::iterator it_out;
-    static vector<const float>::iterator it_m_row;
-    static vector<const float>::iterator it_v;
+
     // Size check
     if (v_out.size() != m_left.size()){
         v_out.resize(m_left.size());
     }
+
+    /*
+    //
+    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 = m_left[i].begin();
-        it_v = v_right.begin();
+        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){
@@ -307,6 +384,19 @@
         }
         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> STATES_OBSERVER_DELAY::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;
@@ -314,16 +404,17 @@
     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;
+    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 = m_left[i].begin();
-        it_v = v_right.begin();
+        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){
@@ -338,6 +429,19 @@
         }
         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> STATES_OBSERVER_DELAY::Get_VectorPlus(const vector<float> &v_a, const vector<float> &v_b, bool is_minus) // v_a + (or -) v_b
@@ -403,16 +507,17 @@
     if (v_out.size() != numRow_m_left){
         v_out.resize(numRow_m_left);
     }
+    /*
     // Iterators
     static vector<float>::iterator it_out;
     static vector<float>::iterator it_m_row;
-    static vector<const float>::iterator it_v;
+    static vector<float>::iterator it_v;
     //
     it_out = v_out.begin();
     for (size_t i = 0; i < numRow_m_left; ++i){
         *it_out = 0.0;
         it_m_row = (*it_m_left).begin();
-        it_v = v_right.begin();
+        it_v = vector<float>(v_right).begin();
         for (size_t j = 0; j < (*it_m_left).size(); ++j){
             // *it_out += m_left[i][j] * v_right[j];
             if (*it_m_row != 0.0 && *it_v != 0.0){
@@ -428,5 +533,22 @@
         it_out++;
         it_m_left++;
     }
+    */
+
+    //
+    // Indexing
+    for (size_t i = 0; i < numRow_m_left; ++i){
+        //
+        v_out[i] = 0.0;
+        //
+        for (size_t j = 0; j < v_right.size(); ++j){
+            if ( (*it_m_left)[j] != 0.0 && v_right[j] != 0.0)
+                v_out[i] += (*it_m_left)[j]*v_right[j];
+        }
+        //
+        it_m_left++;
+    }
+
+
     return v_out;
 }
diff -r 0699f8e638ca -r 085d41355949 STATES_OBSERVER_DELAY.h
--- a/STATES_OBSERVER_DELAY.h	Wed Jan 11 09:30:18 2017 +0000
+++ b/STATES_OBSERVER_DELAY.h	Fri Feb 10 18:27:14 2017 +0000
@@ -6,6 +6,12 @@
 
 using std::vector;
 
+/*
+// For debugging
+#include <iostream>
+using std::cout;
+//
+*/
 
 //-----------------------------------------------------------------------//
 // Note: if the "delay_sample" was set to "0", the observer will be the regular observer
@@ -57,9 +63,11 @@
     // Assign continuous-time version of system matrices
     void assign_At(float* At_in, size_t n_in); // Continuous-time version
     void assign_Bt(float* Bt_in, size_t n_in, size_t p_in); // Continuous-time version
+    void assign_Lt(float* Lt_in, size_t n_in, size_t d_in, size_t q_in); // Continuous-time version
     // ** Assign the continuous-time version of system matrices by matrices
     void assign_At(const vector<vector<float> > &At_in);
     void assign_Bt(const vector<vector<float> > &Bt_in);
+    void assign_Lt(const vector<vector<float> > &Lt_in);
     // Assign discrete-time version of system matrices directly
     void assign_Ad(float* Ad_in, size_t n_in); // Discrete-time version
     void assign_Bd(float* Bd_in, size_t n_in, size_t p_in); // Discrete-time version