Source code for co2mpas.core.model.physical.gear_box.manual

# -*- 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 manual gear shifting.
"""
import collections
import numpy as np
import schedula as sh
from .at_gear import CMV

dsp = sh.BlueDispatcher(
    name='manual GS model', description='Models the manual gear shifting.'
)


[docs]@sh.add_function(dsp, outputs=['engine_max_speed_95']) def calculate_engine_max_speed_95( full_load_speeds, idle_engine_speed, engine_max_speed, full_load_curve, engine_max_power): """ Calculates the maximum engine speed [RPM] at 95% of the nominal power. :param full_load_speeds: T1 map speed vector [RPM]. :type full_load_speeds: numpy.array :param idle_engine_speed: Engine speed idle median and std [RPM]. :type idle_engine_speed: (float, float) :param engine_max_speed: Maximum allowed engine speed [RPM]. :type engine_max_speed: float :param full_load_curve: Vehicle full load curve. :type full_load_curve: function :param engine_max_power: Engine nominal power [kW]. :type engine_max_power: float :return: Maximum engine speed [RPM] at 95% of the nominal power. :rtype: float """ from scipy.interpolate import InterpolatedUnivariateSpline as Spl speeds = [idle_engine_speed[0] - idle_engine_speed[1], engine_max_speed] speeds.extend(full_load_speeds) speeds = np.unique(speeds) n = [engine_max_speed] n.extend( Spl(speeds, full_load_curve(speeds) / engine_max_power - 0.95).roots() ) return max(n)
# noinspection PyMissingOrEmptyDocstring
[docs]class MGS(CMV):
[docs] def __init__(self, *args, **kwargs): super(MGS, self).__init__(*args, **kwargs)
# noinspection PyMethodOverriding,PyMethodOverriding
[docs] def fit(self, full_load_curve, engine_speed_at_max_power, road_loads, engine_max_speed_95, velocity_speed_ratios, idle_engine_speed): self.velocity_speed_ratios = velocity_speed_ratios # noinspection PyProtectedMember from co2mpas.defaults import dfl from .mechanical import _calculate_req_power as calc_power_req d = dfl.functions.MGS vel = np.arange(d.MIN_VEL, d.MAX_VEL, d.DELTA_VEL, float)[:, None] g_id, vsr = zip(*[(k, v) for k, v in sorted( velocity_speed_ratios.items(), reverse=True ) if k]) s = np.round(np.divide(vel, vsr), 1) p = full_load_curve(s) b = np.zeros_like(p, bool) g_id, idle = np.array(g_id), idle_engine_speed[0] j = g_id == 1 b[:, j] = s[:, j] < idle j = g_id == 2 b[:, j] = s[:, j] < idle * 0.9 j = np.in1d(g_id, (1, 2), True, True) b[:, j] = s[:, j] < idle + 0.125 * (engine_speed_at_max_power - idle) b |= s > engine_max_speed_95 b[:, j] |= p[:, j] < (calc_power_req(road_loads, vel) / d.PREC_FLC) v = np.repeat(vel, b.shape[1], 1) v[b] = np.nan d, u = np.nanmin(v, 0), np.nanmax(v, 0) d[-1], u[0] = 0, dfl.INF self.clear() self.update(collections.OrderedDict(zip(g_id, zip(d, u)))) self[0] = (0, 0) return self
[docs]@sh.add_function(dsp, outputs=['MGS', 'MVL']) def define_msg_and_mvl( full_load_curve, road_loads, velocity_speed_ratios, engine_max_speed_95, idle_engine_speed, engine_speed_at_max_power): """ Calculates the maximum velocity from full load curve. :param full_load_curve: Vehicle full load curve. :type full_load_curve: function :param road_loads: Cycle road loads [N, N/(km/h), N/(km/h)^2]. :type road_loads: list, tuple :param velocity_speed_ratios: Constant velocity speed ratios of the gear box [km/(h*RPM)]. :type velocity_speed_ratios: dict[int | float] :param engine_max_speed_95: Maximum engine speed [RPM] at 95% of the nominal power. :type engine_max_speed_95: float :param idle_engine_speed: Engine speed idle median and std [RPM]. :type idle_engine_speed: (float, float) :param engine_speed_at_max_power: Engine speed at engine nominal power [RPM]. :type engine_speed_at_max_power: float :return: Maximum velocity and gear at maximum velocity [km/h, -]. :return: float, int """ from .at_gear import MVL mgs = MGS().fit( full_load_curve, engine_speed_at_max_power, road_loads, engine_max_speed_95, velocity_speed_ratios, idle_engine_speed ) mvl = MVL() mvl.update(mgs) mvl.velocity_speed_ratios = velocity_speed_ratios return mgs, mvl
[docs]@sh.add_function( dsp, inputs=[ 'cycle_type', 'velocity_speed_ratios', 'MVL', 'idle_engine_speed', 'full_load_curve', 'engine_speed_at_max_power' ], outputs=['correct_gear'] ) def correct_gear_v4( cycle_type, velocity_speed_ratios, mvl, idle_engine_speed, full_load_curve, engine_speed_at_max_power): """ Returns a function to correct the gear predicted according to :func:`correct_gear_mvl`, :func:`correct_gear_full_load` and driveability rules. :param cycle_type: Cycle type (WLTP or NEDC). :type cycle_type: str :param velocity_speed_ratios: Constant velocity speed ratios of the gear box [km/(h*RPM)]. :type velocity_speed_ratios: dict[int | float] :param mvl: Matrix velocity limits (upper and lower bound) [km/h]. :type mvl: MVL :param idle_engine_speed: Engine speed idle median and std [RPM]. :type idle_engine_speed: (float, float) :param full_load_curve: Vehicle full load curve. :type full_load_curve: function :param engine_speed_at_max_power: Rated engine speed [RPM]. :type engine_speed_at_max_power: float :return: A function to correct the predicted gear. :rtype: callable """ from .at_gear import correct_gear_v0 cg = correct_gear_v0( cycle_type, velocity_speed_ratios, mvl, idle_engine_speed, full_load_curve ) cg.fit_correct_driveability_rules(engine_speed_at_max_power) return cg
[docs]@sh.add_function(dsp, outputs=['gears'], weight=sh.inf(1, 0), inputs=[ 'correct_gear', 'MGS', 'times', 'velocities', 'accelerations', 'motive_powers' ]) def prediction_gears_gsm_v1( correct_gear, gsm, times, velocities, accelerations, motive_powers): """ Predicts gears with a gear shifting model (mgs) [-]. :param correct_gear: A function to correct the gear predicted. :type correct_gear: callable :param gsm: A gear shifting model (cmv or gspv or dtgs). :type gsm: MSG :param times: Time vector [s]. :type times: numpy.array :param velocities: Vehicle velocity [km/h]. :type velocities: numpy.array :param accelerations: Vehicle acceleration [m/s2]. :type accelerations: numpy.array :param motive_powers: Motive power [kW]. :type motive_powers: numpy.array :return: Predicted gears. :rtype: numpy.array """ gears = gsm.predict( times, velocities, accelerations, motive_powers, correct_gear=correct_gear ) return gears