A sparse MPC solver for walking motion generation (old version).
solver/qp_solver.cpp
Go to the documentation of this file.
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 }