Engee documentation
Notebook

The workflow of system identification

Identification is the process of constructing a mathematical model of a dynamic object based on experimental data.

In [ ]:
Pkg.add(["DataFrames", "CSV", "ControlSystemIdentification"])
using DataFrames, CSV, ControlSystemIdentification;

An approximate identification workflow looks like this:image.png

First, you need to conduct an experiment to collect system data. Then we select the structure of the model that we want to fit to this data and the identification algorithm. Next, the data obtained is "adjusted" to the selected structure. The identification result is checked against a validation dataset. If the identification result turns out to be unsatisfactory, it is necessary to go back and change the structure of the model or the identification algorithm.

Collecting experimental data

First of all, experimental data must be obtained for identification. In this example, the experiment data is uploaded to Engee from a CSV file. We will divide the experimental data into 2 parts: the first will be used for identification, the second for validation.

In [ ]:
Import_data = "data.csv" 
table = CSV.read(Import_data, DataFrame);
inputdata = Float64.(table[:, 2]); 
outputdata = Float64.(table[:, 3]);

Identification data:

In [ ]:
Ts = 0.1;
identdata  = iddata(outputdata[1:Int32(end/2)], inputdata[1:Int32(end/2)], Ts);   
plot(identdata)     
Out[0]:

Validation data:

In [ ]:
valdata  = iddata(outputdata[Int32(end/2):end], inputdata[Int32(end/2):end], Ts);   
plot(valdata)   
Out[0]:

Model structure selection and identification

We will identify a linear stationary system in the state space. First, let's choose the order of the system equal to 1.

In [ ]:
nx = 1; # порядок системы
res = subspaceid(identdata, nx; verbose=true)
Out[0]:
N4SIDStateSpace{ControlSystemsBase.StateSpace{ControlSystemsBase.Discrete{Float64}, Float64}, LinearAlgebra.Hermitian{Float64, Matrix{Float64}}, LinearAlgebra.Hermitian{Float64, Matrix{Float64}}, Matrix{Float64}, Matrix{Float64}, Matrix{Float64}, Vector{Float64}, LinearAlgebra.SVD{Float64, Float64, Matrix{Float64}, Vector{Float64}}, Float64}
A = 
 0.8129112616785744
B = 
 -0.38362425489543245
C = 
 -4.560011287091462
D = 
 0.02359847501341137

Sample Time: 0.1 (seconds)
Discrete-time state-space model

Validation of the model

In [ ]:
simplot(valdata, res) 
Out[0]:

As we can see, the identified model does not sufficiently reproduce the dynamics of the real system.

Model structure modification and identification

Let's take a step back and change the structure of the model. Let the order of the system be 2 this time.

In [ ]:
nx = 2; # порядок системы
res = subspaceid(identdata, nx; verbose=true)
Out[0]:
N4SIDStateSpace{ControlSystemsBase.StateSpace{ControlSystemsBase.Discrete{Float64}, Float64}, LinearAlgebra.Hermitian{Float64, Matrix{Float64}}, LinearAlgebra.Hermitian{Float64, Matrix{Float64}}, Matrix{Float64}, Matrix{Float64}, Matrix{Float64}, Vector{Float64}, LinearAlgebra.SVD{Float64, Float64, Matrix{Float64}, Vector{Float64}}, Float64}
A = 
  0.8165117145544952  0.3939768143396654
 -0.3883413482702869  0.6670669737460359
B = 
 -0.45785009806936194
 -0.31617858798326837
C = 
 -4.42362835383083  3.228268638993534
D = 
 0.03893922777217982

Sample Time: 0.1 (seconds)
Discrete-time state-space model

Validation of the model

In [ ]:
simplot(valdata, res) 
Out[0]:

This time, we are satisfied with the accuracy of identification.

Conclusion

In this example, we got acquainted with the workflow of system identification based on experimental data obtained from the CSV table.