## Saturday, March 9, 2019

### First attempt at a linear model for an LCL filter

In the previous blog post I described how I am trying to use machine learning to create a functional relationship between the grid voltage and the filter capacitor voltage with respect to the grid current for a dc-ac converter connected to an ac grid through an LCL filter.

So, if that is a bit of a mouthful, here is what it is in a flow:

Inverter - Inductor - Filter Capacitor - Inductor - Grid

The idea is can we determine how much the voltage across the filter capacitor  should be for a particular value of current injected into the grid? The grid voltage can be measured. So, we have:

1. Measured value of grid voltage
2. Reference of current injected into the grid

We need a reference for the voltage across the filter capacitor. Why? Because we have already succeeded in controlling the voltage across with a state feedback controller based on Linear Quadratic Controller.

I ran a free simulation. What that means is I adjusted the modulation index of the dc-ac converter to random values and checked what would be the values of grid voltage, grid current and filter capacitor. All this is for training a machine learning algorithm. And I showed in the previous blog post, the plot of this.

Now, to the next stage. Take the output file and convert it to a .csv file that Pandas can read. Pandas is a data processing package available in Python as part of the PyData library.

This is an extract of the DataFrame which is what you call a database in Pandas:

Time Ammeter_Lfinv Ammeter_Lfgrid Voltmeter_Cfilter Voltmeter_Vgrid inv1trainer_modsignal pwm_carr pwm_s1logic
0 0.00001 -2.968437 -0.003901 -0.095838 0.640844 2.368476e-17 0.200 0.0
1 0.00002 -5.663500 -0.014377 -0.309820 1.217527 2.368476e-17 0.400 0.0
2 0.00003 -8.951290 -0.037764 -0.734868 1.922236 4.946608e-03 0.602 0.0
3 0.00004 -11.932744 -0.070674 -1.276453 2.562736 4.946608e-03 0.800 0.0
4 0.00005 -14.905593 -0.116192 -1.964789 3.203073 9.874666e-03 1.000 0.0

Just the top 5 rows. The data frame has a total of 199999 rows. So that's quite a bit of data.

With this, we are now going to try to create a linear model. What we are trying to do is predict the voltage across the filter capacitor. This will be our output 'y'. The inputs are the grid current which we call x1 (input 1) and the grid voltage x2 (input 2). What we want is:

y = b0 + b1*x1 + b2*x2

If we can achieve this, we have a way to calculate the reference capacitor voltage for any given grid voltage and a reference grid current.

We use linear regression. Linear regression will build exactly the above model with data that we pass to it in order to generate the co-efficients b1 and b2 and the intercept b0. The theory behind it is fairly mathematically intense and maybe I will read about it in detail some day. But in short, linear regression generates these constants by trying to minimize the residual sum of squares for all the data points that we are using to train this model:

RSS = (y1 - b0 - b1*x1_1 - b2*x2_1)^2 + (y2 - b0 - b1*x1_2 - b2*x2_2)^2 + ... +
(yn - b0 - b1*x1_n - b2*x2_n)^2

When there are n samples. We have a total of 199999 samples. But we don't want to use all of them. We want to split them into a training set and a testing set. So, let's do a 70%-30% split - 70% of the data is for training and the rest we will use for testing.

I am using the LinearRegression package available with scikit-learn. As I am getting started with machine learning, I am going to try to keep this simple. I will have to add complexity as I go on. For now, this is a good start.

This is what I do:

```y = df['Voltmeter_Cfilter']
x = df[['Ammeter_Lfgrid', 'Voltmeter_Vgrid']]
x_train, x_test, y_train, y_test = train_test_split(x, y, test_size=0.3)
inv_model = LinearRegression()
inv_model.fit(x_train, y_train)
```

The next part is to check how accurate the model is with test data:

```predictions = inv_model.predict(x_test)
plt.figure(figsize=(12,8))
sns.scatterplot(x=y_test, y=predictions)
```

And this is a scatter plot of the prediction of the capacitor voltage versus the actual voltage from the simulation. Most of the scatter lot is in a straight line which is a good sign. But the bad news is that there is some deviation and that deviation is of the order of magnitude of 50V. The filter capacitor and the grid are separated by a small inductor of the order of around 1 mH. Such a difference in voltage of 50V could produce huge spikes in the current.

The final equation turns out to be:

vcf = -0.01157 + 0.04176*igrid + 1.0587*vgrid

Even before trying to simulate this, I am pretty sure it won't work. But still this has been a good first step as I try to apply my rudimentary machine learning in power electronics. I hope as time goes by I will be able to apply more accurate models that can actually be of use.