Example of calculation routine CPID

The PID method corresponding to a classic PID controller is programmed as explained below. It includes an optionnal filter term of the derivative term, an antiwindup and deadband zone:

  1. SUBROUTINE CPID(Reg,U,Y,YT,PARA,ISIMO)
  2. USE SIRENE_parametres, ONLY : LONG
  3. USE IFICH , ONLY : JREGS
  4. USE TEMPS , ONLY : T
  5. USE D_REGULATION, ONLY : Regulateur_t
  6. USE D_GLOBAL, ONLY : sProgActif
  7.  
  8. IMPLICIT NONE
  9.  
  10. TYPE(Regulateur_t), INTENT(INOUT) :: Reg
  11. INTEGER, INTENT(IN) :: ISIMO
  12. REAL(KIND=LONG), INTENT(IN) :: Y,YT
  13. REAL(KIND=LONG), INTENT(INOUT) :: U,PARA
  14.  
  15. INTEGER :: IU,IY
  16. REAL(KIND=LONG) :: KP,N,TI,TD,AWU,EOLD,SE,DE,E,STI,A1,A2,U2
  17.  
  18. !-----Si ISIMO=0 c'est un PID monovariable, si ISIMO=1 et s'il y a plusieurs U on duplique U
  19. !-----Si ISIMO=I<0 il est appelé à partir d'ATVPID et c'est l'indice du U et du Y qu'on doit
  20. !----- utiliser pour décaller le U et Y global pour DYMAX et les variables de l'antiwindup
  21. INTEGER, PARAMETER :: NMES=$NSIRE,LMES=$LSIRE
  22. !-----On gère l'antiwindup
  23. LOGICAL SATURE
  24. CHARACTER MESP*(LMES)
  25.  
  26. !-----On utilise DTU et non plus DT (POM 2/6/99)
  27. COMMON/SIRE/MESP(NMES)
  28.  
  29. DIMENSION Y(:),YT(:),U(:),PARA(:)
  30. !-----Affectations
  31. KP=PARA(1)
  32. TI=PARA(2)
  33. TD=PARA(3)
  34. N=PARA(4)
  35. AWU=PARA(5)
  36. EOLD=PARA(6)
  37. SE=PARA(7)
  38. DE=PARA(8)
  39. !-----Calcul pour cette methode
  40. !-----Nouvel ecart (e = y* - y)
  41. E=YT(1)-Y(1)
  42. !-----Recherche de l'indice global pour Y et pour U (POM 14/3/5)
  43. IF(ISIMO.LT.0) THEN
  44. IY=ABS(ISIMO)
  45. IU=ABS(ISIMO)
  46. ELSE
  47. IY=1
  48. IU=1
  49. ENDIF
  50. !-----On gère une bande morte (POM 21/07/04)
  51. IF(ABS(E).LT.Reg%tY(IY)%DYMax) THEN
  52. IF(sProgActif=='SIRENE') THEN
  53. WRITE(JREGS,MESP(87)) T,'DYMax',Reg%num,IY,Reg%tY(IY)%DYMax,E,0.
  54. ELSEIF(sProgActif=='FLUVIA') THEN
  55. WRITE(JREGS,MESP(76)) T,'DYMax',Reg%num,IY,Reg%tY(IY)%DYMax,E,0.
  56. ENDIF
  57. E=0.
  58. ENDIF
  59. !-----Terme integral (approximation de Tustin)
  60. !-----On gère l'antiwindup (POM 16/07/04)
  61. IF(TI.NE.0.) THEN
  62. STI=KP*Reg%tU(IU)%VarU%DT/TI*(EOLD+E)/2
  63. ELSE
  64. STI=0.
  65. ENDIF
  66. IF(AWU.EQ.1.) THEN
  67. SATURE=Reg%tU(IU)%FiltreU%iFlagBloc>=3 .AND. Reg%tU(IU)%FiltreU%iFlagBloc/=5
  68. IF(.NOT.SATURE) THEN
  69. SE=SE+STI
  70. ENDIF
  71. ELSE
  72. SE=SE+STI
  73. ENDIF
  74. !-----Terme derive
  75. IF(TD.NE.0.) THEN
  76. IF(N.EQ.0.) THEN
  77. !-----------Terme derive sans filtre (backward difference)
  78. !-----------Avec une consigne y* constante
  79. DE=KP/Reg%tU(IU)%VarU%DT*TD*(E-EOLD)
  80. ELSE
  81. !-----------Terme derive avec filtre (backward difference)
  82. !-----------Avec une consigne y* constante
  83. A1=1/(1+N*Reg%tU(IU)%VarU%DT/TD)
  84. A2=KP*N*A1
  85. DE=A1*DE+A2*(E-EOLD)
  86. ENDIF
  87. ENDIF
  88. !-----Calcul de la commande
  89. U(1)=KP*E+SE+DE
  90. !-----Ancien ecart
  91. EOLD=E
  92. !-----Affectations
  93. PARA(6)=EOLD
  94. PARA(7)=SE
  95. PARA(8)=DE
  96. !-----Si plusieurs U (SIMO) on duplique la meme ouverture
  97. !-----(interessant dans le cas de plusieurs vannes identiques en parallele, en mode V par exemple)
  98. IF(ISIMO.GT.0) THEN
  99. U2=U(1)
  100. U(:)=U2
  101. ENDIF
  102.  
  103. END SUBROUTINE CPID

Download

If you want another PID equation, you can always copy and paste this subroutine into a USER regulation module and modify it as you want (do the same with the LPID -> LUSER subroutine to read the parameters).