Same error values are copied for different input parameters when using MATLAB Experiment Manager

2 visualizzazioni (ultimi 30 giorni)
I am trying to run the find gains for PID controller for a powertrain using genetic algorithm. In order to find optimal generations and populations of the genetic algorithm I run almost 1600 experminets in which the following parameters change. So, the input of the model is a WLTP drive cycle (1800s) long. I want to see if I train the Genetic Algorithm on only 30s and find the gains and then using those gains run the whole cycle to calculate the error.
But when I run the experiment I get the same error for all the 3 times with same population and generation combinantion:
However, when i check the simulink model the gains are different for each iteration which means the errors are somehow not updated in the table. I have tried different changes in the code but noting works. Here is the code, if someone could suggest some improvements:
function [mean_abs_error] = Experiment2Function1(params)
tend = params.time;
% Measure the current time before running the simulation
start_simulation_time = tic;
no_var = 2;
lb = [params.lbP params.lbI];
ub = [params.ubP params.ubI];
%GA options
ga_opt = optimoptions('ga','Display','off','Generations',params.generations,'PopulationSize',params.population,'PlotFcns',@gaplotbestf);
obj_fn = @(k) optimization_PID(k);
%GA Command
[k, best] = ga((obj_fn),no_var,[],[],[],[],lb,ub,[],ga_opt)
% Measure the simulation time
simulation_time = toc(start_simulation_time);
%%
% Calculate Error
tend = 1800;
sim("Model1.slx")
driveCycleTime = DriveCycle(:,1);
driveCycleSpeed = DriveCycle(:,2);
index1800s = driveCycleTime <= tend;
driveCycle1800s = [driveCycleTime(index1800s), driveCycleSpeed(index1800s)];
% Extract the simulated result for the first 1800 seconds
simulatedTime = tout(tout <= tend);
simulatedSpeed = v_act_lim(tout <= tend);
% Interpolate the simulated result to match the drive cycle time points
simulatedSpeedInterp = interp1(simulatedTime, simulatedSpeed, driveCycle1800s(:, 1), 'linear');
% Calculate and plot the error
error = (driveCycle1800s(:, 2) - simulatedSpeedInterp)./ driveCycle1800s(:,2)*100;
abs_error = abs(error);
% Exclude Infinite Values
validIndices = isfinite(abs_error);
validAbsError = abs_error(validIndices);
mean_abs_error = mean(validAbsError)
end
The objective function is as follows:
function cost = optimization_PID(k)
assignin("base", "k", k);
sim("Model1.slx");
itae_values = ITAE.Data;
cost = sum(itae_values);
end

Risposte (1)

Himanshu
Himanshu il 17 Lug 2024
Hey Muhammad,
The issue seems to be that the simulation results are not correctly captured and used for error calculations, which might be due to improper handling of workspace variables or incorrect assignment of simulation outputs. To address this, You need to ensure that variables are accurately assigned and retrieved from the base workspace, and that the simulation results are correctly captured and utilized. The approach involves careful management of the scope of variables and ensuring proper evaluation and assignment of simulation data.
In the optimization_PID function, I made the following change to ensure the ITAE values are fetched directly from the base workspace:
function cost = optimization_PID(k)
assignin("base", "k", k);
sim("Model1.slx");
itae_values = evalin("base", "ITAE.Data");
cost = sum(itae_values);
end
In the main experiment function, I used evalin to fetch simulation results, ensuring variables like DriveCycle, tout, and v_act_lim are accurately captured. This ensures that the interpolated simulated results match the drive cycle time points and that error values are validated to exclude infinite values:
function [mean_abs_error] = Experiment2Function1(params)
tend = params.time;
start_simulation_time = tic;
no_var = 2;
lb = [params.lbP params.lbI];
ub = [params.ubP params.ubI];
ga_opt = optimoptions('ga','Display','off','Generations',params.generations,'PopulationSize',params.population,'PlotFcns',@gaplotbestf);
obj_fn = @(k) optimization_PID(k);
[k, best] = ga((obj_fn),no_var,[],[],[],[],lb,ub,[],ga_opt)
simulation_time = toc(start_simulation_time);
tend = 1800;
sim("Model1.slx")
driveCycleTime = evalin("base", "DriveCycle(:,1)");
driveCycleSpeed = evalin("base", "DriveCycle(:,2)");
index1800s = driveCycleTime <= tend;
driveCycle1800s = [driveCycleTime(index1800s), driveCycleSpeed(index1800s)];
simulatedTime = evalin("base", "tout(tout <= tend)");
simulatedSpeed = evalin("base", "v_act_lim(tout <= tend)");
simulatedSpeedInterp = interp1(simulatedTime, simulatedSpeed, driveCycle1800s(:, 1), 'linear');
error = (driveCycle1800s(:, 2) - simulatedSpeedInterp)./ driveCycle1800s(:,2)*100;
abs_error = abs(error);
validIndices = isfinite(abs_error);
validAbsError = abs_error(validIndices);
mean_abs_error = mean(validAbsError)
end
Hope this helps!

Community Treasure Hunt

Find the treasures in MATLAB Central and discover how the community can help you!

Start Hunting!

Translated by