Difference between matlab ss function and Simulink State-Space block

I want to do induction motor state space model simulation, so I built it with ss function and set the zero initial conditions, but after I fed it with input by lsim function, the output diverged. When I built it with simulink state-space block, fed the same input, and set the same initial conditions, it converged and got pretty good result, which made me think what's the difference between these two state space modeling methods. What aspects should I pay attention if I want to make ss in matlab converge?
Update: I attached code in matlab and SImulink block for better understanding
Simulink Block and Solver setting:
The simulink block configurations are the same in matlab
Simulink solver setting:
MATLAB code:
%% Basic Setting
f = 10000; % Sampling Frequency
Ts = 1/f;
%% Data Preparation(Not Important
out1 = out;
ab0_voltage1 = out1.voltage_ab0;
ab0_current1 = out1.current_ab0;
rotation_f1 = out1.speed;
start_time = 0;
sampling_time = 5;
start_point = start_time*f+1;
sampling_points = sampling_time*f-1;
t_ind = start_point:start_point+sampling_points;
u = ab0_voltage1(t_ind,2:3); %Input
i = ab0_current1(t_ind,2:3);
flux_init = out.flux_ab(start_point,2:3);
w = mean(out.w_e(end,2));
%% Parameterization of State Space A B C D
x = [6.14,0.037874419,0.387125581,4.987617956];
Rs = x(1);
lls_dot = x(2);
Lm_dot = x(3);
Rr_dot = x(4);
%% State Space modeling
A = [-Rr_dot/Lm_dot, -w, Rr_dot,0;
w, -Rr_dot/Lm_dot, 0,Rr_dot;
Rr_dot/(Lm_dot*lls_dot), w/lls_dot, -(Rr_dot+Rs)/lls_dot, 0;
-w/lls_dot, Rr_dot/(Lm_dot*lls_dot), 0, -(Rr_dot+Rs)/lls_dot];
B = [0, 0;
0, 0;
1/lls_dot, 0;
0, 1/lls_dot];
C = [zeros(2),eye(2)];
D =zeros(2);
sys = ss(A,B,C,D,Ts)
%% Response
t = 0:Ts:sampling_time-Ts;
x0 = [flux_init,i(1,1:2)]; % initial conditions setting
y = lsim(sys,u,t,x0)

7 Comments

@Fangjun Jiang are there solver settings in matlab? (not simulink)
Is the system inherently stable?
Could it be the input excites one of the virbration mode?
@Sam Chak It's the induction motor inverse gamma state space model. The motor should be stable, and the inputs in matlab ss and simulink state-space block are the same. They should display the same output.
@Raymond Wong, Thanks for the clarification. This is indeed a little strange. In thoery, if the system is inherently stable, the output response should not diverge no matter what input is fed into the system, so long as the input is bounded and does not excite the vibration mode of the system.
Got this error mesage:
error: 'out' undefined
@Sam Chak I forgot to upload the data file named by 'out.mat'. Sorry about that. See attached.

Sign in to comment.

 Accepted Answer

I found the issue. It turned out the model I built in MATLAB at first is the Discrete-time state-space model, which I didn't pay attention to. After I made it Continuous-time state-space model, it converged. In the code, the chage is shown below. @Sam Chak Technically they're the same model, but I'm not sure why the continuos version converge and the discrete version diverge.
% sys = ss(A,B,C,D,Ts) Discrete-time state-space model
sys = ss(A,B,C,D) % Continuous-time state-space model

11 Comments

Hi Raymond,
The issue, as you noted, is that the A,B,C,D matrices in your code and as used in Simulnk define a continuous-time state space model. The correct representation in Matlab would then be:
sys = ss(A,B,C,D); % continuous-time state space model
You can also specify a sample time of 0
sys = ss(A,B,C,D,0); % continuous-time state space model
If you want to discretize that model, use c2d.
Also, lsim and Simulink still won't, in general, yield the exact same result for continous-time state space models. Simulink uses an ode solver, while lsim() actually uses c2d under the hood, with a possible exception for ss models with internal time delays, which aren't relevant for this discussion..
@Paul Thanks for pointing out my typo, I corrected it and updated. I'm a bit curious that why the mathematically same models, discrete and continuous, display different stable situation. For this specific configuration, the discrete model is not stable amd the continuous model is stable.
I can't attempt to recreate this result without knowing the value of w.
I attached a data file named with 'out.mat' in the question description, the code should work if you import this file. @Paul
load(websave('out', 'https://www.mathworks.com/matlabcentral/answers/uploaded_files/1056590/out.mat'));
f = 10000; % Sampling Frequency
Ts = 1/f;
%% Data Preparation(Not Important
out1 = out;
ab0_voltage1 = out1.voltage_ab0;
ab0_current1 = out1.current_ab0;
rotation_f1 = out1.speed;
Warning: Unrecognized field name "speed".
start_time = 0;
sampling_time = 5;
start_point = start_time*f+1;
sampling_points = sampling_time*f-1;
t_ind = start_point:start_point+sampling_points;
u = ab0_voltage1(t_ind,2:3); %Input
i = ab0_current1(t_ind,2:3);
flux_init = out.flux_ab(start_point,2:3);
w = mean(out.w_e(end,2));
%% Parameterization of State Space A B C D
x = [6.14,0.037874419,0.387125581,4.987617956];
Rs = x(1);
lls_dot = x(2);
Lm_dot = x(3);
Rr_dot = x(4);
%% State Space modeling
A = [-Rr_dot/Lm_dot, -w, Rr_dot,0;
w, -Rr_dot/Lm_dot, 0,Rr_dot;
Rr_dot/(Lm_dot*lls_dot), w/lls_dot, -(Rr_dot+Rs)/lls_dot, 0;
-w/lls_dot, Rr_dot/(Lm_dot*lls_dot), 0, -(Rr_dot+Rs)/lls_dot];
B = [0, 0;
0, 0;
1/lls_dot, 0;
0, 1/lls_dot];
C = [zeros(2),eye(2)];
D =zeros(2);
The continuous model is:
sysc = ss(A,B,C,D);
Its poles are all in the LHP, so sysc represents a stable system.
pole(sysc)
ans =
1.0e+02 * -1.3931 + 3.0338i -1.3931 - 3.0338i -1.6737 + 0.6997i -1.6737 - 0.6997i
The discretized model, assuming a ZOH, is
sysd = c2d(sysc,Ts);
All poles are inside the unit circle, so also stable
abs(pole(sysd))
ans = 4×1
0.9862 0.9862 0.9834 0.9834
What is the code that lead to the statement "the discrete model is not stable"?
@PaulI used the function isstable(sys) @Sam Chak mentioned to test the stability. The result of discrete model is logical 0.
Please show the code that develops the "continuous model" and the "discrete model" that are input to isstable. Can't offer any adiditonal help without that.
Thanks@Paul. Check out the code below. The stability of discrete model discrete_sys_stability is 0 and the stability of continuous model continuous_sys_stability is 1.
%% Basic Setting
f = 10000; % Sampling Frequency
Ts = 1/f;
%% Parameterization of State Space A B C D
x = [6.14,0.037874419,0.387125581,4.987617956];
Rs = x(1);
lls_dot = x(2);
Lm_dot = x(3);
Rr_dot = x(4);
w = 373.353308802356;
%% State Space modeling
A = [-Rr_dot/Lm_dot, -w, Rr_dot,0;
w, -Rr_dot/Lm_dot, 0,Rr_dot;
Rr_dot/(Lm_dot*lls_dot), w/lls_dot, -(Rr_dot+Rs)/lls_dot, 0;
-w/lls_dot, Rr_dot/(Lm_dot*lls_dot), 0, -(Rr_dot+Rs)/lls_dot];
B = [0, 0;
0, 0;
1/lls_dot, 0;
0, 1/lls_dot];
C = [zeros(2),eye(2)];
D =zeros(2);
dis_sys = ss(A,B,C,D,Ts);
discrete_sys_stability = isstable(dis_sys)
discrete_sys_stability = logical
0
con_sys = ss(A,B,C,D);
continuous_sys_stability = isstable(con_sys)
continuous_sys_stability = logical
1
This line is inccorrect in modeling discrete system
dis_sys = ss(A, B, C, D, Ts);
because the discrete-time system has a different set of A, B, C, D.
In short, .
% Basic Setting
f = 10000; % Sampling Frequency
Ts = 1/f;
%% Parameterization of State Space A B C D
x = [6.14,0.037874419,0.387125581,4.987617956];
Rs = x(1);
lls_dot = x(2);
Lm_dot = x(3);
Rr_dot = x(4);
w = 373.353308802356;
%% State Space modeling
A = [-Rr_dot/Lm_dot, -w, Rr_dot,0;
w, -Rr_dot/Lm_dot, 0,Rr_dot;
Rr_dot/(Lm_dot*lls_dot), w/lls_dot, -(Rr_dot+Rs)/lls_dot, 0;
-w/lls_dot, Rr_dot/(Lm_dot*lls_dot), 0, -(Rr_dot+Rs)/lls_dot];
B = [0, 0;
0, 0;
1/lls_dot, 0;
0, 1/lls_dot];
C = [zeros(2),eye(2)];
D =zeros(2);
sysc = ss(A,B,C,D);
Check_sysC = isstable(sysc)
Check_sysC = logical
1
sysd = c2d(sysc,Ts);
Check_sysD = isstable(sysd)
Check_sysD = logical
1
You've got it. Use c2d() to develop the discrete-time approximation to a continous-time model. Check the c2d doc page for the available options for the conversion. Good luck with rest of your project.

Sign in to comment.

More Answers (2)

There are limited number of settings when calling lsim(sys,u,t,x0,method). You need to change the settings in Simulink to match the MATLAB simulation time vector. Most likely, choose discrete solver with fixed step size in Simulink. This is just to make the two simulation results match.
If the outputs in Simulink converge using the default settings, then the system is stable. Most likely, the step size in MATLAB is too large which caused it to diverge.

1 Comment

The solver setting in simulink is ode8 with fixed-step, and the fixed step size is 1e-4 which is the Ts in matlab ss function.

Sign in to comment.

I have added one line after sys = ss(A,B,C,D,Ts) to determine whether system is stable or not.
isstable(sys)
isstable(sys) returns a logical value of 1 (true) if the dynamic system model sys has stable dynamics, and a logical value of 0 (false) otherwise.

Asked:

on 5 Jul 2022

Edited:

on 19 Apr 2023

Community Treasure Hunt

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

Start Hunting!