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.
optimierung.zip - Download der oben beschriebenen Programme.
Übung
|
projektwoche.zip - Download einiger Ergebnisdaten der Projektwoche.
autogui.zip - Aktueller Stand der Java-Simulationsumgebung.
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."