[an error occurred while processing this directive]   Suche  
 

Zeilenkommandos

Simulink Modelle können einerseits aus dem Modellfenster heraus mit Simulation -> Start, andererseit auch aus dem Matlab Arbeitsfenster mit dem Kommando:
   sim
gestartet werden. Bei der Simulation werden als Default-Werte für die Parameter die im Modell festgelegten Werte verwendet. Die Default-Werte können aber teils mittels des sim-Kommandos, teils mittels anderer Zeilenkommandos auch abgeändert werden.

Beispiel 1:

Das nachfolgende Modell beschreibt ein zweidimensionales System gewöhnlicher Differentialgleichungen.

Modell des Ruby-Oszillators

Die beiden Funktionsblöcke haben als Werte zu Expression:

F1-2.5e-6*u(1) - 1.5e-18*u(2)*u(1) + 2.1e-6
F20.6*u(2)*u(1) - 0.18*u(2) + 0.016*(1+u(1))

beschreiben also das Modell eines Ruby-Oszillators, das wir in Kontollsignale, Beispiel 3 schon kennengelernt haben. Wenn dieses Modell unter dem Namen 'ruby1' im aktuellen Arbeitsverzeichnis gespeichert ist, dort also den Dateinamen 'ruby1.mdl' hat, können wir mit:

   [t,x] = sim('ruby1');
einen Simulationslauf starten. Die notwendigen Parameter werden hier dem Modell entnommen, könnten aber auch über das Matlab-Fenster eingegeben werden. Als Ergebnisse werden ausgegeben:
  • die Integrationsstützpunkte im (n*1)-Vektor t,
  • die Zustandswerte des Modells zu den Zeitpunkten tk im (n*2)-Vektor x.
In diesem einfachen Fall ist leicht zu sehen, daß das Modell zwei Zustandswerte hat, einen pro Integrator-Block. Welche Spalte des Ergebnisvektors x zu welchem Integrator gehört, kann man an den Anfangswerten erkennen. Die Zustandswerte sind gleichzeitig die Ausgangswerte, die im Modell y genannt werden, also die von uns gewünschten Ergebnisse.
Bei komplexeren Modellen lässt sich diese Frage nicht so einfach beantworten. Es gibt gibt deshalb diverse Hilfsmittel zur Untersuchung eines Modelles, die wir zum Teil auch schon benutzt haben. Erinnert sei an Kommandos wie:
   sizes = Modellname([],[],[],0)
   [sizes,x0] = Modellname([],[],[],0)
   [sizes,x0,states] = Modellname([],[],[],0)

Wir können sie z.B. mittels:

   plot(t,x);
graphisch darstellen.

Zu beachten ist, dass die Ergebnisse des sim-Kommandos nichts mit den Scope-Blöcken des Modells zu tun haben. Es empfiehlt sich in vielen Fällen sogar, Blöcke zur graphischen Ausgabe der Ergebnisse aus dem Modell zu entfernen, da der Aufwand zum Aufbau der Graphikfenster den Gesamtaufwand dominieren kann.
Wenn wir im Modell, den Scope-Block 'aus y(1)' entfernen, erhalten wir mit dem sim-Kommando trotzdem denselben x-Wert wie zuvor. Wenn wir spezielle Ausgabewerte, ähnlich wie in den Scope-Blöcken erhalten wollen, müssen wir im Modell die Scope-Blöcke durch Out-Blöcke ersetzen.

Modell mit Out-Bloecken

Die in die Out-Blöcke einfließenden Ergebnisvektoren sind auch als Ergebnis des sim-Kommandos zugänglich. Der Vektor des Out-Blockes 1 im 3. Ergebnis-Parameter, der des Out-Blockes 2 im 4. Ergebnis-Parameter und so fort. Die Out-Blöcke eine Modelles werden durchnumeriert, man findet die Nummer, die sogenannte Port-Nummer, im Innerern des jeweiligen Out-Blockes angegeben. Das Kommando:
   [t,x,y1,y2] = sim('ruby3')
wobei 'ruby3' der Name des Modells mit den Out-Blöcken ist, liefert in y1 also die Werte zu y(1) und in y2 die Werte zu y(2). Die Matrix x ist in diesem Falle identisch mit der Matrix [y1,y2]. Da die Ergebnisvektoren jetzt sowieso schon im Matlab-Namensraum verfügbar sind, kann man sie mit Hilfe der Matlab-Graphik darstellen, die gegenüber der Simulink-Graphik etwas mehr Möglichkeiten anbietet.
   semilogy(t,y2)
liefert z.B. eine halblogarithmische Darstellung des Graphen von y(2) gegen die Zeit t.

Semilogarithmische Darstellung von y(2)

Wir haben hier ein Modell mit 2 Out-Blöcken mit dem sim-Kommando aufgerufen und auf der linken Seite des sim-Aufrufes für jeden Out-Block einen eigenen Ergebnisvektor (im allgemeinen: Ergebnismatrix) angegeben. Es ist aber auch möglich, dort nur einen Namen anzugeben:
   [t,x,y] = sim('ruby3'):
In y wird jetzt eine Matrix mit length(t) Zeilen und 2 Spalten abgelegt, in der ersten Spalte finden wir den Ergebnisvektor zu Out-Block 1, in der zweiten den zu Out-Block 2.

Start- und Stop-Zeit eines Simulationslaufes können direkt im zweiten Aufruf-Argument des sim-Kommando angegeben werden, sie überschreiben dann die Default-Werte aus dem Modell.

 [t,x,y] = sim('ruby3',[0,4.9e+5])
startet also einem Simulationslauf des Modells 'ruby3' von 0 bis 4.9e+5. Da 0 der Default-Wert für die Start-Zeit ist, hätte man diesen Wert nicht angeben müssen.
 [t,x,y] = sim('ruby3',4.9e+5)
würde dasselbe Ergebnis liefern.

Andere Parameter-Werte kann man mit dem simset-Kommando setzen, welche das sind, lässt sich mit dem simset-Kommando auch abfragen:

   simset
liefert die Antwort:
         Solver: [ 'VariableStepDiscrete' |
                   'ode45' | 'ode23' | 'ode113' | 'ode15s' | 'ode23s' |
                   'FixedStepDiscrete' |
                   'ode5' | 'ode4' | 'ode3' | 'ode2' | 'ode1' ]
         RelTol: [ positive scalar {1e-3} ]
         AbsTol: [ positive scalar {1e-6} ]
         Refine: [ positive integer {1} ]
        MaxStep: [ positive scalar {auto} ]
    InitialStep: [ positive scalar {auto} ]
       MaxOrder: [ 1 | 2 | 3 | 4 | {5} ]
      FixedStep: [ positive scalar ]
   OutputPoints: [ {'specified'} | 'all' ]
OutputVariables: [ {'txy'} | 'tx' | 'ty' | 'xy' | 't' | 'x' | 'y' ]
     SaveFormat: [ {'Matrix'} | 'Structure' | 'StructureWithTime']
        MaxRows: [ non-negative integer {0} ]
     Decimation: [ positive integer {1} ]
   InitialState: [ vector {[]} ]
 FinalStateName: [ string {''} ]
          Trace: [ comma separated list of 'minstep', 'siminfo', 'compile' {''}]
   SrcWorkspace: [ 'base' | {'current'} | 'parent' ]
   DstWorkspace: [ 'base' | {'current'} | 'parent' ]
      ZeroCross: [ {'on'} | 'off' ]
Das simset-Kommando erzeugt eine Datenstruktur 'options', die die Parameter-Werte des Modells beschreibt bzw. verändert. options kann als drittes Aufruf-Argument im sim-Kommando verwendet werden.

Wir formulieren nun ein M-File mit dem Inhalt:

   tic;
   [ts,xs,ys]=sim('ruby3',[0 2e6],simset('AbsTol',1.0e-8, ...
      'RelTol',1.0e-6,'Solver','ode15s','InitialState', [-1;0]));
   toc
   plot(ts,xs);
mit dem:
  • die Durchlaufszeit gestoppt wird (tic und toc)
  • der Ruby Laser Oszillator von 0 bis 2e6 mit Hilfe des Integrators 'ode15s' und den angegebenen Toleranzen und Anfangswerten simuliert wird
  • die Ergebnisse graphisch dargestellt werden
Drei Punkte am Ende einer Zeile zeigen in Matlab an, dass ein Kommando in der nächsten Zeile fortgesetzt wird.

Als Durchlaufzeit erhalten wir etwa 3.2 sec. Wenn wir anstelle des steifen Integrators 'ode15s' den nicht-steifen Integrator 'ode45' verwenden, ergibt sich eine Durchlaufzeit von etwa 12.3 sec. Die Zeitmessungen können auch auf demselben Rechner von Lauf zu Lauf schwanken, die hier angegebenen Werte beziehen sich auf einen 200MHz Pentium Rechner mit 32 MB Hauptspeicher und Simulink Version 3.

Wir hatten in Beispiel 3 im Abschnitt Ereignissteuerung gesehen, dass das Problem des Ruby Laser Oszillators nur in der ersten Phase, etwa bis 4.85e5 steif ist und danach wohl besser mit einem nicht-steifen Integrator zu integrieren ist. Beim Simulationsaufruf über ein M-File bereitet es keine große Mühe, den Integrator zu einem vorgegebenen Zeitpunkt zu wechseln. Wir führen dazu zunächst eine Simulation mit ode15s bis 4.85e5 aus und halten die Zustandswerte zu diesem Zeitpunkt in einem Vektor 'speicher' fest, danach benutzen wir von 4.85e5 bis 2e6 den Integrator ode45. Als Anfangswerte für den zweiten Teil des Simulationslaufes benutzen wir das Endergebnis aus dem ersten Teil.

   tic;
   [ts,xs,ys]=sim('ruby3',[0 4.85e5],simset('AbsTol',1.0e-8,'RelTol',1.0e-6, ...
       'Solver','ode15s','InitialState',[-1;0],'FinalStateName','speicher'));
   [tn,xn,yn]=sim('ruby3',[4.85e5 2e+6],simset('Solver','ode45', ...
       'InitialState',speicher));
   toc
   plot([ts;tn],[xs;xn]) 
Beachten Sie, dass als Wert von 'FinalStateName' ein String 'speicher' angegeben wurde, als Wert von InitialState dagegen der Vektorname speicher.

Im plot-Kommando wurden die Vektoren ts und tn bzw. die Matrizen xs und xn aneinandergehängt.

Das simset-Kommando kann auch ausserhalb des sim-Kommandos aufgerufen werden, man muss der erzeugten Datenstruktur dann einen Namen zuweisen, den man im sim-Kommando zitiert. Im folgenden M-File wird diese Datenstruktur vor dem zweiten Simulationslauf abgeändert:

   tic;
   opt = simset('AbsTol',1.0e-8,'RelTol',1.0e-6, ...
    'Solver','ode15s','InitialState', [-1;0],'FinalStateName','speicher');
   [ts,xs,ys]=sim('ruby3',[0 4.85e5],opt);
   opt = simset(opt,'Solver','ode45','InitialState', speicher);
   [tn,xn,yn]=sim('ruby3',[4.85e5 2e+6],opt);
   toc
   plot([ts;tn],[xs;xn])
Als Durchlaufzeit ergeben sich hier 1.2 sec. Trotz des Aufwandes für den Wechsel des Integrators, erhält man hier also die kürzeste Durchlaufzeit.

Weitere Zeilenkommandos

Es sollen nicht alle Zeilenkommandos zu Simulink mit allen Details vorgestellt werden. Wir beschränken uns stattdessen auf einige Anwendungsbeispiele. Dabei wollen wir annehmen, daß das folgende Simulink-Modell mit dem Namen ruby4 und nur diese, gerade auf dem Bildschirm geöffnet ist.

Modellbeispiel

  • gcs liefert den Namen des aktuellen Simulink Modelles.
    » gcs
    ans =
    ruby4
  • gcb liefert den Namen des aktuellen Blockes im aktuellen Simulink Modelles.
    » gcb
    ans =
    ruby4/Scope3
    Wenn wir nun im Subsystem Ggl2 ein Block mit Namen F1 anklicken, liefert ein nachfolgendes:
    » gcb
    ans =
    ruby4/Dgl2/F1
  • gcbh liefert das Handle des aktuellen Blockes im aktuellen Simulink Modelles.
    » gcbh
    ans =
    48.0009
  • simget liefert Simulationsparameter eines Modells, Werte von Parametern oder die 'OptionStructure'.
    » simget(gcs)
    ans = 
                 AbsTol: 1.0000e-006
                  Debug: 'off'
             Decimation: 1
           DstWorkspace: 'current'
         FinalStateName: ''
              FixedStep: 'auto'
           InitialState: []
            InitialStep: 'auto'
               MaxOrder: 5
             SaveFormat: 'Matrix'
                MaxRows: 0
                MaxStep: 0.1000
           OutputPoints: 'all'
        OutputVariables: ''
                 Refine: 1
                 RelTol: 0.0010
                 Solver: 'ode45'
           SrcWorkspace: 'base'
                  Trace: ''
              ZeroCross: 'on'
    » rt = simget('ruby4','RelTol')
    rt =
        0.0010
    
  • find_system listet die Bauteile des angegebenen Modelles auf.
    » find_system('ruby4')
    ans = 
        'ruby4'
        'ruby4/Dgl2'
        'ruby4/Dgl2/F1'
        'ruby4/Dgl2/F2''
        'ruby4/Dgl2/Mux'
        'ruby4/Dgl2/y(1)'
        'ruby4/Dgl2/y(2)'
        'ruby4/Dgl2/aus: y(1)'
        'ruby4/Dgl2/aus: y(2)'
        'ruby4/Schrittweite'
        'ruby4/Schrittzahl'
        'ruby4/Scope'
        'ruby4/Scope1'
        'ruby4/Scope2'
        'ruby4/Scope3'
    Hierbei sind:
    • 'ruby4': Name des Modells
    • 'Dgl2', 'Schrittweite', 'Schrittzahl': Namen von Subsystemen
    • 'F1', 'F2', 'Mux', 'y(1)', 'y(2)', 'aus: y(1)', 'aus: y(2)', 'Scope', 'Scope1', 'Scope2', 'Scope3': Namen von Blöcken

  • get_param liefert Informationen über die Parameter eines Simulink-Objektes und deren Werte.
    » get_param('ruby4/Dgl2/Mux','ObjectParameters')
    ans = 
                              Name: [1x1 struct]
                               Tag: [1x1 struct]
                       Description: [1x1 struct]
                              Type: [1x1 struct]
                            Parent: [1x1 struct]
                            ....................
                            Inputs: [1x1 struct]
                   .............................
    » get_param('ruby4/Dgl2/Mux','Inputs')
    ans =
    2

  • set_param besetzt Parameterwerte eines Simulink-Objektes.
    » set_param('ruby4/Dgl2/Mux','Inputs',3)
    liefert Fehlermeldung
    » set_param('ruby4/Dgl2/Mux','ForegroundColor','red')
    zeigt den Mux-Block in rot.

Beispiel 2:

Wir arbeiten hier mit einem M-Skript in einer Datei bsp2m.m und diese befinde sich im selben Verzeichnis wie das folgende Simulink-Modell bsp2.mdl.

Der Integrator arbeitet mit dem Anfangswert 1, der Transport Delay-Block mit Initial Input 1. Der Sign-Block liefert also zu Beginn der Integration den Wert 1 und bei exakter Rechnung müßte in der ersten Integrationsphase, also bis zum ersten Wechsel des Ausgangswertes des Sign-Blockes, der Integrator-Block die Werte von exp(-t) liefern.
Der erste Wechsel des Ausgabewertes des Sign-Blockes findet statt, wenn das Eingangssignal den Wert 0.5 erreicht hat, bei exakter Rechnung also zum Zeitpunkt log(0.5)-1, wobei die Reduzierung um 1 durch den Time-Delay-Block bewirkt wird.
Im getriggerten Subsystem Leiter wird der Funktionswert u+log(0.5)-1 zum Zeitpunkt u berechnet, zu dem sich numerisch y(t-1)-0.5 ≤ 0 ergibt. Der Funktionswert liefert also die Differenz zwischen numerisch berechneter und exakter Nullstelle von y(t-1)-0.5. wird. Anders formuliert, den Fehler der numerischen Berechnung dieser Nullstelle.

Das Skript bsp2m.m dient diesmal dazu mehrere Simulationsläufe mit demselben bzw. einem leicht modifizierten Modell durchzuführen und die dabei ermittelten Fehler bei der Nullstellenberechnung zu sammeln und darzustellen. Durchgeführt werden drei Simulationsreihen mit jeweils 14 Simulationsläufen. Die Simulationen innerhalb eines Laufes unterscheiden sich durch die vorgegebene relative bzw. absolute Toleranz bei der Integration. mit ode45. Die drei Simulationsreihen unterscheiden sich wie folgt:

  1. .Simulationsreihe: Integration mit Nullstellenbestimmung, mit Hit-crossing Block
  2. .Simulationsreihe: Integration ohne Nullstellenbestimmung, mit Hit-crossing-Block
  3. .Simulationsreihe: Integration mit Nullstellenbestimmung, ohne Hit-crossing-Block
Auf das Ergebnis-Diagramm sind wir schon früher eingegangen, so daß hier nur die Funktion des M-Files erläutert wird.

% Simulationsreihe 1 und 2
% Folge von Simulationslaeufen mit unterschiedlichen Toleranzen
  for rt=1:14
   rtl = 10^(-rt);
   atl = 10^(-2*rt);
%  Simulationsreihe 1, Lauf rt
   [t,x,y]=sim('bsp2',[0 4],simset('RelTol',rtl,'AbsTol',atl,'ZeroCross','on'));
%  size(y) liefer Zeilen- und Spaltenzahl der Ergebnismatrix y
   nn = size(y);
%  Abspeichern des letzten Wertes von y, y wird als eindimensionaler
%  Vektor behandelt, da y nur eine Spalte aufweist, ist dies kein Problem
   mit(rt)=abs(y(nn(1)));
%  Simulationsreihe 2, Lauf rt
   [t,x,y]=sim('bsp2',[0 4],simset('RelTol',rtl,'AbsTol',atl,'ZeroCross','off'));
   nn = size(y);
   ohne(rt)=abs(y(nn(1)));
  end
% Entfernen der Verbindung zwischen Integrator und HC-Block.
% Angegeben wird neben dem Block auch die Port-Nummer, da es aber
% Jeweils nur einen Ausgangs- bzw. Eingangs-Port gibt, ist diese
% Angabe problemlos.
delete_line('bsp2','Integrator/1','HC-Block/1');
% Entfernen des HC-Blockes aus dem Modell
  delete_block('bsp2/HC-Block');
% Siumlationsreihe 3
  for rt=1:14
   rtl = 10^(-rt);
   atl = 10^(-2*rt);
   [t,x,y]=sim('bsp2',[0 4],simset('RelTol',rtl,'AbsTol',atl,'ZeroCross','on'));
   nn = size(y);
   mitohne(rt)=abs(y(nn(1)));
  end
% Rekonstruktion des ursprünglichen Modells
  add_block('bsp2sec/HC-Block','bsp2/HC-Block');
  add_line('bsp2','Integrator/1','HC-Block/1');
% graphische Darstellung der Fehler mit semilogarithmischer
% Skalierung der y-Achse
  semilogy(1:14,[mit;ohne;mitohne])

Während sich die mit set_param gesetzen Parameterwerte nicht auf gespeicherte Simulink-Modell auswirken, tun dies die Kommandos delete_block und delete_line sehr wohl. Mit Hilfe der beiden Kommandos add_block und add_line wird der ursprüngliche Zustand des Modelles wieder hergestellt. Bei der vorliegenden Simulink Version 3 ist Voraussetzung für die korrekte Arbeit des add_block-Kommandos, daß das Modell bsp2sec, aus dem ein Block kopiert wird, gerade das aktuelle System ist.