@sh.add_function(dsp, outputs=['hybrid_modes'])
def identify_hybrid_modes(
times, gear_box_speeds_in, engine_speeds_out, idle_engine_speed,
on_engine, is_serial, has_motor_p2_planetary):
"""
Identify the hybrid mode status (0: EV, 1: Parallel, 2: Serial).
:param times:
Time vector [s].
:type times: numpy.array
:param gear_box_speeds_in:
Gear box speed [RPM].
:type gear_box_speeds_in: numpy.array
:param engine_speeds_out:
Engine speed [RPM].
:type engine_speeds_out: numpy.array
:param idle_engine_speed:
Idle engine speed and its standard deviation [RPM].
:type idle_engine_speed: (float, float)
:param on_engine:
If the engine is on [-].
:type on_engine: numpy.array
:param is_serial:
Is the vehicle serial hybrid?
:type is_serial: bool
:param has_motor_p2_planetary:
Has the vehicle a motor in planetary P2?
:type has_motor_p2_planetary: bool
:return:
Hybrid mode status (0: EV, 1: Parallel, 2: Serial).
:rtype: numpy.array
"""
# noinspection PyProtectedMember
from ..gear_box.mechanical import _shift
from ....report import _correlation_coefficient
if has_motor_p2_planetary:
return on_engine.astype(int)
if is_serial:
return np.where(on_engine, 2, 0)
mode = on_engine.astype(int)
es, gbs = engine_speeds_out, gear_box_speeds_in
b = idle_engine_speed[0] > gbs
b |= (gbs - idle_engine_speed[1]) > es
mode[on_engine & b] = 2
i = np.where(mode == 1)[0]
mode[i[~co2_utl.get_inliers(gbs[i] / es[i], 3)[0]]] = 2
mode = co2_utl.median_filter(times, mode, 4)
mode = co2_utl.clear_fluctuations(times, mode, 4).astype(int)
mode[~on_engine] = 0
with np.errstate(divide='ignore', invalid='ignore'):
for i, j in sh.pairwise(_shift(mode)):
if mode[i] and times[j - 1] - times[i] < 5:
if _correlation_coefficient(es[i:j], gbs[i:j]) < .6:
mode[i:j] = 3 - mode[i]
return mode