How to access the derivative of my Simulink states through the command model(t,x,u,'derivs')

5 views (last 30 days)
YI YANG on 4 Mar 2017
Commented: Yannic Beyer on 12 Jul 2022
I was trying to code up a center difference linearization function for a Simulink system, my code are as follows:
if true
%
function [A,B,C,D] = lin_cen_diff(x0,u0)
% obtain some basic system information
[sys,~,~,~] = Turbocharged_engine_ioblock_r2016a([],[],[],'compile');
num_states = sys(1);
num_outputs = sys(3);
num_inputs = sys(4);
% allocate memory for state matrics;
A = zeros(num_states, num_states);
B = zeros(num_states, num_inputs);
C = zeros(num_outputs,num_states);
D = zeros(num_outputs,num_inputs);
% set the perturbation to be 1
epsilon = 0.1;
% compute the A matrix
for i = 1:num_states
vec = zeros(num_states,1);
vec(i) = 1;
x_pos = x0' + epsilon * vec;
x_neg = x0' - epsilon * vec;
derivs_pos = Turbocharged_engine_ioblock_r2016a(0,x_pos,u0,'derivs');
derivs_neg = Turbocharged_engine_ioblock_r2016a(0,x_neg,u0,'derivs');
A(:,i) = (derivs_pos - derivs_neg)/(2*epsilon);
end
% compute the B matrix
for j = 1:num_inputs
vec = zeros(num_inputs,1);
vec(j) = 1;
u_pos = u0' + epsilon * vec;
u_neg = u0' - epsilon * vec;
derivs_pos = Turbocharged_engine_ioblock_r2016a(0,x0,u_pos,'derivs');
derivs_neg = Turbocharged_engine_ioblock_r2016a(0,x0,u_neg,'derivs');
B(:,j) = (derivs_pos - derivs_neg)/(2*epsilon);
end
% compute the C matrix
for k = 1:num_states
C(k,k) = 1;
end
Turbocharged_engine_ioblock_r2016a([],[],[],'term');
end
end
However, no matter how I change the value of "t,x,u" the command
if true
% Turbocharged_engine_ioblock_r2016a(0,x_pos,u0,'derivs');
end
always give me exact same answer, could any of you give me some suggestion on how to modify the code? or where is the bug?

Sam McDonald on 7 Mar 2017
You will need to compute the outputs of the model prior to computing the derivatives. The is likely the cause of you seeing the same result regardless of input.
outputs = testModel(t, x, u, 'outputs');
derivs = testModel(t, x, u, 'derivs');
Documentation page for the "model" function: https://www.mathworks.com/help/simulink/slref/model_cmd.html
The "outputs" phase is called before the "derivs" phase of the "model" function even though the output is not being returned from the function. This is necessary as all of the state derivatives are essentially signals somewhere in the model and thus, for a particular time-step, it is required to execute the "outputs" phase to calculate the value of these signals, prior to executing the "derivs" phase, which identifies the state derivatives.
Note that simulating a model with the "model" function will not produce results that are exactly the same as the ones produced by Simulink as the solvers for MATLAB and Simulink are separate implementations of the same algorithm. Simulink in addition uses error control and correction, as well as zero-crossing detection which is unavailable with the MATLAB Solvers. This function is intended to be used for linear analysis etc. only. If it is required to include these techniques then the "sim" function needs to be used. More information on this function is available at the following location:
Sam McDonald on 8 Mar 2017
Edited: Sam McDonald on 8 Mar 2017
What does your current code look like?
What are you getting as output for derivs_pos and derivs_neg when computing your B matrix? Make sure you are computing the output prior to computing the derivatives of the states.
As far as the documentation states, using the 'derivs' argument will return the derivatives of the continuous states of the model at time t.
Yannic Beyer on 12 Jul 2022
I also had the problem that the B matrix was always zero. In my case it was because I had activated an external input. I had to switch this off:
The debugging of the function linmod2 helped me to find the problem.