MATLAB code for fuzzy logic based battery scheduling for 24 hours in microgrid to minimize cost and grid dependency
15 views (last 30 days)
Show older comments
% Define input variables
time = [1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24];
solar_power = [0 0 0 0 0 0 0 0.008 0.15 0.301 0.418 0.478 0.956 0.842 0.315 0.169 0.022 0 0 0 0 0 0 0];
wind_power = [0.119 0.119 0.119 0.119 0.119 0.061 0.119 0.087 0.119 0.206 0.585 0.694 0.261 0.158 0.119 0.087 0.119 0.119 0.087 0.119 0.087 0.087 0.061 0.041];
microturbine_power = [6.0024 6 6.0065 6.0118 6.0024 6 6 6 6 6 6 6 6 6 6 6.006 6 6 6 6 6.0034 6.0036 6 6];
battery_soc = zeros(1, 24); % Initialize with zeros for 24 hours
power_demand = [52 50 50 51 56 53 70 75 76 80 78 74 72 72 76 80 85 88 90 87 78 71 65 56];
price_electricity = [0.23 0.19 0.14 0.12 0.12 0.20 0.23 0.38 1.50 4 4 4 1.5 4 2 1.95 0.6 0.41 0.35 0.43 1.17 0.54 0.30 0.26];
% Define input membership functions
fis = addInput(fis, 'input', 'BatterySoC', [0 100]);
fis = addMf(fis, 'input', 1, 'Low', 'gaussmf', [20 0]);
fis = addMf(fis, 'input', 2, 'Medium', 'gaussmf', [15 50]);
fis = addMf(fis, 'input', 3, 'High', 'gaussmf', [15 100]);
fis = addInput(fis, 'input', 'PowerDemand', [0 100]);
fis = addMf(fis, 'input', 1, 'Low', 'gaussmf', [15 0]);
fis = addMf(fis, 'input', 2, 'Medium', 'gaussmf', [15 50]);
fis = addMf(fis, 'input', 3, 'High', 'gaussmf', [15 100]);
fis = addInput(fis, 'input', 'PriceElectricity', [0 4]);
fis = addMf(fis, 'input', 1, 'Low', 'gaussmf', [0.2 0]);
fis = addMf(fis, 'input', 2, 'Medium', 'gaussmf', [0.2 2]);
fis = addMf(fis, 'input', 3, 'High', 'gaussmf', [0.2 4]);
fis = addInput(fis, 'input', 'SolarPower', [0 1]);
fis = addMf(fis, 'input', 1, 'Low', 'gaussmf', [0.2 0]);
fis = addMf(fis, 'input', 2, 'Medium', 'gaussmf', [0.2 0.5]);
fis = addMf(fis, 'input', 3, 'High', 'gaussmf', [0.2 1]);
fis = addInput(fis, 'input', 'WindPower', [0 1]);
fis = addMf(fis, 'input', 1, 'Low', 'gaussmf', [0.2 0]);
fis = addMf(fis, 'input', 2, 'Medium', 'gaussmf', [0.2 0.5]);
fis = addMf(fis, 'input', 3, 'High', 'gaussmf', [0.2 1]);
fis = addInput(fis, 'input', 'MicroturbinePower', [0 6.5]);
fis = addMf(fis, 'input', 1, 'Low', 'gaussmf', [0 2]);
fis = addMf(fis, 'input', 2, 'Medium', 'gaussmf', [1 3.5]);
fis = addMf(fis, 'input', 3, 'High', 'gaussmf', [3 6.5]);
% Define output membership functions
fis = addInput(fis, 'output', 'BatteryPower', [-5 5]);
fis = addMf(fis, 'output', 1, 'Discharge', 'gaussmf', [0.5 -5]);
fis = addMf(fis, 'output', 2, 'NoChange', 'gaussmf', [0.5 0]);
fis = addMf(fis, 'output', 3, 'Charge', 'gaussmf', [0.5 5]);
% Define rules
ruleList = [
FLrules
0 0 0 0 0
0 0 0 0 1
0 0 0 0 2
0 0 0 1 0
0 0 0 1 1
0 0 0 1 2
0 0 0 2 0
0 0 0 2 1
0 0 0 2 2
0 0 1 0 0
0 0 1 0 1
0 0 1 0 2
0 0 1 1 0
0 0 1 1 1
0 0 1 1 2
0 0 1 2 0
0 0 1 2 1
0 0 1 2 2
0 0 2 0 0
0 0 2 0 1
0 0 2 0 2
0 0 2 1 0
0 0 2 1 1
0 0 2 1 2
0 0 2 2 0
0 0 2 2 1
0 0 2 2 2
0 1 0 0 0
0 1 0 0 1
0 1 0 0 2
0 1 0 1 0
0 1 0 1 1
0 1 0 1 2
0 1 0 2 0
0 1 0 2 1
0 1 0 2 2
0 1 1 0 0
0 1 1 0 1
0 1 1 0 2
0 1 1 1 0
0 1 1 1 1
0 1 1 1 2
0 1 1 2 0
0 1 1 2 1
0 1 1 2 2
0 1 2 0 0
0 1 2 0 1
0 1 2 0 2
0 1 2 1 0
0 1 2 1 1
0 1 2 1 2
0 1 2 2 0
0 1 2 2 1
0 1 2 2 2
0 2 0 0 0
0 2 0 0 1
0 2 0 0 2
0 2 0 1 0
0 2 0 1 1
0 2 0 1 2
0 2 0 2 0
0 2 0 2 1
0 2 0 2 2
0 2 1 0 0
0 2 1 0 1
0 2 1 0 2
0 2 1 1 0
0 2 1 1 1
0 2 1 1 2
0 2 1 2 0
0 2 1 2 1
0 2 1 2 2
0 2 2 0 0
0 2 2 0 1
0 2 2 0 2
0 2 2 1 0
0 2 2 1 1
0 2 2 1 2
0 2 2 2 0
0 2 2 2 1
0 2 2 2 2
1 0 0 0 0
1 0 0 0 1
1 0 0 0 2
1 0 0 1 0
1 0 0 1 1
1 0 0 1 2
1 0 0 2 0
1 0 0 2 1
1 0 0 2 2
1 0 1 0 0
1 0 1 0 1
1 0 1 0 2
1 0 1 1 0
1 0 1 1 1
1 0 1 1 2
1 0 1 2 0
1 0 1 2 1
1 0 1 2 2
1 0 2 0 0
1 0 2 0 1
1 0 2 0 2
1 0 2 1 0
1 0 2 1 1
1 0 2 1 2
1 0 2 2 0
1 0 2 2 1
1 0 2 2 2
1 1 0 0 0
1 1 0 0 1
1 1 0 0 2
1 1 0 1 0
1 1 0 1 1
1 1 0 1 2
1 1 0 2 0
1 1 0 2 1
1 1 0 2 2
1 1 1 0 0
1 1 1 0 1
1 1 1 0 2
1 1 1 1 0
1 1 1 1 1
1 1 1 1 2
1 1 1 2 0
1 1 1 2 1
1 1 1 2 2
1 1 2 0 0
1 1 2 0 1
1 1 2 0 2
1 1 2 1 0
1 1 2 1 1
1 1 2 1 2
1 1 2 2 0
1 1 2 2 1
1 1 2 2 2
1 2 0 0 0
1 2 0 0 1
1 2 0 0 2
1 2 0 1 0
1 2 0 1 1
1 2 0 1 2
1 2 0 2 0
1 2 0 2 1
1 2 0 2 2
1 2 1 0 0
1 2 1 0 1
1 2 1 0 2
1 2 1 1 0
1 2 1 1 1
1 2 1 1 2
1 2 1 2 0
1 2 1 2 1
1 2 1 2 2
1 2 2 0 0
1 2 2 0 1
1 2 2 0 2
1 2 2 1 0
1 2 2 1 1
1 2 2 1 2
1 2 2 2 0
1 2 2 2 1
1 2 2 2 2
2 0 0 0 0
2 0 0 0 1
2 0 0 0 2
2 0 0 1 0
2 0 0 1 1
2 0 0 1 2
2 0 0 2 0
2 0 0 2 1
2 0 0 2 2
2 0 1 0 0
2 0 1 0 1
2 0 1 0 2
2 0 1 1 0
2 0 1 1 1
2 0 1 1 2
2 0 1 2 0
2 0 1 2 1
2 0 1 2 2
2 0 2 0 0
2 0 2 0 1
2 0 2 0 2
2 0 2 1 0
2 0 2 1 1
2 0 2 1 2
2 0 2 2 0
2 0 2 2 1
2 0 2 2 2
2 1 0 0 0
2 1 0 0 1
2 1 0 0 2
2 1 0 1 0
2 1 0 1 1
2 1 0 1 2
2 1 0 2 0
2 1 0 2 1
2 1 0 2 2
2 1 1 0 0
2 1 1 0 1
2 1 1 0 2
2 1 1 1 0
2 1 1 1 1
2 1 1 1 2
2 1 1 2 0
2 1 1 2 1
2 1 1 2 2
2 1 2 0 0
2 1 2 0 1
2 1 2 0 2
2 1 2 1 0
2 1 2 1 1
2 1 2 1 2
2 1 2 2 0
2 1 2 2 1
2 1 2 2 2
2 2 0 0 0
2 2 0 0 1
2 2 0 0 2
2 2 0 1 0
2 2 0 1 1
2 2 0 1 2
2 2 0 2 0
2 2 0 2 1
2 2 0 2 2
2 2 1 0 0
2 2 1 0 1
2 2 1 0 2
2 2 1 1 0
2 2 1 1 1
2 2 1 1 2
2 2 1 2 0
2 2 1 2 1
2 2 1 2 2
2 2 2 0 0
2 2 2 0 1
2 2 2 0 2
2 2 2 1 0
2 2 2 1 1
2 2 2 1 2
2 2 2 2 0
2 2 2 2 1
2 2 2 2 2
];
fis = addrule(fis, ruleList);
% Initialize variables
battery_capacity = 30; % kWh
battery_soc(1) = 100; % Initial state of charge in percentage
% Fuzzy inference for each hour
for hour = 1:24
input = [
battery_soc(hour), ...
power_demand(hour), ...
price_electricity(hour), ...
solar_power(hour), ...
wind_power(hour), ...
microturbine_power(hour)
];
% Perform fuzzy inference
output = evalfis(input, fis);
% Update battery state of charge
if output < 0
% Discharging
battery_soc(hour + 1) = battery_soc(hour) + output / battery_capacity * 100;
elseif output > 0
% Charging
battery_soc(hour + 1) = battery_soc(hour) + output / battery_capacity * 100;
else
% No change
battery_soc(hour + 1) = battery_soc(hour);
end
% Ensure battery SoC stays within [0, 100] range
battery_soc(hour + 1) = max(0, min(100, battery_soc(hour + 1)));
% Display results
fprintf('Hour %d: Battery SoC = %.2f%%, Battery Power = %.2f kW\n', hour, battery_soc(hour), output);
if output > 0
fprintf('Battery is charging with %.2f kW\n', output);
elseif output < 0
fprintf('Battery is discharging with %.2f kW\n', -output);
else
fprintf('Battery is neither charging nor discharging\n');
end
end
Accepted Answer
Sam Chak
on 19 Sep 2023
Edited: Sam Chak
on 20 Sep 2023
Hi @REENA
There are many syntax errors because the name and behavior of some functions in Fuzzy Logic Toolbox have changed since R2018b version. I corrected some. Perhaps you can follow up, and post the revised code here again, so that I can check.
% Define input variables
time = [1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24];
solar_power = [0 0 0 0 0 0 0 0.008 0.15 0.301 0.418 0.478 0.956 0.842 0.315 0.169 0.022 0 0 0 0 0 0 0];
wind_power = [0.119 0.119 0.119 0.119 0.119 0.061 0.119 0.087 0.119 0.206 0.585 0.694 0.261 0.158 0.119 0.087 0.119 0.119 0.087 0.119 0.087 0.087 0.061 0.041];
microturbine_power = [6.0024 6 6.0065 6.0118 6.0024 6 6 6 6 6 6 6 6 6 6 6.006 6 6 6 6 6.0034 6.0036 6 6];
battery_soc = zeros(1, 24); % Initialize with zeros for 24 hours
power_demand = [52 50 50 51 56 53 70 75 76 80 78 74 72 72 76 80 85 88 90 87 78 71 65 56];
price_electricity = [0.23 0.19 0.14 0.12 0.12 0.20 0.23 0.38 1.50 4 4 4 1.5 4 2 1.95 0.6 0.41 0.35 0.43 1.17 0.54 0.30 0.26];
% Create a Mamdani fuzzy inference system
fis = mamfis('Name', "Fuzzy_BatterySoC_Ctrl"); % <-- this line was missing previously
% Define input membership functions
fis = addInput(fis, [0 100], 'Name', 'BatterySoC');
fis = addMF(fis, 'BatterySoC', 'gaussmf', [20 0], 'Name', 'Low');
fis = addMF(fis, 'BatterySoC', 'gaussmf', [15 50], 'Name', 'Medium');
fis = addMF(fis, 'BatterySoC', 'gaussmf', [15 100], 'Name', 'High');
fis = addInput(fis, [0 100], 'Name', 'PowerDemand');
fis = addMF(fis, 'PowerDemand', 'gaussmf', [15 0], 'Name', 'Low');
fis = addMF(fis, 'PowerDemand', 'gaussmf', [15 50], 'Name', 'Medium');
fis = addMF(fis, 'PowerDemand', 'gaussmf', [15 100], 'Name', 'High');
fis = addInput(fis, [0 4], 'Name', 'PriceElectricity');
fis = addMF(fis, 'PriceElectricity', 'gaussmf', [0.2 0], 'Name', 'Low');
fis = addMF(fis, 'PriceElectricity', 'gaussmf', [0.2 2], 'Name', 'Medium');
fis = addMF(fis, 'PriceElectricity', 'gaussmf', [0.2 4], 'Name', 'High');
fis = addInput(fis, [0 1], 'Name', 'SolarPower');
fis = addMF(fis, 'SolarPower', 'gaussmf', [0.2 0.0], 'Name', 'Low');
fis = addMF(fis, 'SolarPower', 'gaussmf', [0.2 0.5], 'Name', 'Medium');
fis = addMF(fis, 'SolarPower', 'gaussmf', [0.2 1.0], 'Name', 'High');
fis = addInput(fis, [0 1], 'Name', 'WindPower');
fis = addMF(fis, 'WindPower', 'gaussmf', [0.2 0.0], 'Name', 'Low');
fis = addMF(fis, 'WindPower', 'gaussmf', [0.2 0.5], 'Name', 'Medium');
fis = addMF(fis, 'WindPower', 'gaussmf', [0.2 1.0], 'Name', 'High');
fis = addInput(fis, [0 6.5], 'Name', 'MicroturbinePower');
fis = addMF(fis, 'MicroturbinePower', 'gaussmf', [1 2.0], 'Name', 'Low'); % check sigma
fis = addMF(fis, 'MicroturbinePower', 'gaussmf', [1 3.5], 'Name', 'Medium');
fis = addMF(fis, 'MicroturbinePower', 'gaussmf', [3 6.5], 'Name', 'High');
figure(1)
TL = tiledlayout(3, 2);
nexttile()
plotmf(fis, 'input', 1)
nexttile()
plotmf(fis, 'input', 2)
nexttile()
plotmf(fis, 'input', 3)
nexttile()
plotmf(fis, 'input', 4)
nexttile()
plotmf(fis, 'input', 5)
nexttile()
plotmf(fis, 'input', 6)
title(TL, 'Input MFs of Fuzzy Battery Variables')
% Define output membership functions
fis = addOutput(fis, [-5 5], 'Name', 'BatteryPower');
fis = addMF(fis, 'BatteryPower', 'gaussmf', [0.5 -5], 'Name', 'Discharge');
fis = addMF(fis, 'BatteryPower', 'gaussmf', [0.5 0], 'Name', 'NoChange');
fis = addMF(fis, 'BatteryPower', 'gaussmf', [0.5 5], 'Name', 'Charge');
figure(2)
plotmf(fis, 'output', 1), grid on
title('Output MFs of BatteryPower')
13 Comments
Sam Chak
on 24 Sep 2023
The designs of some membership functions (MFs) over the universe of discourse of each fuzzy variable sometimes result in no rules being fired for the Output (Battery Action) in certain situations. This leads to the defuzzified output value being set to its mean range value of 0.5. I have run some tests in the code below. You can see the eight situations that result in a "No rules fired for Output 1" warning. The MFs should be designed to cover the entire universe of discourse of each fuzzy variable.
If you can explain why the MFs are designed this way, perhaps I can guide you, although I am not a Battery Expert.
% Define input variables
% time = [1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24];
SP = [0 0 0 0 0 0 0 0.008 0.15 0.301 0.418 0.478 0.956 0.842 0.315 0.169 0.022 0 0 0 0 0 0 0];
WP = [0.119 0.119 0.119 0.119 0.119 0.061 0.119 0.087 0.119 0.206 0.585 0.694 0.261 0.158 0.119 0.087 0.119 0.119 0.087 0.119 0.087 0.087 0.061 0.041];
MTP = [36.0024 36 36.0065 36.0118 36.0024 36 36 36 36 36 36 36 36 36 36 36.006 36 36 36 36 36.0034 36.0036 36 36];
BSoC = zeros(1, 24); % Initialize with zeros for 24 hours
PD = [52 50 50 51 56 53 70 75 76 80 78 74 72 72 76 80 85 88 90 87 78 71 65 56];
Pgen = [36.12 36.12 36.13 36.13 36.12 36.06 36.12 36.09 36.27 36.51 37.00 37.17 37.22 37.00 36.43 36.26 36.14 36.12 36.09 36.12 36.09 36.09 36.06 36.04];
% EP = [0.23 0.19 0.14 0.12 0.12 0.20 0.23 0.38 1.50 4 4 4 1.5 4 2 1.95 0.6 0.41 0.35 0.43 1.17 0.54 0.30 0.26];
% Pgen = SP + WP + MTP;
% Output = Pgen - power_demand;
% Create a Mamdani fuzzy inference system
fis = mamfis('Name', "Fuzzy_BatteryAction");
% Define membership functions for 3 Fuzzy input variables
fis = addInput(fis, [0 100], 'Name', 'BSoC');
fis = addMF(fis, 'BSoC', 'trimf', [ 0 20 30], 'Name', 'Low');
fis = addMF(fis, 'BSoC', 'trimf', [20 50 80], 'Name', 'Medium');
fis = addMF(fis, 'BSoC', 'trimf', [70 85 100], 'Name', 'High');
fis = addInput(fis, [50 100], 'Name', 'PD');
fis = addMF(fis, 'PD', 'trimf', [50 60 70], 'Name', 'Low');
fis = addMF(fis, 'PD', 'trimf', [65 75 85], 'Name', 'Medium');
fis = addMF(fis, 'PD', 'trimf', [80 90 100], 'Name', 'High');
fis = addInput(fis, [35 40], 'Name', 'Pgen');
fis = addMF(fis, 'Pgen', 'trimf', [35 35.5 36], 'Name', 'Low');
fis = addMF(fis, 'Pgen', 'trimf', [36 36.5 37], 'Name', 'Medium');
fis = addMF(fis, 'Pgen', 'trimf', [37 38 39], 'Name', 'High');
figure(1)
TL = tiledlayout(3, 1);
nexttile()
plotmf(fis, 'input', 1), grid on, ylabel('\mu')
nexttile()
plotmf(fis, 'input', 2), grid on, ylabel('\mu')
nexttile()
plotmf(fis, 'input', 3), grid on, ylabel('\mu')
title(TL, 'Input MFs of Battery Variables')
% Define membership functions for 1 Fuzzy output variable
fis = addOutput(fis, [0 1], 'Name', 'BatteryAction');
fis = addMF(fis, 'BatteryAction', 'trimf', [0 0.3 0.6], 'Name', 'Charge');
fis = addMF(fis, 'BatteryAction', 'trimf', [0.4 0.7 0.9], 'Name', 'Discharge');
fis = addMF(fis, 'BatteryAction', 'trimf', [0.8 0.9 1.0], 'Name', 'Float');
figure(2)
plotmf(fis, 'output', 1), grid on
title('Output MFs of Battery Action')
% Define 27 rules
ruleList = [
1 1 1 3 1 1
2 1 1 2 1 1
3 1 1 2 1 1
1 2 1 3 1 1
2 2 1 2 1 1
3 2 1 2 1 1
1 3 1 3 1 1
2 3 1 2 1 1
3 3 1 2 1 1
1 1 2 1 1 1
2 1 2 1 1 1
3 1 2 3 1 1
1 2 2 3 1 1
2 2 2 2 1 1
3 2 2 2 1 1
1 3 2 3 1 1
2 3 2 2 1 1
3 3 2 2 1 1
1 1 3 1 1 1
2 1 3 2 1 1
3 1 3 2 1 1
1 2 3 1 1 1
2 2 3 2 1 1
3 2 3 2 1 1
1 3 3 1 1 1
2 3 3 2 1 1
3 3 3 2 1 1];
fis = addRule(fis, ruleList);
% Check if each rule is fired over the universe of discourse of each fuzzy variable
ruleview(fis)
%% Running some tests
% Test 0: Mean of universe of discourse
out0 = evalfis(fis, [50 75 37.5])
% Test 1: Left extreme of universe of discourse of BSoC
out1 = evalfis(fis, [0 75 37.5])
% Test 2: Right extreme of universe of discourse of BSoC
out2 = evalfis(fis, [100 75 37.5])
% Test 3: Left extreme of universe of discourse of PD
out3 = evalfis(fis, [50 50 37.5])
% Test 4: Right extreme of universe of discourse of PD
out4 = evalfis(fis, [50 100 37.5])
% Test 5: Left extreme of universe of discourse of Pgen
out5 = evalfis(fis, [50 75 35])
% Test 6: When Pgen = 36
out6 = evalfis(fis, [50 75 36])
% Test 7: When Pgen = 37
out7 = evalfis(fis, [50 75 37])
% Test 8: Right extreme of universe of discourse of Pgen (39 < Pgen < 40)
out8 = evalfis(fis, [50 75 40])
%% ----- User-supplied Data -----
% Initialize variables
battery_capacity = 30; % kW
BSoC(1) = 100; % Initial state of charge of the battery in percentage
% Fuzzy inference for each hour
for hour = 1:24
input = [
BSoC(hour), ...
PD(hour), ...
Pgen(hour), ...
]
% Perform fuzzy inference
output = evalfis(fis, input)
% Update battery state of charge
if output < 0
% Discharging
BSoC(hour + 1) = BSoC(hour) + output / battery_capacity * 100;
elseif output > 0
% Charging
BSoC(hour + 1) = BSoC(hour) + output / battery_capacity * 100;
else
% No change
BSoC(hour + 1) = BSoC(hour);
end
% Ensure battery SoC stays within [20, 80] range
BSoC(hour + 1) = max(20, min(80, BSoC(hour + 1)));
% Display results
fprintf('Hour %d: Battery SoC = %.2f, Battery Power = %.2f \n', hour, BSoC(hour), output);
if output > 0
fprintf('Battery is charging with %.2f kW\n', output);
elseif output < 0
fprintf('Battery is discharging with %.2f kW\n', -output);
else
fprintf('Battery is neither charging nor discharging\n');
end
end
More Answers (1)
Sam Chak
on 24 Sep 2023
Hi @REENA
I can fix the warning message in the fuzzy system. Could you please interpret the meaning of the output values for me? Do they make sense to you? If they don't, then you may need to reshape the membership functions (MFs) of the output.
% Define input variables
% time = [1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24];
SP = [0 0 0 0 0 0 0 0.008 0.15 0.301 0.418 0.478 0.956 0.842 0.315 0.169 0.022 0 0 0 0 0 0 0];
WP = [0.119 0.119 0.119 0.119 0.119 0.061 0.119 0.087 0.119 0.206 0.585 0.694 0.261 0.158 0.119 0.087 0.119 0.119 0.087 0.119 0.087 0.087 0.061 0.041];
MTP = [36.0024 36 36.0065 36.0118 36.0024 36 36 36 36 36 36 36 36 36 36 36.006 36 36 36 36 36.0034 36.0036 36 36];
BSoC = zeros(1, 24); % Initialize with zeros for 24 hours
PD = [52 50 50 51 56 53 70 75 76 80 78 74 72 72 76 80 85 88 90 87 78 71 65 56];
Pgen = [36.12 36.12 36.13 36.13 36.12 36.06 36.12 36.09 36.27 36.51 37.00 37.17 37.22 37.00 36.43 36.26 36.14 36.12 36.09 36.12 36.09 36.09 36.06 36.04];
% EP = [0.23 0.19 0.14 0.12 0.12 0.20 0.23 0.38 1.50 4 4 4 1.5 4 2 1.95 0.6 0.41 0.35 0.43 1.17 0.54 0.30 0.26];
% Pgen = SP + WP + MTP;
% Output = Pgen - power_demand;
% Create a Mamdani fuzzy inference system
fis = mamfis('Name', "Fuzzy_BatteryAction");
% Define membership functions for 3 Fuzzy input variables
fis = addInput(fis, [0 100], 'Name', 'BSoC');
fis = addMF(fis, 'BSoC', 'linzmf', [20 30], 'Name', 'Low');
fis = addMF(fis, 'BSoC', 'trimf', [20 50 80], 'Name', 'Medium');
fis = addMF(fis, 'BSoC', 'linsmf', [70 85], 'Name', 'High');
fis = addInput(fis, [50 100], 'Name', 'PD');
fis = addMF(fis, 'PD', 'linzmf', [60 70], 'Name', 'Low');
fis = addMF(fis, 'PD', 'trimf', [65 75 85], 'Name', 'Medium');
fis = addMF(fis, 'PD', 'linsmf', [80 90], 'Name', 'High');
fis = addInput(fis, [35 40], 'Name', 'Pgen');
fis = addMF(fis, 'Pgen', 'linzmf', [35.5 36], 'Name', 'Low');
fis = addMF(fis, 'Pgen', 'trimf', [35.5 36.5 37.5], 'Name', 'Medium');
fis = addMF(fis, 'Pgen', 'linsmf', [37 38], 'Name', 'High');
figure(1)
TL = tiledlayout(3, 1);
nexttile()
plotmf(fis, 'input', 1), grid on, ylabel('\mu')
nexttile()
plotmf(fis, 'input', 2), grid on, ylabel('\mu')
nexttile()
plotmf(fis, 'input', 3), grid on, ylabel('\mu')
title(TL, 'Input MFs of Battery Variables')
% Define membership functions for 1 Fuzzy output variable
fis = addOutput(fis, [0 1], 'Name', 'BatteryAction');
fis = addMF(fis, 'BatteryAction', 'trimf', [0 0.3 0.6], 'Name', 'Charge');
fis = addMF(fis, 'BatteryAction', 'trimf', [0.4 0.7 0.9], 'Name', 'Discharge');
fis = addMF(fis, 'BatteryAction', 'trimf', [0.8 0.9 1.0], 'Name', 'Float');
figure(2)
plotmf(fis, 'output', 1), grid on
title('Output MFs of Battery Action')
% Define 27 rules
ruleList = [
1 1 1 3 1 1
2 1 1 2 1 1
3 1 1 2 1 1
1 2 1 3 1 1
2 2 1 2 1 1
3 2 1 2 1 1
1 3 1 3 1 1
2 3 1 2 1 1
3 3 1 2 1 1
1 1 2 1 1 1
2 1 2 1 1 1
3 1 2 3 1 1
1 2 2 3 1 1
2 2 2 2 1 1
3 2 2 2 1 1
1 3 2 3 1 1
2 3 2 2 1 1
3 3 2 2 1 1
1 1 3 1 1 1
2 1 3 2 1 1
3 1 3 2 1 1
1 2 3 1 1 1
2 2 3 2 1 1
3 2 3 2 1 1
1 3 3 1 1 1
2 3 3 2 1 1
3 3 3 2 1 1];
fis = addRule(fis, ruleList);
% Check if each rule is fired over the universe of discourse of each fuzzy variable
ruleview(fis)
%% ----- User-supplied Data -----
% Initialize variables
battery_capacity = 30; % kW
BSoC(1) = 100; % Initial state of charge of the battery in percentage
% Fuzzy inference for each hour
for hour = 1:24
input = [
BSoC(hour), ...
PD(hour), ...
Pgen(hour), ...
]
% Perform fuzzy inference
output = evalfis(fis, input)
% Update battery state of charge
if output < 0
% Discharging
BSoC(hour + 1) = BSoC(hour) + output / battery_capacity * 100;
elseif output > 0
% Charging
BSoC(hour + 1) = BSoC(hour) + output / battery_capacity * 100;
else
% No change
BSoC(hour + 1) = BSoC(hour);
end
% Ensure battery SoC stays within [20, 80] range
BSoC(hour + 1) = max(20, min(80, BSoC(hour + 1)));
% Display results
fprintf('Hour %d: Battery SoC = %.2f, Battery Power = %.2f \n', hour, BSoC(hour), output);
if output > 0
fprintf('Battery is charging with %.2f kW\n', output);
elseif output < 0
fprintf('Battery is discharging with %.2f kW\n', -output);
else
fprintf('Battery is neither charging nor discharging\n');
end
end
3 Comments
Sam Chak
on 25 Sep 2023
Hi @REENA
Advice: When adding code to your comment, please click the Code icon and insert the MATLAB code in the grey field. Afterward, hit the Run icon . Also, display the plots (using plotmf() and ruleview()) as I did in the corrected code. This will enable me to easily track the changes you have made.
Request: As a battery researcher, I assume you have a good understanding of Battery State of Charge, Power Demand, Power Generation, and Battery Action. However, I would appreciate it if you could explain what they are and how the three inputs allow you to manually determine the Battery Action (output). At this point, I'm not concerned with Fuzzy Logic but rather seeking to understand how the system should work from a Battery Expert's perspective, not a Fuzzy Expert's.
See Also
Categories
Find more on Fuzzy Inference System Modeling in Help Center and File Exchange
Products
Community Treasure Hunt
Find the treasures in MATLAB Central and discover how the community can help you!
Start Hunting!