📄 motorc1.c.bak
字号:
/*
* Asynchronous motor electromagnetic model bolck based on the C S-Function.
*
* -------------------------------------------------------------------------
* | See matlabroot/simulink/src/sfuntmpl_doc.c for a more detailed template |
* -------------------------------------------------------------------------
*
* Copyright 2004 The Zelri Author: LiuChen
* $Revision: 0.13b $
*/
#define S_FUNCTION_LEVEL 2
#define S_FUNCTION_NAME motorc1
#include "simstruc.h"
#include "math.h"
#define RS_PARAM(S) ssGetSFcnParam(S, 0)
#define LLS_PARAM(S) ssGetSFcnParam(S, 1)
#define LM_PARAM(S) ssGetSFcnParam(S, 2)
#define RR_PARAM(S) ssGetSFcnParam(S, 3)
#define LLR_PARAM(S) ssGetSFcnParam(S, 4)
#define P_PARAM(S) ssGetSFcnParam(S, 5)
#define TS_PARAM(S) ssGetSFcnParam(S, 6)
#define UWrptrs ssGetInputPortRealSignalPtrs(S, 0)
#define UVptrs ssGetInputPortRealSignalPtrs(S, 1)
#define Xptrs ssGetDiscStates(S)
#define YIptrs ssGetOutputPortRealSignal(S,0)
#define YTEMptrs ssGetOutputPortRealSignal(S,1)
#define YFLptrs ssGetOutputPortRealSignal(S,2)
#define PI 3.1415926
static real_T squr2abc[3][2] = {{0.6667 , 0 },
{-0.3333, 0.577367 },
{-0.3333, -0.577367 }
};
static real_T abc2squr[2][3] = {{1, -0.5, -0.5 },
{0, 0.866, -0.866 }
};
/* Function: mdlInitializeSizes ===============================================
*
* S-Function blocks sizes information:
*
* output port 1: motor's stator current [isa isb isc]
* output port 2: motor's electromagnetic torque Tem (Nm)
* output port 3: motor's stator Flux link Fls
*
* input port 1: motor's speed wr (rad/s)
* input port 2: stator phase voltage [Ua0 Ub0 Uc0]
*
* parameters: electrical parameters and sample time
[Rs Lls Lm Rr Llr p Ts]
*
* discrete states: motor's flux link in alpha-beta reference
* [flsa flsb flra flrb Upresd Upresq Wrpr]
*/
static void mdlInitializeSizes(SimStruct *S){
ssSetNumSFcnParams(S, 7); // [Rs Lls Lm Rr Llr p Ts]
if (ssGetNumSFcnParams(S) != ssGetSFcnParamsCount(S)) {
return;
}
// discreted states: [flsd flsq flrd flrq Upresd Upresq Revpr]
ssSetNumContStates(S, 0);
ssSetNumDiscStates(S, 7);
if (!ssSetNumInputPorts(S, 2)) return;
ssSetInputPortWidth(S, 0, 1);
ssSetInputPortWidth(S, 1, 3);
ssSetInputPortRequiredContiguous(S, 0, false); // direct input signal access
ssSetInputPortRequiredContiguous(S, 1, false);
ssSetInputPortDirectFeedThrough(S, 0, 0);
ssSetInputPortDirectFeedThrough(S, 1, 0);
if (!ssSetNumOutputPorts(S, 3)) return;
ssSetOutputPortWidth(S, 0, 3);
ssSetOutputPortWidth(S, 1, 1);
ssSetOutputPortWidth(S, 2, 2);
ssSetNumSampleTimes(S, 1);
ssSetNumRWork(S, 0);
ssSetNumIWork(S, 0);
ssSetNumPWork(S, 0);
ssSetNumModes(S, 0);
ssSetNumNonsampledZCs(S, 0);
ssSetOptions(S, 0);
}
// Function: mdlInitializeSampleTimes =========================================
static void mdlInitializeSampleTimes(SimStruct *S){
ssSetSampleTime(S, 0, *mxGetPr(TS_PARAM(S)));
ssSetOffsetTime(S, 0, 0.0);
}
// Function: mdlInitializeConditions ========================================
#define MDL_INITIALIZE_CONDITIONS
#if defined(MDL_INITIALIZE_CONDITIONS)
static void mdlInitializeConditions(SimStruct *S){
int_T i=0;
for (i = 0; i < ssGetNumDiscStates(S); i++)
Xptrs[i] = 0;
}
#endif
// Function: mdlStart =======================================================
#undef MDL_START
#if defined(MDL_START)
static void mdlStart(SimStruct *S){
}
#endif
// Function: mdlOutputs =======================================================
static void mdlOutputs(SimStruct *S, int_T tid){
int_T i = 0;
int_T j = 0;
// define voltage & current vector in alpha-beta reference
real_T Isqur[4] = {0.0};
real_T Iabc[3] = {0.0};
real_T Lls = *mxGetPr(LLS_PARAM(S)); // get parameters
real_T Llr = *mxGetPr(LLR_PARAM(S));
real_T Lm = *mxGetPr(LM_PARAM(S));
real_T Rs = *mxGetPr(RS_PARAM(S));
real_T Rr = *mxGetPr(RR_PARAM(S));
real_T p = *mxGetPr(P_PARAM(S));
real_T Tem;
real_T w = Xptrs[6]; // get wr state
// get states -- stator and rotor's flux link in alpha-beta ref.
real_T FluxLink[4] = {0.0};
real_T Ls = Lls+Lm; // process parameters
real_T Lr = Llr+Lm;
real_T m = Lm*Lm - Ls*Lr;
real_T C[4][4] = {0.0};
C[0][0] = -1*Lr/m;
C[0][2] = Lm/m;
C[1][1] = -1*Lr/m;
C[1][3] = Lm/m;
C[2][0] = Lm/m;
C[2][2] = -1*Ls/m;
C[3][1] = Lm/m;
C[3][3] = -1*Ls/m;
/* { {-1*Lr/m, 0, Lm/m, 0 },
{0, -1*Lr/m, 0, Lm/m },
{Lm/m, 0, -1*Ls/m, 0 },
{0, Lm/m, 0, -1*Ls/m }
*/
// get flux link value
for (i=0;i<4;i++){
FluxLink[i] = Xptrs[i];
}
// compute currents in alpha-beta reference
for(i=0; i<4;i++){
for(j=0;j<4;j++)
Isqur[i] += C[i][j]*FluxLink[j];
}
// compute electromagnetic torque and send to outport 2
Tem = 2*p*Lm*(FluxLink[0]*FluxLink[3]-FluxLink[1]*FluxLink[2])/(3*m);
// compute stator current in ABC reference
for(i=0;i<3;i++){
for(j=0;j<2;j++)
Iabc[i] += squr2abc[i][j]*Isqur[j];
YIptrs[i] = Iabc[i];
}
// output stator Flux link
YTEMptrs[0] = Tem;
YFLptrs[0] = Xptrs[0];
YFLptrs[1] = Xptrs[1];
}
// Function: mdlUpdate ======================================================
#define MDL_UPDATE /* Change to #undef to remove function */
#if defined(MDL_UPDATE)
static void mdlUpdate(SimStruct *S, int_T tid){
real_T Lls = *mxGetPr(LLS_PARAM(S)); // get parameters
real_T Llr = *mxGetPr(LLR_PARAM(S));
real_T Lm = *mxGetPr(LM_PARAM(S));
real_T Rs = *mxGetPr(RS_PARAM(S));
real_T Rr = *mxGetPr(RR_PARAM(S));
real_T p = *mxGetPr(P_PARAM(S));
real_T SampleTime = *mxGetPr(TS_PARAM(S));
real_T w = *UWrptrs[0]*p;
real_T Ls = Lls+Lm; // process parameters
real_T Lr = Llr+Lm;
real_T m = Lm*Lm - Ls*Lr;
real_T A[4][4] = {0.0};
real_T B[4][4] = {{1,0,0,0},
{0,1,0,0},
{0,0,0,0},
{0,0,0,0}
};
real_T Vsqur[4] = {0.0};
real_T Vinterp[4] = {0.0};
real_T K1[4] = {0.0}; // define the RK
real_T K2[4] = {0.0};
real_T K3[4] = {0.0};
real_T K4[4] = {0.0};
int_T i=0;
int_T j=0;
A[0][0] = Lr*Rs/m;
A[0][2] = -1*Lm*Rs/m;
A[1][1] = Lr*Rs/m;
A[1][3] = -1*Lm*Rs/m;
A[2][0] = -1*Lm*Rr/m;
A[2][2] = Ls*Rr/m;
A[2][3] = -1*w;
A[3][1] = -1*Lm*Rr/m;
A[3][2] = w;
A[3][3] = Ls*Rr/m;
/*{ {Lr*Rs/m, 0, -1*Lm*Rs/m, 0 },
{0 , Lr*Rs/m, 0, -1*Lm*Rs/m },
{-1*Lm*Rr/m, 0, Ls*Rr/m, -1*w },
{0 , -1*Lm*Rr/m, w, Ls*Rr/m }};*/
// compute voltage in alpha-beta reference
for(i=0;i<2;i++){
for(j=0;j<3;j++)
Vsqur[i] += abc2squr[i][j]**UVptrs[j];
}
// compute the voltage interpolated value
for (i=0;i<2;i++){
Vinterp[i] = (Vsqur[i]+Xptrs[i+4])/2;
}
// using RK method to compute the states' new value
for (i=0;i<4;i++){
for(j=0;j<4;j++)
K1[i] += A[i][j]*Xptrs[j] + B[i][j]*Xptrs[j+4];
}
for (i=0;i<4;i++){
for(j=0;j<4;j++)
K2[i] += A[i][j]*(Xptrs[j]+SampleTime*K1[j]/2) + B[i][j]*Vinterp[j];
}
for (i=0;i<4;i++){
for(j=0;j<4;j++)
K3[i] += A[i][j]*(Xptrs[j]+SampleTime*K2[j]/2) + B[i][j]*Vinterp[j];
}
for (i=0;i<4;i++){
for(j=0;j<4;j++)
K4[i] += A[i][j]*(Xptrs[j]+SampleTime*K3[j]) + B[i][j]*Vsqur[j];
}
// update the flux link states
for(i=0;i<4;i++)
Xptrs[i] += SampleTime*(K1[i]+2*K2[i]+2*K3[i]+K4[i])/6;
// update the voltage states
for(i=0;i<2;i++)
Xptrs[i+4] = Vsqur[i];
// update the wr states
Xptrs[6] = w;
}
#endif /* MDL_UPDATE */
// Function: mdlTerminate ===========================================================
static void mdlTerminate(SimStruct *S){
UNUSED_ARG(S);
}
#ifdef MATLAB_MEX_FILE /* Is this file being compiled as a MEX-file? */
#include "simulink.c" /* MEX-file interface mechanism */
#else
#include "cg_sfun.h" /* Code generation registration function */
#endif
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -