Exemple de routine de calcul CPID
La méthode PID correspond à un PID classique, avec filtre éventuel sur le terme dérivé, antiwindup et bande morte. Il est programmé de la manière suivante :
SUBROUTINE CPID(Reg)
USE SIRENE_parametres, ONLY : LONG
USE TEMPS , ONLY : T
USE D_REGULATION, ONLY : Regulateur_t
IMPLICIT NONE
TYPE(Regulateur_t), INTENT(INOUT) :: Reg
REAL(KIND=LONG), POINTER :: KP,N,TI,TD,AWU,EOLD,SE,DE
REAL(KIND=LONG) :: E,STI,A1,A2,U2
LOGICAL SATURE !< Détection de l'anti wind-up
INTEGER :: iU !< Compteur pour les commandes U
! Pointeurs pour faciliter la lecture du code
KP=>Reg%tPara(1)
TI=>Reg%tPara(2)
TD=>Reg%tPara(3)
N=>Reg%tPara(4)
AWU=>Reg%tPara(5)
EOLD=>Reg%tPara(6)
SE=>Reg%tPara(7)
DE=>Reg%tPara(8)
! Calcul pour cette methode
! Nouvel ecart (e = y* - y)
E=Reg%tY(1)%YTVal-Reg%tY(1)%VarY%V
! On gère une bande morte (POM 21/07/04)
IF(ABS(E).LT.Reg%tY(IY)%DYMax) THEN
E=0.
ENDIF
! Terme integral (approximation de Tustin)
IF(TI.NE.0.) THEN
STI=KP*Reg%tU(1)%VarU%DT/TI*(EOLD+E)/2
ELSE
STI=0.
ENDIF
! On gère l'antiwindup en utilisant le code de blocage du filtre de la commande :
!> 0 = Fonctionnement libre normal
!> 1 = Caractéristique volontairement bloquée (Valeur calée par Umin>=Umax à la lecture du XML)
!> 2 = Caractéristique bloquée par problème de régulation (Umin, Umax, surverse, hors-loi vanne mixte)
!> 3 = FiltreU => Umin atteint
!> 4 = FiltreU => Umax atteint
!> 5 = FiltreU => DUmin atteint
!> 6 = FiltreU => DUmav atteint
SATURE=Reg%tU(1)%FiltreU%iFlagBloc>=3 .AND. Reg%tU(1)%FiltreU%iFlagBloc/=5
IF(AWU == 0. .OR. .NOT.SATURE) THEN
SE=SE+STI
ENDIF
! Terme derive
IF(TD.NE.0.) THEN
IF(N.EQ.0.) THEN
! Terme derive sans filtre (backward difference)
! Avec une consigne y* constante
DE=KP/Reg%tU(1)%VarU%DT*TD*(E-EOLD)
ELSE
! Terme derive avec filtre (backward difference)
! Avec une consigne y* constante
A1=1/(1+N*Reg%tU(1)%VarU%DT/TD)
A2=KP*N*A1
DE=A1*DE+A2*(E-EOLD)
ENDIF
ENDIF
! Calcul de la commande
Reg%tU(1)%VarU%V=KP*E+SE+DE
! Ancien ecart
EOLD=E
! Si plusieurs U (SIMO) on duplique la meme ouverture
! (interessant dans le cas de plusieurs vannes identiques en parallele, en mode V par exemple)
DO iU=1, Reg%nbrU
Reg%tU(iU)%VarU%V = Reg%tU(1)%VarU%V
ENDDO
END SUBROUTINE CPIDSi vous voulez un PID différent vous pouvez toujours copier cette routine dans un module USER et la modifier comme bon vous semble (dans ce cas faire aussi cela pour la routine LPID -> LUSER pour la lecture des paramètres)