加载中…
个人资料
徐文力
徐文力
  • 博客等级:
  • 博客积分:0
  • 博客访问:2,514
  • 关注人气:45
  • 获赠金笔:0支
  • 赠出金笔:0支
  • 荣誉徽章:
正文 字体大小:

利用S-Function实现PID算法

(2016-04-27 16:17:23)
标签:

s-function

pid

控制

自动化

分类: 控制工程

利用S-Function实现PID算法

连续PID: 

http://s11/mw690/002nTqVZty71eWh1A4W8a&690

离散PID:

http://s14/mw690/002nTqVZzy71eWmxnR34d&690



连续PID子系统结构:

离散PID子系统结构:


连续PID算法S-Function文件

 

#include 

#include "PID0_sf.h"

#include "PID0_sf_private.h"

#include "simstruc.h"

#include "fixedpoint.h"

#if defined(RT_MALLOC) || defined(MATLAB_MEX_FILE)

 

extern void *PID0_malloc(SimStruct *S);

 

#endif

 

#ifndef __RTW_UTFREE__

#if defined (MATLAB_MEX_FILE)

 

extern void * utMalloc(size_t);

extern void utFree(void *);

 

#endif

#endif                                 

 

#if defined(MATLAB_MEX_FILE)

#include "rt_nonfinite.c"

#endif

 

static const char_T *RT_MEMORY_ALLOCATION_ERROR =

  "memory allocation error in generated S-Function";

 

 

#define MDL_INITIALIZE_CONDITIONS

 

static void mdlInitializeConditions(SimStruct *S)

{

  B_PID0_T *_rtB;

  _rtB = ((B_PID0_T *) ssGetLocalBlockIO(S));

 

  

  ((real_T*) ssGetDWork(S, 0))[0] = rtInf;

  ((real_T*) ssGetDWork(S, 0))[2] = rtInf;

 

  

  ((X_PID0_T *) ssGetContStates(S))->Integrator_CSTATE = 0.0;

}

 

 

#define MDL_START

 

static void mdlStart(SimStruct *S)

{

  

#if defined(RT_MALLOC) || defined(MATLAB_MEX_FILE)

#  if defined(MATLAB_MEX_FILE)

 

  

  rt_InitInfAndNaN(sizeof(real_T));

 

  

  if (!ssIsVariableStepSolver(S)) {

    ssSetErrorStatus(S, "This Simulink Coder generated "

                     "S-Function cannot be used in a simulation with "

                     "a solver type of fixed-step "

                     "because this S-Function was created from a model with "

                     "solver type of variable-step solver and it has continuous time blocks. "

                     "See the Solver page of the simulation parameters dialog.");

    return;

  }

 

#  endif

 

  PID0_malloc(S);

  if (ssGetErrorStatus(S) != (NULL) ) {

    return;

  }

 

#endif

 

  {

  }

}

 

 

static void mdlOutputs(SimStruct *S, int_T tid)

{

  

  real_T rtb_Derivative;

  real_T rtb_Integrator;

  real_T rtb_Gain;

  B_PID0_T *_rtB;

  _rtB = ((B_PID0_T *) ssGetLocalBlockIO(S));

 

  

  _rtB->Gain2 = (*(real_T *)(mxGetData(Kd(S)))) * *((const real_T **)

    ssGetInputPortSignalPtrs(S, 0))[0];

 

  

  {

    real_T t = ssGetT(S);

    real_T timeStampA = ((real_T*) ssGetDWork(S, 0))[0];

    real_T timeStampB = ((real_T*) ssGetDWork(S, 0))[2];

    real_T *lastU = &((real_T*) ssGetDWork(S, 0))[1];

    if (timeStampA >= t && timeStampB >= t) {

      rtb_Derivative = 0.0;

    } else {

      real_T deltaT;

      real_T lastTime = timeStampA;

      if (timeStampA < timeStampB) {

        if (timeStampB < t) {

          lastTime = timeStampB;

          lastU = &((real_T*) ssGetDWork(S, 0))[3];

        }

      } else if (timeStampA >= t) {

        lastTime = timeStampB;

        lastU = &((real_T*) ssGetDWork(S, 0))[3];

      }

 

      deltaT = t - lastTime;

      rtb_Derivative = (((B_PID0_T *) ssGetLocalBlockIO(S))->Gain2 - *lastU++) /

        deltaT;

    }

  }

 

  

  rtb_Gain = (*(real_T *)(mxGetData(Kp(S)))) * *((const real_T **)

    ssGetInputPortSignalPtrs(S, 0))[0];

 

  

  _rtB->Gain1 = (*(real_T *)(mxGetData(Ki(S)))) * *((const real_T **)

    ssGetInputPortSignalPtrs(S, 0))[0];

 

  

  rtb_Integrator = ((X_PID0_T *) ssGetContStates(S))->Integrator_CSTATE;

 

  

  ((real_T *)ssGetOutputPortSignal(S, 0))[0] = (rtb_Gain + rtb_Integrator) +

    rtb_Derivative;

 

  

  UNUSED_PARAMETER(tid);

}

 

 

#define MDL_UPDATE

 

static void mdlUpdate(SimStruct *S, int_T tid)

{

  B_PID0_T *_rtB;

  _rtB = ((B_PID0_T *) ssGetLocalBlockIO(S));

 

  

  {

    real_T timeStampA = ((real_T*) ssGetDWork(S, 0))[0];

    real_T timeStampB = ((real_T*) ssGetDWork(S, 0))[2];

    real_T* lastTime = &((real_T*) ssGetDWork(S, 0))[0];

    real_T* lastU = &((real_T*) ssGetDWork(S, 0))[1];

    if (timeStampA != rtInf) {

      if (timeStampB == rtInf) {

        lastTime = &((real_T*) ssGetDWork(S, 0))[2];

        lastU = &((real_T*) ssGetDWork(S, 0))[3];

      } else if (timeStampA >= timeStampB) {

        lastTime = &((real_T*) ssGetDWork(S, 0))[2];

        lastU = &((real_T*) ssGetDWork(S, 0))[3];

      }

    }

 

    *lastTime = ssGetT(S);

    *lastU++ = ((B_PID0_T *) ssGetLocalBlockIO(S))->Gain2;

  }

 

  

  UNUSED_PARAMETER(tid);

}

 

 

#define MDL_DERIVATIVES

 

static void mdlDerivatives(SimStruct *S)

{

  

  {

    ((XDot_PID0_T *) ssGetdX(S))->Integrator_CSTATE = ((B_PID0_T *)

      ssGetLocalBlockIO(S))->Gain1;

  }

}

 

 

static void mdlTerminate(SimStruct *S)

{

 

#if defined(RT_MALLOC) || defined(MATLAB_MEX_FILE)

 

  if (ssGetUserData(S) != (NULL) ) {

    rt_FREE(ssGetLocalBlockIO(S));

  }

 

  rt_FREE(ssGetUserData(S));

 

#endif

 

}

 

 

#define MDL_CHECK_PARAMETERS

#if defined(MDL_CHECK_PARAMETERS) && defined(MATLAB_MEX_FILE)

 

static void mdlCheckParameters(SimStruct *S)

{

  

  if (mxIsComplex(ssGetSFcnParam(S, 0))) {

    ssSetErrorStatus(S,"Parameter 'Kd' has to be a non complex array.");

    return;

  }

 

  if (!mxIsDouble(ssGetSFcnParam(S, 0))) {

    ssSetErrorStatus(S,"Parameter 'Kd' has to be a double array.");

    return;

  }

 

  if ((mxGetNumberOfDimensions(ssGetSFcnParam(S, 0)) != 2) ||

      (mxGetDimensions(ssGetSFcnParam(S, 0))[0] != 1) ||

      (mxGetDimensions(ssGetSFcnParam(S, 0))[1] != 1) ) {

    ssSetErrorStatus(S,"Parameter 'Kd' has to be a [1x1] array.");

    return;

  }

 

  

  if (mxIsComplex(ssGetSFcnParam(S, 1))) {

    ssSetErrorStatus(S,"Parameter 'Ki' has to be a non complex array.");

    return;

  }

 

  if (!mxIsDouble(ssGetSFcnParam(S, 1))) {

    ssSetErrorStatus(S,"Parameter 'Ki' has to be a double array.");

    return;

  }

 

  if ((mxGetNumberOfDimensions(ssGetSFcnParam(S, 1)) != 2) ||

      (mxGetDimensions(ssGetSFcnParam(S, 1))[0] != 1) ||

      (mxGetDimensions(ssGetSFcnParam(S, 1))[1] != 1) ) {

    ssSetErrorStatus(S,"Parameter 'Ki' has to be a [1x1] array.");

    return;

  }

 

  

  if (mxIsComplex(ssGetSFcnParam(S, 2))) {

    ssSetErrorStatus(S,"Parameter 'Kp' has to be a non complex array.");

    return;

  }

 

  if (!mxIsDouble(ssGetSFcnParam(S, 2))) {

    ssSetErrorStatus(S,"Parameter 'Kp' has to be a double array.");

    return;

  }

 

  if ((mxGetNumberOfDimensions(ssGetSFcnParam(S, 2)) != 2) ||

      (mxGetDimensions(ssGetSFcnParam(S, 2))[0] != 1) ||

      (mxGetDimensions(ssGetSFcnParam(S, 2))[1] != 1) ) {

    ssSetErrorStatus(S,"Parameter 'Kp' has to be a [1x1] array.");

    return;

  }

}

 

#endif                                 

 

#if defined(RT_MALLOC) || defined(MATLAB_MEX_FILE)

#  include "PID0_mid.h"

#endif

 

 

static void mdlInitializeSizes(SimStruct *S)

{

  ssSetNumSampleTimes(S, 1);           

  ssSetNumContStates(S, 1);            

  ssSetNumNonsampledZCs(S, 0);         

  ssSetZCCacheNeedsReset(S, 0);

  ssSetDerivCacheNeedsReset(S, 0);

 

  

  if (!ssSetNumOutputPorts(S, 1))

    return;

 

  

  if (!ssSetOutputPortVectorDimension(S, 0, 1))

    return;

  if (ssGetSimMode(S) != SS_SIMMODE_SIZES_CALL_ONLY) {

    ssSetOutputPortDataType(S, 0, SS_DOUBLE);

  }

 

  ssSetOutputPortSampleTime(S, 0, 0.0);

  ssSetOutputPortOffsetTime(S, 0, 0.0);

  ssSetOutputPortOptimOpts(S, 0, SS_REUSABLE_AND_LOCAL);

 

  

  if (!ssSetNumInputPorts(S, 1))

    return;

 

  

  {

    if (!ssSetInputPortVectorDimension(S, 0, 1))

      return;

    if (ssGetSimMode(S) != SS_SIMMODE_SIZES_CALL_ONLY) {

      ssSetInputPortDataType(S, 0, SS_DOUBLE);

    }

 

    ssSetInputPortDirectFeedThrough(S, 0, 1);

    ssSetInputPortSampleTime(S, 0, 0.0);

    ssSetInputPortOffsetTime(S, 0, 0.0);

    ssSetInputPortOverWritable(S, 0, 0);

    ssSetInputPortOptimOpts(S, 0, SS_NOT_REUSABLE_AND_GLOBAL);

  }

 

  ssSetRTWGeneratedSFcn(S, 1);         

 

  

  if (!ssSetNumDWork(S, 1)) {

    return;

  }

 

  

  ssSetDWorkName(S, 0, "DWORK0");

  ssSetDWorkWidth(S, 0, 4);

 

  

  ssSetNumSFcnParams(S, 3);

 

  

#if defined(MATLAB_MEX_FILE)

 

  if (ssGetNumSFcnParams(S) == ssGetSFcnParamsCount(S)) {

 

#if defined(MDL_CHECK_PARAMETERS)

 

    mdlCheckParameters(S);

 

#endif                                 

 

    if (ssGetErrorStatus(S) != (NULL) ) {

      return;

    }

  } else {

    return;                            

  }

 

#endif                                 

 

  

  ssSetOptions(S, (SS_OPTION_RUNTIME_EXCEPTION_FREE_CODE |

                   SS_OPTION_PORT_SAMPLE_TIMES_ASSIGNED ));

 

#if SS_SFCN_FOR_SIM

 

  {

    ssSupportsMultipleExecInstances(S, true);

    ssHasStateInsideForEachSS(S, false);

  }

 

#endif

 

}

 

 

static void mdlInitializeSampleTimes(SimStruct *S)

{

  

  ssSetSampleTime(S, 0, 0.0);

 

  

  ssSetOffsetTime(S, 0, 0.0);

}

 

#if defined(MATLAB_MEX_FILE)

# include "fixedpoint.c"

# include "simulink.c"

#else

# undef S_FUNCTION_NAME

# define S_FUNCTION_NAME               PID0_sf

# include "cg_sfun.h"

#endif                                 

 

 

 

离散PID算法S-Function文件

 

#include 

#include "Discrete_sf.h"

#include "Discrete_sf_private.h"

#include "simstruc.h"

#include "fixedpoint.h"

#if defined(RT_MALLOC) || defined(MATLAB_MEX_FILE)

 

extern void *Discrete_malloc(SimStruct *S);

 

#endif

 

#ifndef __RTW_UTFREE__

#if defined (MATLAB_MEX_FILE)

 

extern void * utMalloc(size_t);

extern void utFree(void *);

 

#endif

#endif                                 

 

#if defined(MATLAB_MEX_FILE)

#include "rt_nonfinite.c"

#endif

 

static const char_T *RT_MEMORY_ALLOCATION_ERROR =

  "memory allocation error in generated S-Function";

 

 

#define MDL_INITIALIZE_CONDITIONS

 

static void mdlInitializeConditions(SimStruct *S)

{

  

  ((real_T *)ssGetDWork(S, 0))[0] = 0.0;

 

  

  ((real_T *)ssGetDWork(S, 1))[0] = 0.0;

}

 

 

#define MDL_START

 

static void mdlStart(SimStruct *S)

{

  

#if defined(RT_MALLOC) || defined(MATLAB_MEX_FILE)

#  if defined(MATLAB_MEX_FILE)

 

  

  rt_InitInfAndNaN(sizeof(real_T));

 

#  endif

 

  Discrete_malloc(S);

  if (ssGetErrorStatus(S) != (NULL) ) {

    return;

  }

 

#endif

 

  {

  }

}

 

 

static void mdlOutputs(SimStruct *S, int_T tid)

{

  B_Discrete_T *_rtB;

  _rtB = ((B_Discrete_T *) ssGetLocalBlockIO(S));

  if (ssIsSampleHit(S, 1, 0)) {

    

    _rtB->DiscreteTimeIntegrator = ((real_T *)ssGetDWork(S, 0))[0];

 

    

    _rtB->DiscreteTimeIntegrator1 = ((real_T *)ssGetDWork(S, 1))[0];

  }

 

  if (ssIsSampleHit(S, 0, 0)) {

    

    _rtB->Gain1 = (*(real_T *)(mxGetData(Ki(S)))) * *((const real_T **)

      ssGetInputPortSignalPtrs(S, 0))[0];

 

    

    _rtB->Gain3 = ((*(real_T *)(mxGetData(Kd(S)))) * *((const real_T **)

      ssGetInputPortSignalPtrs(S, 0))[0] - _rtB->DiscreteTimeIntegrator1) *

      (*(real_T *)(mxGetData(N(S))));

 

    

    ((real_T *)ssGetOutputPortSignal(S, 0))[0] = ((*(real_T *)(mxGetData(Kp(S))))

      * *((const real_T **)ssGetInputPortSignalPtrs(S, 0))[0] +

      _rtB->DiscreteTimeIntegrator) + _rtB->Gain3;

  }

 

  

  UNUSED_PARAMETER(tid);

}

 

 

#define MDL_UPDATE

 

static void mdlUpdate(SimStruct *S, int_T tid)

{

  B_Discrete_T *_rtB;

  _rtB = ((B_Discrete_T *) ssGetLocalBlockIO(S));

  if (ssIsSampleHit(S, 1, 0)) {

    

    ((real_T *)ssGetDWork(S, 0))[0] = ((real_T *)ssGetDWork(S, 0))[0] +

      _rtB->Gain1;

 

    

    ((real_T *)ssGetDWork(S, 1))[0] = ((real_T *)ssGetDWork(S, 1))[0] +

      _rtB->Gain3;

  }

 

  

  UNUSED_PARAMETER(tid);

}

 

 

static void mdlTerminate(SimStruct *S)

{

 

#if defined(RT_MALLOC) || defined(MATLAB_MEX_FILE)

 

  if (ssGetUserData(S) != (NULL) ) {

    rt_FREE(ssGetLocalBlockIO(S));

  }

 

  rt_FREE(ssGetUserData(S));

 

#endif

 

}

 

 

#define MDL_CHECK_PARAMETERS

#if defined(MDL_CHECK_PARAMETERS) && defined(MATLAB_MEX_FILE)

 

static void mdlCheckParameters(SimStruct *S)

{

  

  if (mxIsComplex(ssGetSFcnParam(S, 0))) {

    ssSetErrorStatus(S,"Parameter 'Kd' has to be a non complex array.");

    return;

  }

 

  if (!mxIsDouble(ssGetSFcnParam(S, 0))) {

    ssSetErrorStatus(S,"Parameter 'Kd' has to be a double array.");

    return;

  }

 

  if ((mxGetNumberOfDimensions(ssGetSFcnParam(S, 0)) != 2) ||

      (mxGetDimensions(ssGetSFcnParam(S, 0))[0] != 1) ||

      (mxGetDimensions(ssGetSFcnParam(S, 0))[1] != 1) ) {

    ssSetErrorStatus(S,"Parameter 'Kd' has to be a [1x1] array.");

    return;

  }

 

  

  if (mxIsComplex(ssGetSFcnParam(S, 1))) {

    ssSetErrorStatus(S,"Parameter 'Ki' has to be a non complex array.");

    return;

  }

 

  if (!mxIsDouble(ssGetSFcnParam(S, 1))) {

    ssSetErrorStatus(S,"Parameter 'Ki' has to be a double array.");

    return;

  }

 

  if ((mxGetNumberOfDimensions(ssGetSFcnParam(S, 1)) != 2) ||

      (mxGetDimensions(ssGetSFcnParam(S, 1))[0] != 1) ||

      (mxGetDimensions(ssGetSFcnParam(S, 1))[1] != 1) ) {

    ssSetErrorStatus(S,"Parameter 'Ki' has to be a [1x1] array.");

    return;

  }

 

  

  if (mxIsComplex(ssGetSFcnParam(S, 2))) {

    ssSetErrorStatus(S,"Parameter 'Kp' has to be a non complex array.");

    return;

  }

 

  if (!mxIsDouble(ssGetSFcnParam(S, 2))) {

    ssSetErrorStatus(S,"Parameter 'Kp' has to be a double array.");

    return;

  }

 

  if ((mxGetNumberOfDimensions(ssGetSFcnParam(S, 2)) != 2) ||

      (mxGetDimensions(ssGetSFcnParam(S, 2))[0] != 1) ||

      (mxGetDimensions(ssGetSFcnParam(S, 2))[1] != 1) ) {

    ssSetErrorStatus(S,"Parameter 'Kp' has to be a [1x1] array.");

    return;

  }

 

  

  if (mxIsComplex(ssGetSFcnParam(S, 3))) {

    ssSetErrorStatus(S,"Parameter 'N' has to be a non complex array.");

    return;

  }

 

  if (!mxIsDouble(ssGetSFcnParam(S, 3))) {

    ssSetErrorStatus(S,"Parameter 'N' has to be a double array.");

    return;

  }

 

  if ((mxGetNumberOfDimensions(ssGetSFcnParam(S, 3)) != 2) ||

      (mxGetDimensions(ssGetSFcnParam(S, 3))[0] != 1) ||

      (mxGetDimensions(ssGetSFcnParam(S, 3))[1] != 1) ) {

    ssSetErrorStatus(S,"Parameter 'N' has to be a [1x1] array.");

    return;

  }

}

 

#endif                                 

 

#if defined(RT_MALLOC) || defined(MATLAB_MEX_FILE)

#  include "Discrete_mid.h"

#endif

 

 

static void mdlInitializeSizes(SimStruct *S)

{

  ssSetNumSampleTimes(S, 2);           

  ssSetNumContStates(S, 0);            

  ssSetNumNonsampledZCs(S, 0);         

  ssSetZCCacheNeedsReset(S, 0);

  ssSetDerivCacheNeedsReset(S, 0);

 

  

  if (!ssSetNumOutputPorts(S, 1))

    return;

 

  

  if (!ssSetOutputPortVectorDimension(S, 0, 1))

    return;

  if (ssGetSimMode(S) != SS_SIMMODE_SIZES_CALL_ONLY) {

    ssSetOutputPortDataType(S, 0, SS_DOUBLE);

  }

 

  ssSetOutputPortSampleTime(S, 0, 0.0);

  ssSetOutputPortOffsetTime(S, 0, 1.0);

  ssSetOutputPortOptimOpts(S, 0, SS_REUSABLE_AND_LOCAL);

 

  

  if (!ssSetNumInputPorts(S, 1))

    return;

 

  

  {

    if (!ssSetInputPortVectorDimension(S, 0, 1))

      return;

    if (ssGetSimMode(S) != SS_SIMMODE_SIZES_CALL_ONLY) {

      ssSetInputPortDataType(S, 0, SS_DOUBLE);

    }

 

    ssSetInputPortDirectFeedThrough(S, 0, 1);

    ssSetInputPortSampleTime(S, 0, 0.0);

    ssSetInputPortOffsetTime(S, 0, 1.0);

    ssSetInputPortOverWritable(S, 0, 0);

    ssSetInputPortOptimOpts(S, 0, SS_NOT_REUSABLE_AND_GLOBAL);

  }

 

  ssSetRTWGeneratedSFcn(S, 1);         

 

  

  if (!ssSetNumDWork(S, 2)) {

    return;

  }

 

  

  ssSetDWorkName(S, 0, "DWORK0");

  ssSetDWorkWidth(S, 0, 1);

  ssSetDWorkUsedAsDState(S, 0, 1);

 

  

  ssSetDWorkName(S, 1, "DWORK1");

  ssSetDWorkWidth(S, 1, 1);

  ssSetDWorkUsedAsDState(S, 1, 1);

 

  

  ssSetNumSFcnParams(S, 4);

 

  

#if defined(MATLAB_MEX_FILE)

 

  if (ssGetNumSFcnParams(S) == ssGetSFcnParamsCount(S)) {

 

#if defined(MDL_CHECK_PARAMETERS)

 

    mdlCheckParameters(S);

 

#endif                                 

 

    if (ssGetErrorStatus(S) != (NULL) ) {

      return;

    }

  } else {

    return;                            

  }

 

#endif                                 

 

  

  ssSetOptions(S, (SS_OPTION_RUNTIME_EXCEPTION_FREE_CODE |

                   SS_OPTION_PORT_SAMPLE_TIMES_ASSIGNED ));

 

#if SS_SFCN_FOR_SIM

 

  {

    ssSupportsMultipleExecInstances(S, true);

    ssHasStateInsideForEachSS(S, false);

  }

 

#endif

 

}

 

 

static void mdlInitializeSampleTimes(SimStruct *S)

{

  

  ssSetSampleTime(S, 0, 0.0);

  ssSetSampleTime(S, 1, 1.0);

 

  

  ssSetOffsetTime(S, 0, 1.0);

  ssSetOffsetTime(S, 1, 0.0);

}

 

#if defined(MATLAB_MEX_FILE)

# include "fixedpoint.c"

# include "simulink.c"

#else

# undef S_FUNCTION_NAME

# define S_FUNCTION_NAME               Discrete_sf

# include "cg_sfun.h"

#endif                                 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

0

阅读 收藏 喜欢 打印举报/Report
  

新浪BLOG意见反馈留言板 欢迎批评指正

新浪简介 | About Sina | 广告服务 | 联系我们 | 招聘信息 | 网站律师 | SINA English | 产品答疑

新浪公司 版权所有