A sparse MPC solver for walking motion generation (old version).
|
00001 00008 /**************************************** 00009 * INCLUDES 00010 ****************************************/ 00011 #include "qp_solver.h" 00012 #include "state_handling.h" 00013 00014 00015 /**************************************** 00016 * FUNCTIONS 00017 ****************************************/ 00018 00019 00029 qp_solver::qp_solver( 00030 const int N_, 00031 const double Alpha, 00032 const double Beta, 00033 const double Gamma, 00034 const double regularization, 00035 const double tol_) : 00036 problem_parameters (N_, Alpha, Beta, Gamma, regularization) 00037 { 00038 tol = tol_; 00039 00040 gain_alpha = Alpha; 00041 gain_beta = Beta; 00042 gain_gamma = Gamma; 00043 00044 dX = new double[SMPC_NUM_VAR*N](); 00045 } 00046 00047 00058 void qp_solver::form_init_fp ( 00059 const double *x_coord, 00060 const double *y_coord, 00061 const double *init_state, 00062 double* X_) 00063 { 00064 X = X_; 00065 00066 double *control = &X[SMPC_NUM_STATE_VAR*N]; 00067 double *cur_state = X; 00068 double X_tilde[6]; 00069 X_tilde[0] = init_state[0]; 00070 X_tilde[1] = init_state[1]; 00071 X_tilde[2] = init_state[2]; 00072 X_tilde[3] = init_state[3]; 00073 X_tilde[4] = init_state[4]; 00074 X_tilde[5] = init_state[5]; 00075 state_handling::orig_to_tilde (h_initial, X_tilde); 00076 const double *prev_state = X_tilde; 00077 00078 00079 for (int i=0; i<N; i++) 00080 { 00081 //------------------------------------ 00082 /* inv(Cp*B). This is a [2 x 2] diagonal matrix (which is invertible if T^3/6-h*T is 00083 * not equal to zero). The two elements on the main diagonal are equal, and only one of them 00084 * is stored, which is equal to 00085 1/(T^3/6 - h*T) 00086 */ 00087 double iCpB = 1/(spar[i].B[0]); 00088 00089 /* inv(Cp*B)*Cp*A. This is a [2 x 6] matrix with the following structure 00090 iCpB_CpA = [a b c 0 0 0; 00091 0 0 0 a b c]; 00092 00093 a = iCpB 00094 b = iCpB*T 00095 c = iCpB*T^2/2 00096 * Only a,b and c are stored. 00097 */ 00098 double iCpB_CpA[3] = {iCpB, iCpB*spar[i].A3, iCpB*spar[i].A6}; 00099 //------------------------------------ 00100 00101 00102 control[0] = -iCpB_CpA[0]*prev_state[0] - iCpB_CpA[1]*prev_state[1] - iCpB_CpA[2]*prev_state[2] + iCpB*x_coord[i]; 00103 control[1] = -iCpB_CpA[0]*prev_state[3] - iCpB_CpA[1]*prev_state[4] - iCpB_CpA[2]*prev_state[5] + iCpB*y_coord[i]; 00104 00105 cur_state[0] = prev_state[0] + spar[i].A3*prev_state[1] + spar[i].A6*prev_state[2] + spar[i].B[0]*control[0]; 00106 cur_state[1] = prev_state[1] + spar[i].A3*prev_state[2] + spar[i].B[1]*control[0]; 00107 cur_state[2] = prev_state[2] + spar[i].B[2]*control[0]; 00108 cur_state[3] = prev_state[3] + spar[i].A3*prev_state[4] + spar[i].A6*prev_state[5] + spar[i].B[0]*control[1]; 00109 cur_state[4] = prev_state[4] + spar[i].A3*prev_state[5] + spar[i].B[1]*control[1]; 00110 cur_state[5] = prev_state[5] + spar[i].B[2]*control[1]; 00111 00112 00113 prev_state = &X[SMPC_NUM_STATE_VAR*i]; 00114 cur_state = &X[SMPC_NUM_STATE_VAR*(i+1)]; 00115 control = &control[SMPC_NUM_CONTROL_VAR]; 00116 } 00117 00118 00119 // go back to bar states 00120 cur_state = X; 00121 for (int i=0; i<N; i++) 00122 { 00123 state_handling::tilde_to_bar (spar[i].sin, spar[i].cos, cur_state); 00124 cur_state = &cur_state[SMPC_NUM_STATE_VAR]; 00125 } 00126 }