I want to implement a Controller which has an electrical OnePort. The controller should regulates the voltage of the input, to get the maximum power input. The current of the input is constant as long as the voltage is kept under a specific value. If the voltage gets higher than this value, the current is exponentially decreasing. This (voltage-)value is unknown and should be iteratively discovered by the controller by incrementing the voltage, measuring the power and comparing it to the previously measured power.
How can I implement that in OpenModelica?
I tried the following code. I set the Vstart(start = 30)
.
algorithm
Vpv := Vstart;
if P_pv_current > (P_pv_prev + dPthreshold) then
P_pv_prev := P_pv_current;
if increase then
Vstart := Vstart + stepSize;
else
Vstart := Vstart - stepSize;
end if;
elseif P_pv_current < (P_pv_prev-dPthreshold) then
P_pv_prev := P_pv_current;
increase := not increase;
if increase then
Vstart := Vstart + stepSize;
else
Vstart := Vstart - stepSize;
end if;
end if;
Vpv := Vstart;
equation
v1 = Vpv;
i1 = Ipv;
P_pv_current = Vpv * Ipv;
It seems like while simulating it jumps into the if
1 time but after that not anymore. So at the simulation Vpv, Vstart have the value 30.01 and the P_pv_current = P_pv_prev.
I want to implement a Controller which has an electrical OnePort. The controller should regulates the voltage of the input, to get the maximum power input. The current of the input is constant as long as the voltage is kept under a specific value. If the voltage gets higher than this value, the current is exponentially decreasing. This (voltage-)value is unknown and should be iteratively discovered by the controller by incrementing the voltage, measuring the power and comparing it to the previously measured power.
How can I implement that in OpenModelica?
I tried the following code. I set the Vstart(start = 30)
.
algorithm
Vpv := Vstart;
if P_pv_current > (P_pv_prev + dPthreshold) then
P_pv_prev := P_pv_current;
if increase then
Vstart := Vstart + stepSize;
else
Vstart := Vstart - stepSize;
end if;
elseif P_pv_current < (P_pv_prev-dPthreshold) then
P_pv_prev := P_pv_current;
increase := not increase;
if increase then
Vstart := Vstart + stepSize;
else
Vstart := Vstart - stepSize;
end if;
end if;
Vpv := Vstart;
equation
v1 = Vpv;
i1 = Ipv;
P_pv_current = Vpv * Ipv;
It seems like while simulating it jumps into the if
1 time but after that not anymore. So at the simulation Vpv, Vstart have the value 30.01 and the P_pv_current = P_pv_prev.
The solution is that I need to implement a when sample(starttime, timesteps) then
because Openmodelica does not do it on its own.
It would help with a complete model, but it is clear that the model code has an algorithm with an if-statement of the kind:
algorithm
if a>f(b) then
b:=...
...
That is rarely correct in models in Modelica.
Instead you should use when-statements - the difference is that it is only triggered when true - and otherwise keep the value of variables. To make it clearer I would also use pre(b) giving something like:
when P_pv_current > (pre(P_pv_prev) + dPthreshold) then
P_pv_prev = P_pv_current;
if increase then
Vstart = pre(Vstart) + stepSize;
else
Vstart = pre(Vstart) - stepSize;
end if;
elsewhen P_pv_current < (pre(P_pv_prev)-dPthreshold) then
P_pv_prev = P_pv_current;
increase = not pre(increase);
if increase then
Vstart = pre(Vstart) + stepSize;
else
Vstart = pre(Vstart) - stepSize;
end if;
end when;
Vpv = Vstart;
You could have it as an algorithm, but it very rare that an algorithm is needed in model code in Modelica.
PhotoVoltaics.Components.Blocks.MPTrackerSample
could be of interest... – Markus A. Commented Jan 20 at 7:37