Príklady použitia a aplikácie regulátora. PID regulátor - celý popis, použitie. Koordinácia výstupných zariadení spojitých regulátorov

Automatické riadiace systémy (ACS) sú navrhnuté tak, aby automaticky menili jeden alebo viac parametrov riadiaceho objektu za účelom stanovenia požadovaného režimu jeho činnosti. ACS zabezpečuje udržanie stálosti stanovených hodnôt regulovaných parametrov alebo ich zmenu podľa daného zákona, prípadne optimalizuje určité kritériá kvality riadenia. Medzi takéto systémy patria napríklad:

  • stabilizačné systémy,
  • programové riadiace systémy,
  • sledovacie systémy

Ide o pomerne širokú triedu systémov, ktoré možno nájsť kdekoľvek. Ale čo to má spoločné s Unity3D a pravdepodobne najmä s hrami? V princípe je to jednoduché: v každej hre, ktorá nejakým spôsobom využíva simuláciu ako prvok hry, sú implementované samohybné delá, medzi takéto hry patria napríklad Kerbal Space Programm, Digital Combat Simulator (predtým Lock On), Strike Suit Zero, atď. (kto pozná viac príkladov - napíšte do komentárov). V zásade môže každá hra, ktorá simuluje skutočné fyzikálne procesy, vrátane jednoducho kinematiky s dynamikou pohybu, implementovať jedno alebo druhé samohybné delá - tento prístup je jednoduchší, prirodzenejší a vývojár už má sadu hotových nástrojov poskytovaných spoločnosťou najrôznejších Vyšnegradských, Ljapunovovcov, Kalmanov, Čebyševov a iných Kolomogorovcov, takže sa zaobídete bez vynájdenia kolesa, pretože už bola vynájdená natoľko, že sa z nej stala samostatná veda: Teória automatického riadenia. Tu hlavnou vecou nie je preháňať to. Je tu len jeden problém: nehovoria o TAU všade, nie každému, často málo a nie veľmi jasne.

Trochu teórie

Klasický automatický riadiaci systém je znázornený na nasledujúcom obrázku:



Kľúčovým prvkom každej samohybnej zbrane je regulátoračo je zariadenie, ktoré monitoruje stav riadiaceho objektu a poskytuje požadovaný riadiaci zákon. Riadiaci proces zahŕňa: výpočet riadiacej chyby alebo chybového signálu e(t) aký je rozdiel medzi želaným nastavenie(nastavená hodnota resp SP ) a aktuálnu hodnotu procesu (vale procesu resp PV ), po ktorých regulátor generuje riadiace signály (manipulovaná hodnota resp MV ).


Jeden typ regulátora je proporcionálne integrálno-derivačný (PID) regulátor, ktorý generuje riadiaci signál, ktorý je súčtom troch členov: proporcionálneho, integrálneho a diferenciálneho.



Kde chyba nesúladu, ako aj - proporcionálne, - integrálne, - diferenciálne zložky (pojmy) zákona riadenia, ktorý je vo svojej konečnej podobe popísaný nasledujúcimi vzorcami




Proporcionálna zložka P- zodpovedá za tzv proporcionálna regulácia, ktorej význam spočíva v tom, že výstupný signál regulátora pôsobí proti odchýlke regulovanej veličiny (chyba nesúladu alebo nazývaná aj zvyšková) od nastavenej hodnoty. Čím väčšia je chyba nesúladu, tým väčšia je odchýlka príkazu regulátora. Toto je najjednoduchší a najzrejmejší zákon o kontrole. Chyba Zákon proporcionálneho riadenia hovorí, že regulátor sa nikdy nestabilizuje na danej hodnote a zvýšenie koeficientu proporcionality vždy vedie k vlastným osciláciám. Preto je potrebné okrem zákona o pomernom riadení použiť aj integrálne a diferenciálne.


Integrálna zložka I akumuluje (integruje) chybu riadenia, čo umožňuje PID regulátoru eliminovať statickú chybu (stála chyba, zvyšková chyba). Alebo inými slovami: integrálny odkaz vždy zavádza určitú zaujatosť a ak systém podlieha nejakým trvalým chybám, tak ich kompenzuje (kvôli svojej zaujatosti). Ak však takéto chyby neexistujú alebo sú zanedbateľne malé, účinok bude opačný - samotná integrálna zložka zavedie chybu posunu. Z tohto dôvodu sa nepoužíva napríklad pri úlohách s ultrapresným polohovaním. kľúč nevýhodou Integrálny riadiaci zákon je saturačný efekt integrátora (Integrator windup).


Diferenciálna zložka D je úmerná rýchlosti zmeny odchýlky regulovanej veličiny a je navrhnutá tak, aby pôsobila proti odchýlkam od cieľovej hodnoty, ktorá sú predpovedané v budúcnosti. Je pozoruhodné, že diferenciálna zložka eliminuje tlmené oscilácie. Diferenčné riadenie je obzvlášť účinné pre procesy, ktoré majú veľké oneskorenia. Nevýhoda Zákonom diferenciálneho riadenia je jeho nestabilita voči účinkom hluku (Differentiation noise).


V závislosti od situácie je teda možné použiť P-, PD-, PI- a PID-regulátory, ale hlavný zákon riadenia je hlavne proporcionálny (hoci v niektorých špecifických úlohách možno použiť výlučne len prvky diferenciátorov a integrátorov).


Zdalo by sa, že problematika implementácie PID regulátorov je už dávno otrepaná a tu na Habré je pár dobrých článkov na túto tému, vrátane Unity3D, je tam aj dobrý článok PID bez PhD (preklad) a séria článkov články v časopise "Modern Automation Technologies" v dvoch častiach: prvej a druhej. K vašim službám je aj článok na Wikipédii (najkompletnejší si prečítajte v anglickej verzii). A na komunitných fórach Unity3D nie, nie a PID regulátor vyskočí rovnako ako na gamedev.stackexchange


Otázka o implementácii PID regulátorov je o niečo hlbšia, ako sa zdá. Natoľko, že na mladých domácich majstrov, ktorí sa rozhodnú zaviesť takúto regulačnú schému, čaká veľa úžasných objavov a téma je relevantná. Takže dúfam, že tento opus bude pre niekoho užitočný, takže začnime.

Pokus číslo jedna

Ako príklad sa pokúsime implementovať schému ovládania na príklade otáčania ovládania v jednoduchej 2D vesmírnej arkádovej hre, krok za krokom, počnúc od úplného začiatku (zabudli ste, že ide o tutoriál?).


Prečo nie 3D? Pretože implementácia sa nezmení, okrem toho, že budete musieť zapnúť PID regulátor na ovládanie sklonu, vybočenia a natočenia. Problematika správnej aplikácie PID regulácie spolu s kvaterniónmi je síce naozaj zaujímavá, možno ju rozoberiem v budúcnosti, ale aj NASA uprednostňuje Eulerove uhly namiesto kvaternionov, takže si vystačíme s jednoduchým modelom na dvojrozmernom lietadlo.


Na začiatok si vytvorme samotný herný objekt vesmírnej lode, ktorý bude pozostávať zo samotného objektu lode na najvyššej úrovni hierarchie, a pripojíme k nemu podriadený objekt Engine (čisto kvôli špeciálnym efektom). U mňa to vyzerá takto:



A vrháme sa na samotný objekt vesmírnej lode inšpektor všetky druhy komponentov. Pri pohľade do budúcnosti dám snímku obrazovky, ako to bude vyzerať na konci:



Ale to je na neskôr a zatiaľ v ňom nie sú žiadne skripty, iba štandardná pánska súprava: Sprite Render, RigidBody2D, Polygon Collider, Audio Source (prečo?).


V skutočnosti je teraz pre nás najdôležitejšia fyzika a riadenie sa bude vykonávať výlučne cez ňu, inak by použitie PID regulátora stratilo zmysel. Nechajme tiež hmotnosť našej kozmickej lode na 1 kg a všetky koeficienty trenia a gravitácie sú rovné nule - vo vesmíre.


Pretože Okrem samotnej vesmírnej lode existuje kopa ďalších, menej inteligentných vesmírnych objektov, takže najskôr si popíšeme rodičovskú triedu BaseBody, ktorý bude obsahovať odkazy na naše komponenty, metódy inicializácie a deštrukcie, ako aj množstvo ďalších polí a metód, napríklad na implementáciu nebeskej mechaniky:


BaseBody.cs

pomocou UnityEngine; pomocou System.Collections; pomocou System.Collections.Generic; menný priestor Assets.Scripts.SpaceShooter.Bodies ( verejná trieda BaseBody: MonoBehaviour (plávajúca len na čítanie _deafultTimeDelay = 0,05f; verejný statický zoznam _body = nový zoznam (); #region RigidBody verejné Rigidbody2D _rb2d; verejný Collider2D_c2d; #endregion #region Referencie public Transform _myTransform; public GameObject _myObject; ///

/// Objekt, ktorý sa objaví po zničení /// public GameObject_explodePrefab; #endregion #region Verejný zdroj zvuku Zdroj zvuku _audioSource; /// /// Zvuky, ktoré sa prehrávajú pri poškodení /// public AudioClip_hitSounds; /// /// Zvuky, ktoré sa prehrávajú, keď sa objaví objekt /// public AudioClip_awakeSounds; /// /// Zvuky, ktoré sa prehrávajú pred smrťou /// public AudioClip_deadSounds; #endregion #region Premenné vonkajšej sily /// /// Vonkajšie sily pôsobiace na objekt /// public Vector2 _ExternalForces = new Vector2(); /// /// Aktuálny vektor rýchlosti /// public Vector2 _V = new Vector2(); /// /// Aktuálny vektor gravitácie /// public Vector2 _G = new Vector2(); #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 (); PlayRandomSound(_awakeSounds); BaseBody bb = GetComponent (); _body.Add(bb); ) /// /// Zničenie postavy /// public virtual void Destroy() ( _bodies.Remove(this); for (int i = 0; i< _c2d.Length; i++) { _c2d[i].enabled = false; } float _t = PlayRandomSound(_deadSounds); StartCoroutine(WaitAndDestroy(_t)); } /// /// Pred zničením nejaký čas počkáme /// /// Čas čakania /// public IEnumerator WaitAndDestroy(float waitTime) ( return return new WaitForSeconds(waitTime); if (_explodePrefab) ( Instantiate(_explodePrefab, transform.position, Quaternion.identity); ) Destroy(gameObject, _deafultTimeDelay); ) /// /// Prehrať náhodný zvuk /// /// Súbor zvukov /// Trvanie prehrávaného zvuku 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]; _audioClip.length; _audioSource.PlayOneShot(_audioClip); ) return _t; ) /// /// Utrpenie škody /// /// Stupeň poškodenia verejné virtuálne void Poškodenie (poškodenie plaváku) ( PlayRandomSound(_hitSounds); ) ) )


Zdá sa, že sme popísali všetko, čo bolo potrebné, dokonca viac, ako bolo potrebné (v rámci tohto článku). Teraz z nej zdedíme triedu lode Loď, ktorý by sa mal vedieť pohybovať a otáčať:


SpaceShip.cs

pomocou UnityEngine; pomocou System.Collections; pomocou System.Collections.Generic; menný priestor 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( _rotation); Vector2 force = ControlForce(_movement); _rb2d.AddTorque(krútiaci moment); _rb2d.AddRelativeForce(force); ) public float ControlRotate(Vector2 rotation) (floating result = 0f; return result; ) public Vector2 ControlForce(Vector2 move) (Vektor2 výsledok = nový Vector2(); vrátiť výsledok; ) ) )


Aj keď v nej nie je nič zaujímavé, momentálne je to len trieda stub.


Popíšeme aj základnú (abstraktnú) triedu pre všetky vstupné ovládače BaseInputController:


BaseInputController.cs

pomocou UnityEngine; pomocou Assets.Scripts.SpaceShooter.Bodies; menný priestor Assets.Scripts.SpaceShooter.InputController ( verejný zoznam eSpriteRotation (Rigth = 0, hore = -90, vľavo = -180, dole = -270 ) verejná abstraktná trieda BaseInputController: MonoBehaviour ( public GameObject _agentObject; public Ship; _agentBody na logický komponent lode public eSpriteRotation _spriteOrientation = eSpriteRotation.Up; //Je to spôsobené neštandardnou // orientáciou spritu „nahor“ namiesto „doprava“ 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 ) ) )


A nakoniec trieda ovládačov prehrávača PlayerFigtherInput:


PlayerInput.cs

pomocou UnityEngine; pomocou Assets.Scripts.SpaceShooter.Bodies; menný priestor Assets.Scripts.SpaceShooter.InputController ( verejná trieda PlayerFigtherInput: BaseInputController ( verejné prepísanie void ControlRotate(float dt) ( // Určenie polohy myši vzhľadom na prehrávač Vector3 worldPos = Input.mousePosition; worldPos = Camera.main.ScreenToWorld (worldPos); / / Uloženie súradníc ukazovateľa myši float dx = -this.transform.position.x + worldPos.x; float dy = -this.transform.position.y + worldPos.y; //Prejdenie smeru cieľa Vector2 = new Vector2(dx, dy ); _agentBody._target = target; //Vypočítajte rotáciu podľa stlačenia kláves float targetAngle = Mathf.Atan2(dy, dx) * Mathf.Rad2Deg; _agentBody._targetAngle = targetAngle + (float)_spriteOrientation ; ) public override void ControlForce( float dt) ( //Prechod pohyb _agentBody._movement = Input.GetAxis("Vertical") * Vector2.up + Input.GetAxis("Horizontal") * Vector2.right; ) ) )


Zdá sa, že sme skončili, teraz môžeme konečne prejsť k tomu, na čo sa to všetko začalo, t.j. PID regulátory (dúfam, že ste nezabudli?). Jeho implementácia sa zdá byť jednoduchá:


pomocou systému; pomocou System.Collections.Generic; pomocou System.Linq; pomocou System.Text; namespace Assets.Scripts.Regulator ( // Tento atribút je potrebný na to, aby sa polia regulátora // zobrazovali v inšpektore a serializovali verejnú triedu SimplePID ( public float Kp, Ki, Kd; private float lastError; private 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 = chyba; I += chyba * dt; D = (chyba - lastError) / dt; lastError = chyba; float CO = P * Kp + I * Ki + D * Kd ; návrat CO; ) ) )

Vezmeme predvolené hodnoty koeficientov z ničoho: toto bude triviálny jediný koeficient proporcionálneho regulačného zákona Kp = 1, malá hodnota koeficientu pre diferenciálny regulačný zákon Kd = 0,2, čo by malo eliminovať očakávané kolísanie a nulovú hodnotu pre Ki, ktorá bola zvolená preto, že v našom softvéri model nemá žiadne statické chyby (ale vždy ich môžete zaviesť a potom hrdinsky bojovať s pomocou integrátora).


Teraz sa vráťme do našej triedy SpaceShip a skúsme použiť náš výtvor ako ovládač rotácie vesmírnej lode v metóde ControlRotate:


public float ControlRotate(Vector2 rotation) ( float MV = 0f; float dt = Time.fixedDeltaTime; //Vypočítajte chybový uhol floatError = Mathf.DeltaAngle(_myTransform.eulerAngles.z, targetAngle); //Získajte korekčné zrýchlenie MV = _angleController .Update (angleError, dt); return MV; )

PID regulátor vykoná presné uhlové polohovanie kozmickej lode iba pomocou krútiaceho momentu. Všetko je fér, fyzika a samohybné zbrane, takmer ako v reálnom živote.


A bez týchto tvojich Quaternion.Lerp

if (!_rb2d.freezeRotation) rb2d.freezeRotation = true; float deltaAngle = Mathf.DeltaAngle(_myTransform.eulerAngles.z, targetAngle); float T = dt * Mathf.Abs(_rotationSpeed ​​​​/ deltaAngle); // Transformácia uhla na vektor Quaternion rot = Quaternion.Lerp(_myTransform.rotation, Quaternion.Euler(new Vector3(0, 0, targetAngle)), T); // Zmena rotácie objektu _myTransform.rotation = rot;


Výsledný zdrojový kód Ship.cs je pod spojlerom

pomocou UnityEngine; pomocou Assets.Scripts.Regulator; menný priestor 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 krútiaci moment = ControlRotate(_targetAngle); Vector2 force = ControlForce(_movement); _rb2d.AddTorque(krútiaci moment); _rb2d.AddRelativeForce(force); ) public float ControlRotate(float) rotácia) ( float MV = 0f; float dt = Time.fixedDeltaTime; _angle = _myTransform.eulerAngles.z; //Vypočítajte chybový uhol floatError = Mathf.DeltaAngle(_uhol, otočiť); //Získajte korekčné zrýchlenie MV = _angleController. Update( angleError, dt); return MV; ) public Vector2 ControlForce(Vector2 pohyb) ( Vector2 MV = new Vector2(); //Kúsok kódu pre špeciálny efekt bežiaceho motora kvôli if (pohyb != Vector2.zero) ( if (_flame != null) ( _flame.SetActive(true); ) ) else ( if (_flame != null) ( _flame.SetActive(false); ) ) MV = pohyb; návrat MV; )))


všetky? Ideme domov?



WTF! Čo sa deje? Prečo sa loď čudne otáča? A prečo sa tak prudko odráža od iných predmetov? Nefunguje tento hlúpy PID regulátor?


Nerobte paniku! Skúsme prísť na to, čo sa deje.


V momente prijatia novej hodnoty SP dôjde k prudkému (krokovému) skoku v chybovom nesúlade, ktorý, ako si pamätáme, sa vypočíta takto: podľa toho dôjde k prudkému skoku v derivačnej chybe, ktorú vypočítame v tento riadok kódu:


D = (chyba - poslednáChyba) / dt;

Môžete, samozrejme, vyskúšať aj iné diferenciačné schémy, napríklad trojbodové, päťbodové, alebo... ale aj tak to nepomôže. Nemajú radi deriváty ostrých skokov - v takýchto bodoch funkcia nie je rozlíšiteľné. Avšak, stojí za to experimentovať s rôznymi schémami diferenciácie a integrácie, ale potom a nie v tomto článku.


Myslím, že nastal čas na vytvorenie grafov procesu prechodu: postupná akcia od S(t) = 0 do SP(t) = 90 stupňov pre teleso s hmotnosťou 1 kg, dĺžka ramena sily 1 meter a krok diferenciačnej mriežky 0,02 s - rovnako ako v našom príklade v Unity3D (v skutočnosti nie úplne; pri konštrukcii týchto grafov sa nepočítalo s tým, že moment zotrvačnosti závisí od geometrie pevného telesa, takže prechodový proces bude mierne odlišné, ale stále dostatočne podobné na demonštráciu). Všetky hodnoty v tabuľke sú uvedené v absolútnych hodnotách:


Hmm, čo sa tu deje? Kam sa podela reakcia PID regulátora?


Gratulujeme, práve sme sa stretli s takým fenoménom, ako je „kopnutie“. Je zrejmé, že v čase, keď je proces stále PV = 0 a požadovaná hodnota je už SP = 90, potom s numerickou diferenciáciou získame derivačnú hodnotu rádovo 4500, ktorá sa vynásobí Kd = 0,2 a zrátajte s proporcionálnym therom, takže na výstupe dostaneme hodnotu uhlového zrýchlenia 990, a to je už na fyzikálnom modeli Unity3D úplná nehoráznosť (uhlové rýchlosti dosiahnu 18000 deg/s... myslím, že toto je limitná hodnota uhlovej rýchlosti pre RigidBody2D).


  • Možno stojí za to zvoliť koeficienty manuálne, aby skok nebol taký silný?
  • Nie! Najlepšie, čo môžeme týmto spôsobom dosiahnuť, je malá amplitúda derivačného skoku, ale samotný skok zostane taký, aký bol a v tomto prípade sa diferenciálna zložka môže stať úplne neúčinnou.

Môžete však experimentovať.

Pokus číslo dva. Sýtosť

To je predsa logické pohonná jednotka(v našom prípade virtuálne manévrovacie motory SpaceShip) nedokážu zvládnuť žiadne veľké hodnoty, ktoré dokáže vyprodukovať náš bláznivý regulátor. Takže prvá vec, ktorú urobíme, je saturovať výstup regulátora:


public float ControlRotate(Vektor2 rotácia, plávajúci ťah) ( float CO = 0f; float MV = 0f; float dt = Time.fixedDeltaTime; //Výpočet chyby float uholError = Mathf.DeltaAngle(_myTransform.eulerAngles.z, targetAngle); / / Získame korekčné zrýchlenie CO = _angleController.Update(uholError, dt); //Nasýti MV = CO; ak (MV > ťah) MV = ťah; ak (MV< -thrust) MV = -thrust; return MV; }

A opäť prepísaná trieda Loď vyzerá takto:

menný priestor 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_AddqueTorque(); _rb2d.AddRelativeForce(_force); ) public float ControlRotate(float targetAngle, float ťah) ( float CO = 0f; float MV = 0f; float dt = Time.fixedDeltaTime; //Výpočet chyby float uholError = Mathf.DeltaAngle(_myTransform. eulerAngles .z, targetAngle); //Získajte korekčné zrýchlenie CO = _angleController.Update(angleError, dt); //Nasýtite MV = CO; ak (MV > ťah) MV = ťah; ak (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() { } } }


Výsledná schéma našich samohybných zbraní potom bude vyzerať takto


Zároveň je zrejmé, že výstup regulátora CO(t) mierne odlišné od riadenej premennej procesu MV(t).


V skutočnosti z tohto miesta už môžete pridať novú hernú entitu - pohonná jednotka, cez ktorý sa bude riadiť proces, ktorého logika môže byť zložitejšia ako len Mathf.Clamp(), napríklad môžete zaviesť diskretizáciu hodnôt (aby ste nepreťažili hernú fyziku prichádzajúcimi hodnotami v šestine za desatinnou čiarkou), mŕtva zóna (opäť nie Má zmysel preťažovať fyziku ultramalými reakciami), zaviesť oneskorenie do riadenia a nelinearitu (napríklad sigmoid) pohonu a potom vidieť čo z toho vyplýva.


Po spustení hry zistíme, že vesmírna loď sa konečne stala ovládateľnou:



Ak vytvoríte grafy, môžete vidieť, že odpoveď ovládača je takáto:


Tu sa už používajú normalizované hodnoty, uhly sa delia hodnotou SP a výstup regulátora sa normalizuje vzhľadom na maximálnu hodnotu, pri ktorej už nastáva saturácia.

Nižšie je známa tabuľka vplyvu zvýšenia parametrov PID regulátora ( Ako môžem zmenšiť písmo, inak sa tabuľka delenia slov pre pusinky nezmestí?):



A všeobecný algoritmus na manuálne ladenie PID regulátora je nasledujúci:


  1. Vyberáme proporcionálne koeficienty s vypnutými diferenciálnymi a integrálnymi väzbami, kým nezačnú samooscilácie.
  2. Postupným zvyšovaním diferenciálnej zložky sa zbavujeme vlastných oscilácií
  3. Ak sa vyskytne zvyšková chyba riadenia (posunutie), potom ju odstránime pomocou integrálnej zložky.

Neexistujú žiadne všeobecné hodnoty pre parametre PID regulátora: konkrétne hodnoty závisia výlučne od parametrov procesu (jeho prenosovej charakteristiky): PID regulátor, ktorý dokonale spolupracuje s jedným riadiacim objektom, nebude fungovať s iným. Okrem toho sú koeficienty pre proporcionálne, integrálne a diferenciálne zložky tiež vzájomne závislé.


Pokus číslo tri. Ešte raz deriváty

Po priložení barličky v podobe obmedzenia výstupných hodnôt regulátora sme stále nevyriešili najdôležitejší problém nášho regulátora - diferenciálna zložka nepracuje dobre, keď sa chyba na vstupe regulátora postupne mení. V skutočnosti existuje mnoho ďalších bariel, napríklad v momente náhlej zmeny SP „vypnite“ diferenciálny komponent alebo nainštalujte dolnopriepustné filtre medzi SP(t) a operáciu, vďaka ktorej bude chyba postupne narastať, alebo sa môžete úplne otočiť a použiť skutočný Kalmanov filter na vyhladenie vstupných údajov. Vo všeobecnosti existuje veľa barlí a pridajte pozorovateľ Samozrejme, že by som chcel, ale tentoraz nie.


Preto sa vráťme k derivácii chyby nesúladu a pozrime sa na to pozorne:



Všimli ste si niečo? Ak sa pozriete pozorne, zistíte, že vo všeobecnosti sa SP(t) v čase nemení (okrem okamihov zmeny kroku, keď ovládač dostane nový príkaz), t.j. jeho derivácia je nula:





Inými slovami, namiesto derivačnej chyby, ktorá je diferencovateľná nie všade môžeme použiť deriváciu procesu, ktorý je vo svete klasickej mechaniky zvyčajne kontinuálny a všade diferencovaný a schéma nášho automatického riadiaceho systému už bude mať nasledujúcu podobu:




Upravme kód ovládača:


pomocou systému; pomocou System.Collections.Generic; pomocou System.Linq; pomocou System.Text; menný priestor Assets.Scripts.Regulator ( public class SimplePID ( public float Kp, Ki, Kd; private float P, I, D; private float lastPV = 0f; public 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 = chyba; I += chyba * dt; D = -(PV - posledná PV) / dt; posledná PV = PV; plavák CO = Kp * P + Ki * I + Kd * D; návrat CO; ) ) )

A poďme trochu zmeniť metódu ControlRotate:


public float ControlRotate(Vektor2 rotácia, plávajúci ťah) ( float CO = 0f; float MV = 0f; float dt = Time.fixedDeltaTime; //Výpočet chyby float uholError = Mathf.DeltaAngle(_myTransform.eulerAngles.z, targetAngle); / / Získame korekčné zrýchlenie CO = _angleController.Update(uholError, _myTransform.eulerAngles.z, dt); //Nasýtiť MV = CO; ak (CO >< -thrust) MV = -thrust; return MV; }

A-a-a-a... ak hru spustíte, zistíte, že v skutočnosti sa od posledného pokusu nič nezmenilo, čo bolo potrebné dokázať. Ak však odstránite saturáciu, graf odozvy regulátora bude vyzerať takto:


Skok CO(t) je stále prítomný, ale už nie je taký veľký ako na úplnom začiatku, a čo je najdôležitejšie, stal sa predvídateľným, pretože zabezpečuje výhradne proporcionálna zložka a je limitovaná maximálnou možnou chybou nesúladu a proporcionálnym zosilnením PID regulátora (a to už naznačuje, že Kp má zmysel zvoliť menej ako jednotu, napríklad 1/90f), ale nezávisí od kroku diferenciačnej mriežky (t.j. dt). Vo všeobecnosti dôrazne odporúčam použiť skôr deriváciu procesu ako chybu.


Myslím, že teraz to nikoho neprekvapí, ale rovnakým spôsobom ho môžete nahradiť , ale nebudeme sa tým zaoberať, môžete experimentovať a povedať v komentároch, čo z toho vyšlo (najzaujímavejšie)

Pokus číslo štyri. Alternatívne implementácie PID regulátora

Okrem vyššie opísaného ideálneho znázornenia PID regulátora sa v praxi často používa štandardná forma bez koeficientov Ki A Kd, namiesto ktorých sa používajú dočasné konštanty.


Tento prístup je spôsobený skutočnosťou, že množstvo techník ladenia PID regulátora je založené na frekvenčných charakteristikách PID regulátora a procesu. Vlastne celé TAU sa točí okolo frekvenčných charakteristík procesov, takže pre tých, ktorí chcú ísť hlbšie, a zrazu narazia na alternatívnu nomenklatúru, uvediem príklad tzv. štandardná forma PID regulátor:




kde je diferenciačná konštanta, ktorá ovplyvňuje predikciu stavu systému regulátorom,
- integračná konštanta, ovplyvňujúca interval priemerovania chýb integrálnou väzbou.


Základné princípy ladenia PID regulátora v štandardnej forme sú podobné ako pri idealizovanom PID regulátore:

  • zvýšenie proporcionálneho koeficientu zvyšuje výkon a znižuje rezervu stability;
  • s poklesom integrálnej zložky chyba riadenia klesá v priebehu času rýchlejšie;
  • zníženie integračnej konštanty znižuje rezervu stability;
  • zvýšenie diferenciálnej zložky zvyšuje rezervu stability a výkon

Zdrojový kód štandardného formulára nájdete pod spojlerom

menný priestor Assets.Scripts.Regulator ( public class StandartPID ( public float Kp, Ti, Td; public float error, CO; public float P, I, D; private float lastPV = 0f; public StandartPID() ( Kp = 0,1f; Ti = 10000f; Td = 0,5f; odchýlka = 0f; ) public StandardPID(float Kp, float Ti, float Td) ( this.Kp = Kp; this.Ti = Ti; this.Td = Td; ) public float Update(float chyba, float PV, float dt) ( this.error = chyba; P = chyba; I += (1 / Ti) * chyba * dt; D = -Td * (PV - lastPV) / dt; CO = Kp * ( P + I + D); posledná PV = PV; návrat CO; ) ) )

Predvolené hodnoty sú Kp = 0,01, Ti = 10 000, Td = 0,5 - s týmito hodnotami sa loď otáča pomerne rýchlo a má určitú rezervu stability.


Okrem tejto formy PID regulátora, tzv opakujúca sa forma:



Nebudeme sa tým zaoberať, pretože... je relevantná predovšetkým pre hardvérových programátorov pracujúcich s FPGA a mikrokontrolérmi, kde je takáto implementácia oveľa pohodlnejšia a efektívnejšia. V našom prípade - dajme niečo k hromadám na Unity3D - je to len ďalšia implementácia PID regulátora, ktorá nie je o nič lepšia ako ostatné a ešte menej zrozumiteľná, takže sa ešte raz všetci potešme, ako dobre sa dá programovať v útulnom C# , a nie napríklad v strašidelnom a hroznom VHDL.

Namiesto záveru. Kde inde by ste pridali PID regulátor?

Teraz sa pokúsme trochu skomplikovať ovládanie lode pomocou dvojslučkového riadenia: jeden PID regulátor, nám už známy _angleController, je stále zodpovedný za uhlové polohovanie, ale druhý – nový, _angularVelocityController – riadi rýchlosť otáčania:


public float ControlRotate(float targetAngle, float ťah) ( float CO = 0f; float MV = 0f; float dt = Time.fixedDeltaTime; _angle = _myTransform.eulerAngles.z; //Rotačný uhol plávajúceho uhlaError = Mathf.DeltaAngle(_uhol, targetAngle); plávajúci momentCorrectionForAngle = _angleController.Update(angleError, _angle, dt); //regulátor stabilizácie rýchlosti float angularVelocityError = -_rb2d.angularVelocity; plávajúci momentCorrectionForAngularVelocity = _angularVelocityController = _angularVelocityController. výstup ovládača CO = krútiaci momentCorrectionForAngle + krútiaci momentCorrectionForAngularVelocity; //Vzorka v krokoch po 100 CO = Mathf.Round(100f * CO) / 100f; //Saturácia MV = CO; ak (CO > ťah) MV = ťah; ak (CO< -thrust) MV = -thrust; return MV; }

Účelom druhého regulátora je tlmiť prebytočné uhlové rýchlosti zmenou krútiaceho momentu – ide o obdobu prítomnosti uhlového trenia, ktoré sme pri vytváraní herného objektu vypli. Takáto regulačná schéma [možno] umožní získať stabilnejšie správanie lode a dokonca si vystačiť iba s proporcionálnymi regulačnými koeficientmi - druhý regulátor bude tlmiť všetky výkyvy a bude vykonávať funkciu podobnú diferenciálnej zložke prvého regulátora. .


Okrem toho pridáme novú vstupnú triedu hráča - PlayerInputCorvette, v ktorej sa budú otáčať stláčaním pravo-ľavých kláves a označovanie cieľa necháme myšou na niečo užitočnejšie, napríklad na ovládanie veže. . Zároveň tu máme parameter ako _turnRate - ktorý je zodpovedný za rýchlosť/reakciu odbočenia (nie je jasné, kam je lepšie ho umiestniť v InputCONtroller alebo Still Ship).


public class PlayerCorvetteInput: BaseInputController ( public float _turnSpeed ​​​​= 90f; verejné prepísanie void ControlRotate() ( // Vyhľadanie ukazovateľa myši Vector3 worldPos = Input.mousePosition; worldPos = Camera.main.ScreenToWorldPoint(worldPos); // Uloženie relatívneho súradnice ukazovateľa myši float dx = -this.transform.position.x + worldPos.x; float dy = -this.transform.position.y + worldPos.y; //Prejdenie smeru ukazovateľa myši Vector2 target = new Vector2( dx, dy); _agentBody. _target = target; //Vypočítajte rotáciu v súlade so stlačenými klávesmi _agentBody._rotation -= Input.GetAxis("Horizontal") * _turnSpeed ​​​​* Time.deltaTime; ) verejné prepísanie void ControlForce() ( //Postúpenie pohybu _agentBody._movement = Input .GetAxis("Vertical") * Vector2.up; ) )

Kvôli prehľadnosti si tiež položíme na kolená skript na zobrazenie informácií o ladení

menný priestor Assets.Scripts.SpaceShooter.UI ( ladiaci program verejnej triedy: MonoBehaviour ( Ship _ship; BaseInputController _controller; List _pids = nový zoznam (); Zoznam _names = nový zoznam (); Vector2 _orientation = new Vector2(); // Toto použite na inicializáciu void Start() ( _ship = GetComponent (); _controller = GetComponent (); _pids.Add(_ship._angleController); _names.Add("Ovládač uhla"); _pids.Add(_ship._angularVelocityController); _names.Add("Ovládač uhlovej rýchlosti"); ) // Aktualizácia sa volá raz za snímku void Update() ( DrawDebug(); ) Vector3 GetDiretion(eSpriteRotation spriteRotation) ( prepínač (_controller._spriteOrientation) ( prípad 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() ( //Smer rotácie Vector3 vectorToTarget = transform.position + 5f * new Vector3(-Mathf.Sin(_ship._targetAngle * Mathf.Deg2Rad), Mathf.Cos(_ship._targetAngle * Mathf.Deg2Rad), 0f); // Aktuálny smer Nadpis Vector3 = transform.position + 4f * GetDiretion(_controller. _spriteOrientation); //Uhlové zrýchlenie Vector3 krútiaci moment = smer - transform.right * _ship._Torque; Debug.DrawLine(transform.position, vectorToTarget, Color.white); Debug.DrawLine(transform.position, header, Color.green); Debug.DrawLine(nadpis, moment, Farba.červená); ) void OnGUI() ( float x0 = 10; float y0 = 100; float dx = 200; float dy = 40; float PosuvníkKpMax = 1; float PosuvníkKpMin = 0; float SliderKiMax = 0,5f; float SliderKiMin = -.5f; float SliderKdMax = 0,5f; float PosuvníkKdMin = 0; int i = 0; foreach (SimplePID pid v _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(new Rect(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 GUIStylement(); 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(), štýl2); 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); )))))


Trieda Ship tiež prešla nezvratnými mutáciami a teraz by mala vyzerať takto:

menný priestor 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 SimplePID _angularVelocityController = new SimplePID(0f,0f,0f); private float _torque = 0f; public 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 ťah) ( float CO = 0f; float MV = 0f; float dt = Time.fixedDeltaTime; _angle = _myTransform.eulerAngles.z; //Controller uhol rotácie float uholError = Mathf.DeltaAngle(_uhol, targetAngle); plávajúci momentCorrectionForAngle = _uholController.Update(uholError, _uhol, dt); //regulátor stabilizácie rýchlosti float angularVelocityError = -_rb2d.angularVelocity; float momentCorrectionForAngularVelocity = _angularVelocityController.Update(angularVelocityError, -angularVelocityError, dt); //Celkový výstup regulátora CO = krútiaci momentCorrectionForAngle + krútiaci momentCorrectionForAngularVelocity; //Diskretizácia v krokoch po 100 CO = Mathf.Round(100f * CO) / 100f; //Nasýtiť MV = CO; ak (CO > ťah) MV = ťah; if(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() { } } }

Niekoľko ďalších odkazov na ďalšie príklady

Pásmo proporcionality X p, podobne ako odchýlka E, je vyjadrené v jednotkách kontrolovaného parametra. Čím širšie je proporcionálne pásmo Xp, tým menší je výstupný signál Y pre rovnakú odchýlku E.

Mimo pásma proporcionality je výstup Y 0 alebo 100 %.

Keď P-law pracuje, regulátor vytvára impulzy, v ktorých je prítomná iba proporcionálna zložka hodnoty výstupného signálu.


Keď zariadenie pracuje v režime PD regulátora, veľkosť výstupného signálu Yi závisí nielen od veľkosti odchýlky Ei, ale aj od rýchlosti jej zmeny:

Zmena výstupného signálu regulátora s postupnou zmenou odchýlky je znázornená na obrázku. V prvej perióde po skokovej zmene E i vydá regulátor riadiaci impulz, v ktorom sa okrem proporcionálnej zložky spôsobenej nesúladom E i pripočíta diferenciálna (tieňovaná časť) ΔYd, ktorá závisí od hodnoty. koeficientu ΔE i a τ l. V nasledujúcich impulzoch je len proporcionálna zložka, pretože nedochádza k žiadnej zmene E i.


Obrázok ukazuje, že v prvom okamihu, keď nie je žiadna odchýlka (E i =0), nie je výstupný signál (Y i =0). S objavením sa odchýlky E i sa objavujú impulzy, ktorých trvanie sa postupne zvyšuje. Impulzy obsahujú proporcionálnu zložku, ktorá závisí od hodnoty E (netienená časť impulzov) a integrálnu zložku (tieňovaná časť). K zvýšeniu trvania impulzu dochádza v dôsledku zvýšenia integrálnej zložky, ktorá závisí od nesúladu E i a koeficientu τ i.

Diferenciálny proporcionálno-integrálny regulátor je zariadenie, ktoré je inštalované v automatizovaných systémoch na udržanie daného parametra, ktorý je schopný zmeny.

Na prvý pohľad je všetko mätúce, ale PID riadenie sa dá vysvetliť pre figuríny, t.j. ľudí, ktorí nie sú úplne oboznámení s elektronickými systémami a zariadeniami.

Čo je PID regulátor?

PID regulátor je zariadenie zabudované do regulačného obvodu s povinnou spätnou väzbou. Je navrhnutý tak, aby udržiaval stanovené úrovne špecifikovaných hodnôt, napríklad teploty vzduchu.

Zariadenie dodáva riadiaci alebo výstupný signál do riadiaceho zariadenia na základe údajov prijatých zo snímačov alebo snímačov. Kontroléry majú vysokú presnosť prechodných procesov a kvalitu plnenia zadanej úlohy.

Tri koeficienty PID regulátora a princíp činnosti

Úlohou PID regulátora je poskytnúť výstupný signál o výkone potrebnom na udržanie regulovaného parametra na danej úrovni. Na výpočet ukazovateľa sa používa zložitý matematický vzorec, ktorý obsahuje 3 koeficienty - proporcionálny, integrálny, diferenciálny.

Zoberme si ako predmet regulácie nádobu s vodou, v ktorej je potrebné udržiavať teplotu na danej úrovni nastavením stupňa otvorenia ventilu parou.

Pomerná zložka sa objaví v momente nesúladu so vstupnými údajmi. Jednoducho povedané, znie to takto - odoberie sa rozdiel medzi skutočnou a požadovanou teplotou, vynásobí sa nastaviteľným koeficientom a získa sa výstupný signál, ktorý by mal byť privedený do ventilu. Tie. Akonáhle stupne klesnú, spustí sa proces ohrevu, ak stúpnu nad požadovanú úroveň, dôjde k odstaveniu alebo dokonca k ochladeniu.

Nasleduje integrálna zložka, ktorá je určená na kompenzáciu vplyvu prostredia alebo iných rušivých vplyvov na udržanie našej teploty na danej úrovni. Keďže na ovládané zariadenia vždy vplývajú ďalšie faktory, v momente, keď prichádzajú údaje na výpočet proporcionálnej zložky, údaj sa už mení. A čím väčší je vonkajší vplyv, tým silnejšie sú výkyvy ukazovateľa. V dodávanom napájaní dochádza k prepätiam.

Integrálny komponent sa snaží na základe minulých hodnôt teploty vrátiť svoju hodnotu, ak sa zmenila. Proces je podrobnejšie opísaný vo videu nižšie.

Integrál sa používa na odstránenie chýb výpočtom statickej chyby. Hlavná vec v tomto procese je vybrať správny koeficient, inak chyba (nesúlad) ovplyvní aj integrálnu zložku.

Treťou zložkou PID je diferenciácia. Je navrhnutý tak, aby kompenzoval účinky oneskorení, ktoré sa vyskytujú medzi dopadom na systém a spätnou väzbou. Proporcionálny regulátor dodáva energiu, kým teplota nedosiahne požadovanú úroveň, ale chyby sa vždy vyskytujú pri prechode informácií do zariadenia, najmä pri veľkých hodnotách. Môže to spôsobiť prehriatie. Diferenciál predpovedá odchýlky spôsobené oneskorením alebo vplyvom prostredia a vopred zníži dodávaný výkon.

Nastavenie PID regulátora

PID regulátor sa konfiguruje pomocou 2 metód:

  1. Syntéza zahŕňa výpočet parametrov na základe modelu systému. Toto nastavenie je presné, ale vyžaduje hlboké znalosti teórie automatického riadenia. Podlieha iba inžinierom a vedcom. Pretože je potrebné vziať charakteristiky spotreby a urobiť veľa výpočtov.
  2. Manuálna metóda je založená na pokuse a omyle. Na tento účel sa za základ berú údaje hotového systému a vykonajú sa určité úpravy jedného alebo viacerých koeficientov regulátora. Po zapnutí a spozorovaní konečného výsledku sa parametre menia v požadovanom smere. A tak ďalej, kým sa nedosiahne požadovaná úroveň výkonu.

Teoretická metóda analýzy a úpravy sa v praxi používa veľmi zriedka, čo je spôsobené neznalosťou charakteristík riadiaceho objektu a množstvom možných rušivých vplyvov. Častejšie sú experimentálne metódy založené na pozorovaní systému.

Moderné automatizované procesy sú implementované ako špecializované moduly riadené programami na úpravu koeficientov regulátora.

Účel PID regulátora

PID regulátor je navrhnutý tak, aby udržiaval určitú hodnotu na požadovanej úrovni - teplota, tlak, hladina v nádrži, prietok v potrubí, koncentrácia niečoho atď., a to zmenou regulačného účinku na akčných členoch, ako sú automatické regulačné ventily , pomocou proporcionálnych, integračných, diferenciačných veličín na jeho nastavenie.

Účelom použitia je získanie presného riadiaceho signálu, ktorý je schopný riadiť veľké priemyselné odvetvia a dokonca aj reaktory elektrární.

Príklad obvodu regulácie teploty

Na reguláciu teploty sa často používajú PID regulátory, pozrime sa na tento automatický proces na jednoduchom príklade ohrevu vody v nádobe.

Nádoba je naplnená kvapalinou, ktorú je potrebné zahriať na požadovanú teplotu a udržiavať na danej úrovni. Senzor merania teploty je inštalovaný vo vnútri nádrže - alebo je priamo pripojený k PID regulátoru.

Na ohrev kvapaliny dodáme paru, ako je znázornené na obrázku nižšie, s automatickým regulačným ventilom. Samotný ventil prijíma signál z regulátora. Operátor zadá do PID regulátora požadovanú hodnotu teploty, ktorá sa musí udržiavať v nádrži.

Ak sú nastavenia koeficientu regulátora nesprávne, teplota vody bude kolísať, pričom ventil bude buď úplne otvorený, alebo úplne zatvorený. V tomto prípade je potrebné vypočítať koeficienty PID regulátora a znova ich zadať. Ak je všetko vykonané správne, po krátkom čase systém vyrovná proces a teplota v nádobe sa bude udržiavať na nastavenej hodnote, pričom stupeň otvorenia regulačného ventilu bude v strednej polohe.

PID regulátor je hotové zariadenie, ktoré užívateľovi umožní implementovať softvérový algoritmus na riadenie určitých zariadení automatizovaného systému. Budovanie a konfigurácia riadiacich systémov bude oveľa jednoduchšia, ak použijete hotové zariadenia ako TRM148 univerzálny PID regulátor pre 8 kanálov od spoločnosti Aries.

Povedzme, že potrebujete automatizovať udržiavanie správnych klimatických podmienok v skleníku: berte do úvahy teplotu pôdy v blízkosti koreňov rastlín, tlak vzduchu, vlhkosť vzduchu a pôdy a udržiavajte nastavené parametre ovládaním ventilátorov. Nie je nič jednoduchšie, stačí nakonfigurovať PID regulátor.

Najprv si spomeňme, čo je PID regulátor? PID regulátor je špeciálne zariadenie, ktoré vykonáva plynulé presné nastavenie výstupných parametrov tromi spôsobmi: proporcionálne, integrálne a diferenciálne, pričom počiatočné parametre sú vstupné parametre prijímané zo snímačov (tlak, vlhkosť, teplota, osvetlenie atď.).

Vstupný parameter sa privádza na vstup PID regulátora zo snímača, napríklad zo snímača vlhkosti. Regulátor prijme hodnotu napätia alebo prúdu, zmeria ju, potom vykoná výpočty podľa svojho algoritmu a nakoniec odošle signál na príslušný výstup, v dôsledku čoho automatizovaný systém dostane riadiacu akciu. Vlhkosť pôdy sa znížila - zalievanie sa na niekoľko sekúnd zapne.

Cieľom je dosiahnuť užívateľom špecifikovanú hodnotu vlhkosti. Alebo napríklad: osvetlenie sa znížilo - zapnite fytolampy nad rastlinami atď.

PID riadenie

V skutočnosti, aj keď je všetko na pohľad jednoduché, vo vnútri regulátora je matematika komplikovanejšia, všetko sa nedeje v jednom kroku. Po zapnutí závlahy PID regulátor opäť vykoná meranie, zmeria, o koľko sa teraz zmenila vstupná hodnota – takto sa zistí chyba regulácie. Ďalší dopad na výkonný orgán sa upraví s prihliadnutím na nameranú chybu regulácie a tak ďalej v každom kroku kontroly, až kým sa nedosiahne cieľ – užívateľom zadaný parameter.

Na regulácii sa podieľajú tri zložky: proporcionálna, integrálna a diferenciálna. Každá zložka má v každom konkrétnom systéme svoj vlastný stupeň významnosti a čím väčší je príspevok tej či onej zložky, tým výraznejšie by sa mal zmeniť v regulačnom procese.

Pomerná zložka je najjednoduchšia, čím väčšia zmena, tým väčší koeficient (proporcionalita vo vzorci) a na zníženie vplyvu stačí koeficient jednoducho znížiť (násobiteľ).

Povedzme, že vlhkosť pôdy v skleníku je oveľa nižšia ako stanovená - potom by mala byť doba zavlažovania dlhšia o toľko, koľko je aktuálna vlhkosť nižšia ako stanovená. Toto je hrubý príklad, ale toto je všeobecný princíp.

Integrálny komponent - je potrebné zvýšiť presnosť regulácie na základe predchádzajúcich regulačných udalostí: predchádzajúce chyby sa integrujú a robia sa pre ne korekcie, aby sa v konečnom dôsledku dosiahla nulová odchýlka pri regulácii v budúcnosti.

Nakoniec diferenciálna zložka. Tu sa berie do úvahy rýchlosť zmeny regulovanej veličiny. Či už sa špecifikovaná hodnota mení plynulo alebo náhle, regulačné opatrenie by nemalo viesť k nadmerným odchýlkam hodnoty počas regulácie.

Zostáva už len vybrať zariadenie na PID reguláciu. Dnes je ich na trhu veľa, existujú viackanálové, ktoré umožňujú zmeniť niekoľko parametrov naraz, ako vo vyššie uvedenom príklade so skleníkom.

Pozrime sa na návrh regulátora na príklade univerzálneho PID regulátora TRM148 od firmy Aries.

Vstupných osem snímačov poskytuje signály na príslušné vstupy. Signály sú škálované, filtrované, korigované, ich hodnoty je možné zobraziť na displeji prepínaním pomocou tlačidiel.

Výstupy zariadenia sa vyrábajú v rôznych modifikáciách v požadovaných kombináciách:

    relé 4 A 220 V;

    tranzistorové optočleny n–p–n typ 400 mA 60 V;

    triakové optočleny 50 mA 300 V;

    DAC „parameter-prúd 4...20 mA“;

    DAC „parameter-napätie 0...10 V“;

    4...6 V 100 mA výstup na ovládanie polovodičového relé.

Ovládanie teda môže byť analógové alebo digitálne. - sú to impulzy s premenlivou šírkou a analógové - vo forme plynule sa meniaceho napätia alebo prúdu v jednotnom rozsahu: od 0 do 10 V pre napätie a od 4 do 20 mA pre prúdový signál.

Tieto výstupné signály sa presne používajú na ovládanie akčných členov, povedzme čerpadla závlahového systému alebo relé, ktoré zapína a vypína vykurovacie teleso alebo motor na ovládanie ventilu. Na paneli regulátora sú indikátory signálu.


Pre interakciu s PC je regulátor TRM148 vybavený rozhraním RS-485, ktoré umožňuje:

    nakonfigurovať zariadenie na PC (konfiguračné programy sú poskytované zadarmo);

    prenášať aktuálne hodnoty nameraných hodnôt, výstupný výkon regulátora, ako aj akékoľvek programovateľné parametre do siete;

  • prijímať prevádzkové údaje zo siete na generovanie riadiacich signálov.

Možno tvrdiť, že najvyšší výkon poskytuje P-zákon, - na základe pomeru tp / T d .

Ak je však zosilnenie P-regulátora Kr malé (najčastejšie sa to pozoruje s oneskorením), potom to neposkytuje vysokú presnosť riadenia, pretože v tomto prípade je hodnota veľká.

Ak Kp > 10, potom je P-regulátor prijateľný a ak Kp< 10, то требуется введение в закон управления составляющей.

Zákon o regulácii PI

Najčastejšie v praxi je PI regulátor, ktorý má nasledujúce výhody:

  1. Poskytuje nulovú reguláciu.
  2. Celkom jednoduché nastavenie, pretože... Nastavujú sa len dva parametre, a to zosilnenie Kp a integračná časová konštanta Ti. V takomto regulátore je možné optimalizovať hodnotu pomeru Kp/Ti-min, čím je zabezpečená regulácia s minimálnou možnou efektívnou reguláciou.
  3. Nízka citlivosť na šum pri meraniach (na rozdiel od PID regulátora).

Zákon o kontrole PID

Pre najkritickejšie regulačné slučky môžeme odporučiť použitie , poskytuje najvyšší výkon v systéme.

Majte však na pamäti, že sa to robí len s jeho optimálnym nastavením (konfigurujú sa tri parametre).

S rastúcim oneskorením v systéme sa negatívne fázové posuny prudko zvyšujú, čo znižuje účinok diferenciálnej zložky regulátora. Preto sa kvalita PID regulátora pre systémy s veľkým oneskorením stáva porovnateľnou s kvalitou PI regulátora.

Okrem toho prítomnosť šumu v meracom kanáli v systéme s PID regulátorom vedie k významným náhodným výkyvom riadiaceho signálu regulátora, čo zvyšuje rozptyl chyby riadenia a opotrebovanie mechanizmu.

Preto by sa PID regulátor mal voliť pre regulačné systémy s relatívne nízkou hladinou hluku a oneskorením regulácie. Príkladmi takýchto systémov sú systémy regulácie teploty.



Pokračovanie v téme:
Omietka

Každý vie, čo sú obilniny. Koniec koncov, človek začal tieto rastliny pestovať pred viac ako 10 tisíc rokmi. Preto aj dnes také názvy obilnín ako pšenica, raž, jačmeň, ryža,...