Energy generators¶
The energy generator is responsible for determining the amount of energy that is available in the smart grid at each time step (i.e., a local power plant).
Extending this class allows controlling this amount to make the simulation easier, or more difficult, or more realistic, etc., to learning agents.
In order to allow for a large variety of energy generators, the
generate_available_energy()
method, which is responsible for determining the amount available at a given
time step, receives: 1) the current sum of needs of all agents, 2) the current
step, 3) the minimum sum of needs from all agents, and 4) the maximum sum of
needs from all agents.
These data allow, e.g., scaling the available energy to the current number of
agents through their current/min/max total need. As the available energy is
part of the observations, it is important to know the possible bounds of the
generator, in order to specify the observation space (and ultimately to be
able to scale observations to [0, 1]
for easier handling by learning
algorithms). The available_energy_bounds()
serves this purpose. The method could return different bounds at each time
step, but this is not recommended, as this would make it harder to define the
observation space.
In order to create a new energy generator, these two methods must be implemented. Let us assume that we would like an energy generator that returns a realistic amount, based on real-world data, independently of the agents’ needs:
from smartgrid.util import EnergyGenerator
class RealworldEnergyGenerator(EnergyGenerator):
def __init__(self, data):
super().__init__(self)
self.data = data
def generate_available_energy(self,
current_need,
current_step,
min_need,
max_need):
# Retrieve the current step from the data (cycling over the array).
step = current_step %= len(self.data)
energy = self.data[step]
return energy
def available_energy_bounds(self,
current_need,
current_step,
min_need,
max_need):
# As we return values from the data directly, the bounds are simply
# the min and max values of the data.
lower_bound = min(self.data)
upper_bound = max(self.data)
return lower_bound, upper_bound
Note that it is very important that the result of generate_available_energy()
is contained within the bounds specified by available_energy_bounds()
;
otherwise, the observation space might be incorrect, and learning agents will
receive incoherent observations.
The bounds might not need to be extremely precise (although it would be better):
very large values such as 0
and 1_000_000
can be used if no accurate
approximation can be determined.
Once the energy generator is defined, it can be used when instantiating the
World
:
from smartgrid import World
# Generates 100Wh at t=0, then 200Wh at t=1, 300Wh at t=2, 10Wh at t=3,
# 100Wh at t=4, and so on...
data = [100, 200, 300, 10]
generator = RealworldEnergyGenerator(data)
world = World(
agents=..., # Not relevant here
energy_generator=generator
)