% SMD A statespace model of the Spring-Mass-Damper system
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
%
% DESCRIPTION: A statespace model of the Spring-Mass-Damper
%
% CALL:
%           HARMONIC_OSC_1D = ssm(plist('built-in','SMD'))
%
%
% OUTPUTS:
%           - SMD is an SSM object
%
%
% REFERENCES:
%
%
%
% INFO:
%   <a href="matlab:utils.models.displayModelOverview('ssm_model_SMD')">Model Information</a>
%
%
% REFERENCES:
%
%
% VERSION:     $Id: ssm_model_SMD.m,v 1.2 2011/04/29 09:48:34 marc1 Exp $
%
% HISTORY:
%
%
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%


function varargout = ssm_model_SMD(varargin)
  
  % Process inputs
  [info, pl, constructorInfo, fcn] = utils.models.processModelInputs(varargin(:), mfilename, @getModelDescription, @getModelDocumentation, @getVersion, @versionTable);
  if ~isempty(info)
    varargout{1} = info;
    return;
  end
  
  % Build the object
  out = fcn(pl);
  
  % Set the method version string in the minfo object
  if ~isempty(constructorInfo)
    % If this is a user-call via a constructor, then we add history
    out = addHistoryStep(out, constructorInfo, pl);
  end
  
  if nargout > 0
    varargout{1} = out;
    varargout{2} = pl;
  else
    error('!!! Invalid number of output')
  end
end


%--------------------------------------------------------------------------
% AUTHORS EDIT THIS PART
%--------------------------------------------------------------------------

function desc = getModelDescription
  desc = 'A built-in model that constructs a statespace model for the SMD.';
end

function doc = getModelDocumentation
  doc = sprintf([...
    '<br>It constructs a simple spring mass damper test system.<br>\n'...
    ]);
end

% default version is always the first one
function vt = versionTable()
  
  vt = {...
    'Standard', @versionStandard, ...
    };
  
end

% This is the standard SMD model
%
function varargout = versionStandard(varargin)
  
  if nargin == 1 && ischar(varargin{1})
    switch varargin{1}
      case 'plist'
        
        % The plist for this version of this model
        pl = plist();
        
        pl = combine(pl, ssm.getDefaultPlist('from built-in model'));
        
        % set output
        varargout{1} = pl;
        
      case 'description'
        varargout{1} = sprintf([...
          'This is the standard model for the SMD.'
          ]);
      case 'info'
        varargout{1} = [];
      otherwise
        error('unknown inputs');
    end
    return;
  end
  
  % build model
  pl = varargin{1};
  %% parameters array
  paramNames  = {'SMD_W' 'SMD_C' 'SMD_S1' 'SMD_S2' 'SMD_B' 'SMD_D1'};
  paramValues = [0.2 0.5 0 0 1 0];
  paramUnits = unit('s^-1', 's^-1', '', 's', '', 's^2');
  paramDescriptions = {'Oscilator eigen-frequency' 'Oscilator damping factor'...
    'Gain sensing coefficient'  'Gain differential sensing coefficient' ...
    'Actuator gain' 'Actuation cross sensing coefficient'};


  
  % If the user didn't give a 'param names' key to set parameter values,
  % perhaps they gave individual parameter names
  pl = ssm.modelHelper_processInputPlist(pl, ssm_model_SMD('plist','Standard'));
  
  % processing parameters and declaring variables depending on user needs
  [sys.params, sys.numparams] = ssm.modelHelper_declareParameters(pl, paramNames, paramValues, paramDescriptions, paramUnits);
  
  % here computation of the system's matrices
  sys.amats    = {[0 1 ; -SMD_W*SMD_W -2*SMD_C*SMD_W]};
  sys.cmats    = {[1+SMD_S1 SMD_S2]};
  sys.bmats    = {[0;SMD_B] [0 0; 1 0]};
  sys.dmats    = {SMD_D1 [0 1]};
  
  sys.timestep = 0;
  
  sys.name = 'SRPINGMASSDAMPER';
  sys.description = 'standard spring-mass-damper test system';
  
  inputnames    = {'CMD' 'DIST_SMD'};
  inputdescription = {'force noise' 'observation noise'};
  inputvarnames = {{'F'} {'F' 'S'}};
  inputvarunits = {unit('kg m s^-2') [unit('kg m s^-2') unit('m')]};
  inputvardescription = [];
  
  ssnames    = {'SMD'};
  ssdescription = {'TM position and speed'};
  ssvarnames = {{'x' 'xdot'}};
  ssvarunits={[unit('m') unit('m s^-1')]};
  ssvardescription = [];
  
  outputnames    = {'SMD'};
  outputdescription = {'observed position'};
  outputvarnames ={{'OBS'}};
  outputvarunits={unit('m')};
  outputvardescription = [];
  
  %% Build input plist
  sys.inputs = ssmblock.makeBlocksWithData(inputnames, inputdescription, inputvarnames, inputvarunits, inputvardescription);
  sys.outputs = ssmblock.makeBlocksWithData(outputnames, outputdescription, outputvarnames, outputvarunits, outputvardescription);
  sys.states =  ssmblock.makeBlocksWithData(ssnames, ssdescription, ssvarnames, ssvarunits, ssvardescription);
  
  sys = ssm(sys);
  
  varargout{1} = sys;
  
end


%--------------------------------------------------------------------------
% AUTHORS SHOULD NOT NEED TO EDIT BELOW HERE
%--------------------------------------------------------------------------


%--------------------------------------------------------------------------
% Get Version
%--------------------------------------------------------------------------
function v = getVersion
  
  v = '$Id: ssm_model_SMD.m,v 1.2 2011/04/29 09:48:34 marc1 Exp $';
  
end
