00001 #ifndef PMSM_H
00002 #define PMSM_H
00003 
00004 #include <stat/libFN.h>
00005 
00010 using namespace bdm;
00011 
00012 
00013 RV rx ( "{ia ib om th }");
00014 RV ru ( "{ua ub }");
00015 RV ry ( "{oia oib }");
00016 
00017 
00018 
00019 
00020 
00022 class IMpmsm : public diffbifn {
00023 protected:
00024         double Rs, Ls, dt, Ypm, kp, p,  J, Mz;
00025 
00026 public:
00027         IMpmsm() :diffbifn ( ) {dimy=4; dimx = 4; dimu=2;};
00029         void set_parameters ( double Rs0, double Ls0, double dt0, double Ypm0, double kp0, double p0, double J0, double Mz0 ) {Rs=Rs0; Ls=Ls0; dt=dt0; Ypm=Ypm0; kp=kp0; p=p0; J=J0; Mz=Mz0;}
00030 
00031         vec eval ( const vec &x0, const vec &u0 ) {
00032                 
00033                 const double &iam = x0 ( 0 );
00034                 const double &ibm = x0 ( 1 );
00035                 const double &omm = x0 ( 2 );
00036                 const double &thm = x0 ( 3 );
00037                 const double &uam = u0 ( 0 );
00038                 const double &ubm = u0 ( 1 );
00039 
00040                 vec xk( 4 );
00041                 
00042                 xk ( 0 ) = ( 1.0- Rs/Ls*dt ) * iam + Ypm/Ls*dt*omm * sin ( thm ) + uam*dt/Ls;
00043                 
00044                 xk ( 1 ) = ( 1.0- Rs/Ls*dt ) * ibm - Ypm/Ls*dt*omm * cos ( thm ) + ubm*dt/Ls;
00045                 
00046                 xk ( 2 ) = omm + kp*p*p * Ypm/J*dt* ( ibm * cos ( thm )-iam * sin ( thm ) ) - p/J*dt*Mz;
00047                 
00048                 xk ( 3 ) = thm + omm*dt; 
00049                 if ( xk ( 3 ) >pi ) xk ( 3 )-=2*pi;
00050                 if ( xk ( 3 ) <-pi ) xk ( 3 ) +=2*pi;
00051                 return xk;
00052         }
00053 
00054         void dfdx_cond ( const vec &x0, const vec &u0, mat &A, bool full=true ) {
00055                 const double &iam = x0 ( 0 );
00056                 const double &ibm = x0 ( 1 );
00057                 const double &omm = x0 ( 2 );
00058                 const double &thm = x0 ( 3 );
00059                 
00060                 A ( 0,0 ) = ( 1.0- Rs/Ls*dt ); A ( 0,1 ) = 0.0;
00061                 A ( 0,2 ) = Ypm/Ls*dt* sin ( thm ); A ( 0,3 ) = Ypm/Ls*dt*omm * ( cos ( thm ) );
00062                 
00063                 A ( 1,0 ) = 0.0 ; A ( 1,1 ) = ( 1.0- Rs/Ls*dt );
00064                 A ( 1,2 ) = -Ypm/Ls*dt* cos ( thm ); A ( 1,3 ) = Ypm/Ls*dt*omm * ( sin ( thm ) );
00065                 
00066                 A ( 2,0 ) = kp*p*p * Ypm/J*dt* ( - sin ( thm ) );
00067                 A ( 2,1 ) = kp*p*p * Ypm/J*dt* ( cos ( thm ) );
00068                 A ( 2,2 ) = 1.0;
00069                 A ( 2,3 ) = kp*p*p * Ypm/J*dt* ( -ibm * sin ( thm )-iam * cos ( thm ) );
00070                 
00071                 A ( 3,0 ) = 0.0; A ( 3,1 ) = 0.0; A ( 3,2 ) = dt; A ( 3,3 ) = 1.0;
00072         }
00073 
00074         void dfdu_cond ( const vec &x0, const vec &u0, mat &A, bool full=true ) {it_error ( "not needed" );};
00075 
00076 };
00077 
00079 class IMpmsm2o : public diffbifn {
00080         protected:
00081                 double Rs, Ls, dt, Ypm, kp, p,  J, Mz;
00083                 double dia, dib, dom, dth;
00085                 double d2t, cth, sth;
00086                 double iam, ibm, omm, thm, uam, ubm;
00087         public:
00088                 IMpmsm2o() :diffbifn () {dimy=4;dimx=4;dimu=2;};
00090                 void set_parameters ( double Rs0, double Ls0, double dt0, double Ypm0, double kp0, double p0, double J0, double Mz0 ) {Rs=Rs0; Ls=Ls0; dt=dt0; Ypm=Ypm0; kp=kp0; p=p0; J=J0; Mz=Mz0; d2t=dt*dt/2;}
00091 
00092                 vec eval ( const vec &x0, const vec &u0 ) {
00093                 
00094                         iam = x0 ( 0 );
00095                         ibm = x0 ( 1 );
00096                         omm = x0 ( 2 );
00097                         thm = x0 ( 3 );
00098                         uam = u0 ( 0 );
00099                         ubm = u0 ( 1 );
00100 
00101                         cth = cos(thm);
00102                         sth = sin(thm);
00103                         
00104                         dia = (- Rs/Ls*iam +  Ypm/Ls*omm * sth + uam/Ls);
00105                         dib = (- Rs/Ls*ibm -  Ypm/Ls*omm * cth + ubm/Ls);
00106                         dom = kp*p*p * Ypm/J *( ibm * cth-iam * sth ) - p/J*Mz;
00107                         dth = omm;
00108                                                 
00109                         vec xk=zeros ( 4 );
00110                         xk ( 0 ) =  iam + dt*dia;
00111                         xk ( 1 ) = ibm + dt*dib;
00112                         xk ( 2 ) = omm +dt*dom;
00113                         xk ( 3 ) = thm + dt*dth;
00114                         
00115                         if ( xk ( 3 ) >pi ) xk ( 3 )-=2*pi;
00116                         if ( xk ( 3 ) <-pi ) xk ( 3 ) +=2*pi;
00117                         return xk;
00118                 }
00119 
00121                 vec eval2o(const vec &du){
00122                         double dua = du ( 0 )/dt;
00123                         double dub = du ( 1 )/dt;
00124                         
00125                         vec xth2o(4);
00126                         xth2o(0) = (- Rs/Ls*dia +  Ypm/Ls*(dom * sth + omm*cth) + dua/Ls);
00127                         xth2o(1) = (- Rs/Ls*dib -  Ypm/Ls*(dom * cth - omm*sth) + dub/Ls);
00128                         xth2o(2) = kp*p*p * Ypm/J *( dib * cth-ibm*sth - (dia * sth + iam *cth));
00129                         xth2o(3) = dom;
00130                         return xth2o;
00131                 }
00132                 void dfdx_cond ( const vec &x0, const vec &u0, mat &A, bool full=true ) {
00133                          iam = x0 ( 0 );
00134                          ibm = x0 ( 1 );
00135                          omm = x0 ( 2 );
00136                          thm = x0 ( 3 );
00137                 
00138                         A ( 0,0 ) = ( 1.0- Rs/Ls*dt ); A ( 0,1 ) = 0.0;
00139                         A ( 0,2 ) = Ypm/Ls*dt* sin ( thm ); A ( 0,3 ) = Ypm/Ls*dt*omm * ( cos ( thm ) );
00140                 
00141                         A ( 1,0 ) = 0.0 ; A ( 1,1 ) = ( 1.0- Rs/Ls*dt );
00142                         A ( 1,2 ) = -Ypm/Ls*dt* cos ( thm ); A ( 1,3 ) = Ypm/Ls*dt*omm * ( sin ( thm ) );
00143                 
00144                         A ( 2,0 ) = kp*p*p * Ypm/J*dt* ( - sin ( thm ) );
00145                         A ( 2,1 ) = kp*p*p * Ypm/J*dt* ( cos ( thm ) );
00146                         A ( 2,2 ) = 1.0;
00147                         A ( 2,3 ) = kp*p*p * Ypm/J*dt* ( -ibm * sin ( thm )-iam * cos ( thm ) );
00148                 
00149                         A ( 3,0 ) = 0.0; A ( 3,1 ) = 0.0; A ( 3,2 ) = dt; A ( 3,3 ) = 1.0;
00150                 }
00151 
00152                 void dfdu_cond ( const vec &x0, const vec &u0, mat &A, bool full=true ) {it_error ( "not needed" );};
00153 
00154 };
00155 
00157 class IMpmsmStat : public IMpmsm {
00158         public:
00159         IMpmsmStat() :IMpmsm() {};
00161         void set_parameters ( double Rs0, double Ls0, double dt0, double Ypm0, double kp0, double p0, double J0, double Mz0 ) {Rs=Rs0; Ls=Ls0; dt=dt0; Ypm=Ypm0; kp=kp0; p=p0; J=J0; Mz=Mz0;}
00162 
00163         vec eval ( const vec &x0, const vec &u0 ) {
00164                 
00165                 double iam = x0 ( 0 );
00166                 double ibm = x0 ( 1 );
00167                 double omm = x0 ( 2 );
00168                 double thm = x0 ( 3 );
00169                 double uam = u0 ( 0 );
00170                 double ubm = u0 ( 1 );
00171 
00172                 vec xk=zeros ( 4 );
00173                 
00174                 xk ( 0 ) = ( 1.0- Rs/Ls*dt ) * iam + Ypm/Ls*dt*omm * sin ( thm ) + uam*dt/Ls;
00175                 
00176                 xk ( 1 ) = ( 1.0- Rs/Ls*dt ) * ibm - Ypm/Ls*dt*omm * cos ( thm ) + ubm*dt/Ls;
00177                 
00178                 xk ( 2 ) = omm;
00179                 
00180                 xk ( 3 ) = rem(thm + omm*dt,2*pi); 
00181                 return xk;
00182         }
00183 
00184         void dfdx_cond ( const vec &x0, const vec &u0, mat &A, bool full=true ) {
00185 
00186 
00187                 double omm = x0 ( 2 );
00188                 double thm = x0 ( 3 );
00189                 
00190                 A ( 0,0 ) = ( 1.0- Rs/Ls*dt ); A ( 0,1 ) = 0.0;
00191                 A ( 0,2 ) = Ypm/Ls*dt* sin ( thm ); A ( 0,3 ) = Ypm/Ls*dt*omm * ( cos ( thm ) );
00192                 
00193                 A ( 1,0 ) = 0.0 ; A ( 1,1 ) = ( 1.0- Rs/Ls*dt );
00194                 A ( 1,2 ) = -Ypm/Ls*dt* cos ( thm ); A ( 1,3 ) = Ypm/Ls*dt*omm * ( sin ( thm ) );
00195                 
00196                 A ( 2,0 ) = 0.0;
00197                 A ( 2,1 ) = 0.0;
00198                 A ( 2,2 ) = 1.0;
00199                 A ( 2,3 ) = 0.0;
00200                 
00201                 A ( 3,0 ) = 0.0; A ( 3,1 ) = 0.0; A ( 3,2 ) = dt; A ( 3,3 ) = 1.0;
00202         }
00203 
00204         void dfdu_cond ( const vec &x0, const vec &u0, mat &A, bool full=true ) {it_error ( "not needed" );};
00205 
00206 };
00207 
00209 class OMpmsm: public diffbifn {
00210 public:
00211         OMpmsm() :diffbifn () {dimy=2;dimx=4;dimu=2;};
00212 
00213         vec eval ( const vec &x0, const vec &u0 ) {
00214                 vec y ( 2 );
00215                 y ( 0 ) = x0 ( 0 );
00216                 y ( 1 ) = x0 ( 1 );
00217                 return y;
00218         }
00219 
00220         void dfdx_cond ( const vec &x0, const vec &u0, mat &A, bool full=true ) {
00221                 A.clear();
00222                 A ( 0,0 ) = 1.0;
00223                 A ( 1,1 ) = 1.0;
00224         }
00225 };
00226 
00228 #endif //PMSM_H