RPID.py 3.1 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596
  1. from utils import *
  2. REWARD_MIN = 0
  3. REWARD_MAX = 1000
  4. class RPID:
  5. def __init__(self, kp=0, ki=0, kd=0, dt=1, target=15, Kc=0, Ti=0, Td=0, Ts=0, debug=False):
  6. self.Kp = kp # discrete pid kp
  7. self.Ki = ki # discrete pid ki
  8. self.Kd = kd # discrete pid kd
  9. self.T = dt # discrete pid frequency time.
  10. self.Ti = Ti # takahashi ti
  11. self.Td = Td # takahashi td
  12. self.Ts = Ts # takahashi ts
  13. self.Kc = Kc # takahashi kc
  14. self.target = target # pid set point
  15. self.prev_feedback = 0
  16. self.feedback_hist = [0, 0]
  17. self.f_hist = [0]
  18. self.error_hist = [0, 0]
  19. self.debug=debug
  20. def discrete_pid(self, feedback, debug=True):
  21. k1 = self.Kp + self.Ki + self.Kd
  22. k2 = -1 * self.Kp - 2 * self.Kd
  23. k3 = self.Kd
  24. err = self.proportional(feedback)
  25. ret = self.f_hist[-1] + k1 * err + k2 * self.error_hist[-1] + k3 * self.error_hist[-2]
  26. self.error_hist+=[err]
  27. self.feedback_hist+=[feedback]
  28. return ret
  29. def takahashi(self, feedback, debug=True):
  30. err = self.proportional(feedback)
  31. ret = self.f_hist[-1] + self.Kc * (self.feedback_hist[-1] - feedback + self.Ts * err/ self.Ti + self.Td / self.Ts * (2*self.feedback_hist[-1] - feedback - self.feedback_hist[-2]))
  32. self.error_hist+=[err]
  33. self.feedback_hist+=[feedback]
  34. return ret
  35. def pid_clipped(self, feedback, controller=CONTROLLER_TYPE_DISCRETE, debug=True):
  36. pid_value = None
  37. if controller == CONTROLLER_TYPE_TAKAHASHI:
  38. pid_value = self.takahashi(feedback, debug)
  39. elif controller == CONTROLLER_TYPE_DISCRETE:
  40. pid_value = self.discrete_pid(feedback, debug)
  41. else:
  42. pid_value = self.pid(feedback)
  43. if pid_value <= 0.0:
  44. pid_value = REWARD_MIN
  45. elif pid_value >= 1:
  46. pid_value = REWARD_MAX
  47. self.f_hist+=[pid_value]
  48. return pid_value
  49. def error(self, feedback):
  50. return feedback - self.target
  51. def proportional(self, feedback):
  52. return self.error(feedback)
  53. def integral(self, feedback):
  54. return sum(self.feedback_hist[-10:]) + feedback
  55. def derivative(self, feedback):
  56. return (self.error(self.prev_feedback) - self.error(feedback)) / self.T
  57. def write_feedback(self, lead_hist_file):
  58. if len(self.feedback_hist)==0:
  59. return
  60. buf = ''
  61. buf+=str(self.feedback_hist[0])
  62. buf+=','
  63. for i in self.feedback_hist[1:]:
  64. buf+=str(i)+','
  65. with open(lead_hist_file, "w+") as f:
  66. f.write(buf)
  67. def write_fval(self, f_hist_file):
  68. if len(self.f_hist)==0:
  69. return
  70. buf = ''
  71. buf+=str(self.f_hist[0])
  72. buf+=','
  73. for i in self.f_hist[1:]:
  74. buf+=str(i)+','
  75. with open(f_hist_file, "w+") as f:
  76. f.write(buf)
  77. def write(self, lead_hist_file='leads.hist', f_hist_file='f.hist'):
  78. self.write_feedback(lead_hist_file)
  79. self.write_fval(f_hist_file)
  80. def acc(self):
  81. return sum(np.array(self.feedback_hist)==1)/float(len(self.feedback_hist))