classdef EnvironmentBasis_080222 < rl.env.MATLABEnvironment %ENVIRONMENTBASIS: Template for defining custom environment in MATLAB. %% Properties (set properties' attributes accordingly) properties % Specify and initialize environment's necessary properties % Wirkungsgrad der Batterie eta = 0.89; % Be- und Entladeleistung des stationären Soeichers in KW Batt_P = 0.7070 % Kapazität des stationären Speichers in kWh Batt_cap = 5.5305; % Peakleistung PV kW PV_Peak = 10 % %% Festlegung der grenzen zur diskretisierung der Observations % % Erzeugung/Last % load_PV_high = 0.7; % load_PV_low = 0.3; % % % Speicherbeladung; % batt_high = 0.7; % batt_low = 0.3; % % % Strombezugskosten/Einspeisevergütung; % Price_Compense_high = 0.7; % Price_Compense_low = 0.3; %% Arrays mit PV-Einspeisung/Last/Strompreis/Einspeisevergütung/Faktor zur Anpassung von Strompreis und Einspeisevergütung % Aktuell (08.02) konnte noch keine Option identifiziert werden, um die % Zeitreihen unmittelbar aus einer in den Workspace geladenen % Tabelle/Array/arrays zu laden. Problem: Schreibt man die Arrays in voller % länge ins Skript, ist Arbeiten nicht mehr möglich. PV_gen_time = [0 0 0 0] Load_time = [0.582600000000000 0.419400000000000 0.335850000000000 0.306750000000000]; Price_time = [0.240000000000000 0.240000000000000 0.240000000000000 0.240000000000000 ]; Compense_time = [0.0600000000000000 0.0600000000000000 0.0600000000000000 0.0600000000000000]; Faktor_time= [0.537794026189909 0.600676543477868 0.631428982947892 0.679497180270848]; end properties % Initialize system state [eta; Batt_P; Batt_cap; PV_Peak]' State = zeros(4,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 = EnvironmentBasis_080222() % Initialize Observation settings % ObservationInfo = rlFiniteSetSpec({[1 1 1],[1 1 2],[1 1 3],[1 2 1] [1 2 2],[1 2 3],[1 3 1],[1 3 2],[1 3 3],[2 1 1],[2 1 2],[2 1 3],[2 2 1],[2 2 2],[2 2 3],[2 3 1],[2 3 2], [2 3 3],[3 1 1],[3 1 2],[3 1 3],[3 2 1],[3 2 2],[3 2 3],[3 3 1],[3 3 2],[3 3 3]}); ObservationInfo = rlNumericSpec([4 1]); ObservationInfo.Name = 'Observation'; ObservationInfo.Description = ['load_PV_obs, b' ... 'att_obs, Price_Compense_obs', 'timestemp']; % Initialize Action settings ActionInfo = rlFiniteSetSpec([10 11 20 21 30 31 40 41 42 50 51 60 61 70 71 72]); ActionInfo.Name = 'Betriebsmodus'; % The following line implements built-in functions of RL env this = this@rl.env.MATLABEnvironment(ObservationInfo,ActionInfo); end % Apply system dynamics and simulates the environment with the % given action for one step. function [Observation,Reward,IsDone,LoggedSignals] = step(this,Action) LoggedSignals = []; t = this.State(4); % Werte aus Zeitreihen load = this.Load_time(t); % Last in kWh PV_gen = this.PV_gen_time(t); % PV Erzeugung in kWh % in diesem ersten Beispiel sind der Strompreis und die EEG-Vergütung % Konstant actual_price = this.Price_time(t); actual_compense = this.Compense_time(t); % Es wird eine sehr gute (optimale) Prognose angenommen. Daher werden % an den Agent die Lasten, PV-Einspeisung, Strompreise und Vergütungen % für die folge Stunde (für welche die Entschiedungen getroffen werden) % weiter gegeben load_obs = this.Load_time(t+1); PV_gen_obs = this.PV_gen_time(t+1); actual_price_obs = this.Price_time(t+1); actual_compens_obs = this.Compense_time(t+1); Batt_stor = this.State(3)*this.Batt_cap; % Algorithmen für die Betriebsmodi % Modus 1.0 if Action ==10 %% Lastdeckung durch PV % PV_load = min(pv_gen,load); % Lastdeckung durch PV, für den Algorithmus erstmal unbedeutend... load_PV = max(load-PV_gen,0); % Verbleibende Last nach Lastdeckung durch PV PV_left = max(PV_gen-load,0); % Verbleibende PV Leistung nach Lastdeckung %% Lastdeckung durch den Speicher Batt_out = min([this.Batt_P Batt_stor load_PV]); % Lastdeckung durch Batterie Batt_stor = Batt_stor - Batt_out; % Beladung nach der Lastdeckung durch Batterie load_batt = load_PV - Batt_out; % Verbleibende Last nach Lastdeckung durch Batterie %% Lastdeckung durch Netzbezug reward_grid_load = -load_batt*actual_price + 0; % reward für den Netzbezug Grid_load = load_batt; % Lastdeckung durch Netzbezug % load = 0; %% Beladen der Batterie mit PV-Strom temp1 = Batt_stor+(PV_left*this.eta); % Summe aus Speicherfbeladung vor der Beladung und dem Produkt aus Wirkungsgrad und verfügbarem PV-Strom temp2 = Batt_stor+this.Batt_P; % Summe aus Speicherbeladung vor der Beladung und der Maximalen Beladeleistung temp3 = PV_left*this.eta; temp4 = this.Batt_cap-Batt_stor; batt_in = min([temp3 this.Batt_P temp4]); % Beladung im Zeitschritt Batt_stor = min([this.Batt_cap temp1 temp2]); % Speicherbeladung nach der Beladung PV_left = PV_left-(batt_in/this.eta); % Verbleibender PV-Strom nach Batteriebeladung %% Einspeisung PV-Strom ins Netz reward_grid_PV = PV_left*actual_compense; % Reward für den Netzbezug % PV_grid = PV_left; % ins Netz eingespeister PV-Strom reward_Batt_load = 0; reward_Grid_batt = 0; % Modus 1.1 elseif Action == 11 %% Lastdeckung durch PV % PV_load = min(pv_gen,load); % Lastdeckung durch PV load_PV = max(load-PV_gen,0); % Verbleibende Last nach Lastdeckung durch PV PV_left = max(PV_gen-load,0); % Verbleibende PV Leistung nach Lastdeckung %% Lastdeckung durch den Speicher Batt_out = min([this.Batt_P Batt_stor load_PV]); % Lastdeckung durch Batterie Batt_stor = Batt_stor - Batt_out; % Beladung nach der Lastdeckung durch Batterie load_batt = load_PV - Batt_out; % Verbleibende Last nach Lastdeckung durch Batterie %% Lastdeckung durch Netzbezug reward_grid_load = -load_batt*actual_price + 0; % reward für den Netzbezug % Grid_load = load_batt; % Lastdeckung durch Netzbezug % load = 0; %% Beladen der Batterie mit PV-Strom temp1 = Batt_stor+(PV_left*this.eta); % Summe aus Speicherfbeladung vor der Beladung und dem Produkt aus Wirkungsgrad und verfügbarem PV-Strom temp2 = Batt_stor+this.Batt_P; % Summe aus Speicherbeladung vor der Beladung und der Maximalen Beladeleistung temp3 = PV_left*this.eta; temp4 = this.Batt_cap-Batt_stor; batt_in = min([temp3 this.Batt_P temp4]); % Beladung im Zeitschritt Batt_stor = min([this.Batt_cap temp1 temp2]); % Speicherbeladung nach der Beladung PV_left = PV_left-(batt_in/this.eta); % Verbleibender PV-Strom nach Batteriebeladung %% Einspeisung PV-Strom ins Netz reward_grid_PV = PV_left*actual_compense; % Reward für den Netzbezug % PV_grid = PV_left; % ins Netz eingespeister PV-Strom temp1 = this.Batt_P-Batt_out-batt_in; temp2 = this.Batt_cap - Batt_stor; Batt_grid = min([temp1 temp2]); Batt_stor = Batt_stor+(this.eta*Batt_grid); reward_Batt_load = -Batt_grid*actual_price; reward_Grid_batt = 0; % Modus 2.0 elseif Action ==20 %% Lastdeckung durch PV % PV_load = min(PV_gen,load); % Lastdeckung durch PV load_PV = max(load-PV_gen,0); % Verbleibende Last nach Lastdeckung durch PV PV_left = max(PV_gen-load,0); % Verbleibende PV Leistung nach Lastdeckung %% Lastdeckung durch den Speicher Batt_out = min([this.Batt_P Batt_stor load_PV]); % Lastdeckung durch Batterie Batt_stor = Batt_stor - Batt_out; % Beladung nach der Lastdeckung durch Batterie load_batt = load_PV - Batt_out; % Verbleibende Last nach Lastdeckung durch Batterie %% Lastdeckung durch Netzbezug reward_grid_load = -load_batt*actual_price + 0; % reward für den Netzbezug % Grid_load = load_batt; % Lastdeckung durch Netzbezug % load = 0; %% Einspeisung PV-Strom ins Netz reward_grid_PV = PV_left*actual_compense; % Reward für den Netzbezug % PV_grid = PV_left; % ins Netz eingespeister PV-Strom reward_Batt_load = 0; reward_Grid_batt = 0; % Modus 2.1 elseif Action ==21 %% Lastdeckung durch PV % PV_load = min(PV_gen,load); % Lastdeckung durch PV load_PV = max(load-PV_gen,0); % Verbleibende Last nach Lastdeckung durch PV PV_left = max(PV_gen-load,0); % Verbleibende PV Leistung nach Lastdeckung %% Lastdeckung durch den Speicher Batt_out = min([this.Batt_P Batt_stor load_PV]); % Lastdeckung durch Batterie Batt_stor = Batt_stor - Batt_out; % Beladung nach der Lastdeckung durch Batterie load_batt = load_PV - Batt_out; % Verbleibende Last nach Lastdeckung durch Batterie %% Lastdeckung durch Netzbezug reward_grid_load = -load_batt*actual_price + 0; % reward für den Netzbezug % Grid_load = load_batt; % Lastdeckung durch Netzbezug % load = 0; %% Einspeisung PV-Strom ins Netz reward_grid_PV = PV_left*actual_compense; % Reward für den Netzbezug % PV_grid = PV_left; % ins Netz eingespeister PV-Strom temp1 = this.Batt_P-Batt_out; temp2 = Batt_stor; Grid_batt = min([temp1 temp2]); Batt_stor = Batt_stor - Grid_batt; reward_Grid_batt = Grid_batt*actual_compense; reward_Batt_load = 0; % Modus 3.0 elseif Action == 30 %% Lastdeckung durch PV % PV_load = min(PV_gen,load); % Lastdeckung durch PV load_PV = max(load-PV_gen,0); % Verbleibende Last nach Lastdeckung durch PV PV_left = max(PV_gen-load,0); % Verbleibende PV Leistung nach Lastdeckung %% Lastdeckung durch Netzbezug reward_grid_load = -load_PV*actual_price + 0; % reward für den Netzbezug % Grid_load = load_PV; % Lastdeckung durch Netzbezug % load = 0; %% Beladen der Batterie mit PV-Strom temp1 = Batt_stor+(PV_left*this.eta); % Summe aus Speicherfbeladung vor der Beladung und dem Produkt aus Wirkungsgrad und verfügbarem PV-Strom temp2 = Batt_stor+this.Batt_P; % Summe aus Speicherbeladung vor der Beladung und der Maximalen Beladeleistung batt_in = min([PV_left*this.eta this.Batt_P (this.Batt_cap-Batt_stor)]); % Beladung im Zeitschritt Batt_stor = min([this.Batt_cap temp1 temp2]); % Speicherbeladung nach der Beladung PV_left = PV_left-(batt_in/this.eta); % Verbleibender PV-Strom nach Batteriebeladung %% Einspeisung PV-Strom ins Netz reward_grid_PV = PV_left*actual_compense; % Reward für den Netzbezug % PV_grid = PV_left; % ins Netz eingespeister PV-Strom reward_Batt_load = 0; reward_Grid_batt = 0; % Modus 3.1 elseif Action == 31 %% Lastdeckung durch PV % PV_load = min(PV_gen,load); % Lastdeckung durch PV load_PV = max(load-PV_gen,0); % Verbleibende Last nach Lastdeckung durch PV PV_left = max(PV_gen-load,0); % Verbleibende PV Leistung nach Lastdeckung %% Lastdeckung durch Netzbezug reward_grid_load = -load_PV*actual_price + 0; % reward für den Netzbezug % Grid_load = load_PV; % Lastdeckung durch Netzbezug % load = 0; %% Beladen der Batterie mit PV-Strom temp1 = Batt_stor+(PV_left*this.eta); % Summe aus Speicherfbeladung vor der Beladung und dem Produkt aus Wirkungsgrad und verfügbarem PV-Strom temp2 = Batt_stor+this.Batt_P; % Summe aus Speicherbeladung vor der Beladung und der Maximalen Beladeleistung batt_in = min([PV_left*this.eta this.Batt_P (this.Batt_cap-Batt_stor)]); % Beladung im Zeitschritt Batt_stor = min([this.Batt_cap temp1 temp2]); % Speicherbeladung nach der Beladung PV_left = PV_left-(batt_in/this.eta); % Verbleibender PV-Strom nach Batteriebeladung %% Einspeisung PV-Strom ins Netz reward_grid_PV = PV_left*actual_compense; % Reward für den Netzbezug % PV_grid = PV_left; % ins Netz eingespeister PV-Strom temp1 = this.Batt_P-batt_in; temp2 = this.Batt_cap - Batt_stor; Batt_grid = min([temp1 temp2]); Batt_stor = Batt_stor+(this.eta*Batt_grid); reward_Batt_load = -Batt_grid*actual_price; reward_Grid_batt = 0; % Modus 4.0 elseif Action == 40 %% Lastdeckung durch PV % PV_load = min(PV_gen,load); % Lastdeckung durch PV load_PV = max(load-PV_gen,0); % Verbleibende Last nach Lastdeckung durch PV PV_left = max(PV_gen-load,0); % Verbleibende PV Leistung nach Lastdeckung %% Lastdeckung durch Netzbezug reward_grid_load = -load_PV*actual_price + 0; % reward für den Netzbezug % Grid_load = load_PV; % Lastdeckung durch Netzbezug % load = 0; %% Einspeisung PV-Strom ins Netz reward_grid_PV = PV_left*actual_compense; % Reward für den Netzbezug % PV_grid = PV_left; % ins Neempz eingespeisemper PV-Strom reward_Batt_load = 0; reward_Grid_batt = 0; % Modus 4.1 elseif Action == 41 %% Lastdeckung durch PV % PV_load = min(PV_gen,load); % Lastdeckung durch PV load_PV = max(load-PV_gen,0); % Verbleibende Last nach Lastdeckung durch PV PV_left = max(PV_gen-load,0); % Verbleibende PV Leistung nach Lastdeckung %% Lastdeckung durch Netzbezug reward_grid_load = -load_PV*actual_price + 0; % reward für den Netzbezug % Grid_load = load_PV; % Lastdeckung durch Netzbezug % load = 0; %% Einspeisung PV-Strom ins Netz reward_grid_PV = PV_left*actual_compense; % Reward für den Netzbezug % PV_grid = PV_left; % ins Neempz eingespeisemper PV-Strom temp1 = this.Batt_P; temp2 = this.Batt_cap - Batt_stor; Batt_grid = min([temp1 temp2]); Batt_stor = Batt_stor+(this.eta*Batt_grid); reward_Batt_load = -Batt_grid*actual_price; reward_Grid_batt = 0; % Modus 4.2 elseif Action == 42 %% Lastdeckung durch PV % PV_load = min(PV_gen,load); % Lastdeckung durch PV load_PV = max(load-PV_gen,0); % Verbleibende Last nach Lastdeckung durch PV PV_left = max(PV_gen-load,0); % Verbleibende PV Leistung nach Lastdeckung %% Lastdeckung durch Netzbezug reward_grid_load = -load_PV*actual_price + 0; % reward für den Netzbezug % Grid_load = load_PV; % Lastdeckung durch Netzbezug % load = 0; %% Einspeisung PV-Strom ins Netz reward_grid_PV = PV_left*actual_compense; % Reward für den Netzbezug % PV_grid = PV_left; % ins Neempz eingespeisemper PV-Strom temp1 = this.Batt_P; temp2 = Batt_stor; Grid_batt = min([temp1 temp2]); Batt_stor = Batt_stor - Grid_batt; reward_Grid_batt = Grid_batt*actual_compense; reward_Batt_load = 0; % Modus 5.0 elseif Action == 50 %% Lastdeckung durch den Speicher Batt_out = min([this.Batt_P Batt_stor load]); % Lastdeckung durch Batterie Batt_stor = Batt_stor - Batt_out; % Beladung nach der Lastdeckung durch Batterie load_batt = load - Batt_out; % Verbleibende Last nach Lastdeckung durch Batterie %% Lastdeckung durch PV % PV_load = min(PV_gen,load_batt); % Lastdeckung durch PV load_PV = max(load-PV_gen,0); % Verbleibende Last nach Lastdeckung durch PV PV_left = max(PV_gen-load_batt,0); % Verbleibende PV Leistung nach Lastdeckung %% Lastdeckung durch Netzbezug reward_grid_load = -load_PV*actual_price + 0; % reward für den Netzbezug % Grid_load = load_PV; % Lastdeckung durch Netzbezug % load = 0; %% Einspeisung PV-Strom ins Netz reward_grid_PV = PV_left*actual_compense; % Reward für den Netzbezug % PV_grid = PV_left; % ins Netz eingespeister PV-Strom reward_Batt_load = 0; reward_Grid_batt = 0; % Modus 5.1 elseif Action == 51 %% Lastdeckung durch den Speicher Batt_out = min([this.Batt_P Batt_stor load]); % Lastdeckung durch Batterie Batt_stor = Batt_stor - Batt_out; % Beladung nach der Lastdeckung durch Batterie load_batt = load - Batt_out; % Verbleibende Last nach Lastdeckung durch Batterie %% Lastdeckung durch PV % PV_load = min(PV_gen,load_batt); % Lastdeckung durch PV load_PV = max(load-PV_gen,0); % Verbleibende Last nach Lastdeckung durch PV PV_left = max(PV_gen-load_batt,0); % Verbleibende PV Leistung nach Lastdeckung %% Lastdeckung durch Netzbezug reward_grid_load = -load_PV*actual_price + 0; % reward für den Netzbezug % Grid_load = load_PV; % Lastdeckung durch Netzbezug % load = 0; %% Einspeisung PV-Strom ins Netz reward_grid_PV = PV_left*actual_compense; % Reward für den Netzbezug % PV_grid = PV_left; % ins Netz eingespeister PV-Strom temp1 = this.Batt_P-Batt_out; temp2 = Batt_stor; Grid_batt = min([temp1 temp2]); Batt_stor = Batt_stor - Grid_batt; reward_Grid_batt = Grid_batt*actual_compense; reward_Batt_load = 0; % Modus 6.0 elseif Action == 60 %% Lastdeckung durch den Speicher Batt_out = min([this.Batt_P Batt_stor load]); % Lastdeckung durch Batterie Batt_stor = Batt_stor - Batt_out; % Beladung nach der Lastdeckung durch Batterie load_batt = load - Batt_out; % Verbleibende Last nach Lastdeckung durch Batterie %% Lastdeckung durch Netzbezug reward_grid_load = -load_batt*actual_price + 0; % reward für den Netzbezug % Grid_load = load_batt; % Lastdeckung durch Netzbezug % load = 0; %% Einspeisung PV-Strom ins Netz reward_grid_PV = PV_gen * actual_compense; % Reward für den Netzbezug % PV_grid = PV_gen; % ins Netz eingespeister PV-Strom reward_Batt_load = 0; reward_Grid_batt = 0; % Modus 6.1 elseif Action == 61 %% Lastdeckung durch den Speicher Batt_out = min([this.Batt_P Batt_stor load]); % Lastdeckung durch Batterie Batt_stor = Batt_stor - Batt_out; % Beladung nach der Lastdeckung durch Batterie load_batt = load - Batt_out; % Verbleibende Last nach Lastdeckung durch Batterie %% Lastdeckung durch Netzbezug reward_grid_load = -load_batt*actual_price + 0; % reward für den Netzbezug % Grid_load = load_batt; % Lastdeckung durch Netzbezug % load = 0; %% Einspeisung PV-Strom ins Netz reward_grid_PV = PV_gen * actual_compense; % Reward für den Netzbezug % PV_grid = PV_gen; temp1 = this.Batt_P-Batt_out; temp2 = Batt_stor; Grid_batt = min([temp1 temp2]); Batt_stor = Batt_stor - Grid_batt; reward_Grid_batt = Grid_batt*actual_compense; reward_Batt_load = 0; % Modus 7.0 elseif Action == 70 %% Lastdeckung durch Netzbezug reward_grid_load = -load*actual_price + 0; % reward für den Netzbezug % Grid_load = load; % Lastdeckung durch Netzbezug % load = 0; %% Einspeisung PV-Strom ins Netz reward_grid_PV = PV_gen * actual_compense; % Reward für den Netzbezug % PV_grid = PV_gen % ins Netz eingespeister PV-Strom reward_Batt_load = 0; reward_Grid_batt = 0; % Modus 7.1 elseif Action == 71 %% Lastdeckung durch Netzbezug reward_grid_load = -load*actual_price + 0; % reward für den Netzbezug % Grid_load = load; % Lastdeckung durch Netzbezug % load = 0; %% Einspeisung PV-Strom ins Netz reward_grid_PV = PV_gen * actual_compense; % Reward für den Netzbezug % PV_grid = PV_gen; % ins Netz eingespeister PV-Strom temp1 = this.Batt_P; temp2 = this.Batt_cap - Batt_stor; Batt_grid = min([temp1 temp2]); Batt_stor = Batt_stor+(this.eta*Batt_grid); reward_Batt_load = -Batt_grid*actual_price; reward_Grid_batt = 0; % Modus 7.2 elseif Action == 72 %% Lastdeckung durch Netzbezug reward_grid_load = -load*actual_price + 0; % reward für den Netzbezug % Grid_load = load; % Lastdeckung durch Netzbezug % load = 0; %% Einspeisung PV-Strom ins Netz reward_grid_PV = PV_gen * actual_compense; % Reward für den Netzbezug % PV_grid = PV_gen; % ins Netz eingespeister PV-Strom temp1 = this.Batt_P; temp2 = Batt_stor; Grid_batt = min([temp1 temp2]); Batt_stor = Batt_stor - Grid_batt; reward_Grid_batt = Grid_batt*actual_compense; reward_Batt_load = 0; else end % Diskretisierung % Option 1 % Es wird eine obere und untere Grenze festgelegt . Zustände oberhalb der oberen Grenze werden als Hoch(1), zwischen den Grenzen als Mittel(2) und unter der unteren Grenze als Niedrig(3) an den Agent übergeben %% Last und Erzeugung load_PV_obs = round(load_obs/(PV_gen_obs+load_obs)); % Später kann hier eine fixe Höchstlast angenommen werden % if temp > this.load_PV_high % load_PV_obs = 1; % elseif temp <= this.load_PV_high && temp >= this.load_PV_low % load_PV_obs = 2; % else % load_PV_obs = 3; % end %% Speicherbeladung batt_obs = round(Batt_stor/this.Batt_cap); % if temp > this.batt_high % batt_obs = 1; % elseif temp <= this.batt_high && temp >= this.batt_low % batt_obs = 2; % else % batt_obs = 3; % end %% Strompreis und EEG Price_Compense_obs = round(actual_price_obs/(actual_price_obs+actual_compens_obs)); % if temp > this.Price_Compense_high % Price_Compense_obs = 1; % elseif temp <= this.Price_Compense_high && temp >= this.Price_Compense_low % Price_Compense_obs = 2; % else % Price_Compense_obs = 3; % end this.State(4) = this.State(4)+1; timestep = this.State(4); Observation = [load_PV_obs; batt_obs;Price_Compense_obs;timestep]; % Update system states this.State = Observation; Reward = reward_Batt_load + reward_Grid_batt + reward_grid_load + reward_grid_PV; notifyEnvUpdated(this); IsDone = (timestep == length(this.PV_gen_time)); this.IsDone = IsDone; end % Reset environment to initial state and output initial observation function InitialObservation = reset(this) Load_PV_obs0 = 1; batt_obs0 = 0; Price_Compense_obs0 = 1; timestemp0 = 1; InitialObservation = [Load_PV_obs0;batt_obs0;Price_Compense_obs0;timestemp0]; this.State = InitialObservation; % (optional) use notifyEnvUpdated to signal that the % environment has been updated (e.g. to update visualization) notifyEnvUpdated(this); end end methods (Access = protected) % (optional) update visualization everytime the environment is updated % (notifyEnvUpdated is called) function envUpdatedCallback(this) end end end