A controller that is immune to measurement errors and keep the true states at the desired value, also known as "Zero-Torque Control"

Committer:
benson516
Date:
Wed Jan 11 09:32:26 2017 +0000
Revision:
0:533d5685b66c
First compilation of this library

Who changed what in which revision?

UserRevisionLine numberNew contents of line
benson516 0:533d5685b66c 1 #include "MEASUREMENT_ERROR_ADAPTATION_CONTROL.h"
benson516 0:533d5685b66c 2 // The controller is for the plant with (p, n, q) system
benson516 0:533d5685b66c 3 // Dimensions:
benson516 0:533d5685b66c 4 //
benson516 0:533d5685b66c 5 // Inputs, u | States, x
benson516 0:533d5685b66c 6 // p ----> n
benson516 0:533d5685b66c 7 // q -- ^
benson516 0:533d5685b66c 8 // Measurement errors, phi
benson516 0:533d5685b66c 9
benson516 0:533d5685b66c 10 MEASUREMENT_ERROR_ADAPTATION_CONTROL::MEASUREMENT_ERROR_ADAPTATION_CONTROL(size_t num_state, size_t num_in, size_t num_MeasurementError, float samplingTime):
benson516 0:533d5685b66c 11 n(num_state), p(num_in), q(num_MeasurementError), Ts(samplingTime),
benson516 0:533d5685b66c 12 C_error(num_state, vector<float>(num_MeasurementError,0.0)),
benson516 0:533d5685b66c 13 K_full(num_in, vector<float>(num_state,0.0)),
benson516 0:533d5685b66c 14 K_phi(num_MeasurementError, vector<float>(num_state,0.0)),
benson516 0:533d5685b66c 15 N_xd(num_state, vector<float>(num_in, 0.0)),
benson516 0:533d5685b66c 16 N_ud(num_in, vector<float>(num_in, 0.0))
benson516 0:533d5685b66c 17 {
benson516 0:533d5685b66c 18 //
benson516 0:533d5685b66c 19 zeros_n.assign(n, 0.0);
benson516 0:533d5685b66c 20 zeros_p.assign(p, 0.0);
benson516 0:533d5685b66c 21 zeros_q.assign(q, 0.0);
benson516 0:533d5685b66c 22
benson516 0:533d5685b66c 23 // States
benson516 0:533d5685b66c 24 states_est = zeros_n; // states_est, "x_est"
benson516 0:533d5685b66c 25 sys_inputs = zeros_p; // The inputs of the plant, "u"
benson516 0:533d5685b66c 26 sys_output = zeros_n; // The output of the plant, "y"
benson516 0:533d5685b66c 27 MeasurementErrors = zeros_q; // The measurement error of the sensors, "phi"
benson516 0:533d5685b66c 28
benson516 0:533d5685b66c 29 // Command (equalibrium state)
benson516 0:533d5685b66c 30 states_d = zeros_n; // x_d
benson516 0:533d5685b66c 31 inputs_d = zeros_p; // u_d
benson516 0:533d5685b66c 32 command = zeros_p; // r
benson516 0:533d5685b66c 33
benson516 0:533d5685b66c 34
benson516 0:533d5685b66c 35 }
benson516 0:533d5685b66c 36 // Assign Parameters
benson516 0:533d5685b66c 37 void MEASUREMENT_ERROR_ADAPTATION_CONTROL::assign_C_error(float* C_error_in, size_t n_in, size_t q_in){
benson516 0:533d5685b66c 38 // C_error_in is the pointer of a mutidimentional array with size n_in by q_in
benson516 0:533d5685b66c 39 if (n != n_in || q != q_in){
benson516 0:533d5685b66c 40 n = n_in;
benson516 0:533d5685b66c 41 q = q_in;
benson516 0:533d5685b66c 42 zeros_n.resize(n, 0.0);
benson516 0:533d5685b66c 43 zeros_q.resize(q, 0.0);
benson516 0:533d5685b66c 44 C_error.assign(n, zeros_q);
benson516 0:533d5685b66c 45 }
benson516 0:533d5685b66c 46 //
benson516 0:533d5685b66c 47 for (size_t i = 0; i < n; ++i){
benson516 0:533d5685b66c 48 for (size_t j = 0; j < q; ++j){
benson516 0:533d5685b66c 49 // C_error[i][j] = C_error_in[i][j];
benson516 0:533d5685b66c 50 C_error[i][j] = *C_error_in;
benson516 0:533d5685b66c 51 C_error_in++;
benson516 0:533d5685b66c 52 }
benson516 0:533d5685b66c 53 }
benson516 0:533d5685b66c 54 }
benson516 0:533d5685b66c 55 void MEASUREMENT_ERROR_ADAPTATION_CONTROL::assign_K_full(float* K_full_in, size_t p_in, size_t n_in){
benson516 0:533d5685b66c 56 // K_full_in is the pointer of a mutidimentional array with size p_in by n_in
benson516 0:533d5685b66c 57 if (n != n_in || p != p_in){
benson516 0:533d5685b66c 58 p = p_in;
benson516 0:533d5685b66c 59 n = n_in;
benson516 0:533d5685b66c 60 zeros_n.resize(n, 0.0);
benson516 0:533d5685b66c 61 zeros_p.resize(p, 0.0);
benson516 0:533d5685b66c 62 K_full.assign(p, zeros_n);
benson516 0:533d5685b66c 63 }
benson516 0:533d5685b66c 64 //
benson516 0:533d5685b66c 65 for (size_t i = 0; i < p; ++i){
benson516 0:533d5685b66c 66 for (size_t j = 0; j < n; ++j){
benson516 0:533d5685b66c 67 // K_full[i][j] = K_full_in[i][j];
benson516 0:533d5685b66c 68 K_full[i][j] = *K_full_in;
benson516 0:533d5685b66c 69 K_full_in++;
benson516 0:533d5685b66c 70 }
benson516 0:533d5685b66c 71 }
benson516 0:533d5685b66c 72 }
benson516 0:533d5685b66c 73 void MEASUREMENT_ERROR_ADAPTATION_CONTROL::assign_K_phi(float* K_phi_in, size_t q_in, size_t n_in){
benson516 0:533d5685b66c 74 // K_phi_in is the pointer of a mutidimentional array with size q_in by n_in
benson516 0:533d5685b66c 75 if (q != q_in || n != n_in){
benson516 0:533d5685b66c 76 q = q_in;
benson516 0:533d5685b66c 77 n = n_in;
benson516 0:533d5685b66c 78 zeros_q.resize(q, 0.0);
benson516 0:533d5685b66c 79 zeros_n.resize(n, 0.0);
benson516 0:533d5685b66c 80 K_phi.assign(q, zeros_n);
benson516 0:533d5685b66c 81 }
benson516 0:533d5685b66c 82 //
benson516 0:533d5685b66c 83 for (size_t i = 0; i < q; ++i){
benson516 0:533d5685b66c 84 for (size_t j = 0; j < n; ++j){
benson516 0:533d5685b66c 85 // K_phi[i][j] = K_phi_in[i][j];
benson516 0:533d5685b66c 86 K_phi[i][j] = *K_phi_in;
benson516 0:533d5685b66c 87 K_phi_in++;
benson516 0:533d5685b66c 88 }
benson516 0:533d5685b66c 89 }
benson516 0:533d5685b66c 90 }
benson516 0:533d5685b66c 91 //
benson516 0:533d5685b66c 92 void MEASUREMENT_ERROR_ADAPTATION_CONTROL::assign_N_xd(float* N_xd_in, size_t n_in, size_t p_in){
benson516 0:533d5685b66c 93 // N_xd_in is the pointer of a mutidimentional array with size n_in by p_in
benson516 0:533d5685b66c 94 if (n != n_in || p != p_in){
benson516 0:533d5685b66c 95 n = n_in;
benson516 0:533d5685b66c 96 p = p_in;
benson516 0:533d5685b66c 97 zeros_n.resize(n, 0.0);
benson516 0:533d5685b66c 98 zeros_p.resize(p, 0.0);
benson516 0:533d5685b66c 99 N_xd.assign(n, zeros_p);
benson516 0:533d5685b66c 100 }
benson516 0:533d5685b66c 101 //
benson516 0:533d5685b66c 102 for (size_t i = 0; i < n; ++i){
benson516 0:533d5685b66c 103 for (size_t j = 0; j < p; ++j){
benson516 0:533d5685b66c 104 // N_xd[i][j] = N_xd_in[i][j];
benson516 0:533d5685b66c 105 N_xd[i][j] = *N_xd_in;
benson516 0:533d5685b66c 106 N_xd_in++;
benson516 0:533d5685b66c 107 }
benson516 0:533d5685b66c 108 }
benson516 0:533d5685b66c 109 }
benson516 0:533d5685b66c 110 void MEASUREMENT_ERROR_ADAPTATION_CONTROL::assign_N_ud(float* N_ud_in, size_t p_in){
benson516 0:533d5685b66c 111 // N_ud_in is the pointer of a mutidimentional array with size p_in by p_in
benson516 0:533d5685b66c 112 if (p != p_in){
benson516 0:533d5685b66c 113 p = p_in;
benson516 0:533d5685b66c 114 zeros_p.resize(p, 0.0);
benson516 0:533d5685b66c 115 N_ud.assign(p, zeros_p);
benson516 0:533d5685b66c 116 }
benson516 0:533d5685b66c 117 //
benson516 0:533d5685b66c 118 for (size_t i = 0; i < p; ++i){
benson516 0:533d5685b66c 119 for (size_t j = 0; j < p; ++j){
benson516 0:533d5685b66c 120 // N_ud[i][j] = N_ud_in[i][j];
benson516 0:533d5685b66c 121 N_ud[i][j] = *N_ud_in;
benson516 0:533d5685b66c 122 N_ud_in++;
benson516 0:533d5685b66c 123 }
benson516 0:533d5685b66c 124 }
benson516 0:533d5685b66c 125 }
benson516 0:533d5685b66c 126 //
benson516 0:533d5685b66c 127 void MEASUREMENT_ERROR_ADAPTATION_CONTROL::iterateOnce(bool enable){
benson516 0:533d5685b66c 128 //----------------------------//
benson516 0:533d5685b66c 129 // Input: sys_output ("y"), command ("r")
benson516 0:533d5685b66c 130 // Get: sys_inputs ("u")
benson516 0:533d5685b66c 131 //----------------------------//
benson516 0:533d5685b66c 132
benson516 0:533d5685b66c 133 // Control law
benson516 0:533d5685b66c 134 if (enable){
benson516 0:533d5685b66c 135 //
benson516 0:533d5685b66c 136 get_inputs_compensate(); // Get states_d, inputs_d from command
benson516 0:533d5685b66c 137
benson516 0:533d5685b66c 138 // states_est = (sys_output - C_error*MeasurementErrors) - states_d
benson516 0:533d5685b66c 139 get_states_est();
benson516 0:533d5685b66c 140
benson516 0:533d5685b66c 141 // sys_inputs = inputs_d - K_full*states_est
benson516 0:533d5685b66c 142 sys_inputs = Get_VectorPlus(inputs_d, Mat_multiply_Vec(K_full, states_est),true); // minus
benson516 0:533d5685b66c 143 }else{
benson516 0:533d5685b66c 144 sys_inputs = zeros_p;
benson516 0:533d5685b66c 145 }
benson516 0:533d5685b66c 146
benson516 0:533d5685b66c 147 // Integral action
benson516 0:533d5685b66c 148 get_MeasurementErrors_est(enable);
benson516 0:533d5685b66c 149 }
benson516 0:533d5685b66c 150
benson516 0:533d5685b66c 151 // Private functions
benson516 0:533d5685b66c 152 // Command (equalibrium state) related calculation
benson516 0:533d5685b66c 153 void MEASUREMENT_ERROR_ADAPTATION_CONTROL::get_inputs_compensate(void){ // Calculate the compensation variable, states_d and sys_inputs_compensate
benson516 0:533d5685b66c 154 //
benson516 0:533d5685b66c 155 Mat_multiply_Vec(states_d, N_xd, command);
benson516 0:533d5685b66c 156 Mat_multiply_Vec(inputs_d, N_ud, command);
benson516 0:533d5685b66c 157 }
benson516 0:533d5685b66c 158 // Calculate the states_est
benson516 0:533d5685b66c 159 void MEASUREMENT_ERROR_ADAPTATION_CONTROL::get_states_est(void){ // Calculate the sys_outputs from states_est, by mutiplying C_error
benson516 0:533d5685b66c 160 // states_est = (sys_output - C_error*MeasurementErrors) - states_d
benson516 0:533d5685b66c 161 states_est = Get_VectorPlus(Get_VectorPlus(sys_output, Mat_multiply_Vec(C_error, MeasurementErrors), true), states_d, true); // minus
benson516 0:533d5685b66c 162 }
benson516 0:533d5685b66c 163 // Calculate the estimation of MeasurementErrors
benson516 0:533d5685b66c 164 void MEASUREMENT_ERROR_ADAPTATION_CONTROL::get_MeasurementErrors_est(bool enable){ // Calculate the MeasurementErrors
benson516 0:533d5685b66c 165 //
benson516 0:533d5685b66c 166 // Integral action
benson516 0:533d5685b66c 167 // MeasurementErrors -= Ts*(K_phi*states_est)
benson516 0:533d5685b66c 168 if (enable){
benson516 0:533d5685b66c 169 Get_VectorIncrement(MeasurementErrors, Get_VectorScalarMultiply(Mat_multiply_Vec(K_phi,states_est), Ts) , true); // -=
benson516 0:533d5685b66c 170 }else{
benson516 0:533d5685b66c 171 MeasurementErrors = zeros_q;
benson516 0:533d5685b66c 172 }
benson516 0:533d5685b66c 173 }
benson516 0:533d5685b66c 174 // Utilities
benson516 0:533d5685b66c 175 void MEASUREMENT_ERROR_ADAPTATION_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
benson516 0:533d5685b66c 176 static vector<float>::iterator it_out;
benson516 0:533d5685b66c 177 static vector<const float>::iterator it_m_row;
benson516 0:533d5685b66c 178 static vector<const float>::iterator it_v;
benson516 0:533d5685b66c 179 //
benson516 0:533d5685b66c 180 it_out = v_out.begin();
benson516 0:533d5685b66c 181 for (size_t i = 0; i < m_left.size(); ++i){
benson516 0:533d5685b66c 182 *it_out = 0.0;
benson516 0:533d5685b66c 183 it_m_row = m_left[i].begin();
benson516 0:533d5685b66c 184 it_v = v_right.begin();
benson516 0:533d5685b66c 185 for (size_t j = 0; j < m_left[i].size(); ++j){
benson516 0:533d5685b66c 186 // *it_out += m_left[i][j] * v_right[j];
benson516 0:533d5685b66c 187 if (*it_m_row != 0.0 && *it_v != 0.0){
benson516 0:533d5685b66c 188 (*it_out) += (*it_m_row) * (*it_v);
benson516 0:533d5685b66c 189 }else{
benson516 0:533d5685b66c 190 // (*it_out) += 0.0
benson516 0:533d5685b66c 191 }
benson516 0:533d5685b66c 192 // (*it_out) += (*it_m_row) * (*it_v);
benson516 0:533d5685b66c 193 //
benson516 0:533d5685b66c 194 it_m_row++;
benson516 0:533d5685b66c 195 it_v++;
benson516 0:533d5685b66c 196 }
benson516 0:533d5685b66c 197 it_out++;
benson516 0:533d5685b66c 198 }
benson516 0:533d5685b66c 199 }
benson516 0:533d5685b66c 200 vector<float> MEASUREMENT_ERROR_ADAPTATION_CONTROL::Mat_multiply_Vec(const vector<vector<float> > &m_left, const vector<float> &v_right){ // v_out = m_left*v_right
benson516 0:533d5685b66c 201 static vector<float> v_out;
benson516 0:533d5685b66c 202 // Size check
benson516 0:533d5685b66c 203 if (v_out.size() != m_left.size()){
benson516 0:533d5685b66c 204 v_out.resize(m_left.size());
benson516 0:533d5685b66c 205 }
benson516 0:533d5685b66c 206 // Iterators
benson516 0:533d5685b66c 207 static vector<float>::iterator it_out;
benson516 0:533d5685b66c 208 static vector<const float>::iterator it_m_row;
benson516 0:533d5685b66c 209 static vector<const float>::iterator it_v;
benson516 0:533d5685b66c 210 //
benson516 0:533d5685b66c 211 it_out = v_out.begin();
benson516 0:533d5685b66c 212 for (size_t i = 0; i < m_left.size(); ++i){
benson516 0:533d5685b66c 213 *it_out = 0.0;
benson516 0:533d5685b66c 214 it_m_row = m_left[i].begin();
benson516 0:533d5685b66c 215 it_v = v_right.begin();
benson516 0:533d5685b66c 216 for (size_t j = 0; j < m_left[i].size(); ++j){
benson516 0:533d5685b66c 217 // *it_out += m_left[i][j] * v_right[j];
benson516 0:533d5685b66c 218 if (*it_m_row != 0.0 && *it_v != 0.0){
benson516 0:533d5685b66c 219 (*it_out) += (*it_m_row) * (*it_v);
benson516 0:533d5685b66c 220 }else{
benson516 0:533d5685b66c 221 // (*it_out) += 0.0
benson516 0:533d5685b66c 222 }
benson516 0:533d5685b66c 223 // (*it_out) += (*it_m_row) * (*it_v);
benson516 0:533d5685b66c 224 //
benson516 0:533d5685b66c 225 it_m_row++;
benson516 0:533d5685b66c 226 it_v++;
benson516 0:533d5685b66c 227 }
benson516 0:533d5685b66c 228 it_out++;
benson516 0:533d5685b66c 229 }
benson516 0:533d5685b66c 230 return v_out;
benson516 0:533d5685b66c 231 }
benson516 0:533d5685b66c 232 vector<float> MEASUREMENT_ERROR_ADAPTATION_CONTROL::Get_VectorPlus(const vector<float> &v_a, const vector<float> &v_b, bool is_minus) // v_a + (or -) v_b
benson516 0:533d5685b66c 233 {
benson516 0:533d5685b66c 234 static vector<float> v_c;
benson516 0:533d5685b66c 235 // Size check
benson516 0:533d5685b66c 236 if (v_c.size() != v_a.size()){
benson516 0:533d5685b66c 237 v_c.resize(v_a.size());
benson516 0:533d5685b66c 238 }
benson516 0:533d5685b66c 239 //
benson516 0:533d5685b66c 240 for (size_t i = 0; i < v_a.size(); ++i){
benson516 0:533d5685b66c 241 if (is_minus){
benson516 0:533d5685b66c 242 v_c[i] = v_a[i] - v_b[i];
benson516 0:533d5685b66c 243 }else{
benson516 0:533d5685b66c 244 v_c[i] = v_a[i] + v_b[i];
benson516 0:533d5685b66c 245 }
benson516 0:533d5685b66c 246 }
benson516 0:533d5685b66c 247 return v_c;
benson516 0:533d5685b66c 248 }
benson516 0:533d5685b66c 249 vector<float> MEASUREMENT_ERROR_ADAPTATION_CONTROL::Get_VectorScalarMultiply(const vector<float> &v_a, float scale) // scale*v_a
benson516 0:533d5685b66c 250 {
benson516 0:533d5685b66c 251 static vector<float> v_c;
benson516 0:533d5685b66c 252 // Size check
benson516 0:533d5685b66c 253 if (v_c.size() != v_a.size()){
benson516 0:533d5685b66c 254 v_c.resize(v_a.size());
benson516 0:533d5685b66c 255 }
benson516 0:533d5685b66c 256 // for pure negative
benson516 0:533d5685b66c 257 if (scale == -1.0){
benson516 0:533d5685b66c 258 for (size_t i = 0; i < v_a.size(); ++i){
benson516 0:533d5685b66c 259 v_c[i] = -v_a[i];
benson516 0:533d5685b66c 260 }
benson516 0:533d5685b66c 261 return v_c;
benson516 0:533d5685b66c 262 }
benson516 0:533d5685b66c 263 // else
benson516 0:533d5685b66c 264 for (size_t i = 0; i < v_a.size(); ++i){
benson516 0:533d5685b66c 265 v_c[i] = scale*v_a[i];
benson516 0:533d5685b66c 266
benson516 0:533d5685b66c 267 }
benson516 0:533d5685b66c 268 return v_c;
benson516 0:533d5685b66c 269 }
benson516 0:533d5685b66c 270 // Increment
benson516 0:533d5685b66c 271 void MEASUREMENT_ERROR_ADAPTATION_CONTROL::Get_VectorIncrement(vector<float> &v_a, const vector<float> &v_b, bool is_minus){ // v_a += (or -=) v_b
benson516 0:533d5685b66c 272 // Size check
benson516 0:533d5685b66c 273 if (v_a.size() != v_b.size()){
benson516 0:533d5685b66c 274 v_a.resize(v_b.size());
benson516 0:533d5685b66c 275 }
benson516 0:533d5685b66c 276 //
benson516 0:533d5685b66c 277 if (is_minus){ // -=
benson516 0:533d5685b66c 278 for (size_t i = 0; i < v_b.size(); ++i){
benson516 0:533d5685b66c 279 v_a[i] -= v_b[i];
benson516 0:533d5685b66c 280 }
benson516 0:533d5685b66c 281 }else{ // +=
benson516 0:533d5685b66c 282 for (size_t i = 0; i < v_b.size(); ++i){
benson516 0:533d5685b66c 283 v_a[i] += v_b[i];
benson516 0:533d5685b66c 284 }
benson516 0:533d5685b66c 285 }
benson516 0:533d5685b66c 286
benson516 0:533d5685b66c 287 }