pid.c 3.0 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122
  1. /*********************************************************************
  2. *
  3. * pid library for Fraise pic18f device
  4. *
  5. * -pid regulator with maximum output setting
  6. * and anti-windup tracking gain
  7. *********************************************************************
  8. * Author Date Comment
  9. *~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
  10. * Antoine Rousseau dec 2012 Original.
  11. ********************************************************************/
  12. /*
  13. # This program is free software; you can redistribute it and/or
  14. # modify it under the terms of the GNU General Public License
  15. # as published by the Free Software Foundation; either version 2
  16. # of the License, or (at your option) any later version.
  17. #
  18. # This program is distributed in the hope that it will be useful,
  19. # but WITHOUT ANY WARRANTY; without even the implied warranty of
  20. # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
  21. # GNU General Public License for more details.
  22. # You should have received a copy of the GNU General Public License
  23. # along with this program; if not, write to the Free Software
  24. # Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston,
  25. # MA 02110-1301, USA.
  26. */
  27. /*#include <stdlib.h>
  28. #include <stdio.h>
  29. #include <string.h>*/
  30. /*#include <core.h>
  31. #include <fraisedevice.h>
  32. #include <eeparams.h>*/
  33. #include "pid.h"
  34. void pidInit(t_pid *Pid)
  35. {
  36. Pid->Out=0;
  37. Pid->Last=Pid->Int=0;
  38. Pid->GainP=Pid->GainI=Pid->GainD=0;
  39. //Pid->MaxOut=
  40. }
  41. void pidCompute(t_pid *Pid,int err)
  42. {
  43. static t_pid P;
  44. #define MAXINT (1L<<26) // maximum value for integration sum
  45. #define MAXDELTA (1L<<16) // maximum value for diff term
  46. static long out,maxout,delta;
  47. memcpy(&P,Pid,sizeof(P));
  48. maxout=(long)P.MaxOut<<8;
  49. out = (long)err*P.GainP;
  50. if(P.GainI) {
  51. if( ((err>0)&&(P.Int<MAXINT)&&(P.Out<maxout)) || ((err<0)&&(P.Int>(-MAXINT))&&(P.Out>-maxout)) )
  52. P.Int += err; // clip P.Int to [-MAXINT-|err|,MAXINT+|err|] ; don't increase if Output is already saturated (anti-windup)
  53. out+=(P.Int>>4)*P.GainI;
  54. }
  55. if(P.GainD) {
  56. delta=((long)err-P.Last);
  57. if(delta>=MAXDELTA) delta=MAXDELTA-1;
  58. else if(delta<-MAXDELTA) delta=-MAXDELTA;
  59. out+=(delta<<7)*P.GainD;
  60. }
  61. P.Last = err ;
  62. // clipping :
  63. if(out>maxout) P.Out=maxout;
  64. else if(out<-maxout) P.Out=-maxout;
  65. else P.Out = out;
  66. memcpy(Pid,&P,sizeof(P));
  67. }
  68. void pidDeclareEE(t_pid *Pid)
  69. {
  70. EEdeclareChar(&Pid->GainP);
  71. EEdeclareChar(&Pid->GainI);
  72. EEdeclareChar(&Pid->GainD);
  73. EEdeclareInt(&Pid->MaxOut);
  74. }
  75. void pidInput(t_pid *Pid)
  76. {
  77. unsigned char c,c2;
  78. unsigned int i = 0;
  79. c=fraiseGetChar();
  80. if(c == 254) {
  81. fraiseSendCopy();
  82. c2=fraiseGetChar();
  83. switch(c2) {
  84. GETPARAM(0, Pid->GainP, i);
  85. GETPARAM(1, Pid->GainI, i);
  86. GETPARAM(2, Pid->GainD, i);
  87. GETPARAM(3, Pid->MaxOut, i);
  88. }
  89. printf("%d %d\n", c2, i);
  90. }
  91. else switch(c) {
  92. PARAM_CHAR(0, Pid->GainP); break;
  93. PARAM_CHAR(1, Pid->GainI); if(Pid->GainI == 0) Pid->Int = 0; break;
  94. PARAM_CHAR(2, Pid->GainD); break;
  95. PARAM_INT(3, Pid->MaxOut); break;
  96. }
  97. }