160 lines
5.7 KiB
Python
160 lines
5.7 KiB
Python
|
import numpy as np
|
||
|
|
||
|
|
||
|
class DG:
|
||
|
"""simulate a diesel generator"""
|
||
|
|
||
|
def __init__(self, parameters):
|
||
|
self.current_output = None
|
||
|
self.name = parameters.keys()
|
||
|
self.a_factor = parameters['a']
|
||
|
self.b_factor = parameters['b']
|
||
|
self.c_factor = parameters['c']
|
||
|
self.power_output_max = parameters['power_output_max']
|
||
|
self.power_output_min = parameters['power_output_min']
|
||
|
self.ramping_up = parameters['ramping_up']
|
||
|
self.ramping_down = parameters['ramping_down']
|
||
|
|
||
|
def step(self, action_gen):
|
||
|
output_change = action_gen * self.ramping_up
|
||
|
output = self.current_output + output_change
|
||
|
if output > 0:
|
||
|
# output = max(self.power_output_min, min(self.power_output_max, output))
|
||
|
output = max(0, min(self.power_output_max, output))
|
||
|
else:
|
||
|
output = 0
|
||
|
self.current_output = output
|
||
|
|
||
|
def get_cost(self, output):
|
||
|
cost = (self.a_factor * pow(output, 2) + self.b_factor * output + self.c_factor)
|
||
|
return cost
|
||
|
|
||
|
def reset(self):
|
||
|
self.current_output = 0
|
||
|
|
||
|
|
||
|
class Battery:
|
||
|
"""simulate a battery"""
|
||
|
|
||
|
def __init__(self, parameters):
|
||
|
self.current_capacity = None
|
||
|
self.energy_change = None
|
||
|
self.capacity = parameters['capacity']
|
||
|
self.min_soc = parameters['min_soc']
|
||
|
self.max_soc = parameters['max_soc']
|
||
|
self.degradation = parameters['degradation']
|
||
|
self.holding = parameters['holding']
|
||
|
self.max_charge = parameters['max_charge']
|
||
|
# self.max_discharge = parameters['max_discharge']
|
||
|
self.efficiency = parameters['efficiency']
|
||
|
|
||
|
def step(self, action_battery):
|
||
|
energy = action_battery * self.max_charge
|
||
|
current_energy = self.current_capacity * self.capacity
|
||
|
updated_capacity = np.maximum(self.min_soc, np.minimum(self.max_soc, (current_energy + energy) / self.capacity))
|
||
|
# if charge, positive, if discharge, negative
|
||
|
self.energy_change = (updated_capacity - self.current_capacity) * self.capacity
|
||
|
self.current_capacity = updated_capacity # update capacity to current state
|
||
|
|
||
|
def get_cost(self, energy_change):
|
||
|
cost = abs(energy_change) * self.degradation
|
||
|
# cost = abs(energy_change) * self.degradation + energy_hold * self.holding
|
||
|
return cost
|
||
|
|
||
|
def SOC(self):
|
||
|
return self.current_capacity
|
||
|
|
||
|
def reset(self):
|
||
|
self.current_capacity = 0.2
|
||
|
# self.current_capacity = np.random.uniform(0.2, 0.8)
|
||
|
|
||
|
|
||
|
class Solar:
|
||
|
"""simulate a solar panel"""
|
||
|
def __init__(self, parameters):
|
||
|
self.current_power = None
|
||
|
self.output_change = None
|
||
|
self.base_voltage = parameters['V_b']
|
||
|
self.sc_current = parameters['I_sc0']
|
||
|
self.oc_voltage = parameters['V_oc0']
|
||
|
# self.s_resistance = parameters['R_s']
|
||
|
self.sh_resistance = parameters['R_sh']
|
||
|
self.temper_coefficient = parameters['T_c']
|
||
|
self.opex_cofficient = parameters['O_c']
|
||
|
self.refer_irradiance = parameters['I_ref']
|
||
|
self.refer_temperature = parameters['T_ref']
|
||
|
|
||
|
def step(self, temperature, irradiance, action_voltage=0):
|
||
|
I_sc = self.sc_current * (irradiance / self.refer_irradiance)
|
||
|
V_oc = self.oc_voltage + self.temper_coefficient * (temperature - self.refer_temperature)
|
||
|
|
||
|
current = I_sc - (V_oc / self.sh_resistance)
|
||
|
self.current_power = max(self.base_voltage * (1 + action_voltage) * current, 0)
|
||
|
self.output_change = self.base_voltage * action_voltage * current
|
||
|
return self.current_power
|
||
|
|
||
|
def get_cost(self, current_power):
|
||
|
cost = current_power * self.opex_cofficient
|
||
|
return cost
|
||
|
|
||
|
def reset(self):
|
||
|
self.current_power = 0
|
||
|
|
||
|
|
||
|
class Wind:
|
||
|
"""simulate a wind turbine"""
|
||
|
|
||
|
def __init__(self, parameters):
|
||
|
self.current_power = None
|
||
|
self.cutin_speed = parameters['cutin_speed']
|
||
|
self.cutout_speed = parameters['cutout_speed']
|
||
|
self.rated_speed = parameters['rated_speed']
|
||
|
self.air_density = parameters['air_density']
|
||
|
self.rotor_radius = parameters['rotor_radius']
|
||
|
self.power_coefficient = parameters['power_coefficient']
|
||
|
self.generator_efficiency = parameters['generator_efficiency']
|
||
|
self.opex_cofficient = parameters['opex_cofficient']
|
||
|
|
||
|
def step(self, wind_speed):
|
||
|
constant = 0.5 * self.air_density * np.pi * self.rotor_radius ** 2 * self.power_coefficient * self.generator_efficiency
|
||
|
if self.cutin_speed <= wind_speed < self.rated_speed:
|
||
|
self.current_power = constant * wind_speed ** 3 / 1e3
|
||
|
elif self.rated_speed <= wind_speed < self.cutout_speed:
|
||
|
self.current_power = constant * self.rated_speed ** 3 / 1e3
|
||
|
else:
|
||
|
self.current_power = 0
|
||
|
return self.current_power
|
||
|
|
||
|
def gen_cost(self, current_power):
|
||
|
cost = current_power * self.opex_cofficient
|
||
|
return cost
|
||
|
|
||
|
def reset(self):
|
||
|
self.current_power = 0
|
||
|
|
||
|
|
||
|
class Grid:
|
||
|
"""simulate a grid"""
|
||
|
|
||
|
def __init__(self):
|
||
|
self.on = True
|
||
|
self.delta = 1
|
||
|
if self.on:
|
||
|
self.exchange_ability = 100
|
||
|
else:
|
||
|
self.exchange_ability = 0
|
||
|
|
||
|
def get_cost(self, current_price, energy_exchange):
|
||
|
return current_price * energy_exchange * self.delta
|
||
|
|
||
|
def retrieve_past_price(self):
|
||
|
result = []
|
||
|
# 过去24小时的价格起始、结束索引
|
||
|
start_index = max(0, 24 * (self.day - 1) + self.time - 24)
|
||
|
end_index = 24 * (self.day - 1) + self.time
|
||
|
past_price = self.price[start_index:end_index]
|
||
|
result.extend(past_price)
|
||
|
# current_day_price = self.price[24 * self.day:24 * self.day + self.time]
|
||
|
# result.extend(current_day_price)
|
||
|
return result
|