Step function in RL environment cannot call helper functions defined below. Where is my fault?
2 ビュー (過去 30 日間)
古いコメントを表示
Hey there everybody,
I'm currently working on a RL environment for my bachelor's thesis. I've started defining the environment and I'm continuously validating it. When it comes to calling helper functions ('getResistance' and 'ecms'), Matlab cannot find/call these functions that I defined in the optional methods section below.
Outputs are either "Cannot find an exact (case-sensitive) match for 'ecms'" or "Undefined function 'getResistance' for input arguments of type 'double'". Please note that I already exchanged the getResistance function call for the lines of code that are in the function's body.
The code below might help answering my question.
I am very thankful for an answer!
Max
classdef Environment < rl.env.MATLABEnvironment
%ENVIRONMENT: Template for defining custom environment in MATLAB.
%% Properties (set properties' attributes accordingly)
properties
dr1 = load('dr1');
dr2 = load('dr2');
t = 1;
cycle = zeros(6,10);
soc = rand(1,10);
% gear ratios
i_gear = [5.354, 3.243, 2.252, 1.636, 1.211, 1.000, 0.865, 0.717, 0.601]';
% final drive ratio
i_final = 3.07;
% mass factors
k_m = [1.32, 1.16, 1.11, 1.08, 1.07, 1.07, 1.07, 1.06, 1.06]';
% [W] e-motor power
P_e = 15000;
% rolling resistance coefficient
f_roll = 0.011;
% [kg] vehicle mass
m = 1625;
% [kg] additional mass
m_a = 0;
% [m/s^2] gravitational acceleration
g = 9.81;
% [kg/m^3] air density at 20°C
rho_air = 1.2;
% [m^2] air drag coefficient multiplied by face area
cda = 0.54;
% [m] wheel radius
r_wheel = 0.32;
% [W] Power of attachements
P_att = 800;
% drivetrain efficiency
eff_dt = 0.9;
% [J/kg] fuel lower heat value
H_f = 42.5e+6;
% [kg/J] reciprocal fuel lower heat value
e_ICE = 2.35294e-8;
% battery efficiency
eff_bat = 0.95;
% SOC list
soc_list = [0, 0.1, 0.2, 0.3, 0.4, 0.5, 0.6, 0.7, 0.8, 0.9, 1.0];
% [As] battery capacity
Q_b = 20*3600;
% [Ohm] internal resistance of battery
R_int = 0.334 / 20;
% [V] open circuit voltage at SOC from SOC list
V_oc = [37.78, 45.30, 46.01, 46.56, 46.94, 47.38, 48.00, 48.78, 49.68, 50.66, 51.74];
% reference SOC
SOC_ref = 0.55;
% minimal SOC
SOC_min = 0.3;
% maximal SOC
SOC_max = 0.8;
% [rad/s] ICE speed list (0.10472=2pi/60)
w_ICE_list = 0.10472*[1100, 1500, 2000, 2500, 3000, 3500, 4000, 4500, 5000, 5500, 6000, 6300];
% [Nm] ICE torque list
t_ICE_list = [0, 30, 50, 70, 90, 110, 130, 150, 170, 190, 210, 230, 250, 270, 290, 310, 330, 350];
% ICE efficiency map at w_ICE and t_ICE
eff_ICE_table = 0.01*[...
0.01 21.18 26.06 28.71 30.80 32.33 33.35 34.16 34.57 34.16 33.22 32.70 32.21 31.96 31.96 31.96 31.96 31.96
0.01 21.18 26.47 29.72 31.84 33.09 34.16 34.86 35.29 35.00 35.00 34.72 34.02 33.22 32.96 32.33 32.21 32.09
0.01 21.18 26.47 29.72 31.73 32.96 34.02 34.86 35.29 35.29 35.29 35.29 35.15 34.72 34.16 33.48 33.22 33.09
0.01 21.18 26.47 29.41 31.61 32.83 34.02 34.86 35.29 35.29 35.29 35.29 35.29 35.00 34.57 34.29 34.02 33.48
0.01 20.17 25.67 28.42 30.91 32.33 33.48 34.29 35.00 35.29 35.29 35.29 35.29 34.86 34.29 33.88 32.58 32.21
0.01 20.17 25.29 28.24 30.36 31.84 32.83 33.75 34.29 34.72 34.86 34.72 34.43 33.88 33.22 32.33 31.37 30.25
0.01 20.17 24.20 27.50 29.41 30.80 31.73 32.70 33.35 33.88 33.88 33.35 32.58 32.58 31.84 30.80 30.04 29.72
0.01 18.82 23.53 26.47 28.52 29.72 30.80 31.61 31.73 31.61 31.26 31.37 31.14 31.26 30.47 30.04 29.72 29.72
0.01 18.82 23.21 25.51 27.32 28.52 29.72 30.25 30.36 30.25 30.04 30.04 29.62 29.51 29.41 29.41 29.41 29.41
0.01 18.82 21.44 24.20 26.22 27.50 28.62 28.62 28.52 28.52 28.52 28.42 28.52 28.71 28.71 28.71 28.71 28.71
0.01 18.82 20.17 23.02 24.62 25.67 26.31 26.64 26.64 25.82 25.51 24.55 24.55 24.55 24.55 24.55 24.55 24.55
0.01 18.82 20.17 22.00 23.33 24.20 24.91 25.29 25.67 24.91 24.20 24.20 24.20 24.20 24.20 24.20 24.20 24.20];
% [kg/s] consumption rate map at w_ICE and t_ICE
consrate_ICE_table = cell2mat(struct2cell(load('consrate_ICE_table')));
% [rad/s] ICE drag speed list
w_ICE_drag_list = 0.10472*[0, 1000, 2000, 3000, 4000, 5000, 6000];
% [Nm] ICE drag torque list
t_ICE_drag_list = [6.3, 6.3, 8.4, 10.7, 13.1, 17.0, 20.7];
% [rad/s] e-motor speed list
w_em_list = 0.10472*[0, 500, 1000, 1500, 2000, 2500, 3000, 3500, 4000, 4500, 5000, 5500, 6000];
% [Nm] e-motor torque list
t_em_list = 15000 / 40000 *[-260, -230, -200, -170, -140, -110, -80, -50, -20, -11, -5, 0, 5, 10 ,20 ,50, 80, 110, 140, 170, 200, 230, 260];
% e-motor efficiency map at w_em and t_em
eff_em_table = 0.01*[...
0.01 0.01 0.01 0.01 0.01 0.01 0.01 0.01 0.01 0.01 0.01 50.0 50.0 50.0 50.0 50.0 50.0 50.0 50.0 50.0 50.0 50.0 50.0
0.01 10.0 25.0 40.0 62.0 73.6 80.0 85.0 85.0 80.0 70.0 50.0 70.0 80.0 85.0 86.0 82.5 78.7 74.6 71.6 68.8 66.4 64.8
70.0 73.2 77.0 80.0 83.5 86.5 89.4 91.5 90.0 85.0 70.0 50.0 70.0 82.0 90.0 91.6 90.0 87.5 85.5 83.1 81.1 78.8 76.4
80.4 82.2 84.5 86.4 88.3 90.3 91.7 93.0 90.0 83.0 70.0 50.0 70.0 82.0 90.0 92.9 92.3 91.2 89.5 87.5 86.3 85.0 84.0
84.5 86.1 87.8 89.5 91.1 92.7 94.0 94.2 92.0 87.0 70.0 50.0 70.0 85.0 91.2 94.0 93.1 92.2 90.9 59.5 88.0 88.0 88.0
89.5 89.5 89.5 91.0 92.4 93.8 94.5 94.7 93.0 89.0 70.0 50.0 70.0 85.0 91.0 93.4 93.1 92.2 91.0 90.0 90.0 90.0 90.0
91.5 91.5 91.5 91.5 92.8 94.1 94.8 95.3 93.0 88.0 70.0 50.0 70.0 84.0 90.5 93.1 92.8 92.1 91.0 91.0 91.0 91.0 91.0
92.8 92.8 92.8 92.8 92.8 94.1 95.0 95.7 92.7 87.0 70.0 50.0 70.0 82.0 90.0 92.7 92.4 91.8 91.8 91.8 91.8 91.8 91.8
92.6 92.6 92.6 92.6 92.6 93.8 94.7 95.3 92.0 85.0 70.0 50.0 70.0 81.0 89.0 92.2 92.0 91.0 91.0 91.0 91.0 91.0 91.0
93.2 93.2 93.2 93.2 93.2 93.2 94.3 94.7 92.0 85.0 70.0 50.0 70.0 80.0 87.5 91.6 91.0 91.0 91.0 91.0 91.0 91.0 91.0
93.0 93.0 93.0 93.0 93.0 93.0 94.0 94.4 90.4 82.0 70.0 50.0 70.0 80.0 86.5 91.0 90.5 90.5 90.5 90.5 90.5 90.5 90.5
93.5 93.5 93.5 93.5 93.5 93.5 93.5 93.8 90.0 82.0 70.0 50.0 70.0 78.0 85.6 90.3 90.0 90.0 90.0 90.0 90.0 90.0 90.0
92.8 92.8 92.8 92.8 92.8 92.8 92.8 93.0 90.0 80.0 70.0 50.0 70.0 75.0 85.0 88.0 88.0 88.0 88.0 88.0 88.0 88.0 88.0
];
end
properties
% Initialize system state [v, a, alpha, gear, soc]'
State = zeros(5,1)
end
properties(Access = protected)
% Initialize internal flag to indicate episode termination
IsDone = false
end
%% Necessary Methods
methods
% Contructor method creates an instance of the environment
% Change class name and constructor name accordingly
function this = Environment()
% Initialize Observation settings
ObservationInfo = rlNumericSpec([5 1]);
ObservationInfo.Name = 'Vehicle State';
ObservationInfo.Description = 'v, a, alpha, gear, soc';
% Initialize Action settings
ActionInfo = rlNumericSpec([2 1]);
ActionInfo.Name = 'Vehicle Action';
ActionInfo.Description = 'lambda, sigma';
% The following line implements built-in functions of RL env
this = this@rl.env.MATLABEnvironment(ObservationInfo,ActionInfo);
% Initialize property values and pre-compute necessary values
% updateActionInfo(this);
end
% Apply system dynamics and simulates the environment with the
% given action for one step.
function [Observation,Reward,IsDone,LoggedSignals] = step(this,Action)
LoggedSignals = [];
this.soc(1) = this.SOC_ref;
v = this.State(1);
a = this.State(2);
alpha = this.State(3);
gear = this.State(4);
soc = this.State(5);
% calculate driving resistance
F_air = 0.5 * this.rho_air * this.cda * v^2; % [N] air resistance
F_roll = this.f_roll * (this.m + this.m_a) * this.g * cos(alpha); % [N] rolling resistance
F_incl = (this.m + this.m_a) * this.g * sin(alpha); % [N] incline resistance
F_acc = (this.k_m(gear) * this.m + this.m_a) * a; % [N] required force for acceleration
F_w = F_air + F_roll + F_incl + F_acc; % [N] total driving resistance
w_wheel = v / this.r_wheel; % [rad/s] wheel speed
w_crank = w_wheel * this.i_gear(gear) * this.i_final; % [rad/s] crank speed
t_wheel = F_w * this.r_wheel; % [Nm] wheel torque
P_wheel = w_wheel * t_wheel;
P_crank = (P_wheel > 0) * P_wheel / this.eff_dt...
+ (P_wheel == 0) * 0 + ...
+ (P_wheel < 0) * P_wheel * this.eff_dt;
if w_crank > 0
t_crank = P_crank / w_crank; % [Nm] crank torque
else
t_crank = 0; % [Nm] crank torque
end
[t_em_opt, fuel_opt, w_ICE, t_ICE] = ecms(t_crank, w_crank, Action(1), Action(2), soc);
if this.t < length(this.cycle.v)
new_t = this.t + 1;
this.t = new_t;
IsDone = false;
elseif this.t == length(this.cycle.v)
IsDone = true;
end
v = this.cycle.v(this.t);
a = this.cycle.a(this.t);
alpha = this.cycle.alpha(this.t);
gear = this.cycle.gear(this.t);
this.soc(this.t) = soc ;
Observation = [v; a; alpha; gear; soc];
this.State = Observation;
end
% Reset environment to initial state and output initial observation
function [InitialObservation, t, cycle] = reset(this)
this.t = 1;
this.cycle = this.dr1.dr1.dr1_6;
v = this.cycle.v(1);
a = this.cycle.a(1);
alpha = this.cycle.alpha(1);
gear = this.cycle.gear(1);
soc = this.SOC_ref;
InitialObservation = [v; a; alpha; gear; soc];
this.State = InitialObservation;
this.t = 1;
% (optional) use notifyEnvUpdated to signal that the
% environment has been updated (e.g. to update visualization)
% notifyEnvUpdated(this);
end
end
%% Optional Methods (set methods' attributes accordingly)
methods (Access = public)
function [F_w, w_wheel, w_crank, t_crank] = getResistance(v, a, alpha, gear)
F_air = 0.5 * this.rho_air * this.cda * v^2; % [N] air resistance
F_roll = this.f_roll * (this.m + this.m_a) * this.g * cos(alpha); % [N] rolling resistance
F_incl = (this.m + this.m_a) * this.g * sin(alpha); % [N] incline resistance
F_acc = (this.k_m(gear) * this.m + this.m_a) * a; % [N] required force for acceleration
F_w = F_air + F_roll + F_incl + F_acc; % [N] total driving resistance
w_wheel = v / this.r_wheel; % [rad/s] wheel speed
w_crank = w_wheel * this.i_gear(gear) * this.i_final; % [rad/s] crank speed
t_wheel = F_w * this.r_wheel; % [Nm] wheel torque
P_wheel = w_wheel * t_wheel;
P_crank = (P_wheel > 0) * P_wheel / this.eff_dt...
+ (P_wheel == 0) * 0 + ...
+ (P_wheel < 0) * P_wheel * this.eff_dt;
if w_crank > 0
t_crank = P_crank / w_crank; % [Nm] crank torque
else
t_crank = 0; % [Nm] crank torque
end
end
function [t_em_opt, fuel_opt, w_ICE, t_ICE] = ecms(t_crank, w_crank, lambda, sigma, soc)
dt = 1; % [Nm] torque step
lambda = lambda; % equivalence factor
% [Nm] max e-motor torque (powering mode)
T_e_maxp = min(260, this.P_e/w_crank);
% [Nm] max e-motor torque (generating mode)
T_e_maxg = min(260, 1.25*this.P_e/w_crank);
% [Nm] ICE drag torque
t_ICE_drag = interp1(this.w_ICE_drag_list,this.t_ICE_drag_list,w_crank,'linear','extrap');
% [Nm] max ICE torque
if w_crank < 0.10472 * 1250
t_ICE_max = min(350-5.41*(0.10472*1250-w_crank), t_crank + T_e_maxg);
elseif w_crank >= 0.10472 * 1250 && w_crank < 0.10472 * 4000
t_ICE_max = min(350, t_crank + T_e_maxg);
else
t_ICE_max = min(350-0.54*(w_crank-0.10472*4000), t_crank + T_e_maxg);
end
% [Nm] min ICE torque
if t_crank < T_e_maxp - t_ICE_drag
t_ICE_min = 0;
elseif t_crank < T_e_maxp
t_ICE_min = 1;
else
t_ICE_min = t_crank - T_e_maxp;
end
% initialization: set first falue of fuel_opt to large number.
fuel_opt = 1; % [kg/s]
fuel_min = 1; % [kg/s]
t_em_opt = 0; % [Nm]
% modify engine speed to delivers power at min. 1100 rpm
% in case that w_crank < 1100 rpm, the clutch slips
w_ICE = max(0.10472*1100, w_crank);
%%% ECMS algorithm %%%
if w_crank == 0
fuel_opt = 0;
t_em_opt = 0;
elseif w_crank > 0 && w_crank < 115.192 && t_crank > 0 % vehicle launches
% slipping clutch launch (hybrid launch possible)
for t_ICE = t_ICE_min : dt : t_ICE_max % search for optimal ICE/EM ratio
if t_ICE == 0
t_em = t_crank + t_ICE_drag; % [Nm]
else
t_em = t_crank - t_ICE; % [Nm]
end
% [kg/s] current consumption rate
fuel_h = this.e_ICE * 115.192 * t_ICE / interp2(this.t_ICE_list, this.w_ICE_list, this.eff_ICE_table, t_ICE, 115.192) + ...
lambda * (t_em>=0) * 115.192 * t_em / interp2(this.t_em_list, this.w_em_list, this.eff_em_table, t_em, 115.192) + ...
lambda * (t_em <0) * 115.192 * t_em * interp2(this.t_em_list, this.w_em_list, this.eff_em_table, t_em, 115.192);
if fuel_h < fuel_min
fuel_min = fuel_h;
% [kg/s] optimal current consumption rate
fuel_opt = this.e_ICE * 115.192 * t_ICE / interp2(this.t_ICE_list, this.w_ICE_list, this.eff_ICE_table, t_ICE, 115.192);
% [Nm] optimal e-motor torque
t_em_opt = t_em;
end
end
% check feasibility of closed clutch launch (electric only launch)
t_em_l = t_crank + t_ICE_drag;
if t_ICE_min == 0 && t_em_l <= T_e_maxp
fuel_e = lambda * w_crank * t_em_l / interp2(this.t_em_list, this.w_em_list, this.eff_em_table, t_em_l, w_crank);
if fuel_e < fuel_min
fuel_opt = 0;
t_em_opt = t_em_l;
end
end
elseif w_crank > 0 && w_crank < 115.192 && t_crank <= 0 && t_crank > - T_e_maxg - t_ICE_drag %%% vehicle stops
% electric charge only
fuel_opt = 0;
t_em_opt = t_crank + t_ICE_drag;
elseif w_crank > 0 && w_crank < 115.192 && t_crank <= - T_e_maxg - t_ICE_drag
% electric charge only
fuel_opt = 0;
t_em_opt = - T_e_maxg;
elseif w_crank >= 115.192 && t_crank <= - T_e_maxg
% electric charge only
fuel_opt = 0;
t_em_opt = max((t_crank + t_ICE_drag),- T_e_maxg);
elseif w_crank >= 115.192 && t_crank > - T_e_maxg
% hybrid mode possible
for t_ICE = t_ICE_min : dt : t_ICE_max
if t_ICE == 0
t_em = t_crank + t_ICE_drag;
else
t_em = t_crank - t_ICE;
end
fuel_h = this.e_ICE * w_crank * t_ICE / interp2(this.t_ICE_list, this.w_ICE_list, this.eff_ICE_table, t_ICE, w_crank) + ...
ef_RL * (t_em>=0) * w_crank * t_em / interp2(this.t_em_list, this.w_em_list, this.eff_em_table, t_em, w_crank) + ...
ef_RL * (t_em <0) * w_crank * t_em * interp2(this.t_em_list, this.w_em_list, this.eff_em_table, t_em, w_crank);
if fuel_h < fuel_min
fuel_min = fuel_h;
fuel_opt = this.e_ICE * w_ICE * t_ICE / interp2(this.t_ICE_list, this.w_ICE_list, this.eff_ICE_table, t_ICE, w_ICE);
t_em_opt = t_em;
end
end
end
t_ICE = t_crank - t_em_opt;
end
function reward = getreward(sigma, w_ICE, t_ICE, delta_ess, last_ess, deltatorque, DeltaTorque, soc, P_batt_10)
% [kg] last second's fuel consumption of running engine
cons_run = sigma * w_ICE * t_ICE / (this.H_f * interp2(this.t_ICE_list, this.w_ICE_list, this.eff_ICE_table, t_ICE, w_ICE));
% [kg] fuel consumption for engine start (0.3g per start)
cons_start = (delta_ess==1) * 0.0003 * delta_ess;
% penalty for frequent engine starts/stops
startstop = (last_ess<=15) * (0.5 * abs(delta_ess) * cos(pi/15 * last_ess) + 0.5);
% penalty for large engine torque jumps (turbocharged engines)
icetorque = max(0, deltatorque/DeltaTorque - 0.5);
% penalty for difference from reference SOC (0.55)
battery_soc = (soc-0.55)^2/((0.8-soc)*(soc-0.3));
% penalty for large battery power
battery_power = max(0, rms(P_batt_10) - P_batt_max/2);
% total reward
C1 = 1;
C2 = 2;
C3 = 4;
C4 = 2/P_batt_max;
reward = cons_run + cons_start + C1*startstop + C2*icetorque + C3*battery_soc + C4*battery_power;
end
end
methods (Access = protected)
% (optional) update visualization everytime the environment is updated
% (notifyEnvUpdated is called)
function envUpdatedCallback(this)
end
end
end
0 件のコメント
回答 (0 件)
参考
カテゴリ
Help Center および File Exchange で Reinforcement Learning Toolbox についてさらに検索
Community Treasure Hunt
Find the treasures in MATLAB Central and discover how the community can help you!
Start Hunting!