classdef OptimPID < matlab.apps.AppBase

    % Properties that correspond to app components
    properties (Access = public)
        OptimPIDUIFigure               matlab.ui.Figure
        EditField                      matlab.ui.control.NumericEditField
        Label                          matlab.ui.control.Label
        MaximumallowedovershootCheckBox  matlab.ui.control.CheckBox
        TerminatetimeEditField         matlab.ui.control.NumericEditField
        TerminatetimeEditFieldLabel    matlab.ui.control.Label
        CriterionvalueEditField        matlab.ui.control.NumericEditField
        CriterionvalueEditFieldLabel   matlab.ui.control.Label
        OptimizationcriterionListBox   matlab.ui.control.ListBox
        OptimizationcriterionListBoxLabel  matlab.ui.control.Label
        OptimizationalgorithmsListBox  matlab.ui.control.ListBox
        OptimizationalgorithmsListBoxLabel  matlab.ui.control.Label
        SimulinkmodelEditField         matlab.ui.control.EditField
        SimulinkmodelEditFieldLabel    matlab.ui.control.Label
        MultistairssignalPanel         matlab.ui.container.Panel
        SimulationrangeEditField       matlab.ui.control.NumericEditField
        SimulationrangeEditFieldLabel  matlab.ui.control.Label
        HoldCheckBox                   matlab.ui.control.CheckBox
        yvectorEditField               matlab.ui.control.EditField
        yvectorEditFieldLabel          matlab.ui.control.Label
        TimevectorEditField            matlab.ui.control.EditField
        TimevectorEditFieldLabel       matlab.ui.control.Label
        ControllerparametersPanel      matlab.ui.container.Panel
        UpperboundsEditField           matlab.ui.control.EditField
        UpperboundsEditFieldLabel      matlab.ui.control.Label
        LowerboundsEditField           matlab.ui.control.EditField
        LowerboundsEditFieldLabel      matlab.ui.control.Label
        InitialvaluesEditField         matlab.ui.control.EditField
        InitialvaluesEditFieldLabel    matlab.ui.control.Label
        ExitButton                     matlab.ui.control.Button
        HelpButton                     matlab.ui.control.Button
        SimulationButton               matlab.ui.control.Button
        OptimizeButton                 matlab.ui.control.Button
        ViewfileButton                 matlab.ui.control.Button
        ShowplantButton                matlab.ui.control.Button
        CleartrashButton               matlab.ui.control.Button
        CreatefileButton               matlab.ui.control.Button
        ActuatorsaturationPanel        matlab.ui.container.Panel
        UpperlimitEditField            matlab.ui.control.NumericEditField
        UpperlimitEditFieldLabel       matlab.ui.control.Label
        LowerlimitEditField            matlab.ui.control.NumericEditField
        LowerlimitEditFieldLabel       matlab.ui.control.Label
        Button_3                       matlab.ui.control.Button
        Button_2                       matlab.ui.control.Button
        ControllertypePanel            matlab.ui.container.Panel
        SampletimeEditField            matlab.ui.control.NumericEditField
        SampletimeEditFieldLabel       matlab.ui.control.Label
        ButtonGroup                    matlab.ui.container.ButtonGroup
        DiscreteButton                 matlab.ui.control.RadioButton
        ContinuousButton               matlab.ui.control.RadioButton
        ListBox                        matlab.ui.control.ListBox
        ListBoxLabel                   matlab.ui.control.Label
        Button                         matlab.ui.control.Button
    end

    
    methods (Access = public)
   
        function results = set_saturation(app)
           v1=app.LowerlimitEditField.Value; 
           v2=app.UpperlimitEditField.Value;
           if isfinite(v1)||isfinite(v2) 
               set_param('pidctrl_model/PID Controller','LimitOutput','on');
           else, set_param('pidctrl_model/PID Controller','LimitOutput','off'); end
           set_param('pidctrl_model/PID Controller','UpperSaturationLimit',num2str(v2));
           set_param('pidctrl_model/PID Controller','LowerSaturationLimit',num2str(v1));
        end
        
    end
    

    % Callbacks that handle component events
    methods (Access = private)

        % Code that executes after component creation
        function startupFcn(app)
            assignin('base','t_seq',0); assignin('base','y_seq',1);
            assignin('base','keyCriterion',1); assignin('base','Kp',1);
            assignin('base','Ki',1); assignin('base','Kd',1); assignin('base','tn',10);
            load_system('pidctrl_model')
            mod_name=get_param('pidctrl_model/Plant Model','ModelNameDialog');
            app.SimulinkmodelEditField.Value=mod_name;
        end

        % Selection changed function: ButtonGroup
        function ButtonGroupSelectionChanged(app, event)
            switch app.ButtonGroup.SelectedObject.Text
                case 'Continuous'
                    app.SampletimeEditField.Visible='off';
                    app.SampletimeEditFieldLabel.Visible='off';
                    set_param('pidctrl_model/PID Controller','TimeDomain','Continuous')
                case 'Discrete'
                    app.SampletimeEditField.Visible='on';
                    app.SampletimeEditFieldLabel.Visible='on';
                    set_param('pidctrl_model/PID Controller','TimeDomain','Discrete')
                    set_param('pidctrl_model/PID Controller',...
                           'SampleTime',num2str(app.SampletimeEditField.Value));
            end
        end

        % Button pushed function: Button_2
        function Button_2Pushed(app, event)
            app.LowerlimitEditField.Value=-inf; set_saturation(app);
        end

        % Button pushed function: Button_3
        function Button_3Pushed(app, event)
            app.UpperlimitEditField.Value=inf; set_saturation(app);
        end

        % Callback function
        function ButtonPushed(app, event)
           [FileN,~]=uigetfile('*.mdl;*.slx','Select a model name');
           app.SimulinkmodelEditField.Value=FileN;
           SimulinkmodelEditFieldValueChanged(app, event);
        end

        % Value changed function: SimulinkmodelEditField
        function SimulinkmodelEditFieldValueChanged(app, event)
            mod_name=app.SimulinkmodelEditField.Value
            if exist(mod_name)~=4
                app.CreatefileButton.Enable='off';
                errordlg('No such a Simulink model','ERROR'); 
            else
               set_param('pidctrl_model/Plant Model','ModelNameDialog',mod_name);
               load_system(mod_name);
               set_param(mod_name,'InlineParams','on');
               app.CreatefileButton.Enable='on';
               app.ShowplantButton.Enable='on';
               app.ViewfileButton.Enable='off';
            end            
        end

        % Button pushed function: CreatefileButton
        function CreatefileButtonPushed(app, event)
            disp('clicked')
            k=0;
            while 1
                str=['optpidfun_' int2str(k)];
                if ~any([2 3 4 5 6]==exist(str)), break; end
                k=k+1;
            end
            fid=fopen([str,'.m'],'w');
            fprintf(fid,'function y_out=%s(x)\r\n',str);
            fprintf(fid,'%% %s   An objective function for optimal PID controller tuning\r\n',upper(str));
            fprintf(fid,'%%   It describes the relationship between the PID controller parameters\r\n');
            fprintf(fid,'%%   and the chosen performance index.\r\n\r\n');
            fprintf(fid,'%%   The function is automatically created by PID Controller Optimizer.\r\n');
            fprintf(fid,'%%   Date of creation %s\r\n',date);
            strP=['Kp';'Ki';'Kd'];
            switch app.ListBox.Value
                case 'P controller', vv=1; n=1;
                case {'PI controller','Anti-windup PI'}, vv=[1,2]; n=2;
                case 'PD controller', vv=[1,3]; n=2;
                case {'PID controller','Anti-windup PID'}, vv=[1,2,3]; n=3;
                case 'I controller', vv=[2]; n=1;
            end
            fprintf(fid,'W=get_param(''pidctrl_model'',''ModelWorkspace'');\r\n');
            for i=1:length(vv)
                fprintf(fid,'assignin(W,''%s'',x(%d));\r\n',strP(vv(i),:), i);
            end
            fprintf(fid,'try\r\n');  %to enable refreshing of scope, pause is used
            fprintf(fid,'   txy=sim(''pidctrl_model''); y_out=txy.yout(end,1);\r\n');
            fprintf(fid,'catch, y_out=1e10; end\r\n');
            if app.MaximumallowedovershootCheckBox.Value==1
                fprintf(fid,'u=evalin(''base'',''y_seq''); u=u(1);\r\n');
                fprintf(fid,'if max(txy.yout(:,2)-u)/u>1+0.01*%f, y_out=10*y_out; end\r\n',app.EditField.Value);                 
            end
            fprintf(fid,'pause(0.00001)\r\n');
            fclose(fid);
            udata{1}=n; udata{5}=str;
            app.OptimizeButton.Enable='on';
            app.ViewfileButton.Enable='on';
            app.OptimPIDUIFigure.UserData=udata;
        end

        % Button pushed function: ShowplantButton
        function ShowplantButtonPushed(app, event)
           open_system(app.SimulinkmodelEditField.Value);
        end

        % Button pushed function: CleartrashButton
        function CleartrashButtonPushed(app, event)
            for i=0:1000
                str=['optpidfun_' int2str(i)];
                if exist(str)==2, delete([str '.m']); end
            end
        end

        % Button pushed function: ViewfileButton
        function ViewfileButtonPushed(app, event)
            udata=app.OptimPIDUIFigure.UserData; str=udata{5};
            if isempty(str), errordlg('No file to open','ERROR')
            else, eval(['edit ' str]); end
        end

        % Button pushed function: SimulationButton
        function SimulationButtonPushed(app, event)
            try
                t_seq=str2num(app.TimevectorEditField.Value);
                y_seq=str2num(app.yvectorEditField.Value);
                tn=app.SimulationrangeEditField.Value;
            catch
                errordlg('Syntax errors in the multi-stairs vectors','Error...')
            end
            if length(t_seq)~=length(y_seq)
                errordlg('Lengths mismatch in the multi-stairs vectors','Error...')
            end
            assignin('base','t_seq',t_seq);
            assignin('base','y_seq',y_seq); assignin('base','tn',tn); 
            set_param('pidctrl_model','FastRestart','on'); 
            txy=sim('pidctrl_model');            
            set_param('pidctrl_model','FastRestart','off'); 
            app.CriterionvalueEditField.Value=txy.yout(end,1); % display criterion
        end

        % Button pushed function: OptimizeButton
        function OptimizeButtonPushed(app, event)
            set_param('pidctrl_model/Scope','OpenAtSimulationStart','on')
            udata=app.OptimPIDUIFigure.UserData;
            n=udata{1}; str=udata{5}; 
            eval(['Prob.Objective=@', str ';'])
            x0=rand(n,1); 
            if ~isempty(app.InitialvaluesEditField.Value)
                Prob.x0=str2num(app.InitialvaluesEditField.Value); 
            else, Prob.x0=x0; end
            if ~isempty(app.LowerboundsEditField.Value), Prob.lb=str2num(app.LowerboundsEditField.Value); end
            if ~isempty(app.UpperboundsEditField.Value), Prob.ub=str2num(app.UpperboundsEditField.Value); end
            Prob.nvars=n; 
            set_param('pidctrl_model','FastRestart','off');
            assignin('base','tn',app.TerminatetimeEditField.Value)
            assignin('base','t_seq',0); assignin('base','y_seq',1);
            set_param('pidctrl_model','FastRestart','on');
            Prob.options=optimset;
            ff=msgbox('Optimization in process, please wait ...','Please wait');
            switch app.OptimizationalgorithmsListBox.Value
                case 'Plain MATLAB', Prob.solver='fminsearch'; [ctrl_pars,yy0]=fminsearch(Prob);
                case 'Optimization Toolbox', Prob.solver='fminunc'; [ctrl_pars,yy0]=fminunc(Prob);
                case 'Genetic algorithm', Prob.solver='ga'; 
                    Prob.options=optimoptions('ga'); eval(['Prob.fitnessfcn=@', str ';']) 
                    [ctrl_pars,yy0]=ga(Prob);
                case 'Particle swarm', Prob.solver='particleswarm'; 
                    Prob.options=optimoptions('particleswarm'); [ctrl_pars,yy0]=particleswarm(Prob);
            end
            assignin('base','ctrl_pars',ctrl_pars)
            app.InitialvaluesEditField.Value=mat2str(ctrl_pars);
            app.CriterionvalueEditField.Value=yy0;
            app.SimulationButton.Enable='on';
            set_param('pidctrl_model','FastRestart','off');
            pause(0.00001), delete(ff);
        end

        % Button pushed function: ExitButton
        function ExitButtonPushed(app, event)
            close_system('pid_ctrl_model',0), delete(app)
        end

        % Value changed function: OptimizationcriterionListBox
        function OptimizationcriterionListBoxValueChanged(app, event)
            switch app.OptimizationcriterionListBox.Value
                case 'ITAE criterion',   key=1;
                case 'ISE criterion',    key=2;
                case 'IAE criterion',    key=3;
                case 'ITSE criterion',   key=4;
                case 'IT^2SE criterion', key=5; 
                case 'IT^2AE criterion', key=6;
            end 
            assignin('base','keyCriterion',key);
        end

        % Close request function: OptimPIDUIFigure
        function OptimPIDUIFigureCloseRequest(app, event)
            ExitButtonPushed(app, event)
        end

        % Value changed function: LowerlimitEditField
        function LowerlimitEditFieldValueChanged(app, event)
            set_saturation(app);
        end

        % Value changed function: UpperlimitEditField
        function UpperlimitEditFieldValueChanged(app, event)
            set_saturation(app);
        end

        % Value changed function: MaximumallowedovershootCheckBox
        function MaximumValueChanged(app, event)
            value = app.MaximumallowedovershootCheckBox.Value;
            if value==1
                app.EditField.Visible='on'; app.Label.Visible='on';
            else
                app.EditField.Visible='off'; app.Label.Visible='off';
            end
        end
    end

    % Component initialization
    methods (Access = private)

        % Create UIFigure and components
        function createComponents(app)

            % Create OptimPIDUIFigure and hide until all components are created
            app.OptimPIDUIFigure = uifigure('Visible', 'off');
            app.OptimPIDUIFigure.Position = [100 100 548 563];
            app.OptimPIDUIFigure.Name = 'OptimPID';
            app.OptimPIDUIFigure.CloseRequestFcn = createCallbackFcn(app, @OptimPIDUIFigureCloseRequest, true);

            % Create Button
            app.Button = uibutton(app.OptimPIDUIFigure, 'push');
            app.Button.Icon = 'fig1.jpg';
            app.Button.Position = [240 511 21 25];
            app.Button.Text = '';

            % Create ControllertypePanel
            app.ControllertypePanel = uipanel(app.OptimPIDUIFigure);
            app.ControllertypePanel.Title = 'Controller type';
            app.ControllertypePanel.Position = [25 268 236 201];

            % Create ListBoxLabel
            app.ListBoxLabel = uilabel(app.ControllertypePanel);
            app.ListBoxLabel.HorizontalAlignment = 'right';
            app.ListBoxLabel.Position = [20 152 10 22];
            app.ListBoxLabel.Text = '';

            % Create ListBox
            app.ListBox = uilistbox(app.ControllertypePanel);
            app.ListBox.Items = {'P controller', 'PI controller', 'PID controller', 'PD controller', 'I controller', 'Anti-windup PI', 'Anti-windup PID'};
            app.ListBox.Position = [29 107 177 69];
            app.ListBox.Value = 'PID controller';

            % Create ButtonGroup
            app.ButtonGroup = uibuttongroup(app.ControllertypePanel);
            app.ButtonGroup.SelectionChangedFcn = createCallbackFcn(app, @ButtonGroupSelectionChanged, true);
            app.ButtonGroup.Position = [40 46 176 51];

            % Create ContinuousButton
            app.ContinuousButton = uiradiobutton(app.ButtonGroup);
            app.ContinuousButton.Text = 'Continuous';
            app.ContinuousButton.Position = [11 24 83 22];
            app.ContinuousButton.Value = true;

            % Create DiscreteButton
            app.DiscreteButton = uiradiobutton(app.ButtonGroup);
            app.DiscreteButton.Text = 'Discrete';
            app.DiscreteButton.Position = [11 2 66 22];

            % Create SampletimeEditFieldLabel
            app.SampletimeEditFieldLabel = uilabel(app.ControllertypePanel);
            app.SampletimeEditFieldLabel.HorizontalAlignment = 'right';
            app.SampletimeEditFieldLabel.Visible = 'off';
            app.SampletimeEditFieldLabel.Position = [27 15 72 22];
            app.SampletimeEditFieldLabel.Text = 'Sample time';

            % Create SampletimeEditField
            app.SampletimeEditField = uieditfield(app.ControllertypePanel, 'numeric');
            app.SampletimeEditField.Visible = 'off';
            app.SampletimeEditField.Position = [116 15 77 22];
            app.SampletimeEditField.Value = 0.01;

            % Create ActuatorsaturationPanel
            app.ActuatorsaturationPanel = uipanel(app.OptimPIDUIFigure);
            app.ActuatorsaturationPanel.Title = 'Actuator saturation';
            app.ActuatorsaturationPanel.Position = [26 163 237.007299270073 97];

            % Create Button_2
            app.Button_2 = uibutton(app.ActuatorsaturationPanel, 'push');
            app.Button_2.ButtonPushedFcn = createCallbackFcn(app, @Button_2Pushed, true);
            app.Button_2.Icon = 'fig2.jpg';
            app.Button_2.Position = [197 49 21 22];
            app.Button_2.Text = '';

            % Create Button_3
            app.Button_3 = uibutton(app.ActuatorsaturationPanel, 'push');
            app.Button_3.ButtonPushedFcn = createCallbackFcn(app, @Button_3Pushed, true);
            app.Button_3.Icon = 'fig3.jpg';
            app.Button_3.Position = [197 20 21 22];
            app.Button_3.Text = '';

            % Create LowerlimitEditFieldLabel
            app.LowerlimitEditFieldLabel = uilabel(app.ActuatorsaturationPanel);
            app.LowerlimitEditFieldLabel.HorizontalAlignment = 'right';
            app.LowerlimitEditFieldLabel.Position = [12 48 63 22];
            app.LowerlimitEditFieldLabel.Text = 'Lower limit';

            % Create LowerlimitEditField
            app.LowerlimitEditField = uieditfield(app.ActuatorsaturationPanel, 'numeric');
            app.LowerlimitEditField.ValueChangedFcn = createCallbackFcn(app, @LowerlimitEditFieldValueChanged, true);
            app.LowerlimitEditField.Position = [82 48 100 22];
            app.LowerlimitEditField.Value = -Inf;

            % Create UpperlimitEditFieldLabel
            app.UpperlimitEditFieldLabel = uilabel(app.ActuatorsaturationPanel);
            app.UpperlimitEditFieldLabel.HorizontalAlignment = 'right';
            app.UpperlimitEditFieldLabel.Position = [12 20 63 22];
            app.UpperlimitEditFieldLabel.Text = 'Upper limit';

            % Create UpperlimitEditField
            app.UpperlimitEditField = uieditfield(app.ActuatorsaturationPanel, 'numeric');
            app.UpperlimitEditField.ValueChangedFcn = createCallbackFcn(app, @UpperlimitEditFieldValueChanged, true);
            app.UpperlimitEditField.Position = [82 20 100 22];
            app.UpperlimitEditField.Value = Inf;

            % Create CreatefileButton
            app.CreatefileButton = uibutton(app.OptimPIDUIFigure, 'push');
            app.CreatefileButton.ButtonPushedFcn = createCallbackFcn(app, @CreatefileButtonPushed, true);
            app.CreatefileButton.Position = [295 511 121 25];
            app.CreatefileButton.Text = 'Create file';

            % Create CleartrashButton
            app.CleartrashButton = uibutton(app.OptimPIDUIFigure, 'push');
            app.CleartrashButton.ButtonPushedFcn = createCallbackFcn(app, @CleartrashButtonPushed, true);
            app.CleartrashButton.Position = [426 511 100 25];
            app.CleartrashButton.Text = 'Clear trash';

            % Create ShowplantButton
            app.ShowplantButton = uibutton(app.OptimPIDUIFigure, 'push');
            app.ShowplantButton.ButtonPushedFcn = createCallbackFcn(app, @ShowplantButtonPushed, true);
            app.ShowplantButton.Position = [295 482 121 22];
            app.ShowplantButton.Text = 'Show plant';

            % Create ViewfileButton
            app.ViewfileButton = uibutton(app.OptimPIDUIFigure, 'push');
            app.ViewfileButton.ButtonPushedFcn = createCallbackFcn(app, @ViewfileButtonPushed, true);
            app.ViewfileButton.Enable = 'off';
            app.ViewfileButton.Position = [426 482 100 22];
            app.ViewfileButton.Text = 'View file';

            % Create OptimizeButton
            app.OptimizeButton = uibutton(app.OptimPIDUIFigure, 'push');
            app.OptimizeButton.ButtonPushedFcn = createCallbackFcn(app, @OptimizeButtonPushed, true);
            app.OptimizeButton.Enable = 'off';
            app.OptimizeButton.Position = [295 452 121 22];
            app.OptimizeButton.Text = 'Optimize';

            % Create SimulationButton
            app.SimulationButton = uibutton(app.OptimPIDUIFigure, 'push');
            app.SimulationButton.ButtonPushedFcn = createCallbackFcn(app, @SimulationButtonPushed, true);
            app.SimulationButton.Enable = 'off';
            app.SimulationButton.Position = [426 452 100 22];
            app.SimulationButton.Text = 'Simulation';

            % Create HelpButton
            app.HelpButton = uibutton(app.OptimPIDUIFigure, 'push');
            app.HelpButton.Position = [295 422 121 22];
            app.HelpButton.Text = 'Help';

            % Create ExitButton
            app.ExitButton = uibutton(app.OptimPIDUIFigure, 'push');
            app.ExitButton.ButtonPushedFcn = createCallbackFcn(app, @ExitButtonPushed, true);
            app.ExitButton.Position = [426 422 100 22];
            app.ExitButton.Text = 'Exit';

            % Create ControllerparametersPanel
            app.ControllerparametersPanel = uipanel(app.OptimPIDUIFigure);
            app.ControllerparametersPanel.Title = 'Controller parameters';
            app.ControllerparametersPanel.Position = [293 153 230 122];

            % Create InitialvaluesEditFieldLabel
            app.InitialvaluesEditFieldLabel = uilabel(app.ControllerparametersPanel);
            app.InitialvaluesEditFieldLabel.Position = [17 70 71 22];
            app.InitialvaluesEditFieldLabel.Text = 'Initial values';

            % Create InitialvaluesEditField
            app.InitialvaluesEditField = uieditfield(app.ControllerparametersPanel, 'text');
            app.InitialvaluesEditField.Position = [106 70 112 22];

            % Create LowerboundsEditFieldLabel
            app.LowerboundsEditFieldLabel = uilabel(app.ControllerparametersPanel);
            app.LowerboundsEditFieldLabel.Position = [17 42 84 22];
            app.LowerboundsEditFieldLabel.Text = 'Lower bounds ';

            % Create LowerboundsEditField
            app.LowerboundsEditField = uieditfield(app.ControllerparametersPanel, 'text');
            app.LowerboundsEditField.Position = [108 42 109 22];

            % Create UpperboundsEditFieldLabel
            app.UpperboundsEditFieldLabel = uilabel(app.ControllerparametersPanel);
            app.UpperboundsEditFieldLabel.HorizontalAlignment = 'right';
            app.UpperboundsEditFieldLabel.Position = [12 14 81 22];
            app.UpperboundsEditFieldLabel.Text = 'Upper bounds';

            % Create UpperboundsEditField
            app.UpperboundsEditField = uieditfield(app.ControllerparametersPanel, 'text');
            app.UpperboundsEditField.Position = [104 14 113 22];

            % Create MultistairssignalPanel
            app.MultistairssignalPanel = uipanel(app.OptimPIDUIFigure);
            app.MultistairssignalPanel.Title = 'Multi-stairs signal';
            app.MultistairssignalPanel.Position = [294 23 229 116];

            % Create TimevectorEditFieldLabel
            app.TimevectorEditFieldLabel = uilabel(app.MultistairssignalPanel);
            app.TimevectorEditFieldLabel.HorizontalAlignment = 'right';
            app.TimevectorEditFieldLabel.Position = [10 66 67 22];
            app.TimevectorEditFieldLabel.Text = 'Time vector';

            % Create TimevectorEditField
            app.TimevectorEditField = uieditfield(app.MultistairssignalPanel, 'text');
            app.TimevectorEditField.Position = [85 66 128 22];
            app.TimevectorEditField.Value = '[0,12,36,42,54,78]';

            % Create yvectorEditFieldLabel
            app.yvectorEditFieldLabel = uilabel(app.MultistairssignalPanel);
            app.yvectorEditFieldLabel.Position = [16 37 47 22];
            app.yvectorEditFieldLabel.Text = 'y vector';

            % Create yvectorEditField
            app.yvectorEditField = uieditfield(app.MultistairssignalPanel, 'text');
            app.yvectorEditField.Position = [71 37 144 22];
            app.yvectorEditField.Value = '[0.33,1,1.5,3,-1,0.33]';

            % Create HoldCheckBox
            app.HoldCheckBox = uicheckbox(app.MultistairssignalPanel);
            app.HoldCheckBox.Text = 'Hold';
            app.HoldCheckBox.Position = [172 8 47 22];

            % Create SimulationrangeEditFieldLabel
            app.SimulationrangeEditFieldLabel = uilabel(app.MultistairssignalPanel);
            app.SimulationrangeEditFieldLabel.HorizontalAlignment = 'right';
            app.SimulationrangeEditFieldLabel.Position = [9 8 95 22];
            app.SimulationrangeEditFieldLabel.Text = 'Simulation range';

            % Create SimulationrangeEditField
            app.SimulationrangeEditField = uieditfield(app.MultistairssignalPanel, 'numeric');
            app.SimulationrangeEditField.Position = [112 8 33 22];
            app.SimulationrangeEditField.Value = 100;

            % Create SimulinkmodelEditFieldLabel
            app.SimulinkmodelEditFieldLabel = uilabel(app.OptimPIDUIFigure);
            app.SimulinkmodelEditFieldLabel.Position = [24 511 156 25];
            app.SimulinkmodelEditFieldLabel.Text = 'Simulink model';

            % Create SimulinkmodelEditField
            app.SimulinkmodelEditField = uieditfield(app.OptimPIDUIFigure, 'text');
            app.SimulinkmodelEditField.ValueChangedFcn = createCallbackFcn(app, @SimulinkmodelEditFieldValueChanged, true);
            app.SimulinkmodelEditField.Position = [141 511 89 25];

            % Create OptimizationalgorithmsListBoxLabel
            app.OptimizationalgorithmsListBoxLabel = uilabel(app.OptimPIDUIFigure);
            app.OptimizationalgorithmsListBoxLabel.Position = [27 108 156 22];
            app.OptimizationalgorithmsListBoxLabel.Text = 'Optimization algorithms';

            % Create OptimizationalgorithmsListBox
            app.OptimizationalgorithmsListBox = uilistbox(app.OptimPIDUIFigure);
            app.OptimizationalgorithmsListBox.Items = {'Plain MATLAB', 'Optimization Toolbox', 'Genetic algorithm', 'Particle swarm', 'Simulated annealing', 'Pattern search'};
            app.OptimizationalgorithmsListBox.Position = [58 22 206 84];
            app.OptimizationalgorithmsListBox.Value = 'Optimization Toolbox';

            % Create OptimizationcriterionListBoxLabel
            app.OptimizationcriterionListBoxLabel = uilabel(app.OptimPIDUIFigure);
            app.OptimizationcriterionListBoxLabel.Position = [294 344 121 22];
            app.OptimizationcriterionListBoxLabel.Text = 'Optimization criterion ';

            % Create OptimizationcriterionListBox
            app.OptimizationcriterionListBox = uilistbox(app.OptimPIDUIFigure);
            app.OptimizationcriterionListBox.Items = {'ITAE criterion', 'ISE criterion', 'IAE criterion', 'ITSE criterion', 'IT^2SE criterion', 'IT^2AE criterion'};
            app.OptimizationcriterionListBox.ValueChangedFcn = createCallbackFcn(app, @OptimizationcriterionListBoxValueChanged, true);
            app.OptimizationcriterionListBox.Position = [296 288 231 53];
            app.OptimizationcriterionListBox.Value = 'ITAE criterion';

            % Create CriterionvalueEditFieldLabel
            app.CriterionvalueEditFieldLabel = uilabel(app.OptimPIDUIFigure);
            app.CriterionvalueEditFieldLabel.HorizontalAlignment = 'right';
            app.CriterionvalueEditFieldLabel.Position = [298 380 121 22];
            app.CriterionvalueEditFieldLabel.Text = 'Criterion value';

            % Create CriterionvalueEditField
            app.CriterionvalueEditField = uieditfield(app.OptimPIDUIFigure, 'numeric');
            app.CriterionvalueEditField.Position = [429 380 100 22];

            % Create TerminatetimeEditFieldLabel
            app.TerminatetimeEditFieldLabel = uilabel(app.OptimPIDUIFigure);
            app.TerminatetimeEditFieldLabel.Position = [27 482 84 22];
            app.TerminatetimeEditFieldLabel.Text = 'Terminate time';

            % Create TerminatetimeEditField
            app.TerminatetimeEditField = uieditfield(app.OptimPIDUIFigure, 'numeric');
            app.TerminatetimeEditField.Position = [126 482 118 22];
            app.TerminatetimeEditField.Value = 20;

            % Create MaximumallowedovershootCheckBox
            app.MaximumallowedovershootCheckBox = uicheckbox(app.OptimPIDUIFigure);
            app.MaximumallowedovershootCheckBox.ValueChangedFcn = createCallbackFcn(app, @MaximumValueChanged, true);
            app.MaximumallowedovershootCheckBox.Text = 'Maximum allowed overshoot?';
            app.MaximumallowedovershootCheckBox.Position = [24 132 181 22];

            % Create Label
            app.Label = uilabel(app.OptimPIDUIFigure);
            app.Label.HorizontalAlignment = 'right';
            app.Label.Visible = 'off';
            app.Label.Position = [239 132 25 22];
            app.Label.Text = '%';

            % Create EditField
            app.EditField = uieditfield(app.OptimPIDUIFigure, 'numeric');
            app.EditField.Visible = 'off';
            app.EditField.Position = [217 132 31 22];
            app.EditField.Value = 3;

            % Show the figure after all components are created
            app.OptimPIDUIFigure.Visible = 'on';
        end
    end

    % App creation and deletion
    methods (Access = public)

        % Construct app
        function app = OptimPID

            % Create UIFigure and components
            createComponents(app)

            % Register the app with App Designer
            registerApp(app, app.OptimPIDUIFigure)

            % Execute the startup function
            runStartupFcn(app, @startupFcn)

            if nargout == 0
                clear app
            end
        end

        % Code that executes before app deletion
        function delete(app)

            % Delete UIFigure when app is deleted
            delete(app.OptimPIDUIFigure)
        end
    end
end