@sh.add_function(dsp, outputs=['service_battery_initialization_time'])
def identify_service_battery_initialization_time(
alternator_electric_powers, motive_powers,
accelerations, service_battery_state_of_charges,
service_battery_charging_statuses, times,
service_battery_electric_powers_supply_threshold):
"""
Identifies the alternator initialization time delta [s].
:param alternator_electric_powers:
Alternator electric power [kW].
:type alternator_electric_powers: numpy.array
:param motive_powers:
Motive power [kW].
:type motive_powers: numpy.array
:param accelerations:
Vehicle acceleration [m/s2].
:type accelerations: numpy.array
:param service_battery_state_of_charges:
State of charge of the service battery [%].
:type service_battery_state_of_charges: numpy.array
:param service_battery_charging_statuses:
Service battery charging statuses (0: Discharge, 1: Charging, 2: BERS,
3: Initialization) [-].
:type service_battery_charging_statuses: numpy.array
:param times:
Time vector [s].
:type times: numpy.array
:param service_battery_electric_powers_supply_threshold:
Service battery not charging power threshold [kW].
:type service_battery_electric_powers_supply_threshold: float
:return:
Service battery initialization time delta [s].
:rtype: float
"""
bats, p = service_battery_charging_statuses, motive_powers
i = co2_utl.argmax(bats != 0)
if bats[0] == 1 or (i and ((bats[:i] == 0) & (p[:i] == 0)).all()):
s = service_battery_electric_powers_supply_threshold
s = alternator_electric_powers < s
n, i = len(times), int(co2_utl.argmax((s[:-1] != s[1:]) & s[:-1]))
i = min(n - 1, i)
# noinspection PyProtectedMember
from ....engine._thermal import _build_samples, _XGBRegressor
x, y = _build_samples(
alternator_electric_powers, service_battery_state_of_charges, bats,
p, accelerations
)
j = min(i, int(n / 2))
# noinspection PyArgumentEqualDefault
model = _XGBRegressor(
random_state=0,
max_depth=2,
n_estimators=int(min(100.0, 0.25 * (n - j))) or 1,
objective='reg:squarederror'
).fit(x[j:], y[j:])
err = np.abs(y - model.predict(x))
sets = np.array(co2_utl.get_inliers(err)[0], dtype=int)[:i]
if (i and sum(sets) / i < 0.5) or i > j:
from sklearn.tree import DecisionTreeClassifier
reg = DecisionTreeClassifier(max_depth=1, random_state=0)
reg.fit(times[1:i + 1, None], sets)
s, r = reg.tree_.children_left[0], reg.tree_.children_right[0]
s, r = np.argmax(reg.tree_.value[s]), np.argmax(reg.tree_.value[r])
if s == 0 and r == 1:
return reg.tree_.threshold[0] - times[0]
elif r == 0 and not i > j:
return times[i] - times[0]
elif bats[0] == 3:
i = co2_utl.argmax(bats != 3)
return times[i] - times[0]
return 0.0