Aufgabe 19
- Aufgabenstellung
- Lösung (On/Off - Regler)
- Lösung (P-Regler)
- Lösung (Bonus: PI-Regler)
Hinweis: Diese Aufgabe ist besonders interessant, falls Regelungstechnik Teil Ihres Studiengangs ist - besonders, um ein erstes Verständnis für Regelung zu erhalten. Die Aufgabe benötigt jedoch keinerlei Vorwissen und ist daher für jeden lösbar.
Aufgabe 4a: Grundlegende Aufgabenstellung
Ein Raum soll über eine Heizung auf eine Zieltemperatur geregelt werden.
Die Regelung dieses dynamischen Systems erfolgt vereinfacht über ein Ein-/Aus-Prinzip („On/Off-Regler“): Wenn die Temperatur unter dem Zielwert liegt, wird geheizt.
Sobald der Zielwert erreicht oder überschritten ist, wird die Heizung abgeschaltet.
Anforderungen:
-
Der Benutzer gibt folgende Werte ein:
- Starttemperatur in °C
- Zieltemperatur in °C
- Heizleistung pro Zeitschritt (z. B. +0.5 °C)
- Abkühlung pro Zeitschritt bei ausgeschalteter Heizung (z. B. –0.2 °C)
- Simulationsdauer (Anzahl der Zeitschritte)
-
Das Programm soll in jedem Schritt:
- entscheiden, ob die Heizung an- oder ausgeschaltet ist
- die Temperatur entsprechend anpassen
- den Zustand („Heizung AN“ / „Heizung AUS“) und die aktuelle Temperatur ausgeben
Beispielausgabe
Schritt 0: Temp = 18.00 Celsius – Heizung AN
Schritt 1: Temp = 18.50 Celsius – Heizung AN
Schritt 2: Temp = 19.00 Celsius – Heizung AN
...
Schritt 10: Temp = 22.10 Celsius – Heizung AUS
Schritt 11: Temp = 21.90 Celsius – Heizung AN
Aufgabe 4b: Erweiterung: P-Regler
Ein On/Off-Regler reagiert nur auf Überschreiten oder Unterschreiten eines Grenzwerts. In der Praxis werden häufig kontinuierlich wirkende Regler verwendet, z. B. der Proportionalregler (P-Regler).
Der P-Regler berechnet die Heizleistung nun dynamisch, unzwar proportional zur Temperaturabweichung:
Heizleistung = Kp * (Sollwert - Istwert)
Dabei steht Kp für den Verstärkungsfaktor. Er bestimmt, wie stark das System auf eine Abweichung reagiert.
Ändern Sie Ihren Code so, dass die Heizleistung nicht mehr fest ist, sondern vom Regelfehler abhängt. Beachten Sie, dass die User-Eingabe Heizleistung nun durch die Eingabe von Kp ersetzt werden muss. Ebenso ergibt es Sinn, in der Ausgabe statt (On/Off) nun z.B. die aktuelle Heizleistung auszugeben. Experimentieren Sie anschließend mit unterschiedlichen Kp-Werten. ==Achtung: Ist Kp zu groß, kann es zu Überschwingungen und somit Instabilität kommen! Das Ziel ist grundsätzlich, dass sich das System einpendelt, statt immer weiter auszuarten.==
Aufgabe 4c: I-Anteil (PI-Regler)
Ein P-Regler kann sich stabil einpendeln, aber unter Umständen nicht genau den Zielwert erreichen, sodass die Temperatur konstant neben dem Ziel liegt, aber das System nicht mehr schwingt. Diese bleibende Abweichung nennt man stationären Fehler (Steady-State Error).
Um einen Steady-State Error auszugleichen, kann der Regler um ein Integratorglied (I-Anteil) erweitert werden. Der I-Anteil summiert die Schritt-für-Schritt auftretenden Abweichungen über die Zeit auf (so wie ein Integral) und kann so stationäre Fehler langfristig ausgleichen. Die Formel für die Heizleistung lautet dann:
Heizleistung = Kp * fehler + Ki * fehlerSumme
fehlerSummeist eine Variable, die in jedem einzelnen Schritt den aktuellenfehleraufsummiertKiist ein der Verstärkungsfaktor für den I-Anteil, gibt also an, wie stark das I-Glied in das System eingreift
Ergänzen Sie Ihren Code um diesen I-Anteil. Auch hier können Sie anschließend Ki und Kp beliebig verändern und beobachten, wie das System sich verändert.
Hinweis: In diesem Modell bleibt der Regler eher stabil bei Ki < 1. Das ist jedoch ebenso abhängig von der Wahl des Kp und der Abkühlung, ist also keine Garantie.
Schaffen Sie es das System so zu regeln, dass es sich genau auf der Zieltemperatur einpendelt? Dann verstehen Sie jetzt den PI-Regler!
#include <iostream>
using namespace std;
int main() {
double temp, ziel, heizleistung, abkuehlung;
int dauer;
// Eingaben
cout << "Starttemperatur (Celsius): ";
cin >> temp;
cout << "Zieltemperatur (Celsius): ";
cin >> ziel;
cout << "Heizleistung pro Schritt (Celsius): ";
cin >> heizleistung;
cout << "Abkühlung pro Schritt (Celsius): ";
cin >> abkuehlung;
cout << "Anzahl der Schritte: ";
cin >> dauer;
bool heizungAn;
for (int i = 0; i < dauer; ++i) {
// Regelung: Heizung an, wenn Temperatur unter Ziel
heizungAn = temp < ziel;
// Temperatur ändern
if (heizungAn) {
temp += heizleistung;
} else {
temp -= abkuehlung;
}
// Ausgabe
cout << "Schritt " << i << ": Temp = " << temp
<< " Celsius - Heizung " << (heizungAn ? "AN" : "AUS") << endl;
}
return 0;
}
#include <iostream>
using namespace std;
int main() {
double temp, ziel, Kp, abkuehlung;
int schritte;
// Eingaben
cout << "Starttemperatur (Celsius): ";
cin >> temp;
cout << "Zieltemperatur (Celsius): ";
cin >> ziel;
cout << "Verstärkung Kp: ";
cin >> Kp;
cout << "Abkühlung pro Schritt (Celsius): ";
cin >> abkuehlung;
cout << "Anzahl der Zeitschritte: ";
cin >> schritte;
for (int i = 0; i < schritte; ++i) {
double fehler = ziel - temp; // Regelfehler = Soll - Ist
double heizleistung = Kp * fehler; // Stellgröße durch P-Regler
temp += heizleistung; // Heizen
temp -= abkuehlung; // Umgebung kühlt ab
cout << "Schritt " << i
<< " | Temperatur: " << temp << " Celsius"
<< " | Heizleistung: " << heizleistung << endl;
}
return 0;
}
#include <iostream>
using namespace std;
int main() {
double temp, ziel, Kp, Ki, abkuehlung;
int schritte;
// Eingabe
cout << "Starttemperatur (Celsius): ";
cin >> temp;
cout << "Zieltemperatur (Celsius): ";
cin >> ziel;
cout << "Verstärkung Kp (proportional): ";
cin >> Kp;
cout << "Verstärkung Ki (integral): ";
cin >> Ki;
cout << "Abkühlung pro Schritt (Celsius): ";
cin >> abkuehlung;
cout << "Anzahl der Zeitschritte: ";
cin >> schritte;
double fehlerSumme = 0.0;
for (int i = 0; i < schritte; ++i) {
double fehler = ziel - temp; // Regelfehler (Soll - Ist)
fehlerSumme += fehler; // Aufsummieren (Integral-Anteil)
// Stellgröße berechnen
double heizleistung = Kp * fehler + Ki * fehlerSumme;
// Temperaturänderung
temp += heizleistung;
temp -= abkuehlung;
cout << "Schritt " << i
<< " | Temperatur: " << temp << " Celsius"
<< " | Heizleistung: " << heizleistung << endl;
}
return 0;
}