1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146
| !pip install numpy matplotlib import numpy as np import matplotlib.pyplot as plt
class PID: def __init__(self,Kp,Ki,Kd,setpoint=0,sample_time=0.01,output_limit=100.0): self.Kp = Kp self.Ki = Ki self.Kd = Kd self.setpoint = setpoint self.sample_time = sample_time self.output_limit = output_limit
self.pre_error = 0 self.integral = 0 self.integral_limit = output_limit / Ki if Ki > 0 else 0 def update(self,measured_value): error = self.setpoint - measured_value
self.integral += error *self.sample_time
if self.integral_limit > 0: self.integral = max(-self.integral_limit,min(self.integral_limit,self.integral))
derivative = (error - self.pre_error) / self.sample_time
output = self.Kp * error + self.Ki * self.integral + self.Kd * derivative
self.pre_error = error
output = max(-self.output_limit,min(self.output_limit,output))
return output
class MotorSystem: def __init__(self,initial_angle=0.0,inertia=1.0,damping=0.5,load_torque=0.0): self.angle = initial_angle self.velocity = 0.0 self.inertia = inertia self.damping = damping self.load_torque = load_torque
def step(self,control_torque,dt): net_torque = control_torque - self.damping * self.velocity - self.load_torque acceleration = net_torque / self.inertia self.velocity += acceleration * dt self.angle += self.velocity * dt return self.angle
def run_simulation(Kp,Ki,Kd,setpoint,simulation_time=5.0,load=0.0): dt = 0.01 simulation_time = 25.0 num_steps = int(simulation_time / dt)
motor = MotorSystem(initial_angle = 0.0,load_torque=load) pid = PID(Kp,Ki,Kd,setpoint = setpoint,sample_time=dt,output_limit=100.0) time_history = [] angle_history = []
for i in range(num_steps): t = i*dt
control_torque = pid.update(motor.angle)
current_angle = motor.step(control_torque,dt)
time_history.append(t) angle_history.append(current_angle)
return time_history,angle_history
SETPOINT = 90.0
LOAD_TORQUE = 1.0
Kp1, Ki1, Kd1 = 1.0, 0.0, 0.0 time1, angle1 = run_simulation(Kp1, Ki1, Kd1, SETPOINT, load=LOAD_TORQUE)
Kp2, Ki2, Kd2 = 1.0, 0.1, 0.0 time2, angle2 = run_simulation(Kp2, Ki2, Kd2, SETPOINT, load=LOAD_TORQUE)
Kp3, Ki3, Kd3 = 1.0, 0.1, 0.5 time3, angle3 = run_simulation(Kp3, Ki3, Kd3, SETPOINT, load=LOAD_TORQUE)
plt.figure(figsize=(12, 6))
plt.plot(time1, angle1, label=f'P Only (Kp={Kp1})', linestyle='--') plt.plot(time2, angle2, label=f'PI Control (Kp={Kp2}, Ki={Ki2})', linestyle='-.') plt.plot(time3, angle3, label=f'PID Control (Kp={Kp3}, Ki={Ki3}, Kd={Kd3})', linestyle='-')
plt.axhline(SETPOINT, color='r', linestyle=':', label='Set Point')
plt.title(f'PID Control System Response (Load: {LOAD_TORQUE} N·m)') plt.xlabel('Time (s)') plt.ylabel('Angle (degrees)') plt.legend() plt.grid(True) plt.show()
|