Advertisement
Guest User

pid

a guest
May 25th, 2019
116
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
text 5.22 KB | None | 0 0
  1. from datetime import datetime
  2. import rospy
  3.  
  4.  
  5. class PID:
  6. """
  7. This class implements a simple PID control algorithm.
  8. """
  9.  
  10. def __init__(self, kp=0, ki=0, kd=0, lim_high=float("inf"), lim_low=-float("inf")):
  11. """
  12. Initializes PID gains (proportional - kp, integral - ki, derivative - kd) and control values to zero.
  13. """
  14.  
  15. # initialize gains
  16. self.kp = kp # proportional gain
  17. self.ki = ki # integral gain
  18. self.kd = kd # derivative gain
  19.  
  20. # initialize control values
  21. self.up = 0 # P part
  22. self.ui = 0 # I part
  23. self.ui_old = 0 # I part from previous step
  24. self.ud = 0 # D part
  25. self.u = 0 # total control value
  26. self.lim_high = lim_high # control value upper limit
  27. self.lim_low = lim_low # control value lower limit
  28.  
  29. # init referent control value (set-value)
  30. self.ref = 0
  31.  
  32. # init measure control value
  33. self.meas = 0
  34.  
  35. # init time stamp of the previous algorithm step
  36. self.t_old = datetime.now()
  37.  
  38. self.dt = 0
  39.  
  40. # init error from the previous algorithm step
  41. self.error_old = 0
  42.  
  43. # flag indicates first step of the algorithm
  44. self.firstPass = True
  45.  
  46. # ros message formed when create_msg method is called
  47.  
  48. def reset(self):
  49. ''' Resets pid algorithm by setting all P,I,D parts to zero'''
  50. self.up = 0
  51. self.ui = 0
  52. self.ui_old = 0
  53. self.ud = 0
  54. self.u = 0
  55. self.t_old = datetime.now()
  56.  
  57. def set_kp(self, invar):
  58. """ Set proportional gain. """
  59. self.kp = invar
  60.  
  61. def get_kp(self):
  62. """Returns proportional gain"""
  63. return self.kp
  64.  
  65. def set_ki(self, invar):
  66. """ Set integral gain. """
  67. self.ki = invar
  68.  
  69. def get_ki(self):
  70. """Returns integral gain"""
  71. return self.ki
  72.  
  73. def set_kd(self, invar):
  74. """ Set derivative gain. """
  75. self.kd = invar
  76.  
  77. def get_kd(self):
  78. """Returns derivative gain"""
  79. return self.kd
  80.  
  81. def set_lim_high(self, invar):
  82. """Set PID upper limit value"""
  83. self.lim_high = invar
  84.  
  85. def get_lim_high(self):
  86. """Returns PID upper limit value"""
  87. return self.lim_high
  88.  
  89. def set_lim_low(self, invar):
  90. """Set PID lower limit value"""
  91. self.lim_low = invar
  92.  
  93. def get_lim_low(self):
  94. """Returns PID lower limit value"""
  95. return self.lim_low
  96.  
  97. def compute(self, ref, meas, dt):
  98. '''
  99. Performs a PID computation and returns a control value based on
  100. the elapsed time (dt) and the error signal.
  101. :param ref: referent value
  102. :param meas: measured value
  103. :return: control value
  104. '''
  105.  
  106. self.ref = ref
  107. self.meas = meas
  108.  
  109. if self.firstPass:
  110. # This is the first step of the algorithm
  111. # Init time stamp and error
  112. #self.t_old = rospy.Time.now()
  113. self.error_old = ref - meas
  114. self.firstPass = False
  115. return self.u # initialized to zero
  116. else:
  117. ##############################################
  118. ##############################################
  119. # Add your code here
  120. # You should compute elapsed time from the previous step (dt, in seconds),
  121. # compute proportional part (self.up),
  122. # compute integral part (self.ui),
  123. # compute derivative part (self.ud),
  124. # compute total control value (self.u),
  125. # implement saturation function and antiwind-up,
  126. #t = rospy.Time.now()
  127. #self.dt = (t - self.t_old).to_sec()
  128. self.ref = ref
  129. self.meas = meas
  130. error = ref - meas
  131.  
  132. de = error - self.error_old # diff error
  133. self.up = self.kp * error # proportional term
  134.  
  135. if self.ki == 0:
  136. self.ui = 0
  137. else:
  138. self.ui = self.ui_old + self.ki * error * dt # integral term
  139.  
  140. self.ud = self.kd * de / dt # derivative term
  141.  
  142. self.u = self.up + self.ui + self.ud
  143.  
  144. if self.u > self.lim_high:
  145. self.u = self.lim_high
  146. self.ui = self.ui_old # antiwind up
  147. elif self.u < self.lim_low:
  148. self.u = self.lim_low
  149. self.ui = self.ui_old # antiwind up
  150.  
  151. self.ui_old = self.ui # save ui for next step
  152. #self.t_old = t # save t for next step
  153. self.error_old = error
  154.  
  155. # End of added code
  156. ###############################################
  157. ###############################################
  158.  
  159. return self.u
  160.  
  161. def get_pid_values(self):
  162. """ Returns P, I, D components and total control value
  163. """
  164. return [self.up, self.ui, self.ud, self.u]
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement