% experiment 1 Mamdani optimalizace vykresleni a ulozeni grafu
% Martin Radvansky 
% Diplomova prace 2022

%Nacteni a vyhodnoceni hodnot, zobrazeni RMSE pro Mamdani FIS optimalizace
%Optimalizace se provedly na prumernem modelu ze 7 mereni
%Generovani obrazku a sestaveni zpravy z optimalizace

%vstup: v podslozce Output_100 musi existovat soubory z optimalizace a to
%fis s nalezenym optimem a info.mat s informacemi o prubehu optimalizace
%ve slozce Data lezi zdrojova csv jedno pro vzdalenost od splien a
%jedno pro otoceni volantem.

%vystup: v podslozce Images budou vytvoreny obrazky a textovy soubor s
%podrobnostmi k prubehu optimalizace.

clc
clear
close all
clear global

cesta = ".\Output_100";
obrazkydir = ".\Images";
if (~exist(obrazkydir, 'dir'))
       mkdir(obrazkydir);
end
soubor_mfs = "tuned_fis_mfs_";
soubor_mfs_info = "tuned_info_mfs_";
soubor_rul = "tuned_fis_rules_";
soubor_rul_info = "tuned_info_rules_";

spline_vzdal = load('.\Data\Export_J1_Dist.csv');
spline_mean = mean(spline_vzdal);
wheel_angle = load('.\Data\Export_J1_Wheel.csv');
wheel_mean = mean(wheel_angle);

MyFolderInfo = dir(sprintf("%s\\*.fis",cesta));

%prochazime optimalizaci pravidly
RMSE_rules = [];
Num_rules = [];
RMSE_mfs = [];
Cas_Opti_rules = [];
Pocet_Fun_rules = [];
Cas_Opti_mfs = [];
Pocet_Fun_mfs = [];
for i = 1:100
  %pravidla
  model_rul = readfis(sprintf("%s\\%s%d.fis",cesta,soubor_rul,i));    
  tuned_info_rul = load(sprintf("%s\\%s%d.mat",cesta,soubor_rul_info,i));
  RMSE_rules(end+1) = tuned_info_rul.info.tuningOutputs.fval;
  Num_rules(end+1) = length(model_rul.Rules);
  Cas_Opti_rules(end+1) = tuned_info_rul.info.totalRuntime;
  Pocet_Fun_rules(end+1) = tuned_info_rul.info.totalFcnCount;
  
  %funkce prislusnosti
  model_mfs = readfis(sprintf("%s\\%s%d.fis",cesta,soubor_mfs,i));    
  tuned_info_mfs = load(sprintf("%s\\%s%d.mat",cesta,soubor_mfs_info,i));
  RMSE_mfs(end+1) = tuned_info_mfs.info.tuningOutputs.fval;
  Cas_Opti_mfs(end+1) = tuned_info_mfs.info.totalRuntime;
  Pocet_Fun_mfs(end+1) = tuned_info_mfs.info.totalFcnCount;

end
figure(1);
plot(RMSE_rules*900);
figure(2);
plot(RMSE_mfs*900);

vstup_bp=[RMSE_rules*900;RMSE_mfs*900]
vstup_gr=[repmat({'rules'},length(RMSE_rules),1);repmat({'mfs'},length(RMSE_mfs),1)]

%Zobrazeni boxplotu pro nejlepsi RMSE ze vsech populaci *******************
figure(1);
boxplot(RMSE_rules*900,'Labels',{'Pravidla'});
title('Mamdani optimalizace');
ylabel('RMSE [{\circ}]');
saveas(gcf,sprintf("%s\\opti_mam_rul_bp.png",obrazkydir))

figure(2);
boxplot(RMSE_mfs*900,'Labels',{'Funkce příslušnosti'});
title('Mamdani optimalizace')
ylabel('RMSE [{\circ}]');
saveas(gcf,sprintf("%s\\opti_mam_prisl_bp.png",obrazkydir))

% *************************************************************************

%Nejlepsi a nejhorsi RMSE jejich index
minRMSE_rul = min(RMSE_rules*900);
maxRMSE_rul = max(RMSE_rules*900);
minRMSE_mfs = min(RMSE_mfs*900);
maxRMSE_mfs = max(RMSE_mfs*900);

ix_minRMSE_rul = find(RMSE_rules*900 == minRMSE_rul);
ix_maxRMSE_rul = find(RMSE_rules*900 == maxRMSE_rul);

ix_minRMSE_mfs = find(RMSE_mfs*900 == minRMSE_mfs);
ix_maxRMSE_mfs = find(RMSE_mfs*900 == maxRMSE_mfs);

%ploty optimalizaovane rules
%min RMSE nejlepsi
fis_opti_rules = readfis(sprintf("%s\\%s%d.fis",cesta,soubor_rul,ix_minRMSE_rul(1)));  
vystup_eval = evalfis(fis_opti_rules,spline_mean);
 plot(1:length(spline_mean),wheel_mean*900,'LineWidth',1.4); % prumer
    grid on;
    hold on;
    plot(1:length(spline_mean),vystup_eval*900,'LineWidth',1.4);
    title('Natočení volantu v čase, nejlepší RMSE');
    xlabel('Čas [Vzorek x 20 ms]');
    ylabel('Úhel natočení volantu [{\circ}]');
    legend('Original','Fuzzy model','Location','southeast');
    hold off; 
saveas(gcf,sprintf("%s\\mam_best_rules_t.png",obrazkydir));

%prevodni charakteristika
plot(spline_mean,wheel_mean*900,'LineWidth',1.4);
    grid on;
    hold on;
    plot(spline_mean,vystup_eval*900,'LineWidth',1.4);
    title('Závislost úhlu natočení volantu na vzdálenosti od spline');
    xlabel('Vzdálenost od spline [m]');
    ylabel('Úhel natočení volantu [{\circ}]');
    legend('Original','Fuzzy model','Location','southeast');
    hold off;
saveas(gcf,sprintf("%s\\mam_best_rules_prev.png",obrazkydir));

%max RMSE nejhorsi
fis_opti_rules = readfis(sprintf("%s\\%s%d.fis",cesta,soubor_rul,ix_maxRMSE_rul(1)));  
vystup_eval = evalfis(fis_opti_rules,spline_mean);
 plot(1:length(spline_mean),wheel_mean*900,'LineWidth',1.4); % prumer
    grid on;
    hold on;
    plot(1:length(spline_mean),vystup_eval*900,'LineWidth',1.4);
    title('Natočení volantu v čase, nejhorší RMSE');
    xlabel('Čas [Vzorek x 20 ms]');
    ylabel('Úhel natočení volantu [{\circ}]');
    legend('Original','Fuzzy model','Location','southeast');
    hold off; 
saveas(gcf,sprintf("%s\\mam_worst_rules_t.png",obrazkydir));
    
%prevodni charakteristika
plot(spline_mean,wheel_mean*900,'LineWidth',1.4);
    grid on;
    hold on;
    plot(spline_mean,vystup_eval*900,'LineWidth',1.4);
    title('Závislost úhlu natočení volantu na vzdálenosti od spline');
    xlabel('Vzdálenost od spline [m]');
    ylabel('Úhel natočení volantu [{\circ}]');
    legend('Original','Fuzzy model','Location','southeast');
    hold off;
saveas(gcf,sprintf("%s\\mam_worst_rules_prev.png",obrazkydir));
    
%Mamdani optimalizace funkci prislusnosti ********************************
%min RMSE nejlepsi
fis_opti_mfs = readfis(sprintf("%s\\%s%d.fis",cesta,soubor_mfs,ix_minRMSE_mfs(1)));  
vystup_eval = evalfis(fis_opti_mfs,spline_mean);
 plot(1:length(spline_mean),wheel_mean*900,'LineWidth',1.4); % prumer
    grid on;
    hold on;
    plot(1:length(spline_mean),vystup_eval*900,'LineWidth',1.4);
    title('Natočení volantu v čase, nejlepší RMSE');
    xlabel('Čas [Vzorek x 20 ms]');
    ylabel('Úhel natočení volantu [{\circ}]');
    legend('Original','Fuzzy model','Location','southeast');
    hold off; 
saveas(gcf,sprintf("%s\\mam_best_mfs_t.png",obrazkydir));

%prevodni charakteristika
plot(spline_mean,wheel_mean*900,'LineWidth',1.4);
    grid on;
    hold on;
    plot(spline_mean,vystup_eval*900,'LineWidth',1.4);
    title('Závislost úhlu natočení volantu na vzdálenosti od spline');
    xlabel('Vzdálenost od spline [m]');
    ylabel('Úhel natočení volantu [{\circ}]');
    legend('Original','Fuzzy model','Location','southeast');
    hold off;
saveas(gcf,sprintf("%s\\mam_best_mfs_prev.png",obrazkydir));

%ulozime obrazky funkci prislusnosti pro nejlepsi vysledek
vykresli_mfs_mamdani(fis_opti_mfs,sprintf("%s\\mam_best_mfs_input.png",obrazkydir),sprintf("%s\\mam_best_mfs_output.png",obrazkydir))

%max RMSE nejhorsi
fis_opti_mfs = readfis(sprintf("%s\\%s%d.fis",cesta,soubor_mfs,ix_maxRMSE_mfs(1)));  
vystup_eval = evalfis(fis_opti_mfs,spline_mean);
 plot(1:length(spline_mean),wheel_mean*900,'LineWidth',1.4); % prumer
    grid on;
    hold on;
    plot(1:length(spline_mean),vystup_eval*900,'LineWidth',1.4);
    title('Natočení volantu v čase, nejhorší RMSE');
    xlabel('Čas [Vzorek x 20 ms]');
    ylabel('Úhel natočení volantu [{\circ}]');
    legend('Original','Fuzzy model','Location','southeast');
    hold off; 
saveas(gcf,sprintf("%s\\mam_worst_mfs_t.png",obrazkydir));
    
%prevodni charakteristika
plot(spline_mean,wheel_mean*900,'LineWidth',1.4);
    grid on;
    hold on;
    plot(spline_mean,vystup_eval*900,'LineWidth',1.4);
    title('Závislost úhlu natočení volantu na vzdálenosti od spline');
    xlabel('Vzdálenost od spline [m]');
    ylabel('Úhel natočení volantu [{\circ}]');
    legend('Original','Fuzzy model','Location','southeast');
    hold off;
saveas(gcf,sprintf("%s\\mam_worst_mfs_prev.png",obrazkydir));    
    
%Zapis RMSE hodnot do textoveho souboru
fid=fopen(sprintf("%s\\mamdani_Gen_RMSE.txt",obrazkydir),'w');
fprintf(fid, sprintf("Optimalizace Rules RMSE min: %f \n",minRMSE_rul));
fprintf(fid, sprintf("Optimalizace Rules RMSE max: %f \n",maxRMSE_rul));
fprintf(fid, sprintf("Optimalizace Prumerna doba jedne generace (s): %f \n",mean(Cas_Opti_rules)));
fprintf(fid, sprintf("Optimalizace Prumerny pocet volani fitness funkci: %f \n",mean(Pocet_Fun_rules)));

fprintf(fid, sprintf("Optimalizace Funkci příslusnosti RMSE min: %f \n",minRMSE_mfs));
fprintf(fid, sprintf("Optimalizace Funkci příslušnosti RMSE min: %f \n",maxRMSE_mfs));
fprintf(fid, sprintf("Optimalizace Prumerna doba jedne generace (s): %f \n",mean(Cas_Opti_mfs)));
fprintf(fid, sprintf("Optimalizace Prumerny pocet volani fitness funkci: %f \n",mean(Pocet_Fun_mfs)));

%nejlepsi pravidla
min_fis_opti_rules = readfis(sprintf("%s\\%s%d.fis",cesta,soubor_rul,ix_minRMSE_rul(1)));
min_fis_opti_rules_info = load(sprintf("%s\\%s%d.mat",cesta,soubor_rul_info,ix_minRMSE_rul(1)));
fprintf(fid, "\nNejlepsi RMSE pravidla: \n");
for i = 1:length(min_fis_opti_rules.Rules)
    fprintf(fid, sprintf("%d.  %s\n",i,min_fis_opti_rules.Rules(1,i).Description));
end

%nejhorsi pravidla
max_fis_opti_rules = readfis(sprintf("%s\\%s%d.fis",cesta,soubor_rul,ix_maxRMSE_rul(1)));
max_fis_opti_rules_info = load(sprintf("%s\\%s%d.mat",cesta,soubor_rul_info,ix_maxRMSE_rul(1)));
fprintf(fid, "\nNejhorsi RMSE pravidla: \n");
for i = 1:length(max_fis_opti_rules.Rules)
    fprintf(fid, sprintf("%d.  %s\n",i,max_fis_opti_rules.Rules(1,i).Description));
end
fclose(fid);