fork download
  1. import numpy as np
  2. import matplotlib.pyplot as plt
  3.  
  4. # 自適應 PID 結構模擬
  5. class AdaptivePID:
  6. def __init__(self, Kp, Ki, Kd, output_limit, integral_limit, max_error, max_derivative):
  7. self.Kp_base = Kp
  8. self.Ki_base = Ki
  9. self.Kd_base = Kd
  10. self.output_limit = output_limit
  11. self.integral_limit = integral_limit
  12. self.max_error = max_error
  13. self.max_derivative = max_derivative
  14. self.integral = 0.0
  15. self.prev_error = 0.0
  16.  
  17. def compute(self, error, dt):
  18. if dt <= 0.0001:
  19. dt = 0.001
  20.  
  21. derivative = (error - self.prev_error) / dt
  22. error_ratio = min(1.0, abs(error) / self.max_error)
  23. derivative_ratio = min(1.0, abs(derivative) / self.max_derivative)
  24.  
  25. Kp = self.Kp_base * error_ratio
  26. Kd = self.Kd_base * derivative_ratio
  27. Ki = self.Ki_base if abs(error) < (self.max_error * 0.3) else 0.0
  28.  
  29. self.integral += error * dt
  30. self.integral = max(min(self.integral, self.integral_limit), -self.integral_limit)
  31.  
  32. output = Kp * error + Ki * self.integral + Kd * derivative
  33. output = max(min(output, self.output_limit), -self.output_limit)
  34.  
  35. self.prev_error = error
  36. return output
  37.  
  38. # 初始化 PID
  39. pid = AdaptivePID(Kp=1.0, Ki=0.02, Kd=0.1, output_limit=120.0,
  40. integral_limit=50.0, max_error=12.0, max_derivative=5.0)
  41.  
  42. # 模擬範圍 -12 ~ 12 mm 誤差
  43. errors = np.linspace(-12, 12, 200)
  44. dt = 0.02 # 模擬每筆的時間差
  45. outputs = [pid.compute(e, dt) for e in errors]
  46.  
  47. # 畫圖
  48. plt.figure(figsize=(10, 5))
  49. plt.plot(errors, outputs, label="RPM Output")
  50. plt.axhline(120, color='red', linestyle='--', linewidth=0.5, label="RPM Limit (+120)")
  51. plt.axhline(-120, color='blue', linestyle='--', linewidth=0.5, label="RPM Limit (-120)")
  52. plt.title("Adaptive PID: Error vs RPM Output")
  53. plt.xlabel("Position Error (mm)")
  54. plt.ylabel("RPM Output")
  55. plt.grid(True)
  56. plt.legend()
  57. plt.tight_layout()
  58. plt.show()
  59.  
Success #stdin #stdout #stderr 3.46s 71680KB
stdin
Standard input is empty
stdout
Standard output is empty
stderr
Fontconfig error: No writable cache directories