diff --git a/ACS Notebooks/ACS_V9.ipynb b/ACS Notebooks/ACS_V9.ipynb
new file mode 100644
index 0000000000000000000000000000000000000000..5faeaebe0549f968e8977da3423d9a9fc84531c3
--- /dev/null
+++ b/ACS Notebooks/ACS_V9.ipynb
@@ -0,0 +1,622 @@
+{
+ "cells": [
+ {
+ "cell_type": "markdown",
+ "id": "6abc5329-fdea-4f76-ad5f-f6e8ecc8cdac",
+ "metadata": {},
+ "source": [
+ "Design and Simulation of a Grid Forming Inverter\n",
+ "System definition\n",
+ "This notebook presents the complete design and verification of an inverter working as grid forming"
+ ]
+ },
+ {
+ "cell_type": "code",
+ "execution_count": null,
+ "id": "bc402d67",
+ "metadata": {
+ "vscode": {
+ "languageId": "plaintext"
+ }
+ },
+ "outputs": [],
+ "source": [
+ "clear all\n",
+ "% Set the Octave Engine to run the simulation\n",
+ "SetSimulationEnvironment;\n",
+ "% Input Data\n",
+ "Rf = 0.1\n",
+ "Lf = 0.01\n",
+ "Rc = 0.01\n",
+ "Cf = 0.001\n",
+ "Rl = 10\n",
+ "Ll = 0.1\n",
+ "om = 2*pi*50\n",
+ "Vref = sqrt(3)*220"
+ ]
+ },
+ {
+ "cell_type": "markdown",
+ "id": "446033c6",
+ "metadata": {},
+ "source": [
+ "Current Loop\n",
+ "First thing we design the current loop compensating the pole of the inductance and fixing the\n",
+ "bandwidth"
+ ]
+ },
+ {
+ "cell_type": "code",
+ "execution_count": null,
+ "id": "02055711",
+ "metadata": {
+ "vscode": {
+ "languageId": "plaintext"
+ }
+ },
+ "outputs": [],
+ "source": [
+ "ombc = 600*2*pi\n",
+ "Kpc = ombc*Lf\n",
+ "Kic = ombc*Rf"
+ ]
+ },
+ {
+ "cell_type": "markdown",
+ "id": "d3944599",
+ "metadata": {},
+ "source": [
+ "As result we have the following frequency responses\n",
+ "Open loop current"
+ ]
+ },
+ {
+ "cell_type": "code",
+ "execution_count": null,
+ "id": "6a86cc64",
+ "metadata": {
+ "vscode": {
+ "languageId": "plaintext"
+ }
+ },
+ "outputs": [],
+ "source": [
+ "Gc = tf(1,[Lf Rf])\n",
+ "bode(Gc)"
+ ]
+ },
+ {
+ "cell_type": "markdown",
+ "id": "556532ab",
+ "metadata": {},
+ "source": [
+ "Adding the controller to the open loop"
+ ]
+ },
+ {
+ "cell_type": "code",
+ "execution_count": null,
+ "id": "bd6ffa04",
+ "metadata": {
+ "vscode": {
+ "languageId": "plaintext"
+ }
+ },
+ "outputs": [],
+ "source": [
+ "Rcur = tf([Kpc Kic],[1 0])\n",
+ "Gopenc = Rcur*Gc\n",
+ "bode(Gopenc)"
+ ]
+ },
+ {
+ "cell_type": "markdown",
+ "id": "9415b65d",
+ "metadata": {},
+ "source": [
+ "Voltage Loop\n",
+ "The design is performed by tuning the PI control and assuming that ESR does not play a role and\n",
+ "that the current loop is too fast for the voltage loop"
+ ]
+ },
+ {
+ "cell_type": "code",
+ "execution_count": null,
+ "id": "ac110f53",
+ "metadata": {
+ "vscode": {
+ "languageId": "plaintext"
+ }
+ },
+ "outputs": [],
+ "source": [
+ "ombv = 100*2*pi\n",
+ "fim = 60*pi/180\n",
+ "Gv = tf(1,[Cf 0])\n",
+ "[Go Fo]= bode(Gv,ombv)\n",
+ "Fo = Fo*pi/180;\n",
+ "Kpv = cos(-pi+fim-Fo)/Go\n",
+ "Kiv = -sin(-pi+fim-Fo)*ombv/Go"
+ ]
+ },
+ {
+ "cell_type": "code",
+ "execution_count": null,
+ "id": "4dead95b",
+ "metadata": {
+ "vscode": {
+ "languageId": "plaintext"
+ }
+ },
+ "outputs": [],
+ "source": [
+ "Rv = tf([Kpv Kiv],[1 0])\n",
+ "Gopenv = Rv*Gv\n",
+ "margin(Gopenv)"
+ ]
+ },
+ {
+ "cell_type": "code",
+ "execution_count": null,
+ "id": "9d1a0433",
+ "metadata": {
+ "vscode": {
+ "languageId": "plaintext"
+ }
+ },
+ "outputs": [],
+ "source": [
+ "% Set the Octave Engine to run the simulation\n",
+ "SetSimulationEnvironment;\n",
+ "tini = 0;\n",
+ "tfinal = 0.1;\n",
+ "dt = 0.0001;\n",
+ "nflows = 44;\n",
+ "nnode = 23;\n",
+ "maxn = 20;\n",
+ "toll = 0.0001;\n",
+ "% Creating an hybrid diagram containing a power network and control\n",
+ "hy = HybridSystem(nnode,nflows,tini,tfinal,dt,maxn,toll);\n",
+ "% POWER NETWORK TOPOLOGY - Inverter+Filter+Load\n",
+ "% Voltage Source\n",
+ "c1{1} = Signal2Source(1,0,24);\n",
+ "c1{2} = Signal2Source(2,0,25);\n",
+ "c1{3} = Signal2Source(3,0,26);\n",
+ "% Resistor\n",
+ "c1{4} = Resistance(1,4,Rf);\n",
+ "c1{5} = Resistance(2,5,Rf);\n",
+ "c1{6} = Resistance(3,6,Rf);\n",
+ "% Inductor\n",
+ "c1{7} = Inductor(4,7,Lf);\n",
+ "c1{8} = Inductor(5,8,Lf);\n",
+ "c1{9} = Inductor(6,9,Lf);\n",
+ "% Current Sensors\n",
+ "c1{10} = CurrentSensor(7,10,29);\n",
+ "c1{11} = CurrentSensor(8,11,30);\n",
+ "c1{12} = CurrentSensor(9,12,31);\n",
+ "% Capacitor Resistances\n",
+ "c1{13} = Resistance(10,20,Rc);\n",
+ "c1{14} = Resistance(11,21,Rc);\n",
+ "c1{15} = Resistance(12,22,Rc);\n",
+ "% Capacitor Filter\n",
+ "c1{16} = Capacitor(20,23,Cf);\n",
+ "c1{17} = Capacitor(21,23,Cf);\n",
+ "c1{18} = Capacitor(22,23,Cf);\n",
+ "% Line/Load Resistance\n",
+ "c1{19} = Resistance(10,13,Rl);\n",
+ "c1{20} = Resistance(11,14,Rl);\n",
+ "c1{21} = Resistance(12,15,Rl);\n",
+ "% Line/Load Inductor\n",
+ "c1{22} = Inductor(13,16,Ll);\n",
+ "c1{23} = Inductor(14,17,Ll);\n",
+ "c1{24} = Inductor(15,18,Ll);\n",
+ "% Current sensors on line\n",
+ "c1{25} = CurrentSensor(16,19,34);\n",
+ "c1{26} = CurrentSensor(17,19,35);\n",
+ "c1{27} = CurrentSensor(18,19,36);\n",
+ "% Voltage sensors across capacitors\n",
+ "c1{28} = VoltageSensor(10,23,39);\n",
+ "c1{29} = VoltageSensor(11,23,40);\n",
+ "c1{30} = VoltageSensor(12,23,41);\n",
+ "% Adding all the components to the network diagram\n",
+ "hy.AddListComponents2Network(c1);\n",
+ "CONTROL SYSTEM\n",
+ "% Voltage Control\n",
+ "b1{1} = Constant(1,Vref);\n",
+ "b1{2} = Constant(2,0);\n",
+ "b1{3} = Sum(1,42,3,1,-1);\n",
+ "b1{4} = Sum(2,43,4,1,-1);\n",
+ "b1{5} = PI(3,5,Kpv,Kiv,0);\n",
+ "b1{6} = PI(4,6,Kpv,Kiv,0);\n",
+ "% Feedforward and decoupling voltage loop\n",
+ "b1{7} = Sum(5,8,9,1,1);\n",
+ "b1{8} = Sum(6,7,10,1,-1);\n",
+ "b1{9} = Gain(43,8,2*pi*50*Cf);\n",
+ "b1{10} = Gain(42,7,2*pi*50*Cf);\n",
+ "b1{11} = Sum(9,37,11,1,1);\n",
+ "b1{12} = Sum(10,38,12,1,1);\n",
+ "% Current Control\n",
+ "b1{13} = Sum(11,32,13,1,-1);\n",
+ "b1{14} = Sum(12,33,14,1,-1);\n",
+ "b1{15} = PI(13,15,Kpc,Kic,0);\n",
+ "b1{16} = PI(14,17,Kpc,Kic,0);\n",
+ "% Feedforward and decoupling current loop\n",
+ "b1{17} = Sum(15,16,19,1,1);\n",
+ "b1{18} = Sum(17,18,20,1,-1);\n",
+ "b1{19} = Gain(33,16,2*pi*50*Lf);\n",
+ "b1{20} = Gain(32,18,2*pi*50*Lf);\n",
+ "b1{21} = Sum(19,42,21,1,1);\n",
+ "b1{22} = Sum(20,43,22,1,1);\n",
+ "% Park Output Voltage Reference\n",
+ "b1{23} = InvPark(21,22,2,24,25,26,23);\n",
+ "% Angle Reference\n",
+ "b1{24} = Constant(27,2*pi*50);\n",
+ "b1{25} = Integrator(27,23,0);\n",
+ "% Measurement Current Filter\n",
+ "b1{26} = Park(29,30,31,32,33,44,23);\n",
+ "% Measurement Voltage Filter\n",
+ "b1{27} = Park(39,40,41,42,43,44,23);\n",
+ "% Measurement Current Load\n",
+ "b1{28} = Park(34,35,36,37,38,44,23);\n",
+ "% Adding all the components to the Control Schema\n",
+ "hy.AddListComponents2Schema(b1);\n",
+ "% Initialization\n",
+ "hy.Init();\n",
+ "p=1;\n",
+ "% Simulation Loop\n",
+ "while hy.Step()\n",
+ "time(p) = hy.GetTime();\n",
+ "% Park Voltage\n",
+ "out(1,p) = hy.GetFlow(42);\n",
+ "out(2,p) = hy.GetFlow(43);\n",
+ "% Park Currents\n",
+ "out(3,p) = hy.GetFlow(32);\n",
+ "out(4,p) = hy.GetFlow(33);\n",
+ "% Phase Voltages\n",
+ "out(5,p) = hy.GetFlow(39);\n",
+ "out(6,p) = hy.GetFlow(40);\n",
+ "out(7,p) = hy.GetFlow(41);\n",
+ "% Phase Currents\n",
+ "out(8,p) = hy.GetFlow(34);\n",
+ "out(9,p) = hy.GetFlow(35);\n",
+ "out(10,p) = hy.GetFlow(36);\n",
+ "p=p+1;\n",
+ "end"
+ ]
+ },
+ {
+ "cell_type": "markdown",
+ "id": "d03968d1",
+ "metadata": {},
+ "source": [
+ "Park Voltages on the filter"
+ ]
+ },
+ {
+ "cell_type": "code",
+ "execution_count": null,
+ "id": "754899a0",
+ "metadata": {
+ "vscode": {
+ "languageId": "plaintext"
+ }
+ },
+ "outputs": [],
+ "source": [
+ "plot(time,out(1,:),time,out(2,:));"
+ ]
+ },
+ {
+ "cell_type": "markdown",
+ "id": "d1bd8c81",
+ "metadata": {},
+ "source": [
+ "Park Currents on the filter"
+ ]
+ },
+ {
+ "cell_type": "code",
+ "execution_count": null,
+ "id": "cbcf34a5",
+ "metadata": {
+ "vscode": {
+ "languageId": "plaintext"
+ }
+ },
+ "outputs": [],
+ "source": [
+ "plot(time,out(3,:),time,out(4,:));\n",
+ "10"
+ ]
+ },
+ {
+ "cell_type": "markdown",
+ "id": "92064e71",
+ "metadata": {},
+ "source": [
+ "Phase Voltages"
+ ]
+ },
+ {
+ "cell_type": "code",
+ "execution_count": null,
+ "id": "5c863797",
+ "metadata": {
+ "vscode": {
+ "languageId": "plaintext"
+ }
+ },
+ "outputs": [],
+ "source": [
+ "plot(time,out(5,:),time,out(6,:),time,out(7,:));"
+ ]
+ },
+ {
+ "cell_type": "markdown",
+ "id": "e2e5a943",
+ "metadata": {},
+ "source": [
+ "Phase currents"
+ ]
+ },
+ {
+ "cell_type": "code",
+ "execution_count": null,
+ "id": "62874b7a",
+ "metadata": {
+ "vscode": {
+ "languageId": "plaintext"
+ }
+ },
+ "outputs": [],
+ "source": [
+ "plot(time,out(8,:),time,out(9,:),time,out(10,:));"
+ ]
+ },
+ {
+ "cell_type": "markdown",
+ "id": "41f840a9",
+ "metadata": {},
+ "source": [
+ "State Feedback with integrator\n",
+ "We approach now the design in the state space domain\n",
+ "First thing we need to define the system matrices as state space matrices"
+ ]
+ },
+ {
+ "cell_type": "code",
+ "execution_count": null,
+ "id": "deb91998",
+ "metadata": {
+ "vscode": {
+ "languageId": "plaintext"
+ }
+ },
+ "outputs": [],
+ "source": [
+ "Ass = [-Rf/Lf om -1/Lf 0; -om -Rf/Lf 0 -1/Lf; 1/Cf 0 0 om; 0 1/Cf -om 0]\n",
+ "Bss = [1/Lf 0; 0 1/Lf; 0 0; 0 0]"
+ ]
+ },
+ {
+ "cell_type": "markdown",
+ "id": "528744c3",
+ "metadata": {},
+ "source": [
+ "We assume not to measure the current of the load and we treat it as a disturbance\n",
+ "As result we need to add an integrator and extend the system matrices of one order to track vd"
+ ]
+ },
+ {
+ "cell_type": "code",
+ "execution_count": null,
+ "id": "1959c477",
+ "metadata": {
+ "vscode": {
+ "languageId": "plaintext"
+ }
+ },
+ "outputs": [],
+ "source": [
+ "C = [0 0 1 0;0 0 0 1]\n",
+ "Asse = [Ass zeros(4,2);-C zeros(2,2)]\n",
+ "Bsse = [Bss; zeros(2,2)]"
+ ]
+ },
+ {
+ "cell_type": "markdown",
+ "id": "b57c4a8a",
+ "metadata": {},
+ "source": [
+ "We design a pole placement controller"
+ ]
+ },
+ {
+ "cell_type": "code",
+ "execution_count": null,
+ "id": "4f8c3ed8",
+ "metadata": {
+ "vscode": {
+ "languageId": "plaintext"
+ }
+ },
+ "outputs": [],
+ "source": [
+ "p1 = -100+1j*50;\n",
+ "p2 = -100-1j*50;\n",
+ "p3 = -100+1j*50;\n",
+ "p4 = -100-1j*50;\n",
+ "p5 = -1000;\n",
+ "p6 = -1000;\n",
+ "K = place(Asse,Bsse,[p1 p2 p3 p4 p5 p6])"
+ ]
+ },
+ {
+ "cell_type": "markdown",
+ "id": "826765d7",
+ "metadata": {},
+ "source": [
+ "We can now verify in simulation"
+ ]
+ },
+ {
+ "cell_type": "code",
+ "execution_count": null,
+ "id": "99f9fcd5",
+ "metadata": {
+ "vscode": {
+ "languageId": "plaintext"
+ }
+ },
+ "outputs": [],
+ "source": [
+ "tini2 = 0;\n",
+ "tfinal2 = 0.1;\n",
+ "dt2 = 0.0001;\n",
+ "nflows2 = 44;\n",
+ "nnode2 = 23;\n",
+ "maxn2 = 20;\n",
+ "toll2 = 0.0001;\n",
+ "% Creating an hybrid diagram containing a power network and control\n",
+ "hy2 = HybridSystem(nnode2,nflows2,tini2,tfinal2,dt2,maxn2,toll2);\n",
+ "% POWER NETWORK TOPOLOGY - Inverter+Filter+Load\n",
+ "% Voltage Source\n",
+ "c2{1} = Signal2Source(1,0,24);\n",
+ "c2{2} = Signal2Source(2,0,25);\n",
+ "c2{3} = Signal2Source(3,0,26);\n",
+ "% Resistor\n",
+ "c2{4} = Resistance(1,4,Rf);\n",
+ "c2{5} = Resistance(2,5,Rf);\n",
+ "c2{6} = Resistance(3,6,Rf);\n",
+ "% Inductor\n",
+ "c2{7} = Inductor(4,7,Lf);\n",
+ "c2{8} = Inductor(5,8,Lf);\n",
+ "c2{9} = Inductor(6,9,Lf);\n",
+ "% Current Sensors\n",
+ "c2{10} = CurrentSensor(7,10,29);\n",
+ "c2{11} = CurrentSensor(8,11,30);\n",
+ "c2{12} = CurrentSensor(9,12,31);\n",
+ "% Capacitor Resistances\n",
+ "c2{13} = Resistance(10,20,Rc);\n",
+ "c2{14} = Resistance(11,21,Rc);\n",
+ "c2{15} = Resistance(12,22,Rc);\n",
+ "% Capacitor Filter\n",
+ "c2{16} = Capacitor(20,23,Cf);\n",
+ "c2{17} = Capacitor(21,23,Cf);\n",
+ "c2{18} = Capacitor(22,23,Cf);\n",
+ "% Line/Load Resistance\n",
+ "c2{19} = Resistance(10,13,Rl);\n",
+ "c2{20} = Resistance(11,14,Rl);\n",
+ "c2{21} = Resistance(12,15,Rl);\n",
+ "% Line/Load Inductor\n",
+ "c2{22} = Inductor(13,16,Ll);\n",
+ "c2{23} = Inductor(14,17,Ll);\n",
+ "c2{24} = Inductor(15,18,Ll);\n",
+ "% Current sensors on line\n",
+ "c2{25} = CurrentSensor(16,19,34);\n",
+ "c2{26} = CurrentSensor(17,19,35);\n",
+ "c2{27} = CurrentSensor(18,19,36);\n",
+ "% Voltage sensors across capacitors\n",
+ "c2{28} = VoltageSensor(10,23,39);\n",
+ "c2{29} = VoltageSensor(11,23,40);\n",
+ "c2{30} = VoltageSensor(12,23,41);\n",
+ "% Adding all the components to the network diagram\n",
+ "hy2.AddListComponents2Network(c2);\n",
+ "% CONTROL SYSTEM\n",
+ "% Voltage Control\n",
+ "b2{1} = Constant(1,Vref);\n",
+ "b2{2} = Sum(1,42,2,1,-1);\n",
+ "b2{3} = Integrator(2,3,0);\n",
+ "b2{4} = Constant(4,0);\n",
+ "b2{5} = Sum(4,43,5,1,-1);\n",
+ "b2{6} = Integrator(5,6,0);\n",
+ "b2{7} = Gain([32 33 42 43 3 6],21,-K(1,:));\n",
+ "b2{8} = Gain([32 33 42 43 3 6],22,-K(2,:));\n",
+ "% Park Output Voltage Reference\n",
+ "b2{9} = InvPark(21,22,4,24,25,26,23);\n",
+ "% Angle Reference\n",
+ "b2{10} = Constant(27,2*pi*50);\n",
+ "b2{11} = Integrator(27,23,0);\n",
+ "% Measurement Current Filter\n",
+ "b2{12} = Park(29,30,31,32,33,44,23);\n",
+ "% Measurement Voltage Filter\n",
+ "b2{13} = Park(39,40,41,42,43,44,23);\n",
+ "% Measurement Current Load\n",
+ "b2{14} = Park(34,35,36,37,38,44,23);\n",
+ "% Adding all the components to the Control Schema\n",
+ "hy2.AddListComponents2Schema(b2);\n",
+ "% Initialization\n",
+ "hy2.Init();\n",
+ "p=1;\n",
+ "% Simulation Loop\n",
+ "while hy2.Step()\n",
+ "time2(p) = hy2.GetTime();\n",
+ "% Park Voltage\n",
+ "out2(1,p) = hy2.GetFlow(42);\n",
+ "out2(2,p) = hy2.GetFlow(43);\n",
+ "% Park Currents\n",
+ "out2(3,p) = hy2.GetFlow(32);\n",
+ "out2(4,p) = hy2.GetFlow(33);\n",
+ "p=p+1;\n",
+ "end"
+ ]
+ },
+ {
+ "cell_type": "code",
+ "execution_count": null,
+ "id": "7e50a69a",
+ "metadata": {
+ "vscode": {
+ "languageId": "plaintext"
+ }
+ },
+ "outputs": [],
+ "source": [
+ "plot(time2,out2(1,:),time2,out2(2,:));"
+ ]
+ },
+ {
+ "cell_type": "code",
+ "execution_count": null,
+ "id": "df1adc63",
+ "metadata": {
+ "vscode": {
+ "languageId": "plaintext"
+ }
+ },
+ "outputs": [],
+ "source": [
+ "plot(time2,out2(3,:),time2,out2(4,:));"
+ ]
+ }
+ ],
+ "metadata": {
+ "kernelspec": {
+ "display_name": "Octave",
+ "language": "octave",
+ "name": "octave"
+ },
+ "language_info": {
+ "file_extension": ".m",
+ "help_links": [
+ {
+ "text": "GNU Octave",
+ "url": "https://www.gnu.org/software/octave/support.html"
+ },
+ {
+ "text": "Octave Kernel",
+ "url": "https://github.com/Calysto/octave_kernel"
+ },
+ {
+ "text": "MetaKernel Magics",
+ "url": "https://metakernel.readthedocs.io/en/latest/source/README.html"
+ }
+ ],
+ "mimetype": "text/x-octave",
+ "name": "octave",
+ "version": "5.2.0"
+ }
+ },
+ "nbformat": 4,
+ "nbformat_minor": 5
+}