Advertisement
Guest User

PID.py

a guest
Nov 16th, 2018
118
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
text 2.93 KB | None | 0 0
  1. import datetime
  2. import csv
  3. import numpy as np
  4.  
  5.  
  6. class PID(object):
  7.  
  8. def __init__(self, pwm, i2c, v_max, v_min, KP=600, KI=0.001, KD=10):
  9. self.pwm = pwm
  10. self.i2c = i2c
  11. self.v_max = v_max
  12. self.v_min = v_min
  13. self.KP = KP # made these initialized variables so GA can work with PID
  14. self.KI = KI
  15. self.KD = KD
  16.  
  17. def force_normaliser(self, location, G):
  18. '''As the attractive force depends on the distance from the magnet, the force should be normalised to compensate.
  19. The force of the electromagnet is dependent on the square of the distance the maximum current should be proportional to the max distance
  20. '''
  21.  
  22. #checking the reading for errors
  23. if location < self.v_min - 0.5:
  24. raise ValueError(location, self.v_min, 'position read as above the maximum value, probably problem with light source.')
  25. operation_range = self.v_max - self.v_min
  26. #top location is v_min, bottom location is v_max (because a higher position means a larger shadow on the PV cell.)
  27. normalised_distance_from_top = (location - self.v_min) / operation_range
  28. if normalised_distance_from_top > 1.5:
  29. raise ValueError(normalised_distance_from_top, 'NDFT is greater than 1')
  30. elif normalised_distance_from_top > 1:
  31. normalised_distance_from_top = 1
  32. force = G * normalised_distance_from_top ** 2
  33. self.pwm.DC(force)
  34.  
  35. def position(self, position):
  36. target_position = position
  37. i = 0
  38. error_past = 0
  39. Integral = 0
  40. location = np.zeros(1000) # for csv data -> will have 1000 datapoints per chromosome
  41. G = 0
  42. peak_limit = 100
  43.  
  44. current_position = self.i2c.getVoltage()
  45. location[i] = current_position
  46.  
  47. while ((current_position > self.v_min) and (i > 3)) and (current_position < self.v_max): # i > 3 ensures code doesn't stop at the start
  48. try:
  49. current_position = self.i2c.getVoltage()
  50. location[i] = current_position
  51. error = (current_position - target_position)/ target_position
  52.  
  53. V = error - error_past
  54. D = self.KD * V
  55.  
  56. P = error * self.KP
  57. if G != peak_limit:
  58. Integral += error
  59. I = Integral * self.KI
  60.  
  61. G = P + I + D
  62.  
  63. if G > peak_limit:
  64. G = peak_limit
  65. elif G < 0:
  66. G = 0
  67.  
  68. self.force_normaliser(location[i], G)
  69.  
  70. i +=1
  71. error = error_past
  72. except Exception as e: # predicting an error if it lasts more than 1000 cycles
  73. print(e)
  74.  
  75. return location
  76.  
  77. # KP = 600 # Emil's PID parameter values... should probably keep these just in case!
  78. # KI = 0.001
  79. # KD = 10
  80.  
  81.  
  82.  
  83.  
  84. # length = np.transpose(np.linspace(0,999,1000))
  85. # location = np.transpose(location)
  86. # myData = [length, location]
  87. # date = datetime.datetime.now().strftime("%H-%M-%S-%B-%d-%Y")
  88. # filename = './logs/PID-Response-' + date +'.csv'
  89. # myFile = open(filename, 'w')
  90. # with myFile:
  91. # writer = csv.writer(myFile)
  92. # writer.writerows(myData)
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement