function varargout = MPCprogram(varargin)

if nargin == 0  % LAUNCH GUI

	fig = openfig(mfilename,'reuse');

	% Generate a structure of handles to pass to callbacks, and store it. 
	handles = guihandles(fig);
	guidata(fig, handles);
    
    if nargout > 0
		varargout{1} = fig;
	end

elseif ischar(varargin{1}) % INVOKE NAMED SUBFUNCTION OR CALLBACK

	try
		if (nargout)
			[varargout{1:nargout}] = feval(varargin{:}); % FEVAL switchyard
		else
			feval(varargin{:}); % FEVAL switchyard
		end
	catch
		disp(lasterr);
	end

end

function model_open(handles)
% Make sure the diagram is still open
if  isempty(find_system('Name','MPCcontrol')),
	open_system('MPCcontrol'); open_system('MPCcontrol/PressureScope');open_system('MPCcontrol/LevelScope');
	%openfig('MPCprogram.fig','reuse')
	
end

% --------------------------------------------------------------------
function varargout = manuallevelslider_Callback(h, eventdata, handles, varargin)
model_open(handles)

% Get the new value for the levelinput from the slider
NewVal1 = get(h,'Value');

% Set the value of the levelinputCurrentValue to the new value set by slider
set(handles.manuallevelvalue,'String',NewVal1)

% Set the value parameter of the manuallevel_input to the new value
set_param('MPCcontrol/manuallevel_input','value',num2str(NewVal1))

% --------------------------------------------------------------------
function varargout = manuallevelvalue_Callback(h, eventdata, handles, varargin)
model_open(handles)

% Get the new value for the manuallevelvalue
NewStrVal1 = get(h,'String');
NewVal1 = str2double(NewStrVal1);

% Check that the entered value falls within the allowable range
if  isempty(NewVal1) | (NewVal1< 0) | (NewVal1>10),
	% Revert to last value, as indicated by manuallevelslider
	OldVal1 = get(handles.manuallevelslider,'Value');
	set(h,'String',OldVal1)
	
else
	% Set the value of the manuallevelslider to the new value
	set(handles.manuallevelslider,'Value',NewVal1)
	
	% Set the value parameter of the manuallevel_input to the new value
	set_param('MPCcontrol/manuallevel_input','Value',NewStrVal1)
end

% --------------------------------------------------------------------
function varargout = manualpressureslider_Callback(h, eventdata, handles, varargin)

model_open(handles)

NewVal = get(h,'Value');

set(handles.manualpressurevalue,'String',NewVal)
set_param('MPCcontrol/manualpressure_input','Value',num2str(NewVal))

% --------------------------------------------------------------------
function varargout = manualpressurevalue_Callback(h, eventdata, handles, varargin)

model_open(handles)

NewStrVal = get(h,'String');
NewVal = str2double(NewStrVal);

if  isempty(NewVal) | (NewVal< 0) | (NewVal>10),
	OldVal = get(handles.manualpressureslider,'Value');
	set(h,'String',OldVal)
	
else
	set(handles.manualpressureslider,'Value',NewVal)
	set_param('MPCcontrol/manualpressure_input','Value',NewStrVal)
end

% --------------------------------------------------------------------
function varargout = levelsetpointslider_Callback(h, eventdata, handles, varargin)

model_open(handles)

NewVal = get(h,'Value');
oldpressurevalue=get(handles.pressuresetpointslider,'Value');

set(handles.levelsetpointvalue,'String',NewVal)
set_param('MPCcontrol/nlmpcsim','r',mat2str([oldpressurevalue NewVal]));
set_param('MPCcontrol/Levelsetpoint','Value',num2str(NewVal))

% --------------------------------------------------------------------
function varargout = levelsetpointvalue_Callback(h, eventdata, handles, varargin)

model_open(handles)

NewStrVal = get(h,'String');
NewVal = str2double(NewStrVal);
oldpressurevalue=get(handles.pressuresetpointslider,'Value');

if  isempty(NewVal) | (NewVal< 0) | (NewVal>50),
	OldVal = get(handles.levelsetpointslider,'Value');
	set(h,'String',OldVal)
	
else
	set(handles.levelsetpointslider,'Value',NewVal)
    set_param('MPCcontrol/nlmpcsim','r',mat2str([oldpressurevalue NewVal]));
	set_param('MPCcontrol/Levelsetpoint','Value',NewStrVal)
    
end

% --------------------------------------------------------------------
function varargout = pressuresetpointslider_Callback(h, eventdata, handles, varargin)

model_open(handles)

NewVal = get(h,'Value');
oldlevelvalue = get(handles.levelsetpointslider,'Value');

set(handles.pressuresetpointvalue,'String',NewVal)

set_param('MPCcontrol/nlmpcsim','r',mat2str([NewVal oldlevelvalue]))
set_param('MPCcontrol/Pressuresetpoint','Value',num2str(NewVal))

% --------------------------------------------------------------------
function varargout = pressuresetpointvalue_Callback(h, eventdata, handles, varargin)

model_open(handles)

NewStrVal = get(h,'String');
NewVal = str2double(NewStrVal);
oldlevelvalue = get(handles.levelsetpointslider,'Value');

if  isempty(NewVal) | (NewVal< 0) | (NewVal>3.5),
	
	OldVal = get(handles.pressuresetpointslider,'Value');
	set(h,'String',OldVal)
	
else
	set(handles.pressuresetpointslider,'Value',NewVal)
    set_param('MPCcontrol/nlmpcsim','r',mat2str([NewVal oldlevelvalue]));
    set_param('MPCcontrol/Pressuresetpoint','Value',NewStrVal)
    
end

% --------------------------------------------------------------------
function varargout = manualbutton_Callback(h, eventdata, handles, varargin)
model_open(handles)

off = [handles.MPCbutton];
mutual_exclude(off)

set_param('MPCcontrol/manualswitch','Value',num2str(2))

% --------------------------------------------------------------------
function varargout = MPCbutton_Callback(h, eventdata, handles, varargin)
model_open(handles)

off = [handles.manualbutton];
mutual_exclude(off)

set_param('MPCcontrol/manualswitch','Value',num2str(1))

% --------------------------------------------------------------------
function varargout = levelKvalue_Callback(h, eventdata, handles, varargin)
%None of these functions do anything. They are only called upon when the start
%or initialize button is pressed. This is because it was not possible to change
%these values while the simulation was running.
% --------------------------------------------------------------------
function varargout = levelTauvalue_Callback(h, eventdata, handles, varargin)
% --------------------------------------------------------------------
function varargout = levelDelayvalue_Callback(h, eventdata, handles, varargin)
% --------------------------------------------------------------------
function varargout = pressureKvalue_Callback(h, eventdata, handles, varargin)
% --------------------------------------------------------------------
function varargout = pressureTauvalue_Callback(h, eventdata, handles, varargin)
% --------------------------------------------------------------------
function varargout = pressureDelayvalue_Callback(h, eventdata, handles, varargin)
% --------------------------------------------------------------------
function varargout = pressuremeasureweight_Callback(h, eventdata, handles, varargin)
% --------------------------------------------------------------------
function varargout = pressureinputweight_Callback(h, eventdata, handles, varargin)
% --------------------------------------------------------------------
function varargout = levelmeasureweight_Callback(h, eventdata, handles, varargin)
% --------------------------------------------------------------------
function varargout = levelinputweight_Callback(h, eventdata, handles, varargin)
% --------------------------------------------------------------------
function varargout = predictionhorizon_Callback(h, eventdata, handles, varargin)
% --------------------------------------------------------------------
function varargout = controlhorizon_Callback(h, eventdata, handles, varargin)
% --------------------------------------------------------------------
function varargout = Startbutton_Callback(h, eventdata, handles, varargin)
model_open(handles)

%Here the values from the transferfunction is called, and the parameters for the
%MPC controller is calculated
numlev=str2num(get(handles.levelKvalue,'String'));
denlev=str2num(get(handles.levelTauvalue,'String'));
delaylev=str2num(get(handles.levelDelayvalue,'String'));

numpre=str2num(get(handles.pressureKvalue,'String'));
denpre=str2num(get(handles.pressureTauvalue,'String'));
delaypre=str2num(get(handles.pressureDelayvalue,'String'));

numlevpre=str2num(get(handles.levpreKvalue,'String'));
denlevpre=str2num(get(handles.levpreTauvalue,'String'));
delaylevpre=str2num(get(handles.levpreDelayvalue,'String'));

numprelev=str2num(get(handles.prelevKvalue,'String'));
denprelev=str2num(get(handles.prelevTauvalue,'String'));
delayprelev=str2num(get(handles.prelevDelayvalue,'String'));

g22=poly2tfd(numlev,[denlev 0],0,delaylev);
g12=poly2tfd(numlevpre,[denlevpre 1],0,delaylevpre);
g21=poly2tfd(numprelev,[denprelev 0],0,delayprelev);
g11=poly2tfd(numpre,[denpre 1],0,delaypre);

%Because the level output is integrating
nout=[1 0]';
%The length of the step-respons
tfinal=100;
%The sample time is set in the Simulink diagram
delt=get_param('MPCcontrol/Control Lab DA','Dt');
delt=str2num(delt);
model=tfd2step(tfinal,delt,nout,g11,g21,g12,g22);

dmodel=[];

set_param('MPCcontrol/nlmpcsim','modelpd',mat2str([model dmodel]));

%checks the setpointvalues
levelset = get_param('MPCcontrol/Levelsetpoint','Value');
pressureset =get_param('MPCcontrol/Pressuresetpoint','Value');
pressureset=str2num(pressureset);
levelset=str2num(levelset);
r=[pressureset levelset];
set_param('MPCcontrol/nlmpcsim','r',mat2str(r));

%The weights of the object function
lywt=str2num(get(handles.levelmeasureweight,'String'));
pywt=str2num(get(handles.pressuremeasureweight,'String'));
ywt=[pywt lywt];
luwt=str2num(get(handles.levelinputweight,'String'));
puwt=str2num(get(handles.pressureinputweight,'String'));
uwt=[puwt luwt];

m=get(handles.controlhorizon,'String');
p=get(handles.predictionhorizon,'String');
m=str2num(m);
p=str2num(p);
Kmpc=mpccon(model,ywt,uwt,m,p);

set_param('MPCcontrol/nlmpcsim','Kmpc',mat2str(Kmpc));

%starter simuleringen
set_param('MPCcontrol/Constant2','Value',num2str(0));

sim('MPCcontrol');
% --------------------------------------------------------------------
function varargout = stopbutton_Callback(h, eventdata, handles, varargin)

set_param('MPCcontrol/Constant2','Value',num2str(1));

% --------------------------------------------------------------------
function varargout = quitbutton_Callback(h, eventdata, handles, varargin)

model_open(handles);

pos_size = get(handles.figure1,'Position');
user_response = modaldlg([pos_size(1)+pos_size(3)/5 pos_size(2)+pos_size(4)/5]);
switch user_response
case {'no','cancel'}
	% take no action
case 'yes'
	% Prepare to close GUI application window
	%                  .
	%sets the controllers to manual and the valves to open
    
    set_param('MPCcontrol/manualswitch','Value',num2str(2))
    set_param('MPCcontrol/manualpressure_input','Value',num2str(10))
    set_param('MPCcontrol/manuallevel_input','Value',num2str(10))
    pause(0.05);
%stops the simulation
set_param('MPCcontrol/Constant2','Value',num2str(1));    

    pause(0.05);
    save_system('MPCcontrol')
    pause(0.05);
    
    
    delete(handles.figure1)
    close_system('MPCcontrol')
end

% --------------------------------------------------------------------
function varargout = figure1_ResizeFcn(h, eventdata, handles, varargin)
%---------------------------------------------------------------------
function mutual_exclude(off)
set(off,'Value',0)

% --------------------------------------------------------------------
function varargout = levpreKvalue_Callback(h, eventdata, handles, varargin)
% --------------------------------------------------------------------
function varargout = levpreTauvalue_Callback(h, eventdata, handles, varargin)
% --------------------------------------------------------------------
function varargout = levpreDelayvalue_Callback(h, eventdata, handles, varargin)
% --------------------------------------------------------------------
function varargout = prelevTauvalue_Callback(h, eventdata, handles, varargin)
% --------------------------------------------------------------------
function varargout = prelevKvalue_Callback(h, eventdata, handles, varargin)
% --------------------------------------------------------------------
function varargout = prelevDelayvalue_Callback(h, eventdata, handles, varargin)
% --------------------------------------------------------------------
function varargout = Initialise_Callback(h, eventdata, handles, varargin)
model_open(handles);

%Here is a temporary model loaded. This has to be done here, and not in the simulink
%diagram.
set(handles.levelKvalue,'String',num2str(-0.76));
set(handles.levelTauvalue,'String',num2str(10));
set(handles.levelDelayvalue,'String',num2str(2));

set(handles.pressureKvalue,'String',num2str(-0.3));
set(handles.pressureTauvalue,'String',num2str(12));
set(handles.pressureDelayvalue,'String',num2str(1));

set(handles.levpreKvalue,'String',num2str(-0.09));
set(handles.levpreTauvalue,'String',num2str(13));
set(handles.levpreDelayvalue,'String',num2str(1));

set(handles.prelevKvalue,'String',num2str(0.91));
set(handles.prelevTauvalue,'String',num2str(10));
set(handles.prelevDelayvalue,'String',num2str(2));

set(handles.levelmeasureweight,'String',num2str(1));
set(handles.levelinputweight,'String',num2str(1));
set(handles.pressuremeasureweight,'String',num2str(1));
set(handles.pressureinputweight,'String',num2str(1));

set(handles.predictionhorizon,'String',num2str(50));
set(handles.controlhorizon,'String',num2str(10));

%puts the controller in manual at start
off = [handles.MPCbutton];
mutual_exclude(off)
set(handles.manualbutton,'value',1);
model_open(handles)
set_param('MPCcontrol/manualswitch','Value',num2str(2));

numlev=str2num(get(handles.levelKvalue,'String'));
denlev=str2num(get(handles.levelTauvalue,'String'));
delaylev=str2num(get(handles.levelDelayvalue,'String'));

numpre=str2num(get(handles.pressureKvalue,'String'));
denpre=str2num(get(handles.pressureTauvalue,'String'));
delaypre=str2num(get(handles.pressureDelayvalue,'String'));

numlevpre=str2num(get(handles.levpreKvalue,'String'));
denlevpre=str2num(get(handles.levpreTauvalue,'String'));
delaylevpre=str2num(get(handles.levpreDelayvalue,'String'));

numprelev=str2num(get(handles.prelevKvalue,'String'));
denprelev=str2num(get(handles.prelevTauvalue,'String'));
delayprelev=str2num(get(handles.prelevDelayvalue,'String'));

g22=poly2tfd(numlev,[denlev 0],0,delaylev);
g12=poly2tfd(numlevpre,[denlevpre 1],0,delaylevpre);
g21=poly2tfd(numprelev,[denprelev 0],0,delayprelev);
g11=poly2tfd(numpre,[denpre 1],0,delaypre);

nout=[1 0]';
tfinal=100;
set_param('MPCcontrol/Control Lab DA','Dt',num2str(0.3));
set_param('MPCcontrol/Control Lab AD','Dt',num2str(0.3));
delt=get_param('MPCcontrol/Control Lab DA','Dt');
delt=str2num(delt);
model=tfd2step(tfinal,delt,nout,g11,g21,g12,g22);

dmodel=[];

set_param('MPCcontrol/nlmpcsim','modelpd',mat2str([model dmodel]));

lywt=str2num(get(handles.levelmeasureweight,'String'));
pywt=str2num(get(handles.pressuremeasureweight,'String'));
ywt=[pywt lywt];
luwt=str2num(get(handles.levelinputweight,'String'));
puwt=str2num(get(handles.pressureinputweight,'String'));
uwt=[puwt luwt];
m=get(handles.controlhorizon,'String');
p=get(handles.predictionhorizon,'String');
m=str2num(m);
p=str2num(p);
Kmpc=mpccon(model,ywt,uwt,m,p);

set_param('MPCcontrol/nlmpcsim','Kmpc',mat2str(Kmpc));

%puts constraints on the inputs 
usat=[0 0 10 10 10 10];
set_param('MPCcontrol/nlmpcsim','usat',mat2str(usat));

tfilter=[0 0];
set_param('MPCcontrol/nlmpcsim','tfilter',mat2str(tfilter));

%gives the value of ud0
u0=[6.5 5];
d0=[];
ud0=[u0 d0];
set_param('MPCcontrol/nlmpcsim','ud0',mat2str(ud0));

%gives setpoints at startup
set(handles.levelsetpointvalue,'String',num2str(30));
set(handles.levelsetpointslider,'Value',30);
set(handles.pressuresetpointvalue,'String',num2str(1.7));
set(handles.pressuresetpointslider,'Value',1.7);
set_param('MPCcontrol/Pressuresetpoint','value',num2str(1.7));
set_param('MPCcontrol/Levelsetpoint','value',num2str(30));
r=[1.7 30];
set_param('MPCcontrol/nlmpcsim','r',mat2str(r));

%opens the valves at startup
set(handles.manuallevelvalue,'string',num2str(10));
set(handles.manuallevelslider,'value',10);

set(handles.manualpressurevalue,'string',num2str(10));
set(handles.manualpressureslider,'value',10);

set_param('MPCcontrol/To File','Filename','MPCvar');

off = [handles.startlog];
mutual_exclude(off)

set_param('MPCcontrol/Constant1','Value',num2str(1));
set(handles.stoplog,'value',1);


% --------------------------------------------------------------------
function varargout = startlog_Callback(h, eventdata, handles, varargin)
model_open(handles)

off = [handles.stoplog];
mutual_exclude(off)

set_param('MPCcontrol/Constant1','Value',num2str(2));

% --------------------------------------------------------------------
function varargout = stoplog_Callback(h, eventdata, handles, varargin)
model_open(handles)
off = [handles.startlog];
mutual_exclude(off)

set_param('MPCcontrol/Constant1','Value',num2str(1));
