• Najnowsze pytania
  • Bez odpowiedzi
  • Zadaj pytanie
  • Kategorie
  • Tagi
  • Zdobyte punkty
  • Ekipa ninja
  • IRC
  • FAQ
  • Regulamin
  • Książki warte uwagi

Regulator PID algorytm w CPP oraz MatLab Simulink

Aruba Cloud PRO i VPS, Openstack, VMWare, MS Hyper-V
0 głosów
529 wizyt
pytanie zadane 28 listopada 2021 w Algorytmy przez rafaeru Początkujący (330 p.)

Witam, mam problem z napisaniem algorytmu regulatora PID w języku C++ (choć język nie ma tu znaczenia) aby pokrywał się z wynikami zamodelowanego układu w MatLab Simulink (lub uzasadnić dlaczego się nie pokrywa).

Kod algorytmu regulatora (testowany w jdoodle):

#include <iostream>

using namespace std;

double dt = 0.5;

double Kp = 0.1;
double Ki = 0.1;
double Kd = 0.1;

double pre_error = 0;

double integral = 0;

double calculate(double setpoint, double pv) {
    double error = setpoint - pv;
    
    //P
    double Pout = Kp * error;
    
    //I
    integral = integral + (error * dt);
    double Iout = Ki * integral;
    
    //D
    double derivative = (error - pre_error) / dt;
    double Dout = Kd * derivative;
    
    //PID
    double out = Pout + Iout + Dout;
    
    pre_error = error;
    return out;
}

int main() {
    double setpoint = 20;
    double pv = 0;
    
    for (float t = 0; t <= 50; t++) {
        cout << pv << endl;
        double syg_ster = calculate(setpoint, pv);
        //cout << "sygnal sterujacy: " << syg_ster << endl;
        pv += syg_ster;
    }
}

Otrzymujemy przykładowo dla 120 punktów z wartością zadaną 20 oraz warunkiem początkowym 0.

Natomiast zamodelowany regulator PID w MatLab Simulink przedstawia inny wykres:

Na wykresie z Simulink nie ma żadnego przesterowania.

Oraz ustawienia Solvera:

Nie mogę dojść, jaka jest różnica. Pomimo, że regulator z mojego algorytmu działa prawidłowo to nie pokrywa się z tym z MatLaba pomimo tych samych wartości nastaw i nie wiem jak to logicznie uzasadnić. Duży wpływ na wyniki ma zmienna dt (czas próbkowania) ale zmiana sample time w MatLab nie zmienia za wiele. Czy to wina Solvera i użytego w niej Eulera?

Sprawdziłem też inne gotowe algorytmy ale również się nie pokrywają:

https://gist.github.com/bradley219/5373998

https://github.com/pms67/PID

Liczę na waszą pomoc i z góry dziękuje.

 

komentarz 28 listopada 2021 przez edutomek Dyskutant (8,380 p.)
Takie uwagi na szybko:

1) A gdyby tak zasymulować działanie zwykłego integratora (1/s), wyniki też byłyby różne?

2) Kolejnym krokiem byłaby symulacja działania np. inercji pierwszego rzędu (1/1+s). Czy wyniki byłyby różne, czy takie same?

Do czego dążę: jeśli wyniki byłyby różne, przyczyna zapewne tkwi w algorytmie symulacji. Jeśli takie same (podobne), przyczyna jest pewnie w samyej implementacji algorytmu PID.

Wyniki mogą się różnić, ale nie do tego stopnia, że raz wychodzi przebieg asymptotyczny, a raz oscylacyjny.
komentarz 28 listopada 2021 przez rafaeru Początkujący (330 p.)

Mój algorytm inercji 1 rzędu pokazuje dokładnie takie same wyniki jak zasymulowany w MatLab. Więc myślę, że integrator też by był symulowany poprawnie.

Kolega mi podpowiedział, że model z Simulink steruje jednostkowym sprzężeniem zwrotnym a ten z algorytmu 1/s. Sprawdziłem i to by się zgadzało bo po dodaniu członu 1/s otrzymany przebieg jest podobny.

Zaloguj lub zarejestruj się, aby odpowiedzieć na to pytanie.

Podobne pytania

0 głosów
0 odpowiedzi 51 wizyt
0 głosów
1 odpowiedź 170 wizyt
+2 głosów
3 odpowiedzi 1,359 wizyt
pytanie zadane 6 stycznia 2016 w C i C++ przez Wilier Bywalec (2,570 p.)

90,816 zapytań

139,494 odpowiedzi

313,557 komentarzy

60,313 pasjonatów

Motyw:

Akcja Pajacyk

Pajacyk od wielu lat dożywia dzieci. Pomóż klikając w zielony brzuszek na stronie. Dziękujemy! ♡

Sklep oferujący ćwiczenia JavaScript, PHP, rozmowy rekrutacyjne dla programistów i inne materiały

Oto dwie polecane książki warte uwagi. Pełną listę znajdziesz tutaj.

...