powerkite_c.cpp
Go to the documentation of this file.
00001 /*
00002  *    This file is part of ACADO Toolkit.
00003  *
00004  *    ACADO Toolkit -- A Toolkit for Automatic Control and Dynamic Optimization.
00005  *    Copyright (C) 2008-2014 by Boris Houska, Hans Joachim Ferreau,
00006  *    Milan Vukov, Rien Quirynen, KU Leuven.
00007  *    Developed within the Optimization in Engineering Center (OPTEC)
00008  *    under supervision of Moritz Diehl. All rights reserved.
00009  *
00010  *    ACADO Toolkit is free software; you can redistribute it and/or
00011  *    modify it under the terms of the GNU Lesser General Public
00012  *    License as published by the Free Software Foundation; either
00013  *    version 3 of the License, or (at your option) any later version.
00014  *
00015  *    ACADO Toolkit is distributed in the hope that it will be useful,
00016  *    but WITHOUT ANY WARRANTY; without even the implied warranty of
00017  *    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
00018  *    Lesser General Public License for more details.
00019  *
00020  *    You should have received a copy of the GNU Lesser General Public
00021  *    License along with ACADO Toolkit; if not, write to the Free Software
00022  *    Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301  USA
00023  *
00024  */
00025 
00026 
00034 #include <acado_optimal_control.hpp>
00035 #include <acado_gnuplot.hpp>
00036 
00037 
00038 /* >>> start tutorial code >>> */
00039 
00040 int counter;
00041 
00042 USING_NAMESPACE_ACADO
00043 
00044 
00045 void ffcn_model( double *x, double *f, void *user_data ){
00046 
00047                 double          r     =  x[ 0];
00048                 double          phi   =  x[ 1];
00049                 double          theta =  x[ 2];
00050                 double          dr    =  x[ 3];
00051                 double          dphi  =  x[ 4];
00052                 double          dtheta =  x[ 5];
00053                 //double          n     =  x[ 6];
00054                 double          Psi   =  x[ 7];
00055                 double          CL    =  x[ 8];
00056                 //double          W     =  x[ 9];
00057                 double          ddr0  =  x[ 10];
00058                 double          dPsi  =  x[ 11];
00059                 double          dCL   =  x[ 12];
00060 
00061 
00062         // PARAMETERS :
00063         // ------------------------
00064                                              //  PARAMETERS OF THE KITE :
00065                                              //  -----------------------------
00066            double         mk =  850.00;      //  mass of the kite               //  [ kg    ]
00067            double          A =  500.00;      //  effective area                 //  [ m^2   ]
00068            double          V =  720.00;      //  volume                         //  [ m^3   ]
00069            double        cd0 =    0.04;      //  aerodynamic drag coefficient   //  [       ]
00070                                              //  ( cd0: without downwash )
00071            double          K =    0.04;      //  induced drag constant          //  [       ]
00072 
00073 
00074                                              //   PHYSICAL CONSTANTS :
00075                                              //  -----------------------------
00076            double          g =    9.81;      //  gravitational constant         //  [ m /s^2]
00077            double        rho =    1.23;      //  density of the air             //  [ kg/m^3]
00078 
00079                                              //  PARAMETERS OF THE CABLE :
00080                                              //  -----------------------------
00081            double       rhoc = 1450.00;      //  density of the cable           //  [ kg/m^3]
00082            double         cc =    1.00;      //  frictional constant            //  [       ]
00083            double         dc = 0.05614;      //  diameter                       //  [ m     ]
00084 
00085 
00086                                              //  PARAMETERS OF THE WIND :
00087                                              //  -----------------------------
00088            double         w0 =   10.00;      //  wind velocity at altitude h0   //  [ m/s   ]
00089            double         h0 =  100.00;      //  the altitude h0                //  [ m     ]
00090            double         hr =    0.10;      //  roughness length               //  [ m     ]
00091 
00092 
00093 
00094 
00095         // OTHER VARIABLES :
00096         // ------------------------
00097 
00098            double AQ               ;      //  cross sectional area
00099 
00100            double     mc;      //  mass of the cable
00101            double     m ;      //  effective inertial mass
00102            double     m_;      //  effective gravitational mass
00103 
00104            double     Cg;
00105 
00106            double     dm;      //  first  derivative of m     with respect to t
00107 
00108 
00109         // DEFINITION OF PI :
00110         // ------------------------
00111 
00112            double PI = 3.1415926535897932;
00113 
00114 
00115         // ORIENTATION AND FORCES :
00116         // ------------------------
00117 
00118            double h               ;      //  altitude of the kite
00119            double w               ;      //  the wind at altitude h
00120            double we          [ 3];      //  effective wind vector
00121            double nwe             ;      //  norm of the effective wind vector
00122            double nwep            ;      //  -
00123            double ewep        [ 3];      //  projection of ewe
00124            double eta            ;      //  angle eta: cf. [2]
00125            double et          [ 3];      //  unit vector from the left to the right wing tip
00126            double Caer            ;
00127            double Cf              ;      //  simple constants
00128            double CD              ;      //  the aerodynamic drag coefficient
00129            double Fg          [ 3];      //  the gravitational force
00130            double Faer        [ 3];      //  the aerodynamic force
00131            double Ff          [ 3];      //  the frictional force
00132            double F           [ 3];      //  the total force
00133 
00134 
00135         // TERMS ON RIGHT-HAND-SIDE
00136         // OF THE DIFFERENTIAL
00137         // EQUATIONS              :
00138         // ------------------------
00139 
00140            double a_pseudo    [ 3];      //  the pseudo accelaration
00141            double dn              ;      //  the time derivate of the kite's winding number
00142            double ddr             ;      //  second derivative of s     with respect to t
00143            double ddphi           ;      //  second derivative of phi   with respect to t
00144            double ddtheta         ;      //  second derivative of theta with respect to t
00145            double power           ;      //  the power at the generator
00146         // ------------------------                 //  ----------------------------------------------
00147            double regularisation  ;      //  regularisation of controls
00148 
00149 
00150 
00151         //                        MODEL EQUATIONS :
00152         // ===============================================================
00153 
00154 
00155 
00156         // SPRING CONSTANT OF THE CABLE :
00157         // ---------------------------------------------------------------
00158 
00159            AQ      =  PI*dc*dc/4.0                                       ;
00160 
00161         // THE EFECTIVE MASS' :
00162         // ---------------------------------------------------------------
00163 
00164            mc      =  rhoc*AQ*r        ;   // mass of the cable
00165            m       =  mk + mc     / 3.0;   // effective inertial mass
00166            m_      =  mk + mc     / 2.0;   // effective gravitational mass
00167         // -----------------------------   // ----------------------------
00168            dm      =  (rhoc*AQ/ 3.0)*dr;   // time derivative of the mass
00169 
00170 
00171         // WIND SHEAR MODEL :
00172         // ---------------------------------------------------------------
00173 
00174            h       =  r*cos(theta)                                       ;
00175            w       =  log(h/hr) / log(h0/hr) *w0                         ;
00176 
00177 
00178         // EFFECTIVE WIND IN THE KITE`S SYSTEM :
00179         // ---------------------------------------------------------------
00180 
00181            we[0]   =  w*sin(theta)*cos(phi) -              dr    ;
00182            we[1]   = -w*sin(phi)            - r*sin(theta)*dphi  ;
00183            we[2]   = -w*cos(theta)*cos(phi) + r           *dtheta;
00184 
00185 
00186         // CALCULATION OF THE KITE`S TRANSVERSAL AXIS :
00187         // ---------------------------------------------------------------
00188 
00189            nwep    =  pow(                we[1]*we[1] + we[2]*we[2], 0.5 );
00190            nwe     =  pow(  we[0]*we[0] + we[1]*we[1] + we[2]*we[2], 0.5 );
00191            eta     =  asin( we[0]*tan(Psi)/ nwep )                       ;
00192 
00193         // ---------------------------------------------------------------
00194 
00195         // ewep[0] =  0.0                                                ;
00196            ewep[1] =  we[1] / nwep                                       ;
00197            ewep[2] =  we[2] / nwep                                       ;
00198 
00199         // ---------------------------------------------------------------
00200 
00201            et  [0] =  sin(Psi)                                                  ;
00202            et  [1] =  (-cos(Psi)*sin(eta))*ewep[1] - (cos(Psi)*cos(eta))*ewep[2];
00203            et  [2] =  (-cos(Psi)*sin(eta))*ewep[2] + (cos(Psi)*cos(eta))*ewep[1];
00204 
00205 
00206 
00207 
00208         // CONSTANTS FOR SEVERAL FORCES :
00209         // ---------------------------------------------------------------
00210 
00211            Cg      =  (V*rho-m_)*g                                       ;
00212            Caer    =  (rho*A/2.0 )*nwe                                   ;
00213            Cf      =  (rho*dc/8.0)*r*nwe                                 ;
00214 
00215 
00216         // THE DRAG-COEFFICIENT :
00217         // ---------------------------------------------------------------
00218 
00219            CD      =  cd0 + K*CL*CL                                      ;
00220 
00221 
00222 
00223         // SUM OF GRAVITATIONAL AND LIFTING FORCE :
00224         // ---------------------------------------------------------------
00225 
00226            Fg  [0] =  Cg  *  cos(theta)                                  ;
00227         // Fg  [1] =  Cg  *  0.0                                         ;
00228            Fg  [2] =  Cg  *  sin(theta)                                  ;
00229 
00230 
00231         // SUM OF THE AERODYNAMIC FORCES :
00232         // ---------------------------------------------------------------
00233 
00234            Faer[0] =  Caer*( CL*(we[1]*et[2]-we[2]*et[1]) + CD*we[0] )   ;
00235            Faer[1] =  Caer*( CL*(we[2]*et[0]-we[0]*et[2]) + CD*we[1] )   ;
00236            Faer[2] =  Caer*( CL*(we[0]*et[1]-we[1]*et[0]) + CD*we[2] )   ;
00237 
00238 
00239         // THE FRICTION OF THE CABLE :
00240         // ---------------------------------------------------------------
00241 
00242         // Ff  [0] =  Cf  *  cc* we[0]                                   ;
00243            Ff  [1] =  Cf  *  cc* we[1]                                   ;
00244            Ff  [2] =  Cf  *  cc* we[2]                                   ;
00245 
00246 
00247 
00248         // THE TOTAL FORCE :
00249         // ---------------------------------------------------------------
00250 
00251            F   [0] = Fg[0] + Faer[0]                                     ;
00252            F   [1] =         Faer[1] + Ff[1]                             ;
00253            F   [2] = Fg[2] + Faer[2] + Ff[2]                             ;
00254 
00255 
00256 
00257         // THE PSEUDO ACCELERATION:
00258         // ---------------------------------------------------------------
00259 
00260            a_pseudo [0] =  - ddr0
00261                                            + r*(                         dtheta*dtheta
00262                                                          + sin(theta)*sin(theta)*dphi  *dphi   )
00263                                            - dm/m*dr                                     ;
00264 
00265            a_pseudo [1] =  - 2.0*cos(theta)/sin(theta)*dphi*dtheta
00266                                            - 2.0*dr/r*dphi
00267                                            - dm/m*dphi                                   ;
00268 
00269            a_pseudo [2] =    cos(theta)*sin(theta)*dphi*dphi
00270                                            - 2.0*dr/r*dtheta
00271                                            - dm/m*dtheta                                 ;
00272 
00273 
00274 
00275 
00276         // THE EQUATIONS OF MOTION:
00277         // ---------------------------------------------------------------
00278 
00279            ddr          =  F[0]/m                + a_pseudo[0]           ;
00280            ddphi        =  F[1]/(m*r*sin(theta)) + a_pseudo[1]           ;
00281            ddtheta      = -F[2]/(m*r           ) + a_pseudo[2]           ;
00282 
00283 
00284 
00285 
00286 
00287         // THE DERIVATIVE OF THE WINDING NUMBER :
00288         // ---------------------------------------------------------------
00289 
00290            dn           =  (        dphi*ddtheta - dtheta*ddphi     ) /
00291                                            (2.0*PI*(dphi*dphi    + dtheta*dtheta)   )      ;
00292 
00293 
00294 
00295         // THE POWER AT THE GENERATOR :
00296         // ---------------------------------------------------------------
00297 
00298            power        =   m*ddr*dr                                     ;
00299 
00300 
00301 
00302         // REGULARISATION TERMS :
00303         // ---------------------------------------------------------------
00304 
00305 
00306            regularisation =    5.0e2 * ddr0    * ddr0
00307                                                  + 1.0e8 * dPsi    * dPsi
00308                                                  + 1.0e5 * dCL     * dCL
00309                                                  + 2.5e5 * dn      * dn
00310                                                  + 2.5e7 * ddphi   * ddphi
00311                                                  + 2.5e7 * ddtheta * ddtheta
00312                                                  + 2.5e6 * dtheta  * dtheta;
00313         //                   ---------------------------
00314 
00315 
00316 
00317 
00318          f[0] =  dr                             ;
00319          f[1] =  dphi                           ;
00320          f[2] =  dtheta                         ;
00321          f[3] =  ddr0                           ;
00322          f[4] =  ddphi                          ;
00323          f[5] =  ddtheta                        ;
00324          f[6] =  dn                             ;
00325          f[7] =  dPsi                           ;
00326          f[8] =  dCL                            ;
00327          f[9] = (-power + regularisation)*1.0e-6;
00328 
00329 //       counter++;
00330 // 
00331 //       if (counter % 1000 == 0)
00332 //               printf("eval count  %d \n", counter);
00333 
00334 }
00335 
00336 
00337 int main( ){
00338 
00339 
00340         counter = 0;
00341 
00342         // DIFFERENTIAL STATES :
00343         // -------------------------
00344            DifferentialState      r;      //  the length r of the cable
00345            DifferentialState    phi;      //  the angle phi
00346            DifferentialState  theta;      //  the angle theta
00347         // -------------------------      //  -------------------------------------------
00348            DifferentialState     dr;      //  first  derivative of r0    with respect to t
00349            DifferentialState   dphi;      //  first  derivative of phi   with respect to t
00350            DifferentialState dtheta;      //  first  derivative of theta with respect to t
00351         // -------------------------      //  -------------------------------------------
00352            DifferentialState      n;      //  winding number
00353         // -------------------------      //  -------------------------------------------
00354            DifferentialState    Psi;      //  the roll angle Psi
00355            DifferentialState     CL;      //  the aerodynamic lift coefficient
00356         // -------------------------      //  -------------------------------------------
00357            DifferentialState      W;      //  integral over the power at the generator
00358                                           //  ( = ENERGY )
00359 
00360 
00361         // CONTROL :
00362         // -------------------------
00363            Control             ddr0;      //  second derivative of r0    with respect to t
00364            Control             dPsi;      //  first  derivative of Psi   with respect to t
00365            Control              dCL;      //  first  derivative of CL    with respect to t
00366 
00367 
00368 
00369         // THE "RIGHT-HAND-SIDE" OF THE ODE:
00370         // ---------------------------------------------------------------
00371            DifferentialEquation f;
00372 
00373        const int NX = 10;
00374        const int NU = 3 ;
00375 
00376        IntermediateState x( NX + NU );
00377 
00378        x(0) = r;
00379        x(1) = phi;
00380        x(2) = theta;
00381        x(3) = dr;
00382        x(4) = dphi;
00383        x(5) = dtheta;
00384        x(6) = n;
00385        x(7) = Psi;
00386        x(8) = CL;
00387        x(9) = W;
00388 
00389        x(10) = ddr0;
00390        x(11) = dPsi;
00391        x(12) = dCL;
00392 
00393        CFunction kiteModel( 10, ffcn_model );
00394 
00395        f << kiteModel( x );
00396 
00397 
00398             // DEFINE AN OPTIMAL CONTROL PROBLEM:
00399             // ----------------------------------
00400             OCP ocp( 0.0, 18.0, 18 );
00401             ocp.minimizeMayerTerm( W );
00402             ocp.subjectTo( f );
00403 
00404 
00405             // INITIAL VALUE CONSTRAINTS:
00406             // ---------------------------------
00407             ocp.subjectTo( AT_START, n == 0.0 );
00408             ocp.subjectTo( AT_START, W == 0.0 );
00409 
00410 
00411             // PERIODIC BOUNDARY CONSTRAINTS:
00412             // ----------------------------------------
00413             ocp.subjectTo( 0.0, r     , -r     , 0.0 );
00414             ocp.subjectTo( 0.0, phi   , -phi   , 0.0 );
00415             ocp.subjectTo( 0.0, theta , -theta , 0.0 );
00416             ocp.subjectTo( 0.0, dr    , -dr    , 0.0 );
00417             ocp.subjectTo( 0.0, dphi  , -dphi  , 0.0 );
00418             ocp.subjectTo( 0.0, dtheta, -dtheta, 0.0 );
00419             ocp.subjectTo( 0.0, Psi   , -Psi   , 0.0 );
00420             ocp.subjectTo( 0.0, CL    , -CL    , 0.0 );
00421 
00422             ocp.subjectTo( -0.34   <= phi   <= 0.34   );
00423             ocp.subjectTo(  0.85   <= theta <= 1.45   );
00424             ocp.subjectTo( -40.0   <= dr    <= 10.0   );
00425             ocp.subjectTo( -0.29   <= Psi   <= 0.29   );
00426             ocp.subjectTo(  0.1    <= CL    <= 1.50   );
00427             ocp.subjectTo( -0.7    <= n     <= 0.90   );
00428             ocp.subjectTo( -25.0   <= ddr0  <= 25.0   );
00429             ocp.subjectTo( -0.065  <= dPsi  <= 0.065  );
00430             ocp.subjectTo( -3.5    <= dCL   <= 3.5    );
00431 
00432 
00433             // CREATE A PLOT WINDOW AND VISUALIZE THE RESULT:
00434             // ----------------------------------------------
00435 
00436             GnuplotWindow window;
00437             window.addSubplot( r,    "CABLE LENGTH  r [m]" );
00438             window.addSubplot( phi,  "POSITION ANGLE  phi [rad]" );
00439             window.addSubplot( theta,"POSITION ANGLE theta [rad]" );
00440             window.addSubplot( Psi,  "ROLL ANGLE  psi [rad]" );
00441             window.addSubplot( CL,   "LIFT COEFFICIENT  CL" );
00442             window.addSubplot( W,    "ENERGY  W [MJ]" );
00443                 window.addSubplot( phi,theta, "Kite Orbit","theta [rad]","phi [rad]" );
00444 
00445             // DEFINE AN OPTIMIZATION ALGORITHM AND SOLVE THE OCP:
00446             // ---------------------------------------------------
00447 
00448             OptimizationAlgorithm algorithm(ocp);
00449 
00450             algorithm.initializeDifferentialStates("powerkite_states.txt"    );
00451             algorithm.initializeControls          ("powerkite_controls.txt"  );
00452             algorithm.set                         ( MAX_NUM_ITERATIONS, 100  );
00453             algorithm.set                         ( KKT_TOLERANCE    , 1e-2 );
00454 
00455                 algorithm << window;
00456 
00457         algorithm.set( PRINT_SCP_METHOD_PROFILE, YES );
00458 
00459             algorithm.solve();
00460 
00461 
00462 
00463     return 0;
00464 }
00465 /* <<< end tutorial code <<< */


acado
Author(s): Milan Vukov, Rien Quirynen
autogenerated on Thu Aug 27 2015 11:59:49