Three Phase Standalone Inverter with L Filter

The circuit files for this case are in these two links:

circuit_files.zip circuit_files.tar.gz

If you are here to know how to use control functions in the simulator, read this post and run the simulator with the circuit files in the above links. To start, as usual, run the file circuit_solver.py and enter the file standalone_inv as the circuit file. No need to add the .csv extension. The file standalone_inv.csv is in the links above. The parameter file standalone_inv_params.csv can also be found in the links above.

inv1 param inv2 param

Now comes the part about controls. There are two control files in this simulation - one is the phase angle generator angle_gen.py and the other is the current controller currcont_3ph.py. The simulator asks for the control files and these two are entered as shown above. As before without the .py extension. A simulation can contain a single control file or multiple. The purpose of this example is to show how to use multiple control files and more importantly how to exchange signals between control files. This way, you can design cascaded control or embedded control functions.

The next part - the descriptor files. Every control file used in the simulation will have a descriptor file. In this case - angle_gen_desc.csv and currcont_3ph_desc.csv. The purpose of a descriptor file is to define the interface of the control file - the inputs, outputs, static variables, time events and storage variables. More on this:

With the above background, time to go into details with actual code. First the angle_gen.py code.


import math

dt_sample = 100.0e-6
omega = 2*3.141*60.0

if t_clock>=t1:
  ph_angle += omega*dt_sample
  if (ph_angle > 2*math.pi):
    ph_angle = 0.0
  t1 = t1 + dt_sample
control_ph_angle = ph_angle
			

The above code can be described in the following way:

The screenshot below shows the descriptor for angle_gen_desc.csv.

inv3 param

The control function does not have any inputs because there is no need for any. There are no outputs either as the function does not directly affect any controllable component. ph_angle is defined a static variable. This is because of the statement:

ph_angle += omega*dt_sample

This implies ph_angle uses its previous value to compute its current value. Therefore, the value of ph_angle has to be stored for future use and so it is defined as a static variable.

The next row is the definition of the time event t1. From the control code above, t1 is progressed by steps of 100 microseconds so that the control code runs every 100 microseconds when compared the simulation time instant. This could have been a static variable also. Except that time event has a special significance for the simulator. When t1 is updated in the control code, it generates a time event. There could be multiple time events generated in a control code. And there could be several control codes that generate several time events. What the simulator does is to arrange all these time events so that it knows the closest time event from the present instant of time. This is then combined with the next intended simulation time instant generated with the constant simulation time step. The simulator will choose the next simulation time instant to be closes time event or the next simulation time instant whichever is nearer. So time events are a way to control the run frequency of the simulator besides also deciding how often the control code is run.

The last row is the tricky part. The angle generator produces a phase angle that will be used by the current controller. Therefore the phase angle is not an Output. So to make the ph_angle available to the current controller or for that matter any other controller, it is defined as VariableStorage. This means the control variable is stored in a "global" space where it is available for all control functions. Since, this is similar to a global variable, a variable defined as VariableStorage cannot be defined in another control function. However, it can be used and also modified in another function. Since, it is a global variable, care should be taken while using this variable in control functions. To show how this is used, the current controller will be described next.

currcont_3ph.py:

To know more about the interface of the control code, the screenshot of the descriptor file is:

inv4 param

For every control code that you specify, the simulator generates a template descriptor file for you to be able to edit. So you use that as a starting point or use the files provided in the link. The input can be any meter and there can be multiple inputs limited by as many meters there are in the circuit. The name of the input is as it appears in the circuit file. The next column asks you how you want to access the input in the control function. The variable specified is the variable by which the meter output will be made available to you. Lines 19 and 20 use the variables curr_a, curr_b and curr_c that are the meter outputs.

As for the outputs, there can be multiple outputs and these are also accessed by variable names linked with each control tag. Here it is essential that you get both the element name and the name of the control tag matched. Or else you will have an error when the simulator tries to access a control tag in an element that does not exist.

The definition of static variables is quite similar to the previous case. Try to read the control code and figure out how the control works. The current controller works at 100 microseconds while the pulse width modulator works at 1 microseconds. Try changing some of the control parameters or implement you own control along the same lines as above.

The results are:

result1 result2

From the control code, it can be seen that the current reference for the d axis has been set at 10Amps and q axis at 0Amps. The tracking can be seen from the figure.