Erstellen eines Optimierers als modifiziertes Gradientenverfahren gemäß der Vorlage in Kapitel 5.4, Code 5.4-1
Simulator und Guetefunktion
|
|
package opti; import java.awt.*; //package awt für die paint()-Methode nötig. public abstract interface Fehlerfunktion { public abstract double berechneFehler(double[] parameter); /** Fehlerfunktion kann durch Überschreiben der Methode paint() in die Lage versetzt werden, den aktuellen Fehlerverlauf grafisch darzustellen.<br/> Die Methode wird von der paint-Methode eines Canvas-Objekts her aufgerufen. */ public abstract void paint(Graphics2D g); }
Code 0-1: Schnittstelle Fehlerfunktion
|
package opti; import java.awt.*; //package awt für die paint()-Methode nötig. public class FehlerfunktionPIDgeregelterAntrieb implements Fehlerfunktion { public Simulator simulator = null; /**Registrieren eines Simulators*/ public void add(Simulator simulator) { this.simulator = simulator; } public double berechneFehler(double[] parameter) { double gewicht1=1.0,gewicht2=1.0; double fehler = 0; double P = parameter[0]; //z.B. 100 double I = parameter[1]; //z.B. 10 double D = parameter[2]; //z.B. 0 simulator.init(); //ACHTUNG: K und L sind gegenüber der Scilab-Musterlösung in Kaptiel 5.6 vertauscht! simulator.setParameter(1576.1789,0); //K simulator.setParameter(11542.314,1); //L simulator.setParameter(372.33722,2); //M simulator.setParameter(P,3); //P simulator.setParameter(I,4); //I simulator.setParameter(D,5); //D simulator.setParameter(0.01,6); //Tt simulator.setParameter(20.0,7); //omega_viertel_soll simulator.simulieren(); for(int i=0;i<simulator.getAnzahl();i++) { double e = (simulator.getX(i))[0]; double pwm = (simulator.getX(i))[1]; fehler += gewicht1*e; if(pwm>1023) fehler+=gewicht2*(double)(pwm-1023); if(pwm<-1023) fehler+=gewicht2*(double)(-pwm-1023); } return fehler; } /** paint(..) wird bei der Konsolenanwendung nicht verwendet.*/ public void paint(Graphics2D g) { } }
Code 0-2: FehlerfunktionPIDgeregelterAntrieb
|
package opti; import java.awt.*; //package awt für die paint()-Methode nötig. public class OptimiererModGrad extends Optimierer { /**Optimierungsvorgang auslösen. Wird von ergbenden Klassen überschrieben*/ public void optimieren() { /**Faktoren, mit denen die Sprungweite beim Ändern eines Parameters variiert wird.*/ double[] faktor = {-2.0,-1.0,-0.5,0.0,0.5,1.0,2.0}; double[] testfehler = new double[7]; /**Vektorlänge in die Suchrichtung*/ double[] laenge = new double[anzahlParameter]; for(int i=0;i<anzahlParameter;i++) laenge[i]=1.0; /**Fehler mit aktuellem Parametersatz bestimmen:*/ double fehler = fehlerfunktion.berechneFehler(startparameter); double fehler_best = fehler; double fehler_akt = fehler; double[] neueparameter = new double[anzahlParameter]; for(int i=0;i<anzahlParameter;i++) neueparameter[i] = startparameter[i]; boolean fertig = false; int imerk=0,kmerk=0; while(fertig==false) { //Fehler der Varianten bestimmen: for(int i=0;i<anzahlParameter;i++) { for(int k=0;k<faktor.length;k++) { neueparameter[i]+=laenge[i]*faktor[k]; fehler_akt = fehlerfunktion.berechneFehler(neueparameter); if(fehler_akt<fehler_best) { imerk=i; kmerk=k; fehler_best = fehler_akt; } neueparameter[i]-=laenge[i]*faktor[k]; } } neueparameter[imerk]+=laenge[imerk]*faktor[kmerk]; //fehler_best = fehlerfunktion.berechneFehler(neueparameter); if(kmerk!=3) laenge[imerk]*=faktor[kmerk]; /**Sprungweite verbessern für nächsten Schritt*/ if(fehler_akt-fehler_best<epsilon) fertig = true; fehler_akt = fehler_best; System.out.println("aktueller kleinster Fehler: "+fehler_akt); } System.out.println("Start-Parametersatz:"); for(int i=0;i<anzahlParameter;i++) { System.out.println("Parameter Nr.0: "+startparameter[i]); } System.out.println("Startfehler: "+fehler); System.out.println("Minimierter Fehler: "+fehler_best); System.out.println("Bester gefundener Parametersatz:"); for(int i=0;i<anzahlParameter;i++) { System.out.println("Parameter Nr.0: "+neueparameter[i]); } } /** paint(..) wird bei der Konsolenanwendung nicht verwendet.*/ public void paint(Graphics2D g) { } }
Code 0-3: OptimiererModGrad
|
package opti; public class TestOptimiererModGrad { public static void main(String[] args) { SimulatorPIDgeregelterAntrieb simulator = new SimulatorPIDgeregelterAntrieb(); FehlerfunktionPIDgeregelterAntrieb fehlerfunktion = new FehlerfunktionPIDgeregelterAntrieb(); fehlerfunktion.add(simulator); OptimiererModGrad optimierer = new OptimiererModGrad(); optimierer.add(fehlerfunktion); optimierer.startparameter[0] = 100.0; optimierer.startparameter[1] = 10.0; optimierer.startparameter[2] = 0.0; optimierer.optimieren(); } }
Code 0-4: TestOptimiererModGrad
|
package opti; public class TestSimulatorPIDgeregelterAntrieb { public static void main(String[] args) { SimulatorPIDgeregelterAntrieb simulator = new SimulatorPIDgeregelterAntrieb(); simulator.simulationsschritte = 1000; simulator.init(); //ACHTUNG: K und L sind gegenüber der Scilab-Musterlösung in Kaptiel 5.6 vertauscht! simulator.setParameter(1576.1789,0); //K simulator.setParameter(11542.314,1); //L simulator.setParameter(372.33722,2); //M // simulator.setParameter(100.0,3); //P // simulator.setParameter(10.0,4); //I // simulator.setParameter(0.0,5); //D simulator.setParameter(22.0,3); //P simulator.setParameter(6.0,4); //I simulator.setParameter(2.0,5); //D simulator.setParameter(0.01,6); //Tt simulator.setParameter(20.0,7); //omega_viertel_soll simulator.simulieren(); System.out.println("t/s omega/(rad/s) e pwm"); for(int i=0;i<simulator.getAnzahl();i++) { System.out.print(simulator.getT(i)+" "+(simulator.getY(i))[0]); System.out.println(" "+(simulator.getX(i))[0]+" "+(simulator.getX(i))[1] ); } } }
Code 0-5: TestSimulatorPIDgeregelterAntrieb - Testsimulation mit optimierten Regelparametern.

Bild 0-1: Mit Scilab erzeugte Kurven der Java basierten Simulation mit P=22, I=6, D=2.

Übung
|


Beispiel

Bild 0-2: Mit Scilab erzeugte Kurven der Java basierten Simulation mit P=70, I=30, D=10, Datenbasis Projektwoche_Gruppe3_jentsch.zip, "erfühlte Parameter."