%% IMC control with constant "Q" parameter (keeping open-loop poles unmodified in closed loop)
% © 2023, Antonio Sala Piqueras. Universitat Politècnica de València. All rights reserved.
% Objective: designing an IMC controller that does not change the dynamics with respect to the open-loop one because it's considered satisfactory... it's very easy: just set Q to the inverse of the DC gain.
% Video-presentation: http://personales.upv.es/asala/YT/V/imcQcteEN.html
%% Process to be controlled

s=tf('s');
G=3/(0.2*s+1)^2; %  75/(s+5)^2
step(G,4), grid on
dcgain(G)

%% Desired closed-loop behaviour and IMC controller
% Settling time is assumed to be reasonable, we do not want to change the position of the poles or the setpoint response, we just with to make the gain 1 with respect to reference.
% That is trivial in open loop: u=\frac{1}{3}r.
% In closed loop, IMC it would be basically the same (that's the "trick" of IMC, it is designed as it we were in an open loop):

Q=1/3; %explicit IMC

% Equivalently, the resulting controller (implicit IMC) is:

K=Q/(1-G*Q);
zpk(K)

% As predicted by theory, the IMC results in a regulator with integral action. It will reject constant disturbances with no steady-state error.
%% Analysis of the resulting closed loop
% The closed loop will be:

T1=zpk(feedback(G*K,1)) %setpoint to output;
T=minreal(T1,3e-4) %after cancelling with some tolerance
norm(T-G*Q) %T is GQ, apart from numeric round-off issues.
step(T,G/dcgain(G),4), grid on %CL versus OL , setpoint
KS=K*S;zpk(KS)
minreal(zpk(KS),3e-4) %control is just setpoint/3, as in open loop.

% Recall that, from theory, KS is Q.
% Disturbance response:
%
%
%

S=feedback(1,G*K); %dy to y
GS=G*S; %du to y [feedback(G,K) would also work]
step(S,tf(1),4), grid on %OL versus CL in dy
title("Output Disturbance step response"), legend("IMC","Open Loop")
step(GS,G,4), grid on %bc versus ba en du
title("INPUT Disturbance step response"), legend("IMC","Open Loop")