Script to represent constant offset in scaling of data

Hello,
I have the attached simulink model which appears to be working as I need it to. The idea is to scale my SP input from engineering units to 0-100%, which is how the controller operates. That way, my P/I/D settings are directly identical to those entered into the controller, and I can align the matlab data with the controller data.
How would I enter this into a simple matlab script?
K = 100/(MaxEU-MinEU)
C = 100*MinEU/(MaxEU-MinEU)
It correctly multiplies the SP input value by the gain K, then after the gain block adds an offset which is completely independent of the SP input. I am struggling to deal with this 'extra constant input' in a matlab script.
My goal is to have a SISO transfer function between the step input and the output of the first summing junction, that I can easily integrate into the rest of the model with series/parallel connections.
What does not work (as far as I can tell) is EUSP = tf(100/(MaxEU-MinEU) - 100*MinEU/(MaxEU-MinEU))
since it applies a static gain to the step input, including the offset term. With or without the tf.
Perhaps I need to use sumblk and directly assign inputs/outputs? Still a little confused how to set that constant input for the offset term.

8 Comments

hello
I am not sure to understand what is your problem
Are MinEU, MaxEU constants ? or do they evolve with time ?
MinEU and MaxEU are model parameters, and are scalars. They do not change with time, but represent the engineering units for the PV and SP locations of the controller-plant model. The Simulink snippet scales the input variables to a 0-100% reference based on the engineering units. Effectively, I have a y=mx+b transfer function.
My trouble is "how to represent the summing block with a fixed scalar as one of the inputs"
seems to me you give the answer yourself :
in your matlab (initialization script) you define
K = 100/(MaxEU-MinEU)
C = 100*MinEU/(MaxEU-MinEU)
and you use K and C as parameters names in the corresponding simulink blocks, exactly as in your picture, and you should be good
Might have some loss in translation-
I know the Simulink model works. I am interested in how to implement into a simple matlab script (without using Simulink, just standard Matlab). I know how to type in the constant block, but not how to force the input of 'C'.
Neither of these methods for EU or EUSP work correctly:
% EU SCALING
EUtemp = tf(100/(MaxEU-MinEU));
offset = 100*MinEU/(MinEU-MaxEU);
EU = EUtemp + offset;
EUSP = tf(100/(MaxEU-MinEU) - 100*MinEU/(MaxEU-MinEU));
This is getting me pretty close:
MaxEU = 700;
MinEU = -300;
% EU SCALING
gain = tf(100/(MaxEU-MinEU));
offset = tf(100*MinEU/(MaxEU-MinEU));
gain.InputName = 'SP';
gain.OutputName = 'gout';
offset.InputName = 'const';
offset.OutputName = 'oout';
% SUMMING JUNCTIONS
S1 = sumblk("SPpct = gout - oout");
% INTERCONNECTIONS TO CREATE EU OPEN LOOP
EU_OL = connect(gain, offset, S1, {'SP', 'const'}, 'SPpct');
% OPEN LOOP OF PLANT
duration = 3;
StepMag = 500; % THIS SHOULD SCALE OUT TO 80%
figure('f', '1', 'Name', 'Step Response of Closed Loop')
respOpt = RespConfig('InputOffset',[0 1],'Amplitude',[StepMag 0], 'Delay',0.1);
step(EU_OL, duration, respOpt);
It is providing two graphs, and I am interested in the first one which correctly scales the output to 80%. Make sense?
hello again
I could not guess that you wanted to move from simulink to plain matlab
yes your code seems to work fine , but why not make it even simpler ? why create tf objects for simple operators like gains and offset ?
alternative code :
MaxEU = 700;
MinEU = -300;
% EU SCALING
gain = (100/(MaxEU-MinEU));
offset = (100*MinEU/(MaxEU-MinEU));
% OPEN LOOP OF PLANT
duration = 3;
StepMag = 500; % THIS SHOULD SCALE OUT TO 80%
Fs = 100;
dt = 1/Fs;
t = (0:dt:duration)';
t_step = 0.1;
SP = StepMag*(t>=t_step); % input step
SP_normalized = SP*gain - offset; % output (normalized) step
figure('f', '1', 'Name', 'Step Response of Closed Loop')
plot(t,SP_normalized);
Mathieu,
Yes, the request for a simple matlab script was in bold face in the very first post.
I understand I do not need to use tf for gain and offset, but at the same time, it is effectively a gain block. And this is simply a small portion of the larger control system I am implementing. The goal is to integrate this gain/offset strategy into a LTI system so I can utilize matlab's standard control box functionality, such as margin, gain, step, impulse, pzmap, rlocus, etc. If it does not process the EU portion correctly, the gains will be off.
I am not certain if your solution will allow me to take that script and drop it into the larger control system. For example, you did not actually use the step() function - you provided output in a plot that looked like a step with discrete steps.
The hangup is someone may say "y=mx+b is not a LTI system", but somehow Simulink is managing to deal with it.
Larger system below, I need to incorporate this EU change into the SP and PV.
Kp = 1.8;
w = 2.683;
z = 1.234;
theta = 0; % USED FOR EXPONENTIAL TERM
% PID PARAMETERS
Kc = 1.3;
Ti = 1.1;
Td = 0.1;
capture = tf(Kp*w^2, [1 2*w*z w^2]);
model = pole(capture);
Te = -1/model(1);
Td0 = -1/model(2);
% PROCESS GAINS
MinEU = -1211;
MaxEU = 3400;
PWMgain = 0.3;
ExcGain = 8.12;
AltGain = Kp*(MaxEU-MinEU)/100/ExcGain/PWMgain;
PWM = tf(PWMgain); % PWM GAIN
PWM.InputName = 'COpct';
PWM.OutputName = 'EXC';
Exciter = tf([ExcGain], [Te 1]); % EXCITER GAIN AND DELAY
Exciter.InputName = 'EXC';
Exciter.OutputName = 'FLD';
Alternator = tf([AltGain], [Td0 1]); % ALTERNATOR GAIN AND DELAY
Alternator.InputName = 'FLD';
Alternator.OutputName = 'PV';
% EU SCALING
EU = tf(100/(MaxEU-MinEU));
offset = 100*MinEU/(MinEU-MaxEU);
EUPV = EU + offset;
EUPV.InputName = 'PV';
EUPV.OutputName = 'PVpct';
EUSP = tf(100/(MaxEU-MinEU) - 100*MinEU/(MaxEU-MinEU));
EUSP.InputName = 'SP';
EUSP.OutputName = 'SPpct';
% DERIVATIVE ON PROCESS VALUE
DoPV = pid(0, 0, Kc*Td);
DoPV.InputName = 'PVpct';
DoPV.OutputName = 'Deriv';
% PI CONTROLLER
RTAC = pidstd(Kc, Ti, 0);
RTAC.InputName = 'error';
RTAC.OutputName = 'RTACout';
% SUMMING JUNCTIONS
S1 = sumblk("error = SPpct - PVpct");
S2 = sumblk("COpct = RTACout - Deriv");
% INTERCONNECTIONS TO CREATE DoPV LOOP AND FINAL PID FEEDBACK
CL = connect(EUSP, RTAC, PWM, Exciter, Alternator, EUPV, DoPV, S1, S2, "SP", "PV");
% ------------------------------------------------------
duration = 3;
StepMag = 500;
figure('f', '2', 'Name', 'Step Response of Closed Loop')
respOpt = RespConfig('InputOffset', 0, 'Amplitude', StepMag, 'Delay', 0.1);
step(CL, duration, respOpt);
figure('f', '3', 'Name','Margin of Closed Loop System');
margin(CL)
damp(CL)
figure('f', '4', 'Name','Pole Zero Map of Closed Loop System');
pzmap(CL)
grid %, axis([-5 0 -4 4])
figure('f', '5', 'Name','Root Locus of Closed Loop System');
rlocus(CL)
yes you're right , I read a bit too fast your first post - now it's obvious
I supposed indeed that this was just a small portion from a larger project , so I understand the general use of tf objects as you now describe more what the intention is.
seems to me you're on the right track to achieve your goals , I have no further comment so far
when I started matlab 30+ years ago, there where not so many advanced tools and functions to study open and closed loop systems.
so good luck for the future !

Sign in to comment.

Answers (0)

Products

Release

R2024a

Asked:

on 12 May 2024

Commented:

on 14 May 2024

Community Treasure Hunt

Find the treasures in MATLAB Central and discover how the community can help you!

Start Hunting!