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