function sfunc_bsp9_m(block)
setup(block);

% -------------------------------------------------------------------------
% Initialisierung des Simulationsobjektes block
% -------------------------------------------------------------------------

function setup(block)
  
  % Anzahl der Eingangs- und Ausgangsports
  block.NumInputPorts  = 2;     %u, v
  block.NumOutputPorts = 1;     %s2-s1
  
  % Anzahl der zeitkontinuierlichen Zustaende
  block.NumContStates = 4;      %s1, w1, s2, w2

  % Anzahl der Parameter
  block.NumDialogPrms = 9;      %m1, m2, s10, s120, d1, d12, c1, c12, x0
  
  % Dimensionen der Eingangsports
  % Flag DirectFeedthrough kennzeichnet, ob ein Eingang direkt an einem
  % Ausgang auftritt, d.h. y=f(u)
  block.InputPort(1).Dimensions        = 1;
  block.InputPort(1).SamplingMode = 'Sample';
  block.InputPort(1).DirectFeedthrough = false;
  block.InputPort(2).Dimensions        = 1;
  block.InputPort(2).SamplingMode = 'Sample';
  block.InputPort(2).DirectFeedthrough = false;

  % Dimensionen der Ausgangsports  
  block.OutputPort(1).Dimensions       = 1;
  block.OutputPort(1).SamplingMode = 'Sample';
  
  
  % Einstellen der Abtastzeit: [0 0] wird verwendet fuer die
  % zeitkontinuierliche Simulation.
  block.SampleTimes = [0 0];
    
  % ------------------------------------------------
  % NICHT VERAENDERN
  % ------------------------------------------------
  % 
  % Registrieren der einzelnen Methoden
  % Hier: InitializeConditions ... Initialisierung
  %       Outputs ...       Berechnung der Ausgaenge
  %       Derivatives ...   Berechnung der Zustaende
  %       Terminate ...     Konsistentes Beenden der Simulation

  block.RegBlockMethod('InitializeConditions',    @InitConditions); 
  block.RegBlockMethod('Outputs',                 @Output);  
  block.RegBlockMethod('Derivatives',             @Derivatives);  
  block.RegBlockMethod('Terminate',               @Terminate);


% -------------------------------------------------------------------------
% Setzen der Anfangsbedingungen der Zustaende
% -------------------------------------------------------------------------

function InitConditions(block)
  
  % Einlesen der Parameter des Systems
  x0 = block.DialogPrm(9).Data;             %9...x0, 1-8 siehe Derivatives
  
  % Eingabe der Anfangsbedingungen
  x=x0;
  
  % Schreiben auf Objekt block (NICHT VERAENDERN)
  block.ContStates.Data = x;


% -------------------------------------------------------------------------
% Berechnen der Ausgaenge
% -------------------------------------------------------------------------

function Output(block)
  % Shortcut fuer den Zustand
  x = block.ContStates.Data;
  
  y1(1) = x(3) - x(1);    %(s2-s1)
  
  % Schreiben auf Objekt block
  block.OutputPort(1).Data = y1;
  

% -------------------------------------------------------------------------
% Berechnen der Zustaende
% -------------------------------------------------------------------------


% function Derivatives(block)
%   % Einlesen der Parameter des Systems
%   m1   = block.DialogPrm(1).Data;
%   m2   = block.DialogPrm(2).Data;
%   s10  = block.DialogPrm(3).Data; 
%   s120 = block.DialogPrm(4).Data;
%   d1   = block.DialogPrm(5).Data;
%   d12  = block.DialogPrm(6).Data;
%   c1   = block.DialogPrm(7).Data;
%   c12  = block.DialogPrm(8).Data;
%   
%   % Shortcut fuer den Eingang
%   u1 = block.InputPort(1).Data;
%   u2 = block.InputPort(2).Data;
%   
%   % Shortcut fuer die Zustaende
%   x = block.ContStates.Data;
% 
%   % Kraefte
%   fc1 = @(s1) c1*sinh(s1/s10-1);
%   fd1 = @(w1) d1*w1;
%   fc12 = @(s1,s2) c12*sinh((s2-s1)/s120-1);
%   fd12 = @(w1,w2) d12*(w2-w1);
%  
%   % Berechnen der Zustaende
%   
%   dx(1) = x(2);
%   dx(2) = (1/m1)*(-fc1(x(1))-fd1(x(2))+fc12(x(1),x(3))+fd12(x(2),x(4))-u1);
%   dx(3) = x(4);
%   dx(4) = (1/m2)*(-fc12(x(1),x(3))-fd12(x(2),x(4))-u2);
%   
%   % Schreiben auf Objekt block
%   block.Derivatives.Data = dx;

function Derivatives(block)
  %Parameter definieren:
  m1   = block.DialogPrm(1).Data;
  m2   = block.DialogPrm(2).Data;
  s10  = block.DialogPrm(3).Data; 
  s120 = block.DialogPrm(4).Data;
  d1   = block.DialogPrm(5).Data;
  d12  = block.DialogPrm(6).Data;
  c1   = block.DialogPrm(7).Data;
  c12  = block.DialogPrm(8).Data;
  
  % Shortcut fuer den Eingang
  u = block.InputPort(1).Data;
  v = block.InputPort(2).Data;
  
  % Shortcut fuer die Zustaende
  x = block.ContStates.Data;

  %Zustand definieren:
  %x(1)->s1, x(2)->w1, x(3)->s2, x(4)->w2
  dx(1) = x(2);     %=w1 (Geschwindigkeit w1 ist Ableitung des Weges s1)
  dx(2) = (-c1*sinh(x(1)/s10-1)-d1*x(2)-d12*x(2)-c12*sinh(-(x(3)-x(1))/s120+1)+d12*x(4)-u)/m1;
  dx(3) = x(4);     %=w2
  dx(4) = (d12*x(2)+c12*sinh(-(x(3)-x(1))/s120+1)-d12*x(4)-v)/m2;
  
  % Schreiben auf Objekt block
  block.Derivatives.Data = dx;


% -------------------------------------------------------------------------
% Operationen am Ende der Simulation
% -------------------------------------------------------------------------

% Die function Terminate wird hier nicht verwendet,
% muss aber vorhanden sein!
function Terminate(block)
