simulazione Python PID

voti
2

Sto cercando di capire come simulare un sistema di controllo in python. Questo è quello che ho finora:

PID.py - funzioni per impostare Kp, Ki, Kd, ​​e una funzione per generare un'uscita basata su un errore. ex. PID.genout (err)

PIDPlot.py - traccia l'output sulla base di un ingresso a gradino. ecco un esempio del codice:

for i in range(1, 51):

    # summing node
    err = sp - fb

    # PID block
    outv = pid.GenOut(err)

    # control feedback
    if sp > 0:
        fb += (outv - (1.0/i))

    # start with sp = 0, simulate a step input at t(10)
    if i > 5:
        sp = 10

    # add sp and outv to there lists
    sp_list.append(sp)
    fb_list.append(fb)
    sample_list.append(i * .05)



    time.sleep(.05)

Vorrei cambiare la parte che controlla il feedback in modo che modella il mio sistema (Pianta) più da vicino, ma che è dove mi si blocca. Decisi la funzione di trasferimento del sistema (impianto) applicando un passo e registrare i dati trasmessi e plotting esso. Sulla base della curva, guadagno in continua e costante di tempo sono arrivato fino a 0.92 / 16s +1 per la funzione di trasferimento. Quando ho tracciare la risposta al gradino in Python in questo modo:

from numpy import min, max
from scipy import linspace
from scipy.signal import lti, step

# making transfer function
# example from Ogata Modern Control Engineering 
# 4th edition, International Edition page 307

# num and den, can be list or numpy array type
num = [-0.93] 

#denominator of the form s^2 + s +1
den = [16, 1]

tf = lti(num, den)

# get t = time, s = unit-step response
t, s = step(tf)

# recalculate t and s to get smooth plot
t, s = step(tf, T = linspace(min(t), t[-1], 500))

# get i = impulse
#t, i = impulse(tf, T = linspace(min(t), t[-1], 500))

from matplotlib import pyplot as plt

#plt.plot(t, s, t, i)
plt.plot(t, s)
plt.title('Transient-Response Analysis')
plt.xlabel('Time(sec)')
plt.ylabel('Amplitude')
plt.hlines(1, min(t), max(t), colors='r')
plt.hlines(0, min(t), max(t))
plt.xlim(xmax=max(t))
plt.legend(('Unit-Step Response',), loc=0)
plt.grid()
plt.show()

Si abbina i miei dati tracciati bene. Ora come posso usare questa funzione di trasferimento per generare il feedback nella PIDPlot? Poi da lì posso provare a scrivere il codice per la sintonizzazione automatica del PID basato sul sistema (impianto).

È pubblicato 24/05/2013 alle 11:57
dall'utente
In altre lingue...                            


1 risposte

voti
-1
  1. Genera le valutazioni in PIDPlot non ho visto la funzione di trasferimento nel codice, potrebbe mostrarmi?

  2. Se si desidera sintonizzare il PID e trovare la migliore Kp, Ki, Kd per il sistema DC, è necessario premuroso quei calci, i cambiamenti nel grafico. È necessario controllare dinamicamente le costanti PID, che significa che è necessario metodi.

Ecco un utilissimo blog parlando di messa a punto del PID in Python. Ho scritto un algoritmo di controllo PID prima e prendere qualche idea da questo blog, è molto utile.

http://brettbeauregard.com/blog/2011/04/improving-the-beginner%E2%80%99s-pid-tuning-changes/

/*working variables*/
unsigned long lastTime;
double Input, Output, Setpoint;
double ITerm, lastInput;
double kp, ki, kd;
int SampleTime = 1000; //1 sec
void Compute()
{
   unsigned long now = millis();
   int timeChange = (now - lastTime);
   if(timeChange>=SampleTime)
   {
      /*Compute all the working error variables*/
      double error = Setpoint - Input;
      ITerm += (ki * error);
      double dInput = (Input - lastInput);

      /*Compute PID Output*/
      Output = kp * error + ITerm - kd * dInput;

      /*Remember some variables for next time*/
      lastInput = Input;
      lastTime = now;
   }
}

void SetTunings(double Kp, double Ki, double Kd)
{
  double SampleTimeInSec = ((double)SampleTime)/1000;
   kp = Kp;
   ki = Ki * SampleTimeInSec;
   kd = Kd / SampleTimeInSec;
}

void SetSampleTime(int NewSampleTime)
{
   if (NewSampleTime > 0)
   {
      double ratio  = (double)NewSampleTime
                      / (double)SampleTime;
      ki *= ratio;
      kd /= ratio;
      SampleTime = (unsigned long)NewSampleTime;
   }
}

Spero che questo aiuterebbe.

Risposto il 21/05/2015 a 13:39
fonte dall'utente

Cookies help us deliver our services. By using our services, you agree to our use of cookies. Learn more