Salta ai contenuti

PID senza formalismo pesante

Il controllore PID somma tre letture dello stesso errore — presente, passato, tendenza futura — e con quelle tre sole quantità governa la maggior parte degli anelli di controllo costruiti dall’uomo. Questo capitolo lo costruisce un termine alla volta, ne mostra i guasti tipici, e lo usa come modello pulito di “controllore con memoria limitata”.


Un timoniere esperto, alla ruota di una nave, non sterza guardando solo quanto la prua è fuori rotta in questo istante. Tiene conto anche del fatto che la prua è rimasta a sinistra della rotta per un po’ — e che quindi c’è un vento o una corrente da contrastare — e di quanto in fretta la prua sta girando in questo momento, per non sterzare troppo e ritrovarsi fuori rotta dall’altra parte.

Nel 1922 un ingegnere russo-americano osservò esattamente questo, lo mise in equazione, e così facendo descrisse per la prima volta il controllore che oggi governa quasi ogni anello di controllo costruito dall’uomo. Quel controllore si chiama PID, e quelle tre cose che il timoniere fa senza pensarci — guardare l’errore di adesso, l’errore accumulato, la velocità con cui l’errore cambia — sono i suoi tre termini.

Il capitolo precedente di questa Parte, controllare un sistema, ha lasciato un buco preciso. L’Esempio 1 di quel capitolo mostrava un termostato governato da un controllore proporzionale — eroga potenza in proporzione a quanto la temperatura è lontana dal setpoint — e mostrava che quel controllore, da solo, non raggiunge mai il bersaglio: la stanza si assesta a 18 gradi invece di 20, con un errore residuo permanente. Quel residuo ha un nome, errore a regime (o offset), e il PID nasce, tra l’altro, per cancellarlo.

Per chi costruisce sistemi questo conta per due ragioni. La prima è diretta: anelli di controllo con la forma del PID compaiono nel software molto più spesso di quanto si dica — un autoscaler, un rate limiter adattivo, un controllo di budget sono, strutturalmente, controllori a feedback, e capire il PID significa avere il vocabolario per progettarli senza tararli a sensazione. La seconda è concettuale: il PID è l’esempio più pulito che esista di un controllore con memoria limitata, un dispositivo che decide la prossima azione tenendo uno stato minimo. I suoi tre termini si leggono come tre orizzonti temporali — passato, presente, futuro previsto — e quella griglia è utile ben oltre il controllo industriale.

C’è anche una ragione di igiene mentale. Il PID è uno di quei concetti che sembrano banali finché non si guarda da vicino — “somma tre numeri, cosa vuoi che sia” — e che invece nascondono un repertorio di guasti caratteristici: l’errore residuo che non se ne va, l’integrale che si gonfia e produce un overshoot lungo, il termine derivativo che impazzisce su un sensore rumoroso, la corsa al guadagno che porta all’instabilità di colpo. Conoscere questi guasti per nome significa riconoscerli quando ricompaiono — e ricompaiono, sotto altre vesti, in sistemi che non hanno nulla a che fare con bruciatori e timoni. Il valore di studiare il PID non è solo saper tarare un bruciatore: è acquisire un catalogo di patologie del feedback che si ritrovano ovunque ci sia un anello.

Questo capitolo, dunque, non punta a fare di chi legge un progettista di controllori — quello richiede i capitoli successivi della Parte e una buona dose di pratica. Punta a una cosa più modesta e più utile: rendere il PID leggibile. Dopo averlo letto, una frase come “l’autoscaler oscilla perché ha troppo guadagno e troppo ritardo”, o “quel controllo di budget va in windup quando la manopola satura”, dovrebbe suonare non come gergo ma come una diagnosi precisa, con una causa e una cura. È il salto da “il sistema si comporta male” a “il sistema ha questo guasto, noto, con questa contromisura, nota”.

Il PID si colloca subito a valle di control-theory-intro, che fissa il vocabolario su cui questo capitolo si appoggia: plant (il sistema da controllare), setpoint (il valore voluto), variabile controllata, variabile manipolata, errore, anello chiuso. Se quei termini non sono familiari, conviene leggere prima quel capitolo: qui sono dati per acquisiti.

A monte, sul versante della cibernetica, il PID è la concretizzazione di un’idea generale: l’anello a feedback negativo, in cui l’errore misurato torna indietro a guidare l’azione che lo riduce. La cibernetica dice che quell’anello governa i sistemi orientati a uno scopo; il PID dice, in concreto, quale azione produrre a partire dall’errore.

I dispositivi a retroazione precedono di gran lunga la loro teoria. Il regolatore centrifugo che James Watt monta sulla macchina a vapore nel 1788, il regolatore a galleggiante che Ktesibios di Alessandria costruisce intorno al 270 a.C. per gli orologi ad acqua: feedback incarnato nel ferro, senza una teoria. Il PID come legge di controllo a tre termini con un nome ha invece due date precise.

La prima è il 1922. Nicolas Minorsky (1885-1970), ingegnere e matematico russo-americano al servizio della marina degli Stati Uniti, pubblica Directional Stability of Automatically Steered Bodies nel Journal of the American Society of Naval Engineers. Studiando come automatizzare il timone delle navi da guerra, Minorsky parte da un’osservazione: un timoniere umano esperto corregge la rotta in base a tre cose — l’errore di rotta presente, l’errore accumulato nel tempo recente, e la velocità con cui la prua sta girando. Le mette in equazione. È la prima formulazione teorica del controllo a tre termini, e uno dei primi testi formali di teoria del controllo in lingua inglese. Le prove furono condotte sulla corazzata USS New Mexico; il controllo a tre termini teneva la rotta meglio di un timoniere in carne e ossa.

La seconda data è il 1942. John G. Ziegler e Nathaniel B. Nichols, ingegneri della Taylor Instrument Companies, pubblicano Optimum Settings for Automatic Controllers (Transactions of the ASME, vol. 64). È il primo metodo sistematico ed empirico per tarare un PID — scegliere i suoi tre guadagni — a partire da semplici prove sul processo, senza disporre di un modello matematico del plant. Resta a tutt’oggi il punto di partenza didattico della taratura.

Tra gli anni Trenta e Quaranta il PID si diffonde nell’industria di processo — raffinerie, chimica, cartiere — prima come strumento pneumatico, poi elettronico, poi digitale. Oggi è un blocco standard in praticamente ogni PLC e DCS, i calcolatori industriali che governano gli impianti. Stime ricorrenti nella letteratura di control engineering collocano oltre il 90% degli anelli di controllo industriali su un PID o una sua variante più semplice. Nessun altro controllore si avvicina a questa diffusione: è la ragione per cui un capitolo solo sul PID ha senso.

Vale la pena soffermarsi sull’osservazione da cui Minorsky parte, perché contiene già, in nuce, i tre termini, e nessun formalismo.

Un timoniere alle prime armi sterza nel modo più ovvio: guarda di quanto la prua è fuori rotta e gira la ruota in proporzione. È il termine proporzionale, e da solo non basta. Con un vento laterale costante, il timoniere alle prime armi tiene una rotta che è sempre un po’ sottovento rispetto a quella voluta — perché per contrastare il vento serve un timone leggermente girato in permanenza, e con la sola regola proporzionale un timone girato richiede un errore di rotta che resta. La nave viaggia parallela alla rotta giusta, ma spostata. È l’offset, sul mare.

Un timoniere esperto fa due cose in più. La prima: si accorge che la prua è rimasta dalla stessa parte per un po’, deduce che c’è qualcosa di sistematico da contrastare — vento, corrente, un’asimmetria dello scafo — e aggiunge timone in modo cumulativo finché la rotta non torna esatta. È il termine integrale: l’errore che dura viene corretto in misura crescente. La seconda: guarda quanto in fretta la prua sta girando, e se sta rientrando verso la rotta troppo velocemente raddrizza il timone in anticipo, per non oltrepassare la rotta e ritrovarsi a zigzagare. È il termine derivativo.

Minorsky non inventò questo comportamento: lo trovò nel gesto di un buon timoniere e lo tradusse in equazioni. È il motivo per cui il PID, prima di essere una formula, è un modello di una competenza umana — e il motivo per cui le metafore di guida che useremo non sono decorazione, ma il terreno da cui la formula è nata.

Una nota sulla cronologia, per inquadrare il PID rispetto agli altri capitoli di questa Parte. Il PID nasce nel pieno del controllo classico, la fase della disciplina che — come ricostruisce control-theory-intro — si occupa di sistemi con un solo ingresso e una sola uscita e lavora prevalentemente con strumenti di analisi della risposta in frequenza. Minorsky (1922) precede di poco l’epoca d’oro dei Bell Labs, dove negli anni Trenta Harry Nyquist e Hendrik Bode costruiscono i criteri di stabilità che permettono di prevedere se un anello con un dato controllore oscillerà. Il PID è quindi un cittadino del controllo classico: semplice, adatto a problemi a un ingresso e un’uscita, tarabile senza un modello matematico del processo. Il controllo moderno — la rappresentazione in spazio di stato, i metodi di controllo ottimo, il filtro di Kalman, tutti dagli anni Sessanta in poi — non lo ha reso obsoleto. Lo ha affiancato: per un problema scalare ben posto il PID resta, ancora oggi, la scelta giusta, e i capitoli successivi della Parte aggiungono strumenti per i problemi che il PID non sa affrontare, non un suo sostituto.

Prima di qualsiasi formula, due modi distinti di vedere cosa fa un PID. Il primo è una griglia temporale; il secondo è una scena concreta. Sono lo stesso oggetto, e averli entrambi rende la formula quasi inevitabile.

Un PID guarda una sola quantità — l’errore, cioè la differenza tra dove vuoi essere e dove sei — ma la guarda su tre tempi diversi. Tre domande sullo stesso errore.

Il termine proporzionale guarda il presente. La sua domanda è: quanto sono lontano adesso? Se sei molto lontano dal bersaglio, spingi forte; se sei vicino, spingi piano. È una reazione istantanea, proporzionale alla distanza che ti separa dal bersaglio in questo momento.

Il termine integrale guarda il passato. La sua domanda è: da quanto tempo, e di quanto, sono stato lontano? Non gli interessa solo l’errore di adesso, ma l’errore accumulato — l’errore sommato istante dopo istante. Se sei stato un po’ fuori bersaglio per parecchio tempo, quella somma cresce, e il termine integrale spinge sempre di più finché l’errore non sparisce davvero.

Il termine derivativo guarda il futuro previsto. La sua domanda è: verso dove sto andando, e quanto in fretta? Non guarda quanto sei lontano, ma quanto rapidamente la distanza sta cambiando. Se ti stai avvicinando al bersaglio molto in fretta, il termine derivativo frena in anticipo — prima ancora di arrivarci — per non sfondarlo e ritrovarti dall’altra parte.

Presente, passato, futuro previsto. Tre letture dello stesso errore, e il PID le somma. Questa griglia non è solo un trucco mnemonico: è il filo che, alla fine del capitolo, collega il PID al modo in cui un agente software decide la prossima mossa.

Conviene fissare subito una conseguenza di questa lettura, perché spiega il carattere di ciascun termine. Il proporzionale, guardando solo il presente, è onesto ma miope: reagisce a ciò che c’è, niente di più, e per questo non sa che esiste un disturbo costante da contrastare — da qui l’offset. L’integrale, guardando il passato, è tenace ma lento: ci mette tempo ad accumulare abbastanza da contare, e una volta carico ci mette tempo a scaricarsi — da qui il ritardo che introduce e l’overshoot. Il derivativo, guardando la tendenza, è reattivo ma credulone: si fida della pendenza istantanea, e una pendenza istantanea su un segnale rumoroso è quasi tutta rumore — da qui la sua fragilità. Ogni termine ha la virtù e il vizio del suo orizzonte temporale. Il PID non è la somma di tre cose buone: è la somma di tre cose parziali, ciascuna con il suo difetto, scelte perché i loro difetti non si sovrappongono.

Ora una scena concreta. Stai guidando e vuoi tenere l’auto al centro della corsia. L’errore è quanto sei spostato dal centro.

Con il solo termine proporzionale, giri lo sterzo in proporzione a quanto sei fuori centro: molto spostato, sterzata decisa; poco spostato, sterzata leggera. Funziona, in parte. Ma immagina un vento laterale costante che spinge l’auto verso il bordo. Per contrastarlo serve uno sterzo costante, leggermente girato controvento. E qui c’è il problema: con il solo proporzionale, uno sterzo girato richiede un errore diverso da zero — perché lo sterzo è proporzionale all’errore. Risultato: ti assesti in equilibrio, ma spostato dal centro, non sopra il centro. Quel residuo è l’errore a regime, lo stesso del termostato a 18 gradi.

E qui si tocca con mano la trappola del guadagno. Verrebbe da pensare: alzo il guadagno proporzionale, sterzo più deciso per lo stesso scostamento, e l’auto resterà più vicina al centro. Vero, in parte: con un guadagno più alto basta uno scostamento minore per produrre lo sterzo controvento, quindi l’offset si riduce. Ma se continui ad alzarlo, l’auto comincia a reagire in modo brusco a ogni minima irregolarità della strada, sterzi e controsterzi, e a un certo punto l’auto serpeggia invece di tenere la corsia. Hai scambiato un piccolo offset stabile con un’oscillazione: un pessimo affare. Il proporzionale, da solo, ti mette di fronte a questa scelta senza via d’uscita — e sono l’integrale e il derivativo a offrire l’uscita.

Il termine integrale risolve esattamente questo. L’integrale nota: “sono rimasto a sinistra del centro per un po’”. Quella permanenza si accumula, e l’integrale aggiunge progressivamente sterzata controvento — continua ad aggiungerne finché non sei tornato esattamente al centro. A quel punto l’errore è zero, l’integrale smette di crescere, ma resta congelato sul valore di sterzo che serve a tenere testa al vento. L’integrale ha vinto il vento costante.

Il termine derivativo, infine, guarda la velocità con cui ti stai muovendo rispetto al centro. Se stai rientrando verso il centro molto rapidamente, il derivativo lo nota e raddrizzo lo sterzo in anticipo, prima che tu attraversi il centro a tutta velocità e finisca a oscillare da una parte all’altra della corsia. Il derivativo smorza.

Si può vedere la stessa scena al rovescio, guardando cosa succede senza ciascun termine. Senza il proporzionale non reagiresti affatto a quanto sei fuori centro: assurdo, è il cuore del controllo. Senza l’integrale terresti la corsia ma sempre un po’ spostato controvento, e quella deviazione non se ne andrebbe mai. Senza il derivativo, ogni volta che rientri verso il centro lo faresti senza frenare: lo attraverseresti slanciato, finiresti dall’altra parte, e per correggere ripartiresti slanciato di nuovo — uno zigzag che si smorza piano o, se sterzi forte, non si smorza affatto. I tre termini non sono ornamenti l’uno dell’altro: ciascuno copre un guasto che gli altri due non vedono.

Un’osservazione che chiude l’angolo. In questa scena tu sei il controllore, e quello che il PID fa è automatizzare un guidatore. Non un guidatore qualunque: un guidatore che ha sempre lo stesso umore — gli stessi tre guadagni — e che quindi reagisce in modo prevedibile e ripetibile. È sia un pregio (non si distrae, non si stanca, mille copie identiche) sia un limite (non si accorge che la strada è cambiata, continua a guidare con la stessa taratura su un’auto che nel frattempo ha le gomme lisce). Tutta la sezione sui limiti, più avanti, vive in questa tensione.

La stessa scena vale per la doccia di un vecchio appartamento, già usata nel capitolo introduttivo. Il proporzionale: giro la manopola in proporzione a quanto l’acqua è lontana dalla temperatura voluta. L’integrale: “è stata troppo fredda per un bel po’, continuo a girare verso il caldo finché non è giusta”. Il derivativo: “si sta scaldando in fretta, rallento la mano prima che scotti”. E la doccia insegna anche il lato oscuro del derivativo: tra il girare la manopola e il sentire l’acqua cambiare c’è un ritardo, e la temperatura percepita dalla pelle è un segnale rumoroso e impreciso. Un derivativo tarato male su un segnale così reagisce a fluttuazioni che non contano, e peggiora le cose invece di smorzarle.

C’è un terzo modo di tenere insieme i due angoli, più astratto, che torna utile a chi pensa in termini di software. Un PID è una funzione che riceve un solo numero in ingresso — l’errore — e produce un solo numero in uscita — l’azione — ma per farlo mantiene uno stato interno minimo: il valore dell’integrale accumulato fin qui, e l’errore (o la misura) del passo precedente, che serve a calcolare la derivata. Due numeri di stato, non uno di più. Il proporzionale non ha bisogno di stato, perché legge solo il presente; l’integrale e il derivativo sì, perché toccano il passato. Visto così, il PID è il più piccolo controllore “con memoria” che si possa scrivere, ed è esattamente questa lettura — controllore con memoria limitata — che alla fine del capitolo lo collegherà al modo in cui un agente decide la mossa successiva.

Il PID, scritto come somma dei suoi tre termini, è questo:

u(t)=Kpe(t)+Ki0te(τ)dτ+Kdde(t)dtu(t) = K_p \cdot e(t) + K_i \cdot \int_0^t e(\tau)\,d\tau + K_d \cdot \frac{de(t)}{dt}

Decifriamolo simbolo per simbolo, perché ogni pezzo corrisponde a una delle tre letture dell’intuizione.

u(t)u(t) è l’azione di controllo all’istante tt: il numero che il controllore manda all’attuatore — la potenza del bruciatore, l’angolo dello sterzo, il numero di repliche da avviare. È l’unica uscita del controllore.

e(t)e(t) è l’errore all’istante tt, definito come e(t)=SPPV(t)e(t) = SP - PV(t): la differenza tra il setpoint SPSP (il valore voluto) e la variabile controllata PVPV (il valore misurato, la process variable). Errore zero significa bersaglio centrato. È l’unico ingresso del controllore: il PID non guarda altro.

KpK_p, KiK_i, KdK_d sono i tre guadagni: tre numeri, fissati in fase di taratura, che pesano quanto contano rispettivamente il presente, il passato e la tendenza. Scegliere questi tre numeri è progettare il PID.

In parole povere, la formula dice: l’azione da prendere è una somma pesata di tre quantità — l’errore di adesso, l’errore accumulato da quando hai iniziato, e la pendenza con cui l’errore sta cambiando. Niente di più. Vediamo i tre termini uno alla volta.

Prima, però, una nota su due parole della formula che meritano un decoder, perché il lettore target conosce l’integrale e la derivata a intuito ma forse non le ha sotto mano. L’integrale 0te(τ)dτ\int_0^t e(\tau)\,d\tau è, geometricamente, l’area racchiusa tra la curva dell’errore e l’asse zero, da quando il controllore è acceso (τ=0\tau = 0) fino all’istante presente tt. Se l’errore è stato a lungo positivo, quell’area è grande; se l’errore oscilla attorno a zero, le parti sopra e sotto si compensano e l’area resta piccola. La derivata de(t)dt\frac{de(t)}{dt} è la pendenza della curva dell’errore nell’istante tt: quanto ripidamente l’errore sta salendo o scendendo proprio adesso. Area accumulata e pendenza istantanea: con queste due immagini in testa, i tre termini diventano leggibili senza bisogno di analisi formale. Il capitolo ODE a intuizione per dinamiche e controllo le costruisce con calma.

Il termine proporzionale: Kpe(t)K_p \cdot e(t). È l’unico termine senza memoria: dipende solo dall’errore di questo istante, non di cosa è successo prima. È istantaneo e lineare — raddoppia l’errore, raddoppia il contributo. Un KpK_p grande rende la risposta più pronta e riduce (vedremo: non azzera) l’errore a regime; un KpK_p troppo grande porta prima overshoot — la variabile controllata supera il setpoint prima di assestarsi — poi oscillazioni, infine instabilità.

Perché il proporzionale lascia un errore residuo. Questo è il punto che il capitolo introduttivo aveva lasciato aperto, e merita di essere chiuso con cura. Immagina un sistema all’equilibrio, dove la variabile controllata è ferma. Perché resti ferma, l’azione di controllo deve compensare esattamente un disturbo costante — la dispersione di calore di una stanza, il vento laterale, l’attrito di un motore. Quell’azione di compensazione non può essere zero: il disturbo c’è sempre.

Ma con il solo termine proporzionale, u=Kpeu = K_p \cdot e. L’unico modo di avere un’azione uu diversa da zero è avere un errore ee diverso da zero. Quindi il sistema non può assestarsi a errore nullo: si assesta sul valore di errore che, moltiplicato per KpK_p, produce esattamente l’azione che serve a contrastare il disturbo. Quel residuo è l’errore a regime, o offset. Non è un difetto di taratura: è una conseguenza strutturale di un controllore che genera azione solo se c’è errore. Alzare KpK_p lo riduce — serve meno errore per produrre la stessa azione — ma non lo azzera mai, e alzarlo troppo destabilizza. Serve un termine diverso.

Il termine integrale: Ki0te(τ)dτK_i \cdot \int_0^t e(\tau)\,d\tau. L’integrale dell’errore è l’area accumulata tra la curva dell’errore e lo zero, da quando il controllore è stato acceso fino a ora. La proprietà che conta è una sola: finché l’errore è diverso da zero, l’integrale cambia; quando l’errore è stabilmente zero, l’integrale si congela su un valore — che in generale non è zero.

Ed è proprio quel valore congelato a risolvere il problema dell’offset. L’integrale fornisce l’azione di mantenimento costante — la sterzata controvento, la potenza che compensa la dispersione — senza bisogno di alcun errore residuo. In sostanza sposta la responsabilità dell’azione costante: dal termine proporzionale, che per produrla esige un errore, al termine integrale, che la produce ricordando. Per questo un controllore con il termine integrale azzera l’errore a regime, mentre uno puramente proporzionale no.

Il termine integrale ha un prezzo. Aggiunge ritardo di fase: l’azione integrale risponde “in ritardo”, perché deve prima accumulare l’errore prima di reagire in modo apprezzabile. Quel ritardo riduce il margine di stabilità del sistema e tende a produrre overshoot. È il primo esempio di una verità che attraversa tutto il capitolo: azzerare l’offset e mantenere la stabilità sono obiettivi diversi, spesso in tensione.

Il termine derivativo: Kdde(t)dtK_d \cdot \frac{de(t)}{dt}. La derivata dell’errore è la sua pendenza istantanea: positiva se l’errore sta crescendo, negativa se sta calando, grande in valore assoluto se cambia in fretta. Il derivativo è anticipativo: non aspetta che l’errore sia grande, reagisce a quanto sta cambiando. Se ci stiamo avvicinando rapidamente al setpoint — errore che cala ripido — il derivativo produce un’azione di segno opposto che frena, e smorza l’overshoot prima che accada.

Anche il derivativo ha un prezzo, e severo: amplifica il rumore. Un sensore reale non dà mai un valore pulito; dà un valore che oscilla, anche di poco, attorno a quello vero. Quelle piccole oscillazioni, viste come pendenza istantanea, sono enormi: derivare un segnale rumoroso produce un’azione di controllo che salta violentemente da un estremo all’altro, affatica gli attuatori e può destabilizzare. Per questo, in pratica, il termine derivativo è quasi sempre filtrato — e a volte si rinuncia del tutto a usarlo.

Il motivo per cui derivare amplifica il rumore si capisce con un esempio minuscolo. Immagina un sensore fermo sul valore vero, che però a ogni lettura sbaglia di ±0,1\pm 0{,}1 in modo casuale. Il valore non si muove davvero, ma da una lettura all’altra può saltare di 0,20{,}2. Se le letture sono distanti 0,010{,}01 secondi, la pendenza apparente è 0,2/0,01=200{,}2 / 0{,}01 = 20 unità al secondo — un valore enorme, prodotto interamente dal rumore, su una grandezza che in realtà è immobile. Il termine derivativo prende quel 2020 sul serio e lo manda all’attuatore. Più le letture sono frequenti, peggio è: la stessa fluttuazione, divisa per un intervallo più piccolo, dà una pendenza ancora più grande. È per questo che la derivata pura è inservibile su dati reali, e che il filtro sul termine derivativo non è una raffinatezza ma una necessità.

Una sottigliezza che vale la pena rendere esplicita. L’errore è stato definito come e=SPPVe = SP - PV, e il PID agisce per ridurlo. Questa convenzione di segno non è arbitraria: garantisce che l’anello sia a feedback negativo. Quando la variabile controllata sale sopra il setpoint l’errore diventa negativo, e tutti e tre i termini producono un’azione che spinge verso il basso; quando scende sotto, l’errore è positivo e l’azione spinge verso l’alto. L’anello si oppone sempre alla deviazione.

Se per errore si invertisse il segno — collegando il sensore al contrario, o sbagliando il verso dell’attuatore — l’anello diventerebbe a feedback positivo: ogni scostamento genererebbe un’azione che lo aumenta, in una spirale che diverge. Un PID con il segno sbagliato non è un PID tarato male: è un amplificatore di errori. È un guasto banale e devastante, ed è la prima cosa da verificare quando un anello, appena acceso, scappa via invece di stabilizzarsi.

Vale anche la pena ricordare che il PID, da solo, non è nulla: è il blocco “controllore” dentro l’anello chiuso descritto in control-theory-intro. Il setpoint arriva al nodo di confronto, che calcola l’errore; l’errore entra nel PID, che produce l’azione; l’azione passa per l’attuatore e agisce sul plant; il sensore misura la variabile controllata e la riporta al nodo di confronto. Il PID è un pezzo di questa catena — quello che decide cosa fare con l’errore — e la sua bontà si giudica solo guardando come si comporta l’intero anello.

Il PID “completo” scritto sopra è la forma ideale. Nella pratica si usano quasi sempre sue versioni ridotte, ottenute azzerando uno dei guadagni. Vale la pena conoscerle, perché la scelta della forma è una decisione di progetto.

Una nota di vocabolario, perché chi legge documentazione industriale incontra parole diverse dai guadagni KiK_i e KdK_d. Il termine integrale è spesso parametrizzato dal tempo integrale TiT_i, legato a KiK_i da Ki=Kp/TiK_i = K_p / T_i: un TiT_i piccolo significa azione integrale forte. Il termine derivativo è parametrizzato dal tempo derivativo TdT_d, con Kd=KpTdK_d = K_p \cdot T_d. E il guadagno proporzionale stesso, nell’industria di processo, si esprime spesso come banda proporzionale, la percentuale di escursione dell’errore che porta l’attuatore da zero al massimo: banda stretta significa guadagno alto. Sono modi diversi di scrivere gli stessi tre parametri; conoscerli evita di confondersi davanti a uno strumento reale.

Il controllore P, solo proporzionale, è il più semplice: veloce, robusto, ma lascia l’offset. Va bene dove un piccolo errore residuo è tollerabile — per esempio il controllo di livello di un serbatoio di accumulo, dove non importa che il livello sia esattamente al setpoint, basta che resti in un intervallo.

Il controllore PI, proporzionale più integrale, è la forma più usata in assoluto nell’industria di processo. Azzera l’offset grazie all’integrale e non amplifica il rumore, perché non ha il termine derivativo. È la scelta tipica quando la dinamica del processo è lenta e dominata da ritardi, dove anticipare con il derivativo serve poco e rumore filtrare costerebbe più di quanto rende.

Il controllore PD, proporzionale più derivativo, smorza e velocizza ma non azzera l’offset. È tipico del controllo di posizione e di moto — motori, assi di una macchina, bracci robotici — dove la prontezza e lo smorzamento contano molto e un piccolo offset è meno critico.

Il PID completo si usa quando servono entrambe le cose: azzerare l’offset e smorzare le oscillazioni. Anche in questo caso, però, il termine derivativo è quasi sempre tenuto piccolo o filtrato pesantemente, proprio per il problema del rumore.

Il PID implementato in software vive a tempo discreto: il controllore si sveglia a intervalli regolari Δt\Delta t, legge, calcola, attua, e tra un passo e l’altro non fa nulla. L’integrale diventa una somma, la derivata diventa una differenza. Ecco l’anello, con due accorgimenti pratici che spieghiamo dopo il codice.

setpoint = 20.0
Kp, Ki, Kd = 2.0, 0.5, 1.0
dt = 0.1
integrale = 0.0
pv_precedente = sensore.leggi()
while True:
pv = sensore.leggi()
errore = setpoint - pv
# termine proporzionale: il presente
P = Kp * errore
# termine integrale: il passato, con anti-windup
integrale += errore * dt
integrale = clamp(integrale, -limite_i, limite_i)
I = Ki * integrale
# termine derivativo: la tendenza, calcolata sulla misura
derivata_pv = (pv - pv_precedente) / dt
D = -Kd * derivata_pv
u = P + I + D
u = clamp(u, u_min, u_max) # l'attuatore ha limiti fisici
attuatore.applica(u)
pv_precedente = pv
attendi(dt)

Quattro righe portano il peso concettuale. errore = setpoint - pv è il nodo di confronto. integrale += errore * dt accumula l’errore — una somma di Riemann, l’approssimazione discreta dell’integrale. derivata_pv = (pv - pv_precedente) / dt è la pendenza approssimata. u = P + I + D è la legge di controllo.

Ma due righe sono accorgimenti pratici, e meritano attenzione perché senza di essi il PID “ideale” si comporta male nel mondo reale.

La riga integrale = clamp(...) è una forma di anti-windup, e ne parliamo nella sezione sui limiti. La derivata, poi, è calcolata sulla pv e non sull’errore: il termine DD vale Kdd(PV)dt-K_d \cdot \frac{d(PV)}{dt} invece di Kdd(e)dtK_d \cdot \frac{d(e)}{dt}. È la tecnica del derivative-on-measurement, e anche di questa diciamo il perché tra poco. Per ora basta notare che un PID scritto senza questi due accorgimenti funziona sulla carta e delude sul campo.

Tarare un PID significa scegliere KpK_p, KiK_i, KdK_d. Per orientarsi serve sapere, almeno qualitativamente, cosa cambia quando si alza ciascuno. La tabella seguente riassume l’effetto di aumentare un guadagno tenendo fermi gli altri, ed è uno strumento standard nei testi di controllo.

GuadagnoTempo di salitaOvershootTempo di assestamentoErrore a regimeStabilità
KpK_p sudiminuisceaumentacambia pocodiminuiscepeggiora
KiK_i sudiminuisceaumentaaumentasi azzerapeggiora
KdK_d sucambia pocodiminuiscediminuiscenessun effettomigliora

Il tempo di salita è quanto ci mette la variabile controllata a raggiungere il setpoint la prima volta; il tempo di assestamento è quanto ci mette a stabilizzarcisi vicino per restarci. Overshoot, oscillazioni, divergenza sono le patologie della stabilità trattate in dettaglio nel capitolo stabilità, ritardi e oscillazioni della Parte X: la taratura di un PID è, in larga parte, la negoziazione di quei fenomeni.

Due avvertenze su questa tabella. La prima: ogni riga assume che si muova un solo guadagno e si tengano fermi gli altri — ma i tre guadagni non sono indipendenti, e cambiare uno sposta il punto di lavoro alterando l’effetto degli altri. La seconda: l’ultima colonna mostra la tensione centrale. Alzare KpK_p o KiK_i migliora la precisione e la velocità ma peggiora la stabilità; solo KdK_d va, in linea di principio, nella direzione opposta — e solo se il rumore lo permette. Non esiste una taratura che massimizzi tutto: si negozia.

Come si scelgono in concreto i tre guadagni? Il punto di partenza storico è il metodo di Ziegler-Nichols del 1942, nella sua variante più nota — il metodo del ciclo limite.

Si procede così. Si azzerano KiK_i e KdK_d, lasciando solo il proporzionale. Si alza KpK_p progressivamente, finché il sistema entra in oscillazione sostenuta: oscilla con ampiezza costante, né crescente né calante. Il valore di KpK_p a cui questo accade si chiama guadagno ultimo KuK_u, e il periodo dell’oscillazione si chiama periodo ultimo TuT_u. A questo punto si applicano formule fisse. Per un PID completo, nella forma standard:

Kp=0,6KuTi=0,5TuTd=0,125TuK_p = 0{,}6 \cdot K_u \qquad T_i = 0{,}5 \cdot T_u \qquad T_d = 0{,}125 \cdot T_u

dove TiT_i e TdT_d sono il tempo integrale e il tempo derivativo, parametri legati a KiK_i e KdK_d da Ki=Kp/TiK_i = K_p / T_i e Kd=KpTdK_d = K_p \cdot T_d. Le formule mirano a una risposta con uno smorzamento detto quarter-amplitude decay: ogni oscillazione è circa un quarto della precedente.

Esiste anche una seconda variante di Ziegler-Nichols, il metodo della curva di reazione, che lavora in anello aperto: si dà un gradino all’ingresso del processo e si misurano il ritardo e la rapidità della risposta, da cui si ricavano i guadagni con altre formule tabulate.

Perché, allora, in pratica si tara spesso a mano? Ziegler-Nichols è fondamentale didatticamente, ma ha limiti concreti. Il metodo del ciclo limite richiede di portare deliberatamente l’impianto sull’orlo dell’instabilità — accettabile su un banco di prova, spesso inaccettabile e pericoloso su un processo in produzione. Le tarature che produce sono notoriamente aggressive: overshoot intorno al 25%, margini di sicurezza ridotti. E funzionano male su processi con caratteristiche particolari, come un ritardo molto pronunciato.

Per questo, nella pratica, gli strumentisti usano Ziegler-Nichols come punto di partenza e poi rifiniscono a mano osservando la risposta del sistema, oppure ricorrono a metodi più recenti — come l’auto-tuning a relay di Karl Johan Åström e Tore Hägglund (1984), che provoca un’oscillazione controllata e sicura invece di spingere il sistema fino al limite. La taratura manuale tipica segue un ordine preciso: si lascia KiK_i e KdK_d a zero, si alza KpK_p fino a una risposta pronta ma con poco overshoot; si aggiunge KiK_i quel tanto che basta a cancellare l’offset; si aggiunge KdK_d, se serve e se il rumore lo consente, per smorzare le oscillazioni residue. È un mestiere fatto di osservazione e correzione — non così diverso dal modo in cui un timoniere imparava a sterzare.

C’è una ragione di fondo per cui la taratura resta in larga parte un’arte. Le formule di Ziegler-Nichols valgono bene solo per una certa classe di processi — quelli ben approssimati da un guadagno, un ritardo e una costante di tempo — e producono una risposta con un certo gusto, lo smorzamento a un quarto, che a qualcuno va bene e a qualcuno no: chi non tollera nemmeno un piccolo overshoot vuole una taratura più conservativa. Inoltre la “taratura giusta” dipende da cosa il sistema deve fare: un anello che insegue un setpoint che cambia spesso si tara diversamente da un anello che deve solo reggere contro i disturbi a setpoint fisso. Non esiste un numero ottimo nel vuoto: esiste l’ottimo rispetto a un compito e a un gusto, e quei due ingredienti vivono nella testa di chi tara, non in una formula. Per questo, anche nell’era dell’auto-tuning, l’occhio del tecnico che guarda la risposta e decide “così è troppo nervoso, ammorbidisco” non è stato sostituito.

L’integral windup è abbastanza importante da meritare, già qui nella meccanica, un panorama delle contromisure standard — perché un PID scritto senza una di queste, prima o poi, si comporta male. Tutte e tre rispondono alla stessa domanda: cosa fare del termine integrale quando l’attuatore è saturo e accumulare altro errore non serve a niente.

La prima, già vista nello pseudocodice, è il clamping: si limita il valore dell’integrale a un intervallo fisso, scelto in modo che copra l’azione di mantenimento ragionevole e non di più. L’integrale può ancora accumularsi, ma non oltre un tetto: quando il tetto è raggiunto, smette di crescere. È la tecnica più semplice e spesso sufficiente; il difetto è che il tetto va scelto con un po’ di giudizio.

La seconda è la conditional integration, o integrazione condizionata: si sospende del tutto l’accumulo quando l’attuatore è saturo. Il ragionamento è diretto — se l’azione comandata è già oltre quello che l’attuatore può dare, accumulare altro errore è inutile e dannoso, quindi non lo si fa. Appena l’attuatore esce dalla saturazione, l’integrazione riprende. Richiede di sapere quando l’attuatore è saturo, informazione di solito disponibile.

La terza, più raffinata, è la back-calculation: si calcola la differenza tra l’azione che il controllore ha comandato e quella che l’attuatore ha effettivamente erogato — diversa da zero solo in saturazione — e si usa quella differenza per “riportare indietro” il termine integrale, scaricandolo in proporzione a quanto è andato oltre. È un piccolo anello correttivo dentro il controllore, e dà transizioni più morbide rispetto al clamping secco.

Quale scegliere dipende dal sistema, ma il messaggio non cambia: l’anti-windup non è un optional teorico, è parte integrante di un PID che funziona nel mondo reale, dove gli attuatori hanno sempre un limite.

Per giudicare un PID si guarda il suo effetto sull’intero anello, e lo strumento standard è la risposta al gradino: si dà al sistema un cambio di setpoint improvviso — da 16 a 20 gradi, di colpo — e si osserva come la variabile controllata si muove verso il nuovo bersaglio. Quella curva racconta tutto.

Diversi numeri la riassumono, e conviene avere i nomi. Il tempo di salita è quanto la curva impiega a raggiungere per la prima volta il setpoint (o una sua percentuale, spesso il 90%): misura la prontezza. L’overshoot è di quanto la curva supera il setpoint prima di tornare indietro, in genere espresso in percentuale: misura quanto il sistema è “nervoso”. Il tempo di assestamento è quanto la curva impiega a entrare — e restare — dentro una banda stretta attorno al setpoint, diciamo il 2%2\%: misura quando il transitorio è davvero finito. E l’errore a regime è lo scarto che resta quando tutto si è calmato: misura la precisione.

Questi quattro numeri sono in tensione, ed è la tensione che la tabella dei guadagni descriveva. Una taratura che minimizza il tempo di salita tende ad avere overshoot alto; una che azzera l’overshoot tende a essere lenta. Tarare un PID è scegliere un punto in questo spazio di compromessi, guidati da cosa il sistema deve fare: un ascensore non può avere overshoot — supererebbe il piano — e accetta di essere un po’ lento; un sistema di puntamento può accettare un piccolo overshoot in cambio di velocità. Non c’è una risposta al gradino “giusta” in assoluto: c’è quella giusta per il compito.

Una domanda naturale: perché tre? Perché non due, o cinque, o un termine che integra due volte?

La risposta breve è che i tre termini coprono i tre modi strutturalmente diversi in cui si può usare un segnale di errore. Il proporzionale usa il suo valore. L’integrale usa la sua storia accumulata. Il derivativo usa la sua tendenza. Sono tre operazioni qualitativamente distinte sullo stesso segnale, e insieme bastano a soddisfare le tre specifiche più richieste: prontezza (proporzionale), errore a regime nullo (integrale), smorzamento (derivativo).

Si potrebbe andare oltre. Un secondo termine integrale — l’integrale dell’integrale — annulla l’errore a regime anche quando il setpoint non è costante ma cambia a velocità costante (un sistema a “doppio integratore”). Esistono controllori con questa struttura, usati per esempio nell’inseguimento di traiettorie. Ma ogni termine in più aggiunge ritardo di fase, complica la taratura e moltiplica i modi di sbagliare. Il PID è il punto di equilibrio empirico: abbastanza ricco da risolvere la grande maggioranza dei problemi a un ingresso e un’uscita, abbastanza povero da restare tarabile a mano da un tecnico. Non è ottimo per nessun problema in particolare; è abbastanza buono per quasi tutti. È questa, più di ogni teorema, la ragione della sua diffusione.

C’è anche un argomento “dall’alto” che porta allo stesso tre. Una vasta classe di processi reali — quelli che si comportano, con buona approssimazione, come sistemi del primo o del secondo ordine, eventualmente con un ritardo — è governata bene da un controllore che ha esattamente la struttura del PID. Non è una coincidenza fortunata: la teoria del controllo classico mostra che, per quella classe di processi, i tre termini sono ciò che serve per posizionare la risposta dell’anello dove la si vuole. Il PID non è quindi solo un compromesso pratico azzeccato; è anche, per i sistemi più comuni, la forma di controllore che la teoria suggerisce. Le due cose insieme — fondamento teorico per i casi comuni e robustezza pratica fuori da essi — spiegano perché un controllore inventato nel 1922 sia ancora, un secolo dopo, lo standard.

Quattro esempi deliberatamente eterogenei: uno numerico sul meccanismo dell’integrale, uno in codice, uno scenario software reale, uno numerico sulla taratura.

Esempio 1 — Il termostato, e l’integrale che chiude l’offset

Sezione intitolata “Esempio 1 — Il termostato, e l’integrale che chiude l’offset”

Riprendiamo l’Esempio 1 di control-theory-intro e lo portiamo a conclusione. Una stanza è a 16 gradi, il setpoint è 20. La stanza disperde calore verso l’esterno: chiamiamo questa dispersione una potenza persa costante pari a 11 unità. Perché la temperatura resti ferma, il bruciatore deve erogare esattamente 11 unità di potenza.

Con un controllore puramente proporzionale, u=Kpeu = K_p \cdot e con Kp=0,5K_p = 0{,}5. Per erogare 11 unità di potenza serve un errore e=2e = 2: il sistema si assesta a 1818 gradi, non a 2020. È l’offset, lo abbiamo già visto.

Ora aggiungiamo il termine integrale. La legge diventa u=Kpe+Ki(integrale di e)u = K_p \cdot e + K_i \cdot (\text{integrale di } e), con KiK_i un guadagno qualsiasi positivo, diciamo 0,10{,}1. Seguiamo cosa succede. Seguiamo qualche passo, con un intervallo Δt\Delta t unitario per tenere i conti puliti. All’inizio l’errore è grande, e=4e = 4, e l’integrale è zero. L’azione è u=0,54+0,10=2u = 0{,}5 \cdot 4 + 0{,}1 \cdot 0 = 2 — tutta dal proporzionale. Al passo dopo l’integrale ha accumulato il primo errore, vale 44, e se l’errore nel frattempo è sceso a 3,23{,}2 l’azione è u=0,53,2+0,14=1,6+0,4=2u = 0{,}5 \cdot 3{,}2 + 0{,}1 \cdot 4 = 1{,}6 + 0{,}4 = 2. Si nota già la staffetta: man mano che il proporzionale cala, perché l’errore cala, l’integrale cresce e raccoglie il testimone. Più avanti, con errore sceso a 0,50{,}5 e integrale accumulato a, diciamo, 99, l’azione è u=0,25+0,9=1,15u = 0{,}25 + 0{,}9 = 1{,}15: ora è l’integrale a portare quasi tutto il peso.

Il punto è proprio questo passaggio di consegne. Finché l’errore resta diverso da zero — anche piccolo, anche 0,30{,}3 gradi — l’integrale continua ad accumulare: a ogni passo somma un altro pezzetto di errore. L’azione integrale cresce lentamente, ma non si ferma finché l’errore non è davvero zero.

Cresce finché non succede questo: il termine integrale è arrivato a valere esattamente 11 unità di potenza. A quel punto il bruciatore eroga la potenza di mantenimento senza aver bisogno del contributo proporzionale. L’errore può andare a zero. E quando ci va, il termine proporzionale KpeK_p \cdot e diventa zero, ma l’integrale resta congelato su 11 — perché con errore zero non accumula più, ma neanche cala. La stanza si assesta a 2020 gradi esatti.

L’integrale ha fatto una cosa precisa: ha spostato la potenza di mantenimento dal termine proporzionale, che per erogarla pretendeva un errore di 22 gradi, al termine integrale, che la eroga ricordando. È questo, in numeri, il meccanismo con cui il PID cancella l’offset.

C’è un rovescio della medaglia che i numeri rendono visibile. Nel tratto in cui l’errore è ancora positivo ma piccolo, l’integrale ha già accumulato parecchio — somma di tanti pezzetti — e potrebbe aver superato il valore di mantenimento 11. In quel caso, quando l’errore arriva a zero, l’azione totale è ancora sopra quella che serve: il bruciatore eroga più di 11, la stanza continua a scaldarsi, e la temperatura supera i 2020 gradi. È l’overshoot indotto dall’integrale. L’errore diventa allora negativo, l’integrale ricomincia a scaricarsi, e il sistema rientra — magari oscillando un paio di volte attorno al setpoint prima di assestarsi. Questo mostra, su un caso minuscolo, perché aggiungere l’integrale azzera l’offset ma peggiora la stabilità: sono due conti separati, e il secondo è il prezzo del primo.

Una cosa che l’esempio chiarisce, e che vale la pena estrarre. L’offset di un controllore proporzionale non è un difetto di taratura che si possa “aggiustare” alzando KpK_p: è strutturale. Si può ridurre l’offset alzando KpK_p — con KpK_p molto grande basta un errore minuscolo per produrre la potenza di mantenimento — ma non lo si azzera mai, e KpK_p grande porta con sé overshoot e instabilità. L’integrale fa una cosa che nessun valore di KpK_p può fare: produce azione a errore nullo. È un cambiamento qualitativo, non quantitativo, e per questo il termine integrale non è un’opzione di rifinitura ma un pezzo necessario ogni volta che l’offset non è tollerabile.

Esempio 2 — Un PID discreto completo, con i suoi accorgimenti

Sezione intitolata “Esempio 2 — Un PID discreto completo, con i suoi accorgimenti”

Lo pseudocodice della sezione “La meccanica” mostra l’anello. Qui isoliamo le due righe che distinguono un PID “da manuale” da uno che funziona davvero sul campo.

La prima è derivata_pv = (pv - pv_precedente) / dt, con il termine derivativo D=Kdderivata_pvD = -K_d \cdot \text{derivata\_pv}. Calcoliamo la derivata della variabile misurata, non dell’errore. Perché? Immagina che l’operatore cambi il setpoint di colpo, da 20 a 25 gradi. L’errore e=SPPVe = SP - PV fa un salto istantaneo di 5 gradi. La derivata di un salto istantaneo è, matematicamente, un impulso di altezza enorme: il termine derivativo dà all’attuatore uno strappo violentissimo, il derivative kick. La variabile controllata PVPV, invece, non salta a gradino — la temperatura della stanza non può cambiare istantaneamente — quindi derivare la PVPV non produce nessun kick. Si ottiene lo stesso effetto smorzante senza lo strappo. Il segno meno compensa il fatto che, dove la derivata dell’errore è dedt=d(SP)dtd(PV)dt\frac{de}{dt} = \frac{d(SP)}{dt} - \frac{d(PV)}{dt}, con setpoint costante resta d(PV)dt-\frac{d(PV)}{dt}.

La seconda è integrale = clamp(integrale, -limite_i, limite_i): l’anti-windup. Limita di quanto il termine integrale può accumularsi. Senza questo limite, se l’attuatore resta a lungo saturo — al massimo della sua capacità — mentre l’errore persiste, l’integrale si carica a un valore enorme e poi impiega moltissimo tempo a scaricarsi. La sezione “Dove si rompe” lo analizza in dettaglio; qui basta vedere che è una riga di codice, non un dettaglio teorico.

Vale la pena notare anche cosa non compare nello pseudocodice e dovrebbe, in un PID di produzione. Non c’è il filtro passa-basso sul termine derivativo — la differenza (pv - pv_precedente)/dt è una derivata grezza, che su un sensore rumoroso andrebbe lisciata prima di pesarla con KdK_d. Non c’è la gestione del cambio di intervallo: se dt non è costante — e nel software, dove un ciclo può essere ritardato da altro lavoro, spesso non lo è — usare un dt fisso falsa sia l’integrale sia la derivata, e converrebbe misurare il tempo davvero trascorso. Non c’è il bumpless transfer. Lo pseudocodice è volutamente scheletrico per mostrare la struttura dei tre termini; un PID reale è quello scheletro più una manciata di accorgimenti che non cambiano l’idea ma fanno la differenza tra un controllore da slide e uno che regge un impianto.

Un PID reale ha spesso altri accorgimenti — un filtro passa-basso sul termine derivativo, il bumpless transfer per passare da controllo manuale ad automatico senza scossoni — ma queste due righe sono il minimo indispensabile per non avere brutte sorprese.

Mettiamo numeri sul windup, perché detto a parole sembra astratto. Riprendiamo il termostato, ma stavolta la stanza parte molto fredda — diciamo 00 gradi, setpoint 2020 — e il bruciatore ha una potenza massima umax=5u_{max} = 5. All’inizio l’errore è 2020: il termine proporzionale da solo, con Kp=2K_p = 2, vorrebbe già erogare 4040, ben oltre il massimo. L’attuatore satura a 55 e ci resta a lungo, mentre la stanza si scalda piano. In tutto questo tempo l’errore resta grande e positivo, e l’integrale — integrale += errore * dt a ogni passo — accumula senza sosta: dopo molti passi vale, mettiamo, l’equivalente di 3030 unità di potenza. La stanza intanto raggiunge i 2020 gradi e li supera. L’errore diventa negativo, l’attuatore dovrebbe spegnersi — ma l’azione totale è ancora P+IP + I con II gonfio a 3030: anche con PP negativo, la somma resta positiva e il bruciatore continua a scaldare una stanza già calda. Solo dopo che l’errore è rimasto negativo abbastanza a lungo da erodere quei 3030 accumulati, il controllore torna a comandare correttamente. Nel frattempo la temperatura è salita ben oltre 2020: un overshoot lungo e severo, causato non dalla taratura ma dalla saturazione non gestita. La riga clamp che limita l’integrale a, diciamo, ±5\pm 5 — quanto basta a coprire l’azione di mantenimento, non di più — taglia il problema alla radice.

Uno scenario software, senza un grammo di fisica. Un servizio web gira su un certo numero di repliche — istanze identiche dietro un load balancer — e vogliamo che l’utilizzo medio della CPU resti vicino a un valore obiettivo, diciamo il 60%. Sopra quella soglia il servizio rallenta; molto sotto, stiamo sprecando macchine.

Mappiamo sul vocabolario del controllo. Il setpoint è il 60% di utilizzo CPU. La variabile controllata è l’utilizzo CPU effettivamente misurato. La variabile manipolata è il numero di repliche: la manopola dell’autoscaler. Il disturbo è il traffico in ingresso, che nessuno controlla. Il controllore è la logica di autoscaling.

Un autoscaler costruito come puro proporzionale guarda lo scostamento corrente: CPU al 75%, errore del 15%, aggiungi repliche in proporzione. Funziona, ma soffre dello stesso offset del termostato: se c’è una ragione sistematica per cui il servizio gira sopra il target — un carico di fondo costante — il proporzionale si assesta sopra il 60%, non sul 60%. Aggiungere il termine integrale cancella quell’offset: l’integrale accumula lo scostamento e aggiunge repliche finché l’utilizzo non torna davvero al target. Per questo molti autoscaler reali sono, di fatto, controllori PI.

E il windup, qui, è concretissimo. Se le repliche hanno raggiunto il tetto consentito dal cluster ma il carico resta alto, l’utilizzo CPU resta sopra il target: l’errore persiste, e il termine integrale continua ad accumulare anche se aggiungere repliche non è più possibile. Quando il picco di traffico finalmente passa, l’integrale è gonfio: l’autoscaler resta convinto di dover tenere molte repliche e tarda parecchio a ridurle. È esattamente l’integral windup, e si cura con le stesse contromisure: limitare l’accumulo dell’integrale, o smettere di integrare quando si è raggiunto il tetto.

Un dettaglio sul termine derivativo in questo contesto: le metriche di un servizio — CPU, latenza — sono rumorose, oscillano da una misura all’altra. Un termine derivativo non filtrato le deriverebbe, traducendo il rumore in continui aggiungi-e-togli repliche. È la versione software dell’amplificazione del rumore: per questo gli autoscaler tendono a essere P o PI, e quando usano un termine derivativo lo filtrano pesantemente. Lo stesso vale per un rate limiter adattivo o per un controllo del budget di costo: la struttura è quella di un controllore in retroazione, e i guasti che li affliggono — oscillazione, windup, inseguimento del rumore — sono i guasti del PID.

C’è un’altra patologia che questo esempio rende concreta, ed è caratteristica dei sistemi software: il ritardo. Una nuova replica non diventa operativa nell’istante in cui l’autoscaler la chiede — deve essere avviata, scaldata, registrata nel load balancer, e questo richiede secondi o minuti. Nel frattempo l’autoscaler misura una CPU ancora alta, conclude che le repliche aggiunte non bastano, e ne chiede altre. Quando finalmente tutte diventano operative, ce ne sono troppe: la CPU crolla sotto il target, l’autoscaler ne toglie, e il ciclo riparte. È lo scaling oscillation, o flapping, e ha la stessa causa control-theoretic della doccia col tubo lungo: troppo guadagno combinato con troppo ritardo. Le contromisure sono quelle del controllo — abbassare il guadagno, introdurre isteresi (soglie diverse per salire e per scendere), aggiungere finestre di cooldown che impediscono azioni troppo ravvicinate — e si capiscono a fondo nel capitolo stabilità, ritardi e oscillazioni. Senza il vocabolario del controllo, un autoscaler che flappa è un mistero; con quel vocabolario, è un anello con guadagno e ritardo mal bilanciati, e la cura è nota.

La morale dell’esempio vale per ogni anello software con questa forma. Un rate limiter adattivo, un controllo di backpressure in una pipeline di streaming, un sistema che regola la dimensione di un pool di connessioni: progettati senza il vocabolario del controllo, si tarano per tentativi e prima o poi oscillano o vanno in windup; progettati con quel vocabolario, sono riconosciuti per quello che sono — controllori in retroazione — e si può ragionare sulla loro stabilità prima di metterli in produzione, invece di scoprirla a danno fatto. Il PID non è la soluzione di tutti questi casi — molti sono più semplici di un PID completo, alcuni richiedono di più — ma è il modello di riferimento che dà i nomi ai loro guasti.

Un’ultima nota sull’esempio, perché segna una differenza vera con i sistemi fisici. Nel software la variabile manipolata è spesso discreta e grossa: un autoscaler non può avere ”3,73{,}7 repliche”, deve scegliere 33 o 44. La legge di controllo produce un numero continuo, e qualcuno deve arrotondarlo. Quell’arrotondamento è una piccola non linearità che la teoria del PID lineare non vede, e che può alimentare oscillazioni — il controllore vorrebbe una correzione fine, ma il mondo gli concede solo passi interi. È un esempio in piccolo di come il PID, nato per attuatori continui come una valvola, vada usato con un occhio in più quando l’attuatore è una decisione discreta. Non è una ragione per non usarlo: è una ragione per ricordare che la mappa lineare e il territorio software non coincidono mai del tutto.

Esempio 4 — Una taratura Ziegler-Nichols, numeri alla mano

Sezione intitolata “Esempio 4 — Una taratura Ziegler-Nichols, numeri alla mano”

Per rendere concreto il metodo del ciclo limite, seguiamone uno svolgimento. Abbiamo un processo a un ingresso e un’uscita — diciamo il controllo di temperatura di un piccolo forno — e vogliamo tararne il PID.

Si parte solo proporzionali: Ki=0K_i = 0, Kd=0K_d = 0. Si alza KpK_p a scalini. A Kp=1K_p = 1 il forno raggiunge il setpoint e si assesta, magari con un po’ di offset, ma stabile. A Kp=3K_p = 3 la risposta è più nervosa, qualche oscillazione che però si smorza. A Kp=5K_p = 5 succede la cosa che cercavamo: il forno oscilla attorno al setpoint con ampiezza costante, né crescente né calante. Quello è il guadagno ultimo: Ku=5K_u = 5. Si misura il periodo di quell’oscillazione cronometrando il tempo tra due picchi successivi: diciamo Tu=4T_u = 4 minuti.

Ora si applicano le formule. Per un PID completo: Kp=0,6Ku=3K_p = 0{,}6 \cdot K_u = 3; tempo integrale Ti=0,5Tu=2T_i = 0{,}5 \cdot T_u = 2 minuti; tempo derivativo Td=0,125Tu=0,5T_d = 0{,}125 \cdot T_u = 0{,}5 minuti. Da questi, se servono i guadagni nella forma parallela: Ki=Kp/Ti=1,5K_i = K_p / T_i = 1{,}5 al minuto, Kd=KpTd=1,5K_d = K_p \cdot T_d = 1{,}5 minuti.

Tre numeri ricavati da due misure — KuK_u e TuT_u — e da formule fisse. Funziona, e dà un punto di partenza ragionevole. Ma si noti il prezzo: per trovare KuK_u abbiamo dovuto portare deliberatamente il forno in oscillazione sostenuta, cioè sull’orlo dell’instabilità. Su un forno da banco è accettabile; su un reattore chimico in produzione, molto meno. E la taratura ottenuta tende ad avere un overshoot intorno al 25%25\%: se il forno non lo tollera, questi tre numeri sono solo l’inizio, e il tecnico li ammorbidirà a mano osservando la risposta. È il motivo, già anticipato, per cui Ziegler-Nichols è il punto di partenza della taratura, raramente il punto di arrivo.

Dove si incontra concretamente il PID, oltre ai sistemi fisici ovvi.

Nei sistemi fisici e industriali il PID è onnipresente e quasi invisibile. Controllo di temperatura, pressione, portata, livello in ogni impianto di processo. Cruise control dell’automobile, autopiloti, controllo di assetto dei satelliti. Regolazione di motori elettrici, stampanti 3D, macchine utensili. I droni multirotore tengono l’assetto con un PID su ciascun asse — è lo standard de facto. In tutti questi casi il PID è il blocco base, fornito già pronto dentro ogni PLC e ogni DCS. La sua invisibilità non è un caso: un controllore funziona bene esattamente quando smette di farsi notare, perché la variabile che governa resta dove deve stare. Il PID è una delle tecnologie che hanno reso governabili le macchine del Novecento, e lo ha fatto restando talmente in sottofondo che la maggior parte di chi beneficia di un suo anello non sa che esiste.

Nei sistemi software la struttura del controllore a feedback ricorre più di quanto la si nomini. Un autoscaler — come nell’Esempio 3 — è un controllore: l’Horizontal Pod Autoscaler di Kubernetes è strutturalmente un anello in retroazione, storicamente più vicino a un puro proporzionale che a un PID completo. Un rate limiter adattivo regola un tasso di richieste per inseguire un target. Il congestion control di TCP è un parente concettuale: regola la finestra di invio osservando perdite e ritardi. Esistono brevetti che descrivono PID applicati al throttling di ingestione eventi, dove il controllore regola il rate limit sull’errore di lag rispetto a un obiettivo. Riconoscere questi sistemi come anelli di controllo significa poter importare cinquant’anni di sapere su quando oscillano, perché vanno in windup, come si tarano.

Una raccomandazione pratica emerge da questi casi. Quando si progetta un anello software con la forma del controllo, conviene quasi sempre partire dalla forma più semplice — un puro proporzionale, o un PI — e aggiungere termini solo se un guasto osservato lo richiede. Il proporzionale dà la reazione di base; se si vede un offset sistematico, si aggiunge l’integrale; il derivativo si aggiunge per ultimo, con cautela, e solo se le metriche sono abbastanza pulite da sopportare di essere derivate — il che, nei sistemi software, è raro. È lo stesso ordine della taratura manuale di un PID fisico, e ha la stessa ragione: ogni termine in più è potenza in più ma anche un modo in più di sbagliare, e si paga solo quello che serve davvero.

Nei sistemi LLM e agentici il PID compare in due modi distinti, da tenere separati.

Il primo è concreto: il controllo di un budget. Un sistema che insegue un target di costo — “circa 5000 token per task”, “latenza sotto una soglia” — regolando manopole come il budget di reasoning concesso al modello, gli stop token, la lunghezza del prompt, è un controllore in retroazione sul costo. La sua versione proporzionale-integrale azzera lo scostamento sistematico dal budget; e se una manopola satura — il budget di reasoning è già al minimo — può andare in windup esattamente come un autoscaler. Lo stesso schema si applica al controllo di un budget di KV cache, lo stato che un LLM accumula durante la generazione.

Si può rendere il quadro più concreto con uno scenario di agent coding. Immagina un sistema che orchestra molti agenti in parallelo e vuole tenere la spesa oraria complessiva vicino a un tetto. La variabile controllata è la spesa misurata nell’ultima finestra; il setpoint è il budget orario; la variabile manipolata è il numero di agenti che possono lavorare in contemporanea, o il modello che viene loro assegnato (più capace e costoso, oppure più economico). Un controllo puramente proporzionale reagisce allo scostamento corrente: spesa sopra il tetto, riduci la concorrenza. Ma se c’è una deriva sistematica — i task sono diventati mediamente più lunghi — il proporzionale si assesta cronicamente sopra il budget, e qui serve il termine integrale per riportarlo sul tetto. Il termine derivativo, se usato, va trattato con sospetto: la spesa misurata è un segnale rumoroso e a scatti, e derivarlo direttamente farebbe oscillare il numero di agenti. La griglia passato-presente-futuro del PID dice esattamente cosa guardare; resta un’analogia, ma un’analogia che struttura il problema invece di lasciarlo a sensazioni.

Il secondo modo è il legame con l’ottimizzazione, ed è un legame da maneggiare con la classe di affermazione corretta. La discesa del gradiente con momentum — l’ottimizzatore che addestra gran parte delle reti neurali, trattato nel capitolo discesa del gradiente — accumula una media dei gradienti passati per dare “inerzia” all’aggiornamento dei pesi. Strutturalmente, quell’accumulo è la stessa operazione del termine integrale di un PID: una somma del segnale nel tempo. Diversi lavori rendono il parallelo esplicito. Ben Recht, in un post del 2018 sul blog argmin, argomenta che il controllo integrale corrisponde alla discesa del gradiente e che SGD con momentum si legge come un controllore proporzionale-integrale, mentre aggiungere un termine derivativo recupera metodi come Heavy Ball e Nesterov. An e colleghi, in A PID Controller Approach for Stochastic Optimization of Deep Networks (CVPR 2018), propongono un ottimizzatore che aggiunge proprio un termine derivativo per ridurre l’overshoot tipico del momentum.

Va marcata la classe di questo legame, perché è facile sbagliarla. È un’analogia matematica fondata: la corrispondenza vale, ma sotto ipotesi precise — funzioni di costo convesse, sistemi di una certa forma — e Recht stesso è esplicito nel dire che le garanzie valgono solo in classi ristrette di problemi. Non è una filiazione: il momentum, introdotto da Boris Polyak nel 1964, non nasce storicamente “dal PID”. E non è un’equivalenza piena: i teoremi di stabilità del controllo lineare non si trasferiscono all’ottimizzazione di una rete profonda così come sono. È un’analogia di struttura, illuminante e con basi solide, da usare come tale.

Vale la pena chiudere le applicazioni tornando sull’idea con cui il capitolo si è aperto, perché è quella che gli dà valore oltre il controllo industriale.

Il PID è il più piccolo controllore “con memoria” che si possa scrivere: due numeri di stato — l’integrale accumulato e la misura precedente — e una regola che, da quei due numeri più l’osservazione corrente, produce la prossima azione. È un sistema a memoria costante: non importa quanto a lungo gira, lo stato che porta dietro non cresce. E quei due numeri non sono casuali: codificano, in forma compressa, il passato (l’integrale è un riassunto di tutto l’errore visto finora) e la tendenza (la differenza con la misura precedente è la derivata).

Questa è una struttura che ricorre, come analogia, ogni volta che si progetta un sistema che deve agire ripetutamente inseguendo un obiettivo con risorse di memoria limitate. Un agente software che esegue un loop — osserva, decide, agisce, osserva di nuovo — affronta lo stesso problema di fondo: cosa tenere del passato, come pesare lo stato corrente, se e come anticipare. Il PID dà una risposta minimale e onesta a questa domanda: riassumi il passato in un accumulo, leggi il presente, estrapola la tendenza a un passo. Non è la risposta — un agente serio fa molto di più — ma è una griglia di partenza, e una griglia con cinquant’anni di patologie note attaccate: se il tuo “accumulo di stato” non ha un equivalente dell’anti-windup, prima o poi si gonfia; se reagisci troppo forte all’ultima osservazione, oscilli; se la tua “tendenza” è calcolata su un segnale rumoroso, insegui il rumore.

Resta un’analogia, e va ripetuto. Un agente non ha un errore numerico letto da un sensore, non ha una dinamica descritta da un’equazione differenziale, i suoi disturbi possono essere avversari intelligenti e non rumore con belle proprietà. Ma è un’analogia che porta con sé un vocabolario diagnostico — windup, overshoot, guadagno, ritardo, inseguimento del rumore — e quel vocabolario rende dicibili, e quindi affrontabili, guasti che altrimenti restano sensazioni vaghe.

Il PID è semplice, e proprio per questo è facile usarlo male o aspettarsi da lui ciò che non può dare. I limiti contano quanto i meccanismi — e nel caso del PID i limiti sono particolarmente istruttivi, perché ognuno di essi è il punto in cui una disciplina più avanzata trova la sua ragione d’esistere: l’anti-windup nasce dalla saturazione, il controllo robusto dall’incertezza di modello, il model predictive control dai vincoli, il controllo moderno dai problemi a più variabili. Leggere i guasti del PID è, di fatto, leggere la mappa del resto della Parte XI.

L’integral windup, in dettaglio. È la patologia più caratteristica del PID, e la prima cosa che “rompe” la teoria lineare pulita. Ogni attuatore reale ha un limite: un bruciatore ha una potenza massima, un motore una coppia massima, un autoscaler un numero massimo di repliche. Quando la legge di controllo chiede più di quanto l’attuatore può dare, l’attuatore satura — eroga il massimo e basta.

Ora immagina che l’errore persista a lungo mentre l’attuatore è saturo. Il termine integrale non lo sa: continua ad accumulare errore, passo dopo passo, anche se l’azione in più che sta calcolando non ha alcun effetto sul mondo, perché l’attuatore è già al massimo. L’integrale si “carica” a un valore enorme. Poi, finalmente, il sistema raggiunge e supera il setpoint, e l’errore cambia segno. A questo punto il controllore dovrebbe invertire l’azione — ma non può, finché non ha “scaricato” l’integrale gonfiato, e scaricarlo richiede di accumulare errore di segno opposto per molto tempo. Nel frattempo il controllore continua a spingere nella direzione sbagliata: il risultato è un overshoot lungo e severo.

Le contromisure si chiamano collettivamente anti-windup, e sono state descritte nella sezione “La meccanica”: clamping, conditional integration, back-calculation. Vale la pena ribadire qui il punto che le tiene insieme: sono soluzioni note e standard — ma vanno aggiunte deliberatamente. Il PID “ideale” della formula a tre termini non le contiene, e chi implementa quella formula alla lettera, senza pensare alla saturazione dell’attuatore, ha scritto un controllore che funziona in simulazione e delude appena incontra un attuatore reale con un limite reale. Il windup è il punto in cui la teoria pulita e la pratica si separano, ed è la ragione per cui un PID industriale ha sempre, sotto il cofano, qualcosa in più dei tre termini.

Il derivativo amplifica il rumore. Lo abbiamo già detto, ma è un limite che merita di stare qui, perché spiega perché tanti PID reali sono in realtà PI. La derivata di un segnale ha guadagno tanto più alto quanto più alta è la frequenza della componente: e il rumore di misura è, per sua natura, ad alta frequenza. Derivare un segnale rumoroso amplifica il rumore e lo manda all’attuatore. Le contromisure sono filtrare la derivata con un passa-basso, derivare la misura invece dell’errore, o tenere KdK_d piccolo. In molti casi pratici la scelta più saggia è semplicemente non usare il termine derivativo: un PI ben tarato batte un PID con un derivativo che insegue il rumore.

Il derivative kick. Già visto nell’Esempio 2: un termine derivativo che agisce sull’errore dà uno strappo violento all’attuatore a ogni cambio di setpoint, perché la derivata di un gradino è un impulso. Si risolve derivando la variabile misurata invece dell’errore. È un guasto banale da prevenire, ma chi scrive un PID da zero copiando la formula ideale ci cade.

Azzerare l’offset e stabilizzare sono in tensione. Una confusione comune è pensare che il termine integrale, dato che “sistema” l’errore, renda il sistema più stabile. È il contrario. L’integrale azzera l’errore a regime, ma peggiora la stabilità: aggiunge ritardo di fase, riduce il margine, tende a dare overshoot. Velocità, precisione e stabilità sono obiettivi distinti, spesso in conflitto, e il PID li negozia — non li ottiene tutti insieme gratis.

Il termine derivativo non è una palla di cristallo. Capita di leggere il termine derivativo come se “prevedesse il futuro” e quindi rendesse il controllore intelligente. È una lettura fuorviante. Il derivativo fa una cosa sola: estrapola linearmente la tendenza istantanea dell’errore — assume che l’errore continui a cambiare esattamente come sta cambiando in questo microsecondo. È la previsione più povera possibile, valida solo per un orizzonte brevissimo, e per giunta fragile rispetto al rumore. Funziona come smorzatore proprio perché non pretende di sapere molto: reagisce alla pendenza, niente di più. Quando serve davvero una previsione — simulare dove andrà il sistema su un orizzonte lungo, tenendo conto della sua dinamica e dei vincoli — lo strumento è un controllore con un modello esplicito, il model predictive control (in preparazione), non il termine DD di un PID. Confondere i due porta ad aspettarsi dal derivativo garanzie che non può dare.

“Più guadagno è meglio” resta una trappola. Vale per il PID quanto valeva per il controllore proporzionale del capitolo introduttivo. Ogni piccolo incremento di KpK_p o KiK_i sembra un miglioramento — la risposta è più pronta, l’errore cala più in fretta — finché, oltre una soglia, il sistema fa overshoot, poi oscilla con ampiezza crescente, poi diverge. L’instabilità non arriva gradualmente: arriva di colpo, al primo disturbo abbastanza grande. Chi tara “girando la manopola finché va più veloce” porta il sistema sull’orlo senza accorgersene.

Il PID non sa nulla del plant che controlla. È al tempo stesso la sua forza e il suo limite. La forza: un PID si tara senza un modello matematico del processo — basta osservare la risposta — e per questo è applicabile ovunque. Il limite: non potendo ragionare sul sistema, non può sfruttare ciò che del sistema si sa. Su un processo con più ingressi e più uscite accoppiati tra loro, o con vincoli espliciti da rispettare, o con dinamiche fortemente non lineari, il PID arranca, e servono gli strumenti del controllo moderno. Il PID è la scelta giusta per un problema con un ingresso e un’uscita, ben posto: per quello è imbattibile, e per quello è ovunque.

Il PID non gestisce i vincoli, li subisce. Un PID non sa dire “questa azione violerebbe un limite, ne scelgo un’altra”. Sa solo produrre un’azione e, semmai, vederla tagliata dalla saturazione dell’attuatore — con il windup come conseguenza. Se il problema ha vincoli che contano davvero — non superare mai una certa temperatura, non scendere sotto un certo livello, rispettare un limite di sicurezza — il PID non offre garanzie: insegue il setpoint e spera che i vincoli reggano. Gestire i vincoli dentro la logica di decisione è invece esattamente ciò che fa il model predictive control (in preparazione), ed è una delle ragioni per cui esiste.

Un PID tarato una volta lavora, prima o poi, su un plant diverso. La taratura di un PID fotografa il processo com’era nel momento della taratura. Ma i processi cambiano: una macchina si usura, un servizio software cambia codice e profilo di carico, una stagione porta condizioni diverse. Un PID con guadagni fissi continua a usare la fotografia vecchia. Spesso il margine di robustezza basta ad assorbire la deriva; quando non basta, il sistema peggiora lentamente e in modo subdolo — non si rompe di colpo, degrada — finché qualcuno non ritara. È il problema dell’incertezza di modello, e la risposta strutturale è il controllo robusto (in preparazione), che progetta per una famiglia di plant invece che per uno solo.

Un agente LLM non è un sistema dinamico nel senso classico. La griglia passato-presente-futuro del PID, e il vocabolario di windup, overshoot, guadagno, sono lenti utili per ragionare su un loop agentico o su un controllo di budget. Ma vanno usate con onestà. L‘“errore” di un agente è spesso una grandezza semantica — “la risposta è sbagliata” — non un numero letto da un sensore; i “disturbi” possono essere input avversari, non rumore con belle proprietà statistiche; la “stabilità” di un loop agentico non si dimostra con un criterio matematico. Le analogie tra PID e sistemi agentici sono strumenti diagnostici — danno un nome ai guasti, dicono dove guardare — non teoremi trasferibili. Diventano un errore nel momento in cui si pretende di applicare a un agente le garanzie del controllo lineare come se fossero dimostrate.

Il PID lavora bene su una grandezza scalare, fatica su tutto il resto. Tutta la struttura del PID assume che ci sia un errore — un singolo numero — da portare a zero. Funziona magnificamente quando il problema ha questa forma: una temperatura, una velocità, un livello. Ma molti problemi reali non si lasciano ridurre a uno scalare senza perdere qualcosa. Un sistema con più obiettivi che interagiscono — tieni bassa la latenza e basso il costo e alta la qualità — non ha un errore unico, ne ha diversi, e in conflitto. Si può applicare un PID a ciascuno separatamente, ma allora gli anelli interferiscono tra loro, e niente nel PID gestisce quell’interferenza. È il limite che spinge verso il controllo moderno e i metodi a più ingressi e più uscite. Il PID non sbaglia: semplicemente non è lo strumento per quel problema, e usarlo lì significa torturare il problema finché non sembra scalare.

Una chiusura sull’uso onesto di questi limiti. Nessuno di essi è un argomento contro il PID — sono le condizioni del suo dominio. Il PID è imbattibile per quello che è: un controllore scalare, senza modello, tarabile a mano, per problemi a un ingresso e un’uscita ben posti, dove gli attuatori non saturano cronicamente e il processo non cambia troppo nel tempo. Dentro quel recinto non c’è di meglio, e il recinto è enorme — è la ragione del 90% degli anelli industriali. Fuori dal recinto servono altri strumenti, e i capitoli che seguono nella Parte XI li forniscono. Sapere dove finisce il recinto è esattamente ciò che distingue chi usa il PID con cognizione da chi lo applica per abitudine e poi si stupisce quando, fuori dal suo dominio, delude.

  • Controllare un sistema: plant, controller, sensore, attuatore — fissa il vocabolario (plant, errore, setpoint, anello chiuso) e pone, con il termostato proporzionale, il problema dell’offset che questo capitolo chiude. Prerequisito diretto.
  • Overshoot, ritardo, oscillazioni, divergenza — i fenomeni che la taratura del PID negozia: il “perché alzare KiK_i o KpK_p destabilizza” si capisce a fondo lì.
  • Anatomia di un anello: errore, setpoint, guadagno, ritardo — l’anello a feedback negativo di cui il PID è la concretizzazione più diffusa.
  • stabilita-lyapunov-intuizione (in preparazione) — la stabilità resa rigorosa con l’idea di un’energia che decresce: complementare alla taratura empirica del PID.
  • Discesa del gradiente: SGD, momentum, Adam — il momentum come accumulo dei gradienti passati: l’analogia tra termine integrale e momentum si appoggia a questo capitolo.
  • ODE a intuizione per dinamiche e controllo — il PID a tempo continuo è un’equazione differenziale; integrale e derivata a intuito si costruiscono lì.
  • controllo-robusto (in preparazione) — l’incertezza di modello che un PID, tarato su un certo plant, eredita quando il plant cambia.
  • model-predictive-control (in preparazione) — il controllore che usa un modello esplicito del plant per simulare il futuro, dove il PID si limita a un’estrapolazione lineare a un passo.
  • Da feedback e controllo a MDP, Bellman, RL — controllo con modello contro apprendimento senza modello: il PID è l’estremo “struttura fissa, nessun modello esplicito”.
  • Feedback vs feedforward — il PID è feedback puro; nella pratica si combina spesso con un termine feedforward che anticipa i disturbi noti.
  • N. Minorsky, Directional Stability of Automatically Steered Bodies (Journal of the American Society of Naval Engineers, 1922). La prima formulazione teorica del controllo a tre termini, nata dall’osservazione di come sterza un timoniere. Documento storico fondante, leggibile.
  • J. G. Ziegler e N. B. Nichols, Optimum Settings for Automatic Controllers (Transactions of the ASME, vol. 64, 1942). Il primo metodo sistematico di taratura di un PID; tuttora il punto di partenza didattico, da leggere conoscendone i limiti.
  • Z. An, W. Zhu, X. Hu, Q. Zhang, A PID Controller Approach for Stochastic Optimization of Deep Networks (CVPR 2018). Il legame esplicito tra PID e ottimizzazione: un ottimizzatore che aggiunge un termine derivativo per smorzare l’overshoot del momentum.
  • B. Recht, The Best Things in Life Are Model Free (argmin blog, 2018). Una discussione accessibile e onesta della corrispondenza tra controllo integrale, discesa del gradiente e momentum, con i caveat sui limiti di validità.
  • Karl J. Åström e Richard M. Murray, Feedback Systems: An Introduction for Scientists and Engineers (Princeton University Press) — testo introduttivo moderno, disponibile gratuitamente online, con un trattamento completo del PID, dell’anti-windup e del filtraggio del derivativo.