Commit 13f25abc authored by Jan Dinkelbach's avatar Jan Dinkelbach Committed by Markus Mirz
Browse files

add option to adapt VSI control params from command line

parent 3ee0f943
......@@ -29,6 +29,8 @@ int main(int argc, char* argv[]) {
Real timeStep = 0.0001;
String simName = "DP_Slack_PiLine_VSI_with_PF_Init";
Bool pvWithControl = true;
Real cmdScaleP = 1.0;
Real cmdScaleI = 1.0;
CommandLineArgs args(argc, argv);
if (argc > 1) {
......@@ -39,6 +41,10 @@ int main(int argc, char* argv[]) {
simName = args.name;
if (args.options_bool.find("control") != args.options_bool.end())
pvWithControl = args.options_bool["control"];
if (args.options.find("scale_kp") != args.options.end())
cmdScaleI = args.options["scale_kp"];
if (args.options.find("scale_ki") != args.options.end())
cmdScaleI = args.options["scale_ki"];
}
// ----- POWERFLOW FOR INITIALIZATION -----
......@@ -107,7 +113,7 @@ int main(int argc, char* argv[]) {
auto pv = DP::Ph1::AvVoltageSourceInverterDQ::make("pv", "pv", Logger::Level::debug, true);
pv->setParameters(scenario.systemOmega, scenario.pvNominalVoltage, scenario.pvNominalActivePower, scenario.pvNominalReactivePower);
pv->setControllerParameters(scenario.KpPLL, scenario.KiPLL, scenario.KpPowerCtrl, scenario.KiPowerCtrl, scenario.KpCurrCtrl, scenario.KiCurrCtrl, scenario.OmegaCutoff);
pv->setControllerParameters(cmdScaleP*scenario.KpPLL, cmdScaleI*scenario.KiPLL, cmdScaleP*scenario.KpPowerCtrl, cmdScaleI*scenario.KiPowerCtrl, cmdScaleP*scenario.KpCurrCtrl, cmdScaleI*scenario.KiCurrCtrl, scenario.OmegaCutoff);
pv->setFilterParameters(scenario.Lf, scenario.Cf, scenario.Rf, scenario.Rc);
pv->setTransformerParameters(scenario.systemNominalVoltage, scenario.pvNominalVoltage, scenario.transformerNominalPower, scenario.systemNominalVoltage/scenario.pvNominalVoltage, 0, 0, scenario.transformerInductance, scenario.systemOmega);
pv->setInitialStateValues(scenario.pvNominalActivePower, scenario.pvNominalReactivePower, scenario.phi_dInit, scenario.phi_qInit, scenario.gamma_dInit, scenario.gamma_qInit);
......
......@@ -29,6 +29,8 @@ int main(int argc, char* argv[]) {
Real timeStep = 0.0001;
String simName = "EMT_Slack_PiLine_VSI_with_PF_Init";
Bool pvWithControl = true;
Real cmdScaleP = 1.0;
Real cmdScaleI = 1.0;
CommandLineArgs args(argc, argv);
if (argc > 1) {
......@@ -39,6 +41,10 @@ int main(int argc, char* argv[]) {
simName = args.name;
if (args.options_bool.find("control") != args.options_bool.end())
pvWithControl = args.options_bool["control"];
if (args.options.find("scale_kp") != args.options.end())
cmdScaleI = args.options["scale_kp"];
if (args.options.find("scale_ki") != args.options.end())
cmdScaleI = args.options["scale_ki"];
}
// ----- POWERFLOW FOR INITIALIZATION -----
......@@ -105,7 +111,7 @@ int main(int argc, char* argv[]) {
auto pv = EMT::Ph3::AvVoltageSourceInverterDQ::make("pv", "pv", Logger::Level::debug, true);
pv->setParameters(scenario.systemOmega, scenario.pvNominalVoltage, scenario.pvNominalActivePower, scenario.pvNominalReactivePower);
pv->setControllerParameters(scenario.KpPLL, scenario.KiPLL, scenario.KpPowerCtrl, scenario.KiPowerCtrl, scenario.KpCurrCtrl, scenario.KiCurrCtrl, scenario.OmegaCutoff);
pv->setControllerParameters(cmdScaleP*scenario.KpPLL, cmdScaleI*scenario.KiPLL, cmdScaleP*scenario.KpPowerCtrl, cmdScaleI*scenario.KiPowerCtrl, cmdScaleP*scenario.KpCurrCtrl, cmdScaleI*scenario.KiCurrCtrl, scenario.OmegaCutoff);
pv->setFilterParameters(scenario.Lf, scenario.Cf, scenario.Rf, scenario.Rc);
pv->setTransformerParameters(scenario.systemNominalVoltage, scenario.pvNominalVoltage, scenario.transformerNominalPower, scenario.systemNominalVoltage/scenario.pvNominalVoltage, 0, 0, scenario.transformerInductance, scenario.systemOmega);
pv->setInitialStateValues(scenario.pvNominalActivePower, scenario.pvNominalReactivePower, scenario.phi_dInit, scenario.phi_qInit, scenario.gamma_dInit, scenario.gamma_qInit);
......
%% Cell type:markdown id: tags:
# Testing control params
%% Cell type:markdown id: tags:
## Kp study
%% Cell type:code id: tags:
``` python
%%bash
TOP=${TOP:-$(git rev-parse --show-toplevel)}
PATH=${PATH}:${TOP}/build/Examples/Cxx
TIMESTEP=1e-3
DURATION=2.5
for SCALEKP in $(seq 0.01 0.02 0.1)
do
EMT_Slack_PiLine_VSI_with_PF_Init --name="EMT_Slack_PiLine_VSI_with_PF_Init_KP-${SCALEKP}" --option="scale_kp=${SCALEKP}" --timestep=${TIMESTEP} --duration=${DURATION}
done
```
%% Cell type:code id: tags:
``` python
from villas.dataprocessing.readtools import *
from villas.dataprocessing.timeseries import *
import matplotlib.pyplot as plt
import re
import numpy as np
# %matplotlib widget
PEAK1PH_TO_RMS3PH = np.sqrt(3.0/2.0)
scale_kp=np.round(np.arange(0.01,0.1,0.02),2)
```
%% Cell type:markdown id: tags:
## EMT results
%% Cell type:code id: tags:
``` python
ts_dpsim={}
for kp in scale_kp:
modelName = 'EMT_Slack_PiLine_VSI_with_PF_Init_KP-'+str(kp)+'_EMT'
path = 'logs/' + modelName + '/'
dpsim_result_file = path + modelName + '.csv'
ts_dpsim[str(kp)] = read_timeseries_csv(dpsim_result_file)
```
%% Cell type:markdown id: tags:
### States - Active Power
%% Cell type:code id: tags:
``` python
plt.figure(figsize=(12,6))
for kp in scale_kp:
ts_of_interest = ['pv_powerctrl_state_p']
for ts_name, ts_obj in ts_dpsim[str(kp)].items():
if ts_name in ts_of_interest:
plt.plot(ts_obj.time, ts_obj.values, label=ts_name+", kp="+str(kp))
# add references
ts_of_interest = ['pv_powerctrl_input_pref']
for ts_name, ts_obj in ts_dpsim[str(kp)].items():
if ts_name in ts_of_interest:
plt.plot(ts_obj.time, ts_obj.values, label=ts_name, linestyle=':')
plt.legend()
plt.show()
```
%% Cell type:markdown id: tags:
### States - Reactive Power
%% Cell type:code id: tags:
``` python
plt.figure(figsize=(12,6))
for kp in scale_kp:
ts_of_interest = ['pv_powerctrl_state_q']
for ts_name, ts_obj in ts_dpsim[str(kp)].items():
if ts_name in ts_of_interest:
plt.plot(ts_obj.time, ts_obj.values, label=ts_name+", kp="+str(kp))
# add references
ts_of_interest = ['pv_powerctrl_input_qref']
for ts_name, ts_obj in ts_dpsim[str(kp)].items():
if ts_name in ts_of_interest:
plt.plot(ts_obj.time, ts_obj.values, label=ts_name, linestyle=':')
plt.legend()
plt.show()
```
%% Cell type:markdown id: tags:
## Ki study
%% Cell type:code id: tags:
``` python
%%bash
TOP=${TOP:-$(git rev-parse --show-toplevel)}
PATH=${PATH}:${TOP}/build/Examples/Cxx
TIMESTEP=1e-3
DURATION=2.5
for SCALEKI in $(seq 0.1 0.2 2)
do
EMT_Slack_PiLine_VSI_with_PF_Init --name="EMT_Slack_PiLine_VSI_with_PF_Init_KI-${SCALEKI}" --option="scale_ki=${SCALEKI}" --timestep=${TIMESTEP} --duration=${DURATION}
done
```
%% Cell type:code id: tags:
``` python
from villas.dataprocessing.readtools import *
from villas.dataprocessing.timeseries import *
import matplotlib.pyplot as plt
import re
import numpy as np
%matplotlib widget
PEAK1PH_TO_RMS3PH = np.sqrt(3.0/2.0)
scale_ki=np.round(np.arange(0.1,2.1,0.2),1)
```
%% Cell type:markdown id: tags:
## EMT results
%% Cell type:code id: tags:
``` python
ts_dpsim={}
for ki in scale_ki:
modelName = 'EMT_Slack_PiLine_VSI_with_PF_Init_KI-'+str(ki)+'_EMT'
path = 'logs/' + modelName + '/'
dpsim_result_file = path + modelName + '.csv'
ts_dpsim[str(ki)] = read_timeseries_csv(dpsim_result_file)
```
%% Cell type:markdown id: tags:
### States - Active Power
%% Cell type:code id: tags:
``` python
plt.figure(figsize=(12,6))
for ki in scale_ki:
ts_of_interest = ['pv_powerctrl_state_p']
for ts_name, ts_obj in ts_dpsim[str(ki)].items():
if ts_name in ts_of_interest:
plt.plot(ts_obj.time, ts_obj.values, label=ts_name+", ki="+str(ki))
# add references
ts_of_interest = ['pv_powerctrl_input_pref']
for ts_name, ts_obj in ts_dpsim[str(ki)].items():
if ts_name in ts_of_interest:
plt.plot(ts_obj.time, ts_obj.values, label=ts_name, linestyle=':')
plt.legend()
plt.show()
```
%% Cell type:markdown id: tags:
### States - Reactive Power
%% Cell type:code id: tags:
``` python
plt.figure(figsize=(12,6))
for ki in scale_ki:
ts_of_interest = ['pv_powerctrl_state_q']
for ts_name, ts_obj in ts_dpsim[str(ki)].items():
if ts_name in ts_of_interest:
plt.plot(ts_obj.time, ts_obj.values, label=ts_name+", ki="+str(ki))
# add references
ts_of_interest = ['pv_powerctrl_input_qref']
for ts_name, ts_obj in ts_dpsim[str(ki)].items():
if ts_name in ts_of_interest:
plt.plot(ts_obj.time, ts_obj.values, label=ts_name, linestyle=':')
plt.legend()
plt.show()
```
%% Cell type:markdown id: tags:
## Final choice
%% Cell type:code id: tags:
``` python
%%bash
TOP=${TOP:-$(git rev-parse --show-toplevel)}
PATH=${PATH}:${TOP}/build/Examples/Cxx
TIMESTEP=4e-3
DURATION=5
SCALEKP=0.1
SCALEKI=1.0
EMT_Slack_PiLine_VSI_with_PF_Init --name="EMT_Slack_PiLine_VSI_with_PF_Init_KP_${SCALEKP}_KI_${SCALEKI}" --option="scale_kp=${SCALEKP}" --option="scale_ki=${SCALEKI}" --timestep=${TIMESTEP} --duration=${DURATION}
```
%% Cell type:code id: tags:
``` python
kp=0.1
ki=1.0
modelName = 'EMT_Slack_PiLine_VSI_with_PF_Init_KP_'+str(kp)+'_KI_'+str(ki)+'_EMT'
print(modelName)
path = 'logs/' + modelName + '/'
dpsim_result_file = path + modelName + '.csv'
ts_dpsim = read_timeseries_csv(dpsim_result_file)
```
%% Cell type:markdown id: tags:
### States - Active Power
%% Cell type:code id: tags:
``` python
plt.figure(figsize=(12,6))
ts_of_interest = ['pv_powerctrl_state_p']
for ts_name, ts_obj in ts_dpsim.items():
if ts_name in ts_of_interest:
plt.plot(ts_obj.time, ts_obj.values, label=ts_name+", kp="+str(kp)+", ki="+str(ki))
ts_of_interest = ['pv_powerctrl_input_pref']
for ts_name, ts_obj in ts_dpsim.items():
if ts_name in ts_of_interest:
plt.plot(ts_obj.time, ts_obj.values, label=ts_name, linestyle=':')
plt.legend()
plt.show()
```
%% Cell type:markdown id: tags:
### States - Reactive Power
%% Cell type:code id: tags:
``` python
plt.figure(figsize=(12,6))
ts_of_interest = ['pv_powerctrl_state_p']
for ts_name, ts_obj in ts_dpsim.items():
if ts_name in ts_of_interest:
plt.plot(ts_obj.time, ts_obj.values, label=ts_name+", kp="+str(kp)+", ki="+str(ki))
ts_of_interest = ['pv_powerctrl_input_qref']
for ts_name, ts_obj in ts_dpsim.items():
if ts_name in ts_of_interest:
plt.plot(ts_obj.time, ts_obj.values, label=ts_name, linestyle=':')
plt.legend()
plt.show()
```
%% Cell type:code id: tags:
``` python
```
......@@ -111,9 +111,9 @@ void DP::Ph1::AvVoltageSourceInverterDQ::setControllerParameters(Real Kp_pll, Re
Real Kp_powerCtrl, Real Ki_powerCtrl, Real Kp_currCtrl, Real Ki_currCtrl, Real Omega_cutoff) {
mSLog->info("Control Parameters:");
mSLog->info("PLL: K_i = {}, K_p = {}, Omega_Nom = {}", Kp_pll, Ki_pll, Omega_cutoff);
mSLog->info("Power Loop: K_i = {}, K_p = {}", Kp_powerCtrl, Ki_powerCtrl);
mSLog->info("Current Loop: K_i = {}, K_p = {}", Kp_currCtrl, Ki_currCtrl);
mSLog->info("PLL: K_p = {}, K_i = {}, Omega_Nom = {}", Kp_pll, Ki_pll, Omega_cutoff);
mSLog->info("Power Loop: K_p = {}, K_i = {}", Kp_powerCtrl, Ki_powerCtrl);
mSLog->info("Current Loop: K_p = {}, K_i = {}", Kp_currCtrl, Ki_currCtrl);
mSLog->info("Cut-Off Frequency = {}", Omega_cutoff);
// TODO: add and use Omega_nominal instead of Omega_cutoff
......
......@@ -112,9 +112,9 @@ void EMT::Ph3::AvVoltageSourceInverterDQ::setControllerParameters(Real Kp_pll, R
Real Kp_powerCtrl, Real Ki_powerCtrl, Real Kp_currCtrl, Real Ki_currCtrl, Real Omega_cutoff) {
mSLog->info("Control Parameters:");
mSLog->info("PLL: K_i = {}, K_p = {}, Omega_Nom = {}", Kp_pll, Ki_pll, Omega_cutoff);
mSLog->info("Power Loop: K_i = {}, K_p = {}", Kp_powerCtrl, Ki_powerCtrl);
mSLog->info("Current Loop: K_i = {}, K_p = {}", Kp_currCtrl, Ki_currCtrl);
mSLog->info("PLL: K_p = {}, K_i = {}, Omega_Nom = {}", Kp_pll, Ki_pll, Omega_cutoff);
mSLog->info("Power Loop: K_p = {}, K_i = {}", Kp_powerCtrl, Ki_powerCtrl);
mSLog->info("Current Loop: K_p = {}, K_i = {}", Kp_currCtrl, Ki_currCtrl);
mSLog->info("Cut-Off Frequency = {}", Omega_cutoff);
// TODO: add and use Omega_nominal instead of Omega_cutoff
......
Markdown is supported
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment