连续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
加载中,请稍候......