00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024
00025
00026
00034 #include <acado_optimal_control.hpp>
00035 #include <acado_gnuplot.hpp>
00036
00037
00038
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
00054 double Psi = x[ 7];
00055 double CL = x[ 8];
00056
00057 double ddr0 = x[ 10];
00058 double dPsi = x[ 11];
00059 double dCL = x[ 12];
00060
00061
00062
00063
00064
00065
00066 double mk = 850.00;
00067 double A = 500.00;
00068 double V = 720.00;
00069 double cd0 = 0.04;
00070
00071 double K = 0.04;
00072
00073
00074
00075
00076 double g = 9.81;
00077 double rho = 1.23;
00078
00079
00080
00081 double rhoc = 1450.00;
00082 double cc = 1.00;
00083 double dc = 0.05614;
00084
00085
00086
00087
00088 double w0 = 10.00;
00089 double h0 = 100.00;
00090 double hr = 0.10;
00091
00092
00093
00094
00095
00096
00097
00098 double AQ ;
00099
00100 double mc;
00101 double m ;
00102 double m_;
00103
00104 double Cg;
00105
00106 double dm;
00107
00108
00109
00110
00111
00112 double PI = 3.1415926535897932;
00113
00114
00115
00116
00117
00118 double h ;
00119 double w ;
00120 double we [ 3];
00121 double nwe ;
00122 double nwep ;
00123 double ewep [ 3];
00124 double eta ;
00125 double et [ 3];
00126 double Caer ;
00127 double Cf ;
00128 double CD ;
00129 double Fg [ 3];
00130 double Faer [ 3];
00131 double Ff [ 3];
00132 double F [ 3];
00133
00134
00135
00136
00137
00138
00139
00140 double a_pseudo [ 3];
00141 double dn ;
00142 double ddr ;
00143 double ddphi ;
00144 double ddtheta ;
00145 double power ;
00146
00147 double regularisation ;
00148
00149
00150
00151
00152
00153
00154
00155
00156
00157
00158
00159 AQ = PI*dc*dc/4.0 ;
00160
00161
00162
00163
00164 mc = rhoc*AQ*r ;
00165 m = mk + mc / 3.0;
00166 m_ = mk + mc / 2.0;
00167
00168 dm = (rhoc*AQ/ 3.0)*dr;
00169
00170
00171
00172
00173
00174 h = r*cos(theta) ;
00175 w = log(h/hr) / log(h0/hr) *w0 ;
00176
00177
00178
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
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
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
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
00217
00218
00219 CD = cd0 + K*CL*CL ;
00220
00221
00222
00223
00224
00225
00226 Fg [0] = Cg * cos(theta) ;
00227
00228 Fg [2] = Cg * sin(theta) ;
00229
00230
00231
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
00240
00241
00242
00243 Ff [1] = Cf * cc* we[1] ;
00244 Ff [2] = Cf * cc* we[2] ;
00245
00246
00247
00248
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
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
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
00288
00289
00290 dn = ( dphi*ddtheta - dtheta*ddphi ) /
00291 (2.0*PI*(dphi*dphi + dtheta*dtheta) ) ;
00292
00293
00294
00295
00296
00297
00298 power = m*ddr*dr ;
00299
00300
00301
00302
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
00330
00331
00332
00333
00334 }
00335
00336
00337 int main( ){
00338
00339
00340 counter = 0;
00341
00342
00343
00344 DifferentialState r;
00345 DifferentialState phi;
00346 DifferentialState theta;
00347
00348 DifferentialState dr;
00349 DifferentialState dphi;
00350 DifferentialState dtheta;
00351
00352 DifferentialState n;
00353
00354 DifferentialState Psi;
00355 DifferentialState CL;
00356
00357 DifferentialState W;
00358
00359
00360
00361
00362
00363 Control ddr0;
00364 Control dPsi;
00365 Control dCL;
00366
00367
00368
00369
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
00399
00400 OCP ocp( 0.0, 18.0, 18 );
00401 ocp.minimizeMayerTerm( W );
00402 ocp.subjectTo( f );
00403
00404
00405
00406
00407 ocp.subjectTo( AT_START, n == 0.0 );
00408 ocp.subjectTo( AT_START, W == 0.0 );
00409
00410
00411
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
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
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