% **************************************************************************
% CASCADE-FEEDFORWARD CONTROL SIMULATOR 
% COPYRIGHT (C), 1994 T.E. MARLIN
%
% FILENAME : CFFMSIM.M
% WRITTEN BY : F.BOUDREAU
% VERSION : 2.0
% LAST UPDATED : NOVEMBER 1994
% DESCRIPTION OF FILE :
%    MENU FOR SIMULATION OPTIONS, RUNNING SIMULATION AND PRESENTING
%    PLOTS.
% ALL FILES IN THIS PACKAGE :
%    CFF     .M  - MAIN MENU AND ENTRY POINT
%    CFFDAT  .M  - EXTERNAL DATA FILE
%    CFFGRAPH.M  - PLOTS SIMULATION RESULTS
%    CFFM1   .M  - MENU FOR PROCESS T.F. EDITING
%    CFFM2   .M  - MENU FOR PID TUNING
%    CFFM3   .M  - MENU FOR DISTURBANCE T.F. EDITING
%    CFFMFF  .M  - FEEDFORWARD CONTROLLER MENU
%    CFFMSIM .M  - SIMULATION OPTIONS MENU
%    CFFNAME .M  - MENU FOR VARIABLES NAMES, INITIAL VALUES, BOUNDS
%    CFFSIM  .M  - EXECUTES SIMULATION
% **************************************************************************

n = round((tend-tstart)/tstep)+1;    % NO OF 'REGULAR' POINTS
DD = round(D./tstep);                % DISCRETE PROCESS DELAYS
DDd = round(Dd./tstep);              % DISCRETE DISTURBANCE DELAYS
Dffd = round(Dff/tstep);             % DISCRETE FF CONTROLLER DELAY
nsup = max([sum(DD) Dffd DDd])+8;    % # OF EXTRA PTS BEFORE RUN
ntot = n+nsup;                       % TOTAL NO. OF PTS
if ntot>maxit
   tend = tstart+(maxit-nsup-1)*tstep;
end

while 1
   % CALCULATE DISCRETE DEAD TIMES IN ORDER TO ESTIMATE THE NO. OF
   % EXTRA POINTS REQUIRED AT THE BEGINNING OF THE SIMULATION
   % (THESE EXTRA POINTS AVOID REFERENCES TO NEGATIVE VECTOR
   % INDICES DURING THE SIMULATION).  THIS IS USED TO VALIDATE THE
   % Total Simulation Time AND Step Size SPECIFIED, TO MAKE SURE
   % THAT NO VECTORS HAVE LENGTH > maxit (THE LIMIT ON STUDENT VERSION
   % OF MATLAB IS 1024).
   n = round((tend-tstart)/tstep)+1;    % NO OF 'REGULAR' POINTS
   DD = round(D./tstep);                % DISCRETE PROCESS DELAYS
   DDd = round(Dd./tstep);              % DISCRETE DISTURBANCE DELAYS
   Dffd = round(Dff/tstep);             % DISCRETE FF CONTROLLER DELAY
   nsup = max([sum(DD) Dffd DDd])+8;    % # OF EXTRA PTS BEFORE RUN
   ntot = n+nsup;                       % TOTAL NO. OF PTS
   % NOTE: THE INITIAL VALUES OF SIMULATION TIME AND STEP SIZE ARE
   % SUPPLIED IN FILE CFFDAT.M ARE ASSUMED TO BE VALID.

   clc;
   fprintf('**********************************************************************\n')
   fprintf('*                                                                    *\n')
   fprintf('*                         SIMULATION OPTIONS                         *\n')
   fprintf('*                                                                    *\n')
   fprintf('**********************************************************************\n\n')
   fprintf('WHAT PARAMETER WOULD YOU LIKE TO UPDATE ?\n')
   fprintf('                                            Present Values\n')
   fprintf('1) Total Simulation Time                      %-g\n',tend-tstart)
   fprintf('2) Step Size                                  %-g\n',tstep)
   if CASCADE == 0
   fprintf('3) Control Structure                          SINGLE-LOOP\n');
   else
   fprintf('3) Control Structure                          CASCADE\n');
   end
   fprintf('4) Run Simulation WITH Disturbances\n')
   fprintf('5) Run Simulation WITHOUT Disturbances\n')
   fprintf('6) View Plots\n')
   fprintf('7) Quit to Main Menu\n')

   m1 = input('PLEASE ENTER A SELECTION : ');
   if isempty(m1)==1           % RETURN TO MAIN MENU IF <CR> ONLY IS PRESSED
      break
   end
   m1 = round(m1);
   if (m1<1 | m1>7)           % VALIDATES SELECTION
      disp('')
      disp('NOT A VALID SELECTION')
      disp('')
      disp('PRESS ENTER TO CONTINUE')
      pause;
   end

   if m1 == 1
      temp = (maxit-nsup-1)*tstep;
      fprintf('\n If simulation time exceeds %g, time steps will be made larger',temp)
      inp = input('New value for simulation time : ');
      if isempty(inp) ~= 1
	 tend = tstart+inp;
	 if (tend-tstart)/tstep > (maxit-nsup-1)
	    tstep = (tend-tstart)/(maxit-nsup-1);
	 end
     end
   elseif m1 == 2
%      temp = (tend-tstart)/(maxit-nsup-1);
      temp = (tend-tstart+(nsup-8)*tstep)/(maxit-1-8);
      fprintf('\n Time step must >= %g unless simulation time is decreased',temp)
      inp = input('New value for time step size : ');
      if isempty(inp) ~= 1
	 if (inp) <= 0.0
	    disp(' time step must be positive, please reenter')
	    pause (2)
	 else
	    if inp < temp
	       disp('entry too small, set to largest acceptable')
	       pause (2)
	       tstep = temp;
	    else
%               tstep = min(tend-tstart,max(temp,abs(inp)));
	       tstep = max(temp,abs(inp));
	    end
	 end
      end

   elseif m1 == 3
      if CASCADE == 1
	 CASCADE = 0;
	 disp('')
	 disp('In single-loop control, the PID settings are those of the primary');
	 disp('controller; the secondary controller settings are ignored.');
	 disp('');
	 if PRC == 2
	    disp('NOTE: The current Feedback Controllers Mode is PRC2; if this simulation');
	    disp('is run in SINGLE-LOOP mode, the feedback loop will be closed and no');
	    disp('process reaction curve will be generated.');
	 end
	 disp('PRESS ENTER TO CONTINUE');
	 pause;
      else
	 CASCADE = 1;
      end
   elseif m1 == 4
      DISTURBANCE = 1;
      close all
      cffsim;
   elseif m1 == 5
      DISTURBANCE = 0;
      close all
      cffsim;
   elseif m1 == 6
      if EXECUTION == 1
	 cffgraph;
      else
	 disp('')
	 disp('You must run a simulation before you can view the plots.')
	 disp('Press Enter to continue.')
	 pause;     
      end
   elseif m1 == 7
      break
   end % if
end % while
