PID -Funktion entspricht von Matlab zu Python

Post a reply

Smilies
:) :( :oops: :chelo: :roll: :wink: :muza: :sorry: :angel: :read: *x) :clever:
View more smilies

BBCode is ON
[img] is ON
[flash] is OFF
[url] is ON
Smilies are ON

Topic review
   

Expand view Topic review: PID -Funktion entspricht von Matlab zu Python

by Anonymous » 18 Aug 2025, 03:41

Ich schafft es, eine geschlossene Schleife mit Simulink mit der reinen Python "Control" -Bibliothek korrekt zu simulieren. Ich versuche jetzt jedoch, dasselbe mit einer neuen geschlossenen Schleife zu tun, in der ein PID-Controller verwendet wird: < /p>

Code: Select all

import numpy as np
import control as ctl

def nuclear_params(array=[0.0001889, 0, -1.289, 0.2891]):
num = array[:2]
den = [1.0] + array[2:]
ref_start = 0
ref_value = 6.6
steps = 700
timestep = 0.5
Kp, Ki, Kd = 348.52, 17.25, 10.79
return simulation_nuclear(
Kp, Ki, Kd, num, den, ref_start, ref_value, timestep, steps
)

def simulation_nuclear(
Kp, Ki, Kd, num_plant, den_plant, ref_start, ref_value, timestep=0.5, steps=700
):
Ts = timestep

Gc = pid_discrete(Kp, Ki, Kd, Ts, N=1000)
Gp = ctl.TransferFunction(num_plant, den_plant, Ts)

fdback = ctl.feedback(Gc * Gp, 1)

# Time vector and input reference step
t = np.linspace(0, steps, int(round(steps / Ts)) + 1)
ref = np.ones_like(t) * ref_value

# System response
t_out, y_out = ctl.forced_response(fdback, T=t, U=ref)

# Retrieve control output
e = ref - y_out
_, u_m = ctl.forced_response(Gc, T=t, U=e)

return t_out, y_out, u_m
< /code>
mit u_m gibt: < /p>
4610.50075588, 4022.47644969, 3334.11898869, 2705.64516918, 2175.79419241, 1743.04805239
< /code>
Das Hauptproblem ist nun, dass die Kontrollausgabe mehr oder weniger doppelt so hoch ist, dass MATLAB: < /p>
gibt2327.93749436396, 2267.04211542563, 2134.18318770832, 1995.12935675866, 1854.49534374506,
Dieses Ergebnis ist höchstwahrscheinlich der Fehler der PID-Approximationsfunktion PID_DISCRETE , der das kontinuierliche in diskretes Umwandler umwandelt und das beste Ergebnis für den Moment ergibt.

Code: Select all

def pid_continuous(Kp, Ki, Kd, N=1000):
Ti = Kp / Ki
Td = Kd / Kp
s = ctl.TransferFunction.s
Gc = Kp * (1 + 1 / (Ti * s) + (Td * N * s) / (1 + Td * N * s))
return Gc

def pid_discrete(Kp, Ki, Kd, Ts, N=1000, method="tustin"):
Gc_s = pid_continuous(Kp, Ki, Kd, N=N)
return ctl.sample_system(Gc_s, Ts, method=method)

def pid_forward_euler(Kp, Ki, Kd, Ts, N=1000):
z = ctl.TransferFunction.z
if z is None:
raise ValueError("Cannot create z-domain transfer function")
# Forward Euler integrator: IF(z) = Ts*z/(z-1)
integrator = Ts * (z / (z - 1))
# Forward Euler derivative with filter:
# Derivative term: Kd * N * (z-1) / (z + N*Ts - 1)
derivative = (Kd * N * (z - 1)) / (z + N * Ts - 1)
# Parallel form: Kp + Ki*integrator + derivative
pid_controller = Kp + Ki * integrator + derivative

return pid_controller

def pid_backward_euler(Kp, Ki, Kd, Ts, N=1000):
z = ctl.TransferFunction.z
if z is None:
raise ValueError("Cannot create z-domain transfer function")
# Backward Euler integrator: IF(z) = Ts/(z-1)
integrator = Ts / (z - 1)
# Backward Euler derivative with filter
derivative = Kd * N * (z - 1) / (z - 1 + N * Ts)
pid_controller = Kp + Ki * integrator + derivative
return pid_controller

def pid_trapezoidal(Kp, Ki, Kd, Ts, N=1000):
z = ctl.TransferFunction.z
if z is None:
raise ValueError("Cannot create z-domain transfer function")

# Trapezoidal integrator: IF(z) = Ts*(z+1)/(2*(z-1))
integrator = Ts * (z + 1) / (2 * (z - 1))
# Trapezoidal derivative with filter
# This is more complex for trapezoidal - simplified version:
derivative = Kd * 2 * N / (2 + N * Ts) * (z - 1) / z
pid_controller = Kp + Ki * integrator + derivative
return pid_controller
< /code>
Ausgesehen von PID_DISCREete explodieren alle anderen Funktionen entweder oder geben einen Fehler an. Meine Frage ist: Es gibt eine Arbeitsinformation einer PID -Funktion mit Python 
+ Steuerungsbibliothek ?

Top