Source code for co2mpas.core.model.physical.control

# -*- coding: utf-8 -*-
#
# Copyright 2015-2019 European Commission (JRC);
# Licensed under the EUPL (the 'Licence');
# You may not use this work except in compliance with the Licence.
# You may obtain a copy of the Licence at: http://ec.europa.eu/idabc/eupl
"""
Functions and `dsp` model to model the vehicle control strategy.

Sub-Modules:

.. currentmodule:: co2mpas.core.model.physical.control

.. autosummary::
    :nosignatures:
    :toctree: control/

    conventional
    hybrid
"""
import numpy as np
import schedula as sh
from co2mpas.defaults import dfl
from .conventional import dsp as _conventional
from .hybrid import dsp as _hybrid

dsp = sh.BlueDispatcher(
    name='Control', description='Models the vehicle control strategy.'
)

dsp.add_data(
    'min_time_engine_on_after_start', dfl.values.min_time_engine_on_after_start
)


[docs]@sh.add_function(dsp, outputs=['on_engine']) def identify_on_engine( times, engine_speeds_out, idle_engine_speed, min_time_engine_on_after_start): """ Identifies if the engine is on [-]. :param times: Time vector [s]. :type times: 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 min_time_engine_on_after_start: Minimum time of engine on after a start [s]. :type min_time_engine_on_after_start: float :return: If the engine is on [-]. :rtype: numpy.array """ on_engine = engine_speeds_out > idle_engine_speed[0] - idle_engine_speed[1] mask = np.where(identify_engine_starts(on_engine))[0] + 1 ts = np.asarray(times[mask], dtype=float) ts += min_time_engine_on_after_start + dfl.EPS for i, j in np.column_stack((mask, np.searchsorted(times, ts))): on_engine[i:j] = True return on_engine
[docs]@sh.add_function(dsp, outputs=['engine_starts']) def identify_engine_starts(on_engine): """ Identifies when the engine starts [-]. :param on_engine: If the engine is on [-]. :type on_engine: numpy.array :return: When the engine starts [-]. :rtype: numpy.array """ engine_starts = np.zeros_like(on_engine, dtype=bool) engine_starts[:-1] = on_engine[1:] & (on_engine[:-1] != on_engine[1:]) return engine_starts
# noinspection PyMissingOrEmptyDocstring
[docs]def is_hybrid(kwargs): return kwargs.get('is_hybrid')
# noinspection PyMissingOrEmptyDocstring
[docs]def is_not_hybrid(kwargs): return not kwargs.get('is_hybrid', True)
dsp.add_dispatcher( include_defaults=True, dsp=_conventional, dsp_id='conventional_control', inputs=( 'gear_box_type', 'start_stop_activation_time', 'accelerations', 'times', 'idle_engine_speed', 'min_time_engine_on_after_start', 'engine_starts', 'has_start_stop', 'correct_start_stop_with_gears', 'start_stop_model', 'gear_box_speeds_in', 'velocities', 'on_engine', 'gears', {'is_hybrid': sh.SINK} ), outputs=( 'correct_start_stop_with_gears', 'engine_speeds_out_hot', 'on_engine', 'start_stop_activation_time', 'start_stop_model', 'hybrid_modes', ), input_domain=is_not_hybrid ) dsp.add_dispatcher( include_defaults=True, dsp=_hybrid, dsp_id='hybrid_control', inputs=( 'clutch_tc_mean_efficiency', 'idle_engine_speed', 'motor_p0_efficiency', 'motor_p0_maximum_power', 'drive_battery_model', 'belt_mean_efficiency', 'min_time_engine_on_after_start', 'start_stop_activation_time', 'times', 'drive_battery_state_of_charges', 'motor_p2_maximum_powers', 'fuel_map', 'engine_thermostat_temperature', 'motor_p2_efficiency', 'accelerations', 'motor_p0_maximum_power_function', 'on_engine', 'engine_moment_inertia', 'motor_p1_maximum_power_function', 'ecms_s', 'start_stop_hybrid_params', 'motor_p1_speed_ratio', 'auxiliaries_power_loss', 'motor_p1_efficiency', 'final_drive_mean_efficiency', 'motors_electric_powers', 'is_cycle_hot', 'auxiliaries_torque_loss', 'dcdc_converter_efficiency', 'motive_powers', 'motor_p2_electric_powers', 'motor_p0_speed_ratio', 'engine_speeds_out', 'motor_p3_rear_efficiency', 'motor_p1_maximum_power', 'full_load_curve', 'motor_p3_rear_maximum_powers', 'motor_p0_electric_powers', 'is_serial', 'after_treatment_warm_up_duration', 'engine_powers_out', 'hybrid_modes', 'motor_p2_maximum_power', 'engine_speeds_out_hot', 'gear_box_speeds_in', 'gear_box_mean_efficiency', 'motor_p1_electric_powers', 'starter_model', 'motor_p2_planetary_maximum_power_function', 'motor_p4_rear_efficiency', 'motor_p3_front_efficiency', 'final_drive_speeds_in', 'planetary_ratio', 'after_treatment_cooling_duration', 'motor_p2_planetary_maximum_power', 'motor_p2_planetary_electric_powers', 'after_treatment_warm_up_phases', 'gear_box_mean_efficiency_guess', 'motor_p3_front_electric_powers', 'motor_p2_planetary_speed_ratio', 'motor_p4_front_electric_powers', 'motor_p2_planetary_efficiency', 'motor_p4_rear_electric_powers', 'motor_p3_front_maximum_powers', 'motor_p3_rear_electric_powers', 'motor_p4_front_maximum_powers', 'motor_p4_rear_maximum_powers', 'motor_p4_front_maximum_power', 'motor_p3_front_maximum_power', 'engine_coolant_temperatures', 'motor_p3_rear_maximum_power', 'motor_p4_rear_maximum_power', 'motor_p4_front_efficiency', 'planetary_mean_efficiency', 'has_motor_p2_planetary', {'is_hybrid': sh.SINK}, ), outputs=( 'motor_p3_front_electric_powers', 'motor_p2_electric_powers', 'ecms_s', 'motor_p4_front_electric_powers', 'engine_speeds_base', 'hybrid_modes', 'after_treatment_warm_up_phases', 'engine_speeds_out_hot', 'on_engine', 'motor_p2_planetary_electric_powers', 'motor_p3_rear_electric_powers', 'motor_p4_rear_electric_powers', 'start_stop_hybrid_params', 'motor_p1_electric_powers', 'motor_p0_electric_powers', 'force_on_engine', 'start_stop_activation_time' ), input_domain=is_hybrid )