Primjeri uporabe i primjene regulatora. PID regulator - puni opis, primjena. Koordinacija izlaznih uređaja kontinuiranih regulatora

Sustavi automatskog upravljanja (ACS) dizajnirani su za automatsku promjenu jednog ili više parametara upravljačkog objekta kako bi se uspostavio potreban način njegovog rada. ACS osigurava održavanje konstantnosti zadanih vrijednosti reguliranih parametara ili njihovu promjenu prema zadanom zakonu ili optimizira određene kriterije za kvalitetu upravljanja. Na primjer, takvi sustavi uključuju:

  • stabilizacijski sustavi,
  • sustavi kontrole programa,
  • sustavi praćenja

Ovo je prilično široka klasa sustava koji se mogu naći bilo gdje. Ali kakve to veze ima s Unity3D i vjerojatno igrama posebno? U principu, to je jednostavno: u svakoj igri koja na neki način koristi simulaciju kao element igranja, implementiraju se samohodne puške, takve igre uključuju, na primjer, Kerbal Space Programm, Digital Combat Simulator (bivši Lock On), Strike Suit Zero, itd. (tko zna više primjera - napišite u komentarima). U načelu, svaka igra koja simulira stvarne fizičke procese, uključujući jednostavno kinematiku s dinamikom gibanja, može implementirati jedno ili drugo samohodno oružje - ovaj je pristup jednostavniji, prirodniji, a programer već ima skup gotovih alata koje pruža sve vrste Višnjegradskih, Ljapunovih, Kalmana, Čebiševa i ostalih Kolomogorova, tako da možete bez ponovnog pronalaženja kotača, jer već je izmišljena, toliko da je postala zasebna znanost: Teorija automatskog upravljanja. Ovdje je glavna stvar ne pretjerivati. Postoji samo jedan problem: o TAU ne govore svugdje, ne svima, često malo i ne baš jasno.

Malo teorije

Klasični sustav automatskog upravljanja prikazan je na sljedećoj slici:



Ključni element svakog samohodnog oružja je regulator koji je uređaj koji prati stanje objekta upravljanja i osigurava traženi zakon upravljanja. Proces upravljanja uključuje: proračun greške upravljanja ili signala greške e(t) koja je razlika između željenog postavljanje(postavljena točka ili SP ) i trenutna vrijednost procesa (procesna vrijednost ili PV ), nakon čega regulator generira upravljačke signale (manipulirana vrijednost ili MV ).


Jedna vrsta regulatora je proporcionalno-integralno-derivacijski (PID) regulator, koji generira upravljački signal, koji je zbroj tri člana: proporcionalni, integralni i diferencijalni.



Gdje je pogreška neusklađenosti, kao i - proporcionalna, - integralna, - diferencijalna komponenta (članovi) regulacijskog zakona, koja je u svom konačnom obliku opisana sljedećim formulama




Proporcionalna komponenta P- odgovoran je za tzv proporcionalna regulacija, čije je značenje da se izlazni signal regulatora suprotstavlja odstupanju regulirane veličine (greška neusklađenosti ili također nazvana rezidual) od zadane vrijednosti. Što je veća greška neusklađenosti, veće je odstupanje naredbe regulatora. Ovo je najjednostavniji i najočitiji zakon upravljanja. Mana Zakon proporcionalne regulacije je da se regulator nikada ne stabilizira na zadanoj vrijednosti, a povećanje koeficijenta proporcionalnosti uvijek dovodi do samooscilacija. Zato je uz proporcionalni zakon upravljanja potrebno koristiti integralni i diferencijalni zakon.


Integralna komponenta I akumulira (integrira) pogrešku upravljanja, što omogućuje PID regulatoru da eliminira statičku pogrešku (stalna pogreška, zaostala pogreška). Ili drugim riječima: integralna poveznica uvijek unosi neku pristranost a ako je sustav podložan nekim stalnim pogreškama, onda ih kompenzira (zbog svoje pristranosti). Ali ako takvih pogrešaka nema ili su one zanemarivo male, tada će učinak biti suprotan - sama integralna komponenta unijet će pogrešku pomaka. Zbog toga se ne koristi, primjerice, u zadacima ultrapreciznog pozicioniranja. Ključ hendikep Integralni zakon upravljanja je učinak zasićenja integratora (Integrator windup).


Diferencijalna komponenta D proporcionalna je brzini promjene odstupanja kontrolirane varijable i dizajnirana je za suzbijanje odstupanja od ciljne vrijednosti, koja predviđaju se u budućnosti. Važno je napomenuti da diferencijalna komponenta eliminira prigušene oscilacije. Diferencijalno upravljanje je posebno učinkovito za procese koji imaju velika kašnjenja. Hendikep Diferencijalni zakon upravljanja je njegova nestabilnost na djelovanje buke (diferencijacijski šum).


Dakle, ovisno o situaciji, mogu se koristiti P-, PD-, PI- i PID-regulator, ali je glavni zakon regulacije uglavnom proporcionalan (iako se u nekim specifičnim zadacima mogu koristiti isključivo elementi diferencijatora i integratora).


Čini se da je pitanje implementacije PID regulatora odavno otrcano i ovdje na Habréu postoji nekoliko dobrih članaka o ovoj temi, uključujući Unity3D, također postoji dobar članak PID bez doktorata (prijevod) i niz članci u časopisu "Modern Automation Technologies" u dva dijela: prvi i drugi. Na usluzi vam je i članak na Wikipediji (pročitajte najpotpuniji u engleskoj verziji). A na forumima Unity3D zajednice ne, ne, i PID kontroler će se pojaviti baš kao na gamedev.stackexchange


Pitanje implementacije PID regulatora je nešto dublje nego što se čini. Toliko da mnoga prekrasna otkrića očekuju mlade DIYere koji odluče primijeniti takvu regulatornu shemu, a tema je relevantna. Pa se nadam da će ovaj opus nekome biti od koristi, pa krenimo.

Pokušaj broj jedan

Kao primjer, pokušat ćemo implementirati upravljačku shemu pomoću primjera kontrole okretanja u jednostavnoj 2D svemirskoj arkadnoj igri, korak po korak, počevši od samog početka (jeste li zaboravili da je ovo lekcija?).


Zašto ne 3D? Budući da se implementacija neće promijeniti, osim što ćete morati pojačati PID regulator za kontrolu nagiba, skretanja i okretanja. Iako je pitanje ispravne primjene PID kontrole zajedno s kvaternionima doista zanimljivo, možda ću o tome raspravljati u budućnosti, ali čak i NASA preferira Eulerove kutove umjesto kvaterniona, pa ćemo se zadovoljiti jednostavnim modelom na dvodimenzionalnom avion.


Za početak, kreirajmo sam objekt igre svemirski brod, koji će se sastojati od samog stvarnog objekta broda na najvišoj razini hijerarhije, i pripojimo mu objekt dijete Engine (čisto radi specijalnih efekata). Kod mene to izgleda ovako:



I na sam objekt svemirskog broda koji ubacujemo inspektor sve vrste komponenti. Gledajući unaprijed, dat ću snimak zaslona kako će to izgledati na kraju:



Ali to je za kasnije, a za sada u njemu nema skripti, samo standardni džentlmenski set: Sprite Render, RigidBody2D, Polygon Collider, Audio Source (zašto?).


Zapravo, fizika nam je sada najvažnija i upravljanje će se odvijati isključivo preko nje, inače bi upotreba PID regulatora izgubila smisao. Ostavimo i masu naše letjelice 1 kg, a svi koeficijenti trenja i gravitacije jednaki su nuli – u svemiru.


Jer Osim samog svemirskog broda, postoji još hrpa drugih, manje pametnih svemirskih objekata, pa ćemo prvo opisati roditeljsku klasu Osnovno tijelo, koji će sadržavati poveznice na naše komponente, metode inicijalizacije i uništavanja, kao i niz dodatnih polja i metoda, na primjer, za implementaciju nebeske mehanike:


BaseBody.cs

koristeći UnityEngine; koristeći System.Collections; koristeći System.Collections.Generic; namespace Assets.Scripts.SpaceShooter.Bodies ( javna klasa BaseBody: MonoBehaviour ( readonly float _deafultTimeDelay = 0.05f; javni statički popis _tijela = novi popis (); #region RigidBody public Rigidbody2D _rb2d; javni Collider2D_c2d; #endregion #region Reference public Transform _myTransform; javni GameObject _myObject; ///

/// Objekt koji se pojavljuje kada se uništi /// public GameObject_explodePrefab; #endregion #region Audio public AudioSource _audioSource; /// /// Zvukovi koji se reproduciraju prilikom primanja oštećenja /// javni AudioClip_hitSounds; /// /// Zvukovi koji se reprodukuju kada se objekt pojavi /// javni AudioClip_awakeSounds; /// /// Zvukovi koji se sviraju prije smrti /// javni AudioClip_deadSounds; #endregion #region Varijable vanjske sile /// /// Vanjske sile koje djeluju na objekt /// public Vector2 _ExternalForces = new Vector2(); /// /// Vektor trenutne brzine /// javni Vektor2 _V = novi Vektor2(); /// /// Trenutni vektor gravitacije /// javni Vektor2 _G = novi Vektor2(); #endregion public virtual void Awake() ( Init(); ) public virtual void Start() ( ) public virtual void Init() ( _myTransform = this.transform; _myObject = gameObject; _rb2d = GetComponent (); _c2d = GetComponentsInChildren (); _audioSource = GetComponent (); Reproduciraj slučajni zvuk (_probuđeni zvukovi); BaseBody bb = GetComponent (); _tijela.Dodaj(bb); ) /// /// Uništavanje lika /// javna virtualna praznina Destroy() ( _bodies.Remove(this); for (int i = 0; i< _c2d.Length; i++) { _c2d[i].enabled = false; } float _t = PlayRandomSound(_deadSounds); StartCoroutine(WaitAndDestroy(_t)); } /// /// Čekamo neko vrijeme prije uništenja /// /// Vrijeme čekanja /// public IEnumerator WaitAndDestroy(float waitTime) ( yield return new WaitForSeconds(waitTime); if (_explodePrefab) ( Instantiate(_explodePrefab, transform.position, Quaternion.identity); ) Destroy(gameObject, _deafultTimeDelay); ) /// /// Pusti slučajni zvuk /// /// Niz zvukova /// Trajanje reproduciranog zvuka public float PlayRandomSound(AudioClip audioClip) ( float _t = 0; if (audioClip.Length > 0) ( int _i = UnityEngine.Random.Range(0, audioClip.Length - 1); AudioClip _audioClip = audioClip[_i]; _t = _audioClip.length; _audioSource.PlayOneShot(_audioClip); ) return _t; ) /// /// Uzimanje štete /// /// Razina oštećenja public virtual void Damage(float damage) ( PlayRandomSound(_hitSounds); ) ) )


Čini se da smo opisali sve što je trebalo, čak i više nego što je trebalo (u okviru ovog članka). Sada od njega naslijedimo klasu broda Brod, koji bi se trebao moći kretati i okretati:


SpaceShip.cs

koristeći UnityEngine; koristeći System.Collections; koristeći System.Collections.Generic; namespace Assets.Scripts.SpaceShooter.Bodies ( public class Ship: BaseBody ( public Vector2 _movement = new Vector2(); public Vector2 _target = new Vector2(); public float _rotation = 0f; public void FixedUpdate() ( float moment = ControlRotate( _rotacija); Vector2 sila = ControlForce(_movement); _rb2d.AddTorque(torque); _rb2d.AddRelativeForce(force); ) public float ControlRotate(Vector2 rotate) ( float result = 0f; return result; ) public Vector2 ControlForce(Vector2 movement) ( Vektor2 rezultat = novi Vektor2(); vrati rezultat; ) ) )


Iako u njemu nema ničeg zanimljivog, trenutno je to samo nastava.


Također ćemo opisati osnovnu (apstraktnu) klasu za sve ulazne kontrolere BaseInputController:


BaseInputController.cs

koristeći UnityEngine; koristeći Assets.Scripts.SpaceShooter.Bodies; namespace Assets.Scripts.SpaceShooter.InputController ( javni enum eSpriteRotation ( Desno = 0, Gore = -90, Lijevo = -180, Dolje = -270 ) javna apstraktna klasa BaseInputController: MonoBehaviour ( javni GameObject _agentObject; javni Brod _agentBody; // Link na logičku komponentu broda public eSpriteRotation _spriteOrientation = eSpriteRotation.Up; //To je zbog nestandardne // orijentacije spritea "gore" umjesto "desno" public abstract void ControlRotate(float dt); public abstract void ControlForce (float dt); public virtual void Start() ( _agentObject = gameObject; _agentBody = gameObject.GetComponent (); ) public virtual void FixedUpdate() ( float dt = Time.fixedDeltaTime; ControlRotate(dt); ControlForce(dt); ) public virtual void Update() ( //TO DO ) ) )


I na kraju, klasa kontrolera igrača PlayerFigtherInput:


PlayerInput.cs

koristeći UnityEngine; koristeći Assets.Scripts.SpaceShooter.Bodies; namespace Assets.Scripts.SpaceShooter.InputController ( public class PlayerFigtherInput: BaseInputController ( public override void ControlRotate(float dt) ( // Određivanje položaja miša u odnosu na igrača Vector3 worldPos = Input.mousePosition; worldPos = Camera.main.ScreenToWorldPoint (worldPos); / / Spremite koordinate pokazivača miša float dx = -this.transform.position.x + worldPos.x; float dy = -this.transform.position.y + worldPos.y; //Predaj smjer Vector2 target = new Vector2(dx, dy); _agentBody._target = target; //Izračunaj rotaciju prema pritiscima tipki float targetAngle = Mathf.Atan2(dy, dx) * Mathf.Rad2Deg; _agentBody._targetAngle = targetAngle + (float)_spriteOrientation ; ) javno nadjačavanje void ControlForce( float dt) ( //Prolaz kretanja _agentBody._movement = Input.GetAxis("Vertical") * Vector2.up + Input.GetAxis("Horizontal") * Vector2.right; ) ) )


Čini se da smo završili, sada konačno možemo prijeći na ono zbog čega je sve ovo započeto, tj. PID regulatori (nadam se da niste zaboravili?). Njegova se implementacija čini vraški jednostavnom:


korištenje sustava; koristeći System.Collections.Generic; koristeći System.Linq; koristeći System.Text; namespace Assets.Scripts.Regulator ( // Ovaj je atribut neophodan za polja regulatora // za prikaz u inspektoru i serijaliziranu javnu klasu SimplePID ( javni float Kp, Ki, Kd; privatni float lastError; privatni float P, I, D ; public SimplePID() ( Kp = 1f; Ki = 0; Kd = 0.2f; ) public SimplePID(float pFactor, float iFactor, float dFactor) ( this.Kp = pFactor; this.Ki = iFactor; this.Kd = dFactor ; ) public float Update(float error, float dt) ( P = error; I += error * dt; D = (error - lastError) / dt; lastError = error; float CO = P * Kp + I * Ki + D * Kd ; vrati CO; ) ) )

Zadane vrijednosti koeficijenata uzet ćemo iz ničega: to će biti trivijalni pojedinačni koeficijent zakona proporcionalnog upravljanja Kp = 1, mala vrijednost koeficijenta za zakon diferencijalnog upravljanja Kd = 0,2, što bi trebalo eliminirati očekivane fluktuacije i nultu vrijednost za Ki, što je odabrano jer u našem softveru model nema statičkih grešaka (ali ih uvijek možete unijeti, a zatim se herojski boriti uz pomoć integratora).


Sada se vratimo našoj klasi SpaceShip i pokušajmo upotrijebiti našu kreaciju kao kontroler rotacije svemirskog broda u metodi ControlRotate:


public float ControlRotate(Vector2 rotate) ( float MV = 0f; float dt = Time.fixedDeltaTime; //Izračunajte grešku float angleError = Mathf.DeltaAngle(_myTransform.eulerAngles.z, targetAngle); //Dobijte korektivno ubrzanje MV = _angleController .Ažuriraj (angleError, dt); vrati MV; )

PID regulator će izvršiti precizno kutno pozicioniranje letjelice koristeći samo okretni moment. Sve je pošteno, fizika i samohotke, skoro kao u stvarnom životu.


I bez ovih Quaternion.Lerp tvojih

if (!_rb2d.freezeRotation) rb2d.freezeRotation = istina; float deltaAngle = Mathf.DeltaAngle(_myTransform.eulerAngles.z, targetAngle); float T = dt * Mathf.Abs(_rotationSpeed ​​​​/ deltaAngle); // Transformirajte kut u vektor Quaternion rot = Quaternion.Lerp(_myTransform.rotation, Quaternion.Euler(new Vector3(0, 0, targetAngle)), T); // Promjena rotacije objekta _myTransform.rotation = rot;


Rezultirajući izvorni kod Ship.cs je ispod spojlera

koristeći UnityEngine; koristeći Assets.Scripts.Regulator; namespace Assets.Scripts.SpaceShooter.Bodies ( public class Ship: BaseBody ( public GameObject _flame; public Vector2 _movement = new Vector2(); public Vector2 _target = new Vector2(); public float _targetAngle = 0f; public float _angle = 0f; public SimplePID _angleController = new SimplePID(); public void FixedUpdate() ( float moment = ControlRotate(_targetAngle); Vector2 force = ControlForce(_movement); _rb2d.AddTorque(torque); _rb2d.AddRelativeForce(force); ) public float ControlRotate(float rotirati) ( float MV = 0f; float dt = Time.fixedDeltaTime; _angle = _myTransform.eulerAngles.z; //Izračunaj grešku float angleError = Mathf.DeltaAngle(_angle, rotate); //Dohvati korektivno ubrzanje MV = _angleController. Update( angleError, dt); return MV; ) public Vector2 ControlForce(Vector2 movement) ( Vector2 MV = new Vector2(); //Dio koda za poseban učinak pokrenutog motora radi if (kretanja != Vector2.nula) ( if (_flame != null) ( _flame.SetActive(true); ) ) else ( if (_flame != null) ( _flame.SetActive(false); ) ) MV = kretanje; vratiti MV; ) ) )


Svi? Hoćemo li kući?



WTF! Što se događa? Zašto se brod čudno okreće? I zašto se tako oštro odbija od drugih predmeta? Ne radi li ovaj glupi PID regulator?


Nemojte paničariti! Pokušajmo shvatiti što se događa.


U trenutku kada se primi nova SP vrijednost, dolazi do oštrog (stepenastog) skoka u neusklađenosti pogreške, koja se, kao što se sjećamo, izračunava ovako: prema tome, dolazi do oštrog skoka u pogrešci derivacije, koju izračunavamo u ova linija koda:


D = (pogreška - zadnja pogreška) / dt;

Možete, naravno, pokušati s drugim shemama diferencijacije, na primjer, s tri točke, ili s pet točaka, ili ... ali to još uvijek neće pomoći. Pa, ne vole derivate oštrih skokova - na takvim točkama funkcija nije diferencijabilan. Međutim, vrijedi eksperimentirati s različitim shemama diferencijacije i integracije, ali tada, a ne u ovom članku.


Mislim da je došlo vrijeme za izradu grafikona prijelaznog procesa: postupno djelovanje od S(t) = 0 do SP(t) = 90 stupnjeva za tijelo težine 1 kg, duljinu kraka sile od 1 metar i korak diferencijacijske mreže od 0,02 s - baš kao u našem primjeru u Unity3D (zapravo, ne u potpunosti; prilikom konstruiranja ovih grafova nije uzeto u obzir da moment tromosti ovisi o geometriji čvrstog tijela, pa će prijelazni proces biti malo različiti, ali ipak dovoljno slični za demonstraciju). Sve vrijednosti na grafikonu date su u apsolutnim vrijednostima:


Hmm, što se ovdje događa? Gdje je nestao odgovor PID regulatora?


Čestitamo, upravo smo se susreli s takvim fenomenom kao što je "udarac". Očito, u trenutku kada je proces još uvijek PV = 0, a zadana vrijednost je već SP = 90, tada s numeričkom diferencijacijom dobivamo deriviranu vrijednost reda 4500, koja će biti pomnožena s Kd=0,2 i zbrojimo s proporcionalnim teromom, tako da na izlazu dobijemo vrijednost kutne akceleracije od 990, a to je već potpuna sramota za fizički model Unity3D (kutne brzine će doseći 18000 deg/s... Mislim da je ovo granična vrijednost kutne brzine za RigidBody2D).


  • Možda je vrijedno ručno odabrati koeficijente kako skok ne bi bio tako jak?
  • Ne! Najbolje što na ovaj način možemo postići je mala amplituda skoka derivacije, ali će sam skok ostati kakav je bio i u tom slučaju diferencijalna komponenta može postati potpuno neučinkovita.

Međutim, možete eksperimentirati.

Pokušaj broj dva. Zasićenost

Logično je da pogonska jedinica(u našem slučaju, virtualni manevarski motori SpaceShip-a), ne mogu podnijeti velike vrijednosti ​​koje naš ludi regulator može proizvesti. Dakle, prvo što ćemo učiniti je zasićiti izlaz regulatora:


public float ControlRotate(Vector2 rotate, float thrust) ( float CO = 0f; float MV = 0f; float dt = Time.fixedDeltaTime; //Izračunaj grešku float angleError = Mathf.DeltaAngle(_myTransform.eulerAngles.z, targetAngle); / / Dobivamo korektivno ubrzanje CO = _angleController.Update(angleError, dt); //Zasititi MV = CO; if (MV > potisak) MV = potisak; if (MV< -thrust) MV = -thrust; return MV; }

I još jednom prepisana klasa Ship izgleda ovako:

namespace Assets.Scripts.SpaceShooter.Bodies ( public class Ship: BaseBody ( public GameObject _flame; public Vector2 _movement = new Vector2(); public Vector2 _target = new Vector2(); public float _targetAngle = 0f; public float _angle = 0f; public float _thrust = 1f; public SimplePID _angleController = new SimplePID(0.1f,0f,0.05f); public void FixedUpdate() ( _torque = ControlRotate(_targetAngle, _thrust); _force = ControlForce(_movement); _rb2d.AddTorque(_torque); _rb2d.AddRelativeForce(_force); ) public float ControlRotate(float targetAngle, float thrust) ( float CO = 0f; float MV = 0f; float dt = Time.fixedDeltaTime; //Izračunaj grešku float angleError = Mathf.DeltaAngle(_myTransform. eulerAngles .z, targetAngle); //Dohvati korektivno ubrzanje CO = _angleController.Update(angleError, dt); //Zasići MV = CO; if (MV > potisak) MV = potisak; if (MV< -thrust) MV = -thrust; return MV; } public Vector2 ControlForce(Vector2 movement) { Vector2 MV = new Vector2(); if (movement != Vector2.zero) { if (_flame != null) { _flame.SetActive(true); } } else { if (_flame != null) { _flame.SetActive(false); } } MV = movement * _thrust; return MV; } public void Update() { } } }


Konačna shema naših samohodnih topova tada će izgledati ovako


Istodobno postaje jasno da je izlaz regulatora CO(t) malo razlikuje od kontrolirane varijable procesa MV(t).


Zapravo, s ovog mjesta već možete dodati novi entitet igre - pogonska jedinica, kroz koji će se kontrolirati proces, čija logika može biti složenija od Mathf.Clamp(), na primjer, možete uvesti diskretizaciju vrijednosti (kako ne biste preopteretili fiziku igre s vrijednostima koje dolaze u šestinama nakon decimalne točke), mrtva zona (opet, nema smisla opteretiti fiziku ultra-malim reakcijama), uvesti kašnjenje u kontrolu i nelinearnost (na primjer, sigmoid) pogona, a zatim vidjeti što dolazi od toga.


Nakon što smo pokrenuli igru, vidjet ćemo da je svemirski brod konačno postao kontroliran:



Ako izgradite grafikone, možete vidjeti da je odgovor kontrolera postao ovakav:


Ovdje se već koriste normalizirane vrijednosti, kutovi se dijele s SP vrijednošću, a izlaz regulatora se normalizira u odnosu na maksimalnu vrijednost pri kojoj već dolazi do zasićenja.

Ispod je dobro poznata tablica učinka povećanja parametara PID regulatora ( Kako mogu smanjiti font, jer u protivnom tablica za rastavljanje riječi neće odgovarati?):



A opći algoritam za ručno podešavanje PID regulatora je sljedeći:


  1. Odabiremo proporcionalne koeficijente s isključenim diferencijalnim i integralnim vezama dok ne počnu samooscilacije.
  2. Postupnim povećanjem diferencijalne komponente oslobađamo se autooscilacija
  3. Ako postoji zaostala pogreška upravljanja (pomak), tada je uklanjamo integralnom komponentom.

Ne postoje opće vrijednosti za parametre PID regulatora: specifične vrijednosti ovise isključivo o parametrima procesa (njegova prijenosna karakteristika): PID regulator koji savršeno radi s jednim objektom upravljanja neće raditi s drugim. Štoviše, koeficijenti za proporcionalne, integralne i diferencijalne komponente također su međusobno ovisni.


Pokušaj broj tri. Opet izvedenice

Priloživši štaku u vidu ograničenja izlaznih vrijednosti regulatora, još uvijek nismo riješili najvažniji problem našeg regulatora - diferencijalna komponenta ne radi dobro kada se pogreška na ulazu regulatora mijenja stepenasto. Zapravo, postoje mnoge druge štake, na primjer, u trenutku nagle promjene SP-a, "isključite" diferencijalnu komponentu ili instalirajte niskopropusne filtre između SP(t) i operaciju zbog koje će se pogreška postupno povećavati ili se možete potpuno okrenuti i koristiti pravi Kalmanov filtar za izglađivanje ulaznih podataka. Općenito, ima puno štaka, i dodati posmatrač Naravno da bih volio, ali ne ovaj put.


Stoga se vratimo na derivat pogreške neusklađenosti i pogledajmo ga pažljivo:



Jeste li što primijetili? Ako pažljivo pogledate, otkrit ćete da se, općenito, SP(t) ne mijenja tijekom vremena (osim trenutaka promjene koraka kada kontroler primi novu naredbu), tj. njegova derivacija je nula:





Drugim riječima, umjesto pogreške derivacije koja je diferencijabilna ne posvuda možemo upotrijebiti derivaciju procesa, koji je u svijetu klasične mehanike obično kontinuiran i posvuda diferenciran, a dijagram našeg sustava automatskog upravljanja već će imati sljedeći oblik:




Modificirajmo kod kontrolera:


korištenje sustava; koristeći System.Collections.Generic; koristeći System.Linq; koristeći System.Text; imenski prostor Assets.Scripts.Regulator ( javna klasa SimplePID ( javni float Kp, Ki, Kd; privatni float P, I, D; privatni float lastPV = 0f; javni SimplePID() ( Kp = 1f; Ki = 0f; Kd = 0.2f ; ) public SimplePID(float pFactor, float iFactor, float dFactor) ( this.Kp = pFactor; this.Ki = iFactor; this.Kd = dFactor; ) public float Update(float error, float PV, float dt) ( P = greška; I += greška * dt; D = -(PV - lastPV) / dt; lastPV = PV; float CO = Kp * P + Ki * I + Kd * D; return CO; ) ) )

I promijenimo malo ControlRotate metodu:


public float ControlRotate(Vector2 rotate, float thrust) ( float CO = 0f; float MV = 0f; float dt = Time.fixedDeltaTime; //Izračunaj grešku float angleError = Mathf.DeltaAngle(_myTransform.eulerAngles.z, targetAngle); / / Dobivamo korektivno ubrzanje CO = _angleController.Update(angleError, _myTransform.eulerAngles.z, dt); //Zasićiti MV = CO; if (CO >< -thrust) MV = -thrust; return MV; }

I-i-i-i... ako pokrenete igru, vidjet ćete da se zapravo ništa nije promijenilo od zadnjeg pokušaja, što je trebalo i dokazati. Međutim, ako uklonite zasićenje, graf odziva regulatora izgledat će ovako:


Skok CO(t) je i dalje prisutna, ali više nije tako velika kao što je bila na samom početku, a što je najvažnije, postala je predvidljiva, jer osigurava isključivo proporcionalna komponenta, a ograničena je maksimalnom mogućom pogreškom neusklađenosti i proporcionalnim pojačanjem PID regulatora (a to već daje naslutiti da Kp ima smisla odabrati manje od jedinice, na primjer, 1/90f), ali ne ovisi o koraku mreže diferencijacije (tj. dt). Općenito, toplo preporučujem korištenje izvedenice procesa umjesto pogreške.


Mislim da sada nikoga neće iznenaditi, ali na isti način možete ga zamijeniti s , ali nećemo se zadržavati na ovome, možete sami eksperimentirati i reći u komentarima što je ispalo iz toga (najzanimljivije)

Pokušaj broj četiri. Alternativne izvedbe PID regulatora

Osim gore opisanog idealnog prikaza PID regulatora, u praksi se često koristi standardni oblik, bez koeficijenata Ki I Kd, umjesto kojih se koriste privremene konstante.


Ovaj pristup je zbog činjenice da se brojne tehnike ugađanja PID regulatora temelje na frekvencijskim karakteristikama PID regulatora i procesa. Zapravo se cijeli TAU vrti oko frekvencijskih karakteristika procesa, pa ću za one koji žele ići dublje, a odjednom se susreću s alternativnom nomenklaturom, dati primjer tzv. standardna forma PID regulator:




gdje je konstanta diferencijacije koja utječe na predviđanje stanja sustava od strane regulatora,
- integracijska konstanta, koja utječe na interval usrednjavanja pogreške integralnom vezom.


Osnovni principi za podešavanje PID regulatora u standardnom obliku slični su idealiziranom PID regulatoru:

  • povećanjem proporcionalnog koeficijenta povećava se učinak i smanjuje granica stabilnosti;
  • sa smanjenjem integralne komponente, pogreška upravljanja se smanjuje brže tijekom vremena;
  • smanjenje integracijske konstante smanjuje marginu stabilnosti;
  • povećanje diferencijalne komponente povećava marginu stabilnosti i performanse

Izvorni kod standardnog obrasca nalazi se ispod spojlera

imenski prostor Assets.Scripts.Regulator ( javna klasa StandartPID ( javni float Kp, Ti, Td; pogreška javnog float-a, CO; javni float P, I, D; privatni float lastPV = 0f; javni StandartPID() ( Kp = 0.1f; Ti = 10000f; Td = 0.5f; bias = 0f; ) javni StandardPID(float Kp, float Ti, float Td) ( this.Kp = Kp; this.Ti = Ti; this.Td = Td; ) public float Update(float pogreška, float PV, float dt) ( this.error = pogreška; P = pogreška; I += (1 / Ti) * pogreška * dt; D = -Td * (PV - lastPV) / dt; CO = Kp * ( P + I + D); zadnji PV = PV; povratak CO; ) ) )

Zadane vrijednosti su Kp = 0,01, Ti = 10000, Td = 0,5 - s ovim vrijednostima brod se okreće prilično brzo i ima određenu marginu stabilnosti.


Osim ovog oblika PID regulatora, tzv rekurentni oblik:



Nećemo se zadržavati na tome, jer... prvenstveno je relevantan za hardverske programere koji rade s FPGA i mikrokontrolerima, gdje je takva implementacija mnogo praktičnija i učinkovitija. U našem slučaju - dajmo nešto na gomile na Unity3D - ovo je samo još jedna implementacija PID regulatora, koja nije ništa bolja od ostalih i još manje razumljiva, pa se još jednom svi radujemo koliko je dobro programirati u udobnom C# , a ne u jezivom i strašnom VHDL-u, na primjer.

Umjesto zaključka. Gdje biste drugdje dodali PID regulator?

Pokušajmo sada malo zakomplicirati upravljanje brodom pomoću kontrole s dvostrukom petljom: jedan PID regulator, koji nam je već poznat _angleController, i dalje je odgovoran za kutno pozicioniranje, ali drugi - novi, _angularVelocityController - kontrolira brzinu rotacije:


public float ControlRotate(float targetAngle, float potisak) ( float CO = 0f; float MV = 0f; float dt = Time.fixedDeltaTime; _angle = _myTransform.eulerAngles.z; //Kut kontrolera rotacije float angleError = Mathf.DeltaAngle(_angle, targetAngle); float torqueCorrectionForAngle = _angleController.Update(angleError, _angle, dt); //Regulator stabilizacije brzine float angularVelocityError = -_rb2d.angularVelocity; float torqueCorrectionForAngularVelocity = _angularVelocityController.Update(angularVelocityEr ror, -angularVelocityError, dt); //Ukupno izlaz regulatora CO = torqueCorrectionForAngle + torqueCorrectionForAngularVelocity; //Uzorak u koracima od 100 CO = Mathf.Round(100f * CO) / 100f; //Zasićeni MV = CO; if (CO > potisak) MV = potisak; if (CO< -thrust) MV = -thrust; return MV; }

Svrha drugog regulatora je prigušiti prekomjerne kutne brzine promjenom okretnog momenta - to je slično prisutnosti kutnog trenja, koje smo isključili prilikom stvaranja objekta igre. Takva shema upravljanja [moguće] će omogućiti postizanje stabilnijeg ponašanja broda, pa čak i proći samo s proporcionalnim koeficijentima upravljanja - drugi regulator će prigušiti sve fluktuacije, obavljajući funkciju sličnu diferencijalnoj komponenti prvog regulatora .


Dodatno ćemo dodati novu klasu za unos igrača - PlayerInputCorvette, u kojoj će se okreti izvoditi pritiskom na desnu-lijevu tipku, a ostavit ćemo označavanje cilja mišem za nešto korisnije, na primjer, za upravljanje kupolom . U isto vrijeme, sada imamo takav parametar kao što je _turnRate - koji je odgovoran za brzinu/odzivnost skretanja (nije jasno gdje ga je bolje postaviti u InputCOntroller ili ipak Ship).


javna klasa PlayerCorvetteInput: BaseInputController ( public float _turnSpeed ​​​​= 90f; public override void ControlRotate() ( // Pronađite pokazivač miša Vector3 worldPos = Input.mousePosition; worldPos = Camera.main.ScreenToWorldPoint(worldPos); // Pohranite relativnu koordinate pokazivača miša float dx = -this.transform.position.x + worldPos.x; float dy = -this.transform.position.y + worldPos.y; //Predaj smjer pokazivača miša Vector2 target = new Vector2( dx, dy); _agentBody. _target = target; //Izračunaj rotaciju u skladu s pritiscima tipki _agentBody._rotation -= Input.GetAxis("Horizontal") * _turnSpeed ​​​​* Time.deltaTime; ) public override void ControlForce() ( //Prolaz kretanja _agentBody._movement = Unos .GetAxis("Vertical") * Vector2.up; ) )

Također, radi jasnoće, stavit ćemo skriptu na koljena za prikaz informacija o otklanjanju pogrešaka

namespace Assets.Scripts.SpaceShooter.UI ( javna klasa Debugger: MonoBehaviour ( Ship _ship; BaseInputController _controller; List _pids = novi popis (); Popis _names = novi popis (); Vektor2 _orijentacija = novi Vektor2(); // Koristite ovo za inicijalizaciju void Start() ( _ship = GetComponent (); _kontroler = GetComponent (); _pids.Add(_ship._angleController); _names.Add("Kutni regulator"); _pids.Add(_ship._angularVelocityController); _names.Add("Kutna kontrola brzine"); ) // Ažuriranje se poziva jednom po okviru void Update() ( DrawDebug(); ) Vector3 GetDiretion(eSpriteRotation spriteRotation) ( switch (_controller._spriteOrientation) ( case eSpriteRotation.Rigth: return transform.right; case eSpriteRotation.Up: return transform .up; case eSpriteRotation.Left: return -transform.right; case eSpriteRotation.Down: return -transform.up; ) return Vector3.zero; ) void DrawDebug() ( //Smjer rotacije Vector3 vectorToTarget = transform.position + 5f * new Vector3(-Mathf.Sin(_ship._targetAngle * Mathf.Deg2Rad), Mathf.Cos(_ship._targetAngle * Mathf.Deg2Rad), 0f); // Trenutni smjer Vektor3 smjer = transform.position + 4f * GetDiretion(_controller. _spriteOrientation); //Kutno ubrzanje Vector3 moment = smjer - transform.desno * _ship._Torque; Debug.DrawLine(transform.position, vectorToTarget, Color.white); Debug.DrawLine(transform.position, heading, Color.green); Debug.DrawLine(heading, torque, Color.red); ) void OnGUI() ( float x0 = 10; float y0 = 100; float dx = 200; plovak dy = 40; float SliderKpMax = 1; float SliderKpMin = 0; float SliderKiMax = .5f; float SliderKiMin = -,5f; float SliderKdMax = .5f; float SliderKdMin = 0; int i = 0; foreach (SimplePID pid u _pids) ( y0 += 2 * dy; GUI.Box(new Rect(25 + x0, 5 + y0, dx, dy), ""); pid.Kp = GUI.HorizontalSlider(new Rect( 25 + x0, 5 + y0, 200, 10), pid.Kp, SliderKpMin, SliderKpMax); pid.Ki = GUI.HorizontalSlider(novi pravougaonik(25 + x0, 20 + y0, 200, 10), pid.Ki, SliderKiMin, SliderKiMax); pid.Kd = GUI.HorizontalSlider(new Rect(25 + x0, 35 + y0, 200, 10), pid.Kd, SliderKdMin, SliderKdMax); GUIStyle style1 = new GUIStyle(); style1.alignment = TextAnchor.MiddleRight; style1.fontStyle = FontStyle.Bold; style1.normal.textColor = Color.yellow; style1.fontSize = 9; GUI.Label(new Rect(0 + x0, 5 + y0, 20, 10), "Kp ", style1); GUI.Label(new Rect(0 + x0, 20 + y0, 20, 10), "Ki", ​​​​style1); GUI.Label(new Rect(0 + x0, 35 + y0, 20) , 10 ), "Kd", style1); GUIStyle style2 = new GUIStyle(); style2.alignment = TextAnchor.MiddleLeft; style2.fontStyle = FontStyle.Bold; style2.normal.textColor = Color.yellow; style2.fontSize = 9 ; GUI .TextField(new Rect(235 + x0, 5 + y0, 60, 10), pid.Kp.ToString(), style2); GUI.TextField(new Rect(235 + x0, 20 + y0, 60, 10), pid. Ki.ToString(), stil2); GUI.TextField(new Rect(235 + x0, 35 + y0, 60, 10), pid.Kd.ToString(), style2); GUI.Label(new Rect(0 + x0, -8 + y0, 200, 10), _names, style2); ) ) ) )


Klasa Brod također je prošla nepovratne mutacije i sada bi trebala izgledati ovako:

namespace Assets.Scripts.SpaceShooter.Bodies ( public class Ship: BaseBody ( public GameObject _flame; public Vector2 _movement = new Vector2(); public Vector2 _target = new Vector2(); public float _targetAngle = 0f; public float _angle = 0f; public float _thrust = 1f; javni SimplePID _angleController = novi SimplePID(0.1f,0f,0.05f); javni SimplePID _angularVelocityController = novi SimplePID(0f,0f,0f); privatni float _torque = 0f; javni float _Torque ( get ( return _torque; ) ) private Vector2 _force = new Vector2(); public Vector2 _Force ( get ( return _force; ) ) public void FixedUpdate() ( _torque = ControlRotate(_targetAngle, _thrust); _force = ControlForce(_movement, _thrust); _rb2d.AddTorque( _torque); _rb2d.AddRelativeForce(_force); ) public float ControlRotate(float targetAngle, float thrust) ( float CO = 0f; float MV = 0f; float dt = Time.fixedDeltaTime; _angle = _myTransform.eulerAngles.z; //Kontroler kut rotacije float angleError = Mathf.DeltaAngle(_angle, targetAngle); float momentCorrectionForAngle = _angleController.Update(angleError, _angle, dt); //Regulator stabilizacije brzine float angularVelocityError = -_rb2d.angularVelocity; float torqueCorrectionForAngularVelocity = _angularVelocityController.Update(angularVelocityError, -angularVelocityError, dt); //Ukupni izlaz regulatora CO = torqueCorrectionForAngle + torqueCorrectionForAngularVelocity; //Diskretiziraj u koracima od 100 CO = Mathf.Round(100f * CO) / 100f; //Zasićiti MV = CO; if (CO > potisak) MV = potisak; ako (CO< -thrust) MV = -thrust; return MV; } public Vector2 ControlForce(Vector2 movement, float thrust) { Vector2 MV = new Vector2(); if (movement != Vector2.zero) { if (_flame != null) { _flame.SetActive(true); } } else { if (_flame != null) { _flame.SetActive(false); } } MV = movement * thrust; return MV; } public void Update() { } } }

Još nekoliko poveznica na druge primjere

Pojas proporcionalnosti X p, kao i odstupanje E, izražava se u jedinicama kontroliranog parametra. Što je širi proporcionalni pojas X p, to je manji izlazni signal Y za isto odstupanje E.

Izvan proporcionalnog pojasa, Y izlaz je 0 ili 100%.

Kada djeluje P-zakon, regulator proizvodi impulse u kojima je prisutna samo proporcionalna komponenta vrijednosti izlaznog signala.


Kada uređaj radi u načinu rada PD regulatora, veličina izlaznog signala Yi ne ovisi samo o veličini odstupanja Ei, već i o brzini njegove promjene:

Promjena izlaznog signala regulatora uz postupnu promjenu odstupanja prikazana je na slici. U prvom razdoblju nakon koraka promjene E i, regulator izdaje upravljački impuls, u kojem se, uz proporcionalnu komponentu uzrokovanu neusklađenošću E i, dodaje diferencijal (osjenčani dio) ΔYd, koji ovisi o vrijednosti od ΔE i i τ l koeficijenta. U sljedećim impulsima postoji samo proporcionalna komponenta, budući da nema promjene u E i.


Slika pokazuje da u prvom trenutku vremena, kada nema odstupanja (E i =0), nema izlaznog signala (Y i =0). S pojavom odstupanja E i pojavljuju se impulsi čije se trajanje postupno povećava. Impulsi sadrže proporcionalnu komponentu, koja ovisi o vrijednosti E (neosjenčani dio impulsa) i integralnu komponentu (osjenčani dio). Do povećanja trajanja impulsa dolazi zbog povećanja integralne komponente koja ovisi o neusklađenosti E i i koeficijentu τ i.

Diferencijalni proporcionalno-integralni regulator je uređaj koji se ugrađuje u automatizirane sustave za održavanje zadanog parametra koji se može mijenjati.

Na prvi pogled sve je zbunjujuće, ali PID regulacija se može objasniti za lutke, tj. ljudi koji nisu u potpunosti upoznati s elektroničkim sustavima i uređajima.

Što je PID regulator?

PID regulator je uređaj ugrađen u regulacijski krug s obveznom povratnom spregom. Dizajniran je za održavanje utvrđenih razina specificiranih vrijednosti, na primjer, temperature zraka.

Uređaj isporučuje upravljački ili izlazni signal upravljačkom uređaju, na temelju podataka primljenih od senzora ili senzora. Kontroleri imaju visoku točnost prijelaznih procesa i kvalitetu obavljanja dodijeljenog zadatka.

Tri koeficijenta PID regulatora i princip rada

Rad PID regulatora je osigurati izlazni signal o snazi ​​potrebnoj za održavanje kontroliranog parametra na zadanoj razini. Za izračun pokazatelja koristi se složena matematička formula koja sadrži 3 koeficijenta - proporcionalni, integralni, diferencijalni.

Uzmimo kao predmet regulacije posudu s vodom u kojoj je potrebno održavati temperaturu na zadanoj razini podešavanjem stupnja otvaranja ventila parom.

Proporcionalna komponenta pojavljuje se u trenutku neusklađenosti s ulaznim podacima. Jednostavnim riječima to zvuči ovako - uzima se razlika između stvarne i željene temperature, množi se s podesivim koeficijentom i dobiva se izlazni signal koji treba isporučiti ventilu. Oni. Čim stupnjevi padnu, počinje proces zagrijavanja, a ako porastu iznad željene razine, dolazi do gašenja ili čak hlađenja.

Zatim dolazi integralna komponenta, koja je dizajnirana da kompenzira utjecaj okoline ili druge ometajuće utjecaje na održavanje naše temperature na zadanoj razini. Budući da uvijek postoje dodatni čimbenici koji utječu na kontrolirane uređaje, u trenutku kad stignu podaci za izračun proporcionalne komponente, brojka se već mijenja. A što je veći vanjski utjecaj, to su jače fluktuacije pokazatelja. Postoje skokovi u isporučenoj snazi.

Integralna komponenta pokušava, na temelju prošlih vrijednosti temperature, vratiti svoju vrijednost ako se promijenila. Proces je detaljnije opisan u videu u nastavku.

Integral se koristi za otklanjanje pogrešaka izračunavanjem statičke pogreške. Glavna stvar u ovom procesu je odabrati točan koeficijent, inače će pogreška (neusklađenost) također utjecati na integralnu komponentu.

Treća komponenta PID-a je razlikovanje. Dizajniran je za kompenzaciju učinaka kašnjenja koja se javljaju između utjecaja na sustav i povratne informacije. Proporcionalni regulator napaja sve dok temperatura ne dosegne željenu razinu, ali uvijek se pojavljuju greške kada informacije prolaze do uređaja, posebno kod velikih vrijednosti. To može uzrokovati pregrijavanje. Diferencijal predviđa odstupanja uzrokovana kašnjenjima ili utjecajima okoline i unaprijed smanjuje isporučenu snagu.

Postavljanje PID regulatora

PID regulator se konfigurira pomoću 2 metode:

  1. Sinteza uključuje izračunavanje parametara na temelju modela sustava. Ova postavka je točna, ali zahtijeva duboko poznavanje teorije automatskog upravljanja. Podložan je samo inženjerima i znanstvenicima. Budući da je potrebno uzeti karakteristike potrošnje i napraviti hrpu izračuna.
  2. Ručna metoda temelji se na pokušaju i pogrešci. Da biste to učinili, podaci o gotovom sustavu uzimaju se kao osnova, a neke prilagodbe se vrše na jednom ili više koeficijenata regulatora. Nakon uključivanja i promatranja konačnog rezultata, parametri se mijenjaju u željenom smjeru. I tako dalje dok se ne postigne željena razina učinka.

Teorijska metoda analize i podešavanja u praksi se izuzetno rijetko koristi, što je posljedica nepoznavanja karakteristika objekta upravljanja i hrpe mogućih ometajućih utjecaja. Češće su eksperimentalne metode temeljene na promatranju sustava.

Suvremeni automatizirani procesi implementirani su kao specijalizirani moduli kojima upravljaju programi za podešavanje koeficijenata regulatora.

Namjena PID regulatora

PID regulator je dizajniran za održavanje određene vrijednosti na potrebnoj razini - temperatura, tlak, razina u spremniku, protok u cjevovodu, koncentracija nečega itd., promjenom regulacijskog djelovanja na aktuatore, kao što su automatski regulacijski ventili , koristeći proporcionalne, integrirajuće, diferencirajuće količine za svoje postavljanje.

Svrha korištenja je dobiti točan upravljački signal koji je sposoban kontrolirati velike industrije, pa čak i reaktore elektrana.

Primjer kruga za kontrolu temperature

PID regulatori se često koriste za regulaciju temperature; pogledajmo ovaj automatski proces na jednostavnom primjeru zagrijavanja vode u posudi.

Posuda se puni tekućinom koju je potrebno zagrijati na željenu temperaturu i održavati na zadanoj razini. Senzor za mjerenje temperature ugrađen je unutar spremnika - ili je izravno spojen na PID regulator.

Da bismo zagrijali tekućinu, opskrbit ćemo paru, kao što je prikazano na donjoj slici, s automatskim regulacijskim ventilom. Sam ventil prima signal od regulatora. Operater unosi vrijednost zadane temperature u PID regulator koja se mora održavati u spremniku.

Ako su postavke koeficijenta regulatora netočne, temperatura vode će varirati, s ventilom ili potpuno otvorenim ili potpuno zatvorenim. U tom slučaju potrebno je izračunati koeficijente PID regulatora i ponovno ih unijeti. Ako je sve učinjeno ispravno, nakon kratkog vremena sustav će izravnati proces i temperatura u spremniku će se održavati na zadanoj točki, dok će stupanj otvaranja kontrolnog ventila biti u srednjem položaju.

PID regulator je gotov uređaj koji će korisniku omogućiti implementaciju softverskog algoritma za upravljanje određenom opremom automatiziranog sustava. Izgradnja i konfiguracija sustava upravljanja postaje mnogo lakša ako koristite gotove uređaje poput univerzalnog PID regulatora TRM148 za 8 kanala tvrtke Aries.

Recimo, trebate automatizirati održavanje ispravnih klimatskih uvjeta u stakleniku: voditi računa o temperaturi tla u blizini korijena biljaka, tlaku zraka, vlažnosti zraka i tla te održavati postavljene parametre upravljanjem ventilatorima. Nema ništa jednostavnije, samo konfigurirajte PID regulator.

Prvo da se prisjetimo što je PID regulator? PID regulator je poseban uređaj koji vrši kontinuirano precizno podešavanje izlaznih parametara na tri načina: proporcionalno, integralno i diferencijalno, a početni parametri su ulazni parametri dobiveni od senzora (tlak, vlaga, temperatura, osvijetljenost itd.).

Ulazni parametar se dovodi na ulaz PID regulatora iz senzora, na primjer, iz senzora vlage. Regulator prima vrijednost napona ili struje, mjeri je, zatim vrši izračune prema svom algoritmu i na kraju šalje signal na odgovarajući izlaz, kao rezultat čega automatizirani sustav prima upravljačku radnju. Vlažnost tla se smanjila - zalijevanje je uključeno na nekoliko sekundi.

Cilj je postići vrijednost vlažnosti koju odredi korisnik. Ili na primjer: osvjetljenje se smanjilo - uključite fitolampe iznad biljaka itd.

PID kontrola

Zapravo, iako je naizgled sve jednostavno, unutar regulatora matematika je kompliciranija, ne događa se sve u jednom koraku. Nakon uključivanja navodnjavanja, PID regulator ponovno vrši mjerenje, mjereći koliko se sada promijenila ulazna vrijednost - tako se pronalazi pogreška upravljanja. Sljedeći utjecaj na izvršno tijelo prilagodit će se uzimajući u obzir izmjerenu pogrešku regulacije i tako na svakom koraku upravljanja sve dok se ne postigne cilj - parametar zadan od strane korisnika.

U regulaciji sudjeluju tri komponente: proporcionalna, integralna i diferencijalna. Svaka komponenta ima svoj stupanj važnosti u svakom pojedinom sustavu, a što je veći doprinos jedne ili druge komponente, to je značajnije treba mijenjati u procesu regulacije.

Proporcionalna komponenta je najjednostavnija, što je veća promjena, to je veći koeficijent (proporcionalnost u formuli), a za smanjenje utjecaja dovoljno je samo smanjiti koeficijent (multiplikator).

Recimo da je vlažnost tla u stakleniku znatno niža od utvrđene - tada bi vrijeme zalijevanja trebalo biti duže za onoliko koliko je trenutna vlažnost niža od utvrđene. Ovo je grubi primjer, ali ovo je opći princip.

Integralna komponenta - potrebno je povećati točnost regulacije na temelju prethodnih regulacijskih događaja: integriraju se prethodne pogreške i za njih se vrše korekcije kako bi se u konačnici dobilo nulto odstupanje pri regulaciji u budućnosti.

Na kraju, diferencijalna komponenta. Ovdje se uzima u obzir brzina promjene kontrolirane varijable. Neovisno o tome mijenja li se navedena vrijednost glatko ili naglo, regulatorna mjera ne bi trebala dovesti do prekomjernih odstupanja vrijednosti tijekom regulacije.

Ostaje samo odabrati uređaj za PID regulaciju. Danas ih ima mnogo na tržištu, postoje višekanalni koji vam omogućuju promjenu nekoliko parametara odjednom, kao u gornjem primjeru sa staklenikom.

Pogledajmo dizajn regulatora na primjeru univerzalnog PID regulatora TRM148 tvrtke Aries.

Ulaznih osam senzora daje signale odgovarajućim ulazima. Signali se skaliraju, filtriraju, korigiraju, njihove vrijednosti se mogu vidjeti na zaslonu prebacivanjem pomoću gumba.

Izlazi uređaja proizvode se u različitim modifikacijama u potrebnim kombinacijama sljedećeg:

    relej 4 A 220 V;

    tranzistorski optokapleri n–p–n tip 400 mA 60 V;

    triac optocouplers 50 mA 300 V;

    DAC “parametar-struja 4...20 mA”;

    DAC “parametar-napon 0...10 V”;

    4...6 V 100 mA izlaz za upravljanje poluprovodničkim relejem.

Dakle, upravljanje može biti analogno ili digitalno. - to su impulsi promjenjive širine i analogni - u obliku glatko promjenjivog napona ili struje u jedinstvenom rasponu: od 0 do 10 V za napon i od 4 do 20 mA za strujni signal.

Ovi izlazni signali se upravo koriste za upravljanje aktuatorima, recimo, pumpom sustava za navodnjavanje ili relejem koji uključuje i isključuje grijaći element ili motor za upravljanje ventilom. Na ploči regulatora nalaze se indikatori signala.


Za interakciju s računalom, regulator TRM148 opremljen je RS-485 sučeljem koje omogućuje:

    konfigurirajte uređaj na osobnom računalu (programi za konfiguraciju dostupni su besplatno);

    prenijeti trenutne vrijednosti izmjerenih vrijednosti, izlaznu snagu regulatora, kao i sve programabilne parametre u mrežu;

  • primati operativne podatke iz mreže za generiranje kontrolnih signala.

Može se tvrditi da najveću učinkovitost osigurava P-zakon, - na temelju omjera tp / T d .

Međutim, ako je pojačanje P-regulatora Kr malo (najčešće se to opaža s odgodom), tada to ne osigurava visoku točnost upravljanja, jer u ovom slučaju vrijednost je velika.

Ako je Kp > 10, tada je P-regulator prihvatljiv, a ako je Kp< 10, то требуется введение в закон управления составляющей.

PI regulacijski zakon

Najčešći u praksi je PI regulator, koji ima sljedeće prednosti:

  1. Omogućuje nultu regulaciju.
  2. Prilično jednostavno za postavljanje, jer... Podešavaju se samo dva parametra, naime pojačanje Kp i integracijska vremenska konstanta Ti. U takvom regulatoru moguće je optimizirati vrijednost omjera Kp/Ti-min, čime se osigurava regulacija uz minimalnu moguću regulaciju srednjeg kvadrata.
  3. Niska osjetljivost na šum u mjerenjima (za razliku od PID regulatora).

PID zakon regulacije

Za najkritičnije regulacijske petlje, možemo preporučiti korištenje , pružajući najviše performanse u sustavu.

Međutim, imajte na umu da se to radi samo s njegovim optimalnim postavkama (konfigurirana su tri parametra).

S povećanjem kašnjenja u sustavu naglo se povećavaju negativni fazni pomaci, što smanjuje učinak diferencijalne komponente regulatora. Stoga kvaliteta PID regulatora za sustave s velikim kašnjenjem postaje usporediva s kvalitetom PI regulatora.

Osim toga, prisutnost šuma u mjernom kanalu u sustavu s PID regulatorom dovodi do značajnih slučajnih fluktuacija u upravljačkom signalu regulatora, što povećava varijancu pogreške upravljanja i trošenje mehanizma.

Dakle, PID regulator treba odabrati za regulacijske sustave s relativno niskom razinom buke i regulacijskim kašnjenjem. Primjeri takvih sustava su sustavi za kontrolu temperature.



Nastavak teme:
Gips

Svi znaju što su žitarice. Uostalom, čovjek je počeo uzgajati ove biljke prije više od 10 tisuća godina. Zato i danas nazivi žitarica kao što su pšenica, raž, ječam, riža...