Source code for co2mpas.core.model.physical.cycle.WLTP.vel

#!/usr/bin/env python
# -*- 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:
Functions and `dsp` model to calculate the WLTP theoretical velocities.
import numpy as np
import schedula as sh
from co2mpas.defaults import dfl
from ...vehicle import dsp as _vehicle

dsp = sh.BlueDispatcher(
    name='WLTP velocities model',
    description='Returns the theoretical velocities of WLTP.'

[docs]@sh.add_function( dsp, outputs=['resistance_coeffs_regression_curves', 'wltc_data'] ) def get_dfl(base_model): """ Gets default values from wltp base model. :param base_model: WLTP base model. :type base_model: dict :return: Default values from wltp base model. :rtype: list """ params = base_model['params'] keys = 'resistance_coeffs_regression_curves', 'wltc_data' return sh.selector(keys, params, output_type='list')
[docs]@sh.add_function(dsp, outputs=['road_loads'], weight=15) def default_road_loads( vehicle_mass, resistance_coeffs_regression_curves): """ Returns default road loads. :param vehicle_mass: Vehicle mass [kg]. :type vehicle_mass: float :param resistance_coeffs_regression_curves: Regression curve coefficient to calculate the default road loads. :type resistance_coeffs_regression_curves: list[list[float]] :return: Cycle road loads [N, N/(km/h), N/(km/h)^2]. :rtype: list, tuple """ from wltp.experiment import calc_default_resistance_coeffs as func return func(vehicle_mass, resistance_coeffs_regression_curves)
[docs]@sh.add_function(dsp, outputs=['max_speed_velocity_ratio']) def calculate_max_speed_velocity_ratio(speed_velocity_ratios): """ Calculates the maximum speed velocity ratio of the gear box [h*RPM/km]. :param speed_velocity_ratios: Speed velocity ratios of the gear box [h*RPM/km]. :type speed_velocity_ratios: dict[int | float] :return: Maximum speed velocity ratio of the gear box [h*RPM/km]. :rtype: float """ return speed_velocity_ratios[max(speed_velocity_ratios)]
[docs]@sh.add_function(dsp, outputs=['max_velocity']) def calculate_max_velocity(engine_speed_at_max_power, max_speed_velocity_ratio): """ Calculates max vehicle velocity [km/h]. :param engine_speed_at_max_power: Rated engine speed [RPM]. :type engine_speed_at_max_power: float :param max_speed_velocity_ratio: Maximum speed velocity ratio of the gear box [h*RPM/km]. :type max_speed_velocity_ratio: float :return: Max vehicle velocity [km/h]. :rtype: float """ return engine_speed_at_max_power / max_speed_velocity_ratio
[docs]@sh.add_function(dsp, outputs=['wltp_class']) def calculate_wltp_class( wltc_data, engine_max_power, unladen_mass, max_velocity): """ Calculates the WLTP vehicle class. :param wltc_data: WLTC data. :type wltc_data: dict :param engine_max_power: Maximum power [kW]. :type engine_max_power: float :param unladen_mass: Unladen mass [kg]. :type unladen_mass: float :param max_velocity: Max vehicle velocity [km/h]. :type max_velocity: float :return: WLTP vehicle class. :rtype: str """ from wltp.experiment import decideClass ratio = 1000.0 * engine_max_power / unladen_mass return decideClass(wltc_data, ratio, max_velocity)
[docs]@sh.add_function(dsp, outputs=['class_data']) def get_class_data(wltc_data, wltp_class): """ Returns WLTP class data. :param wltc_data: WLTC data. :type wltc_data: dict :param wltp_class: WLTP vehicle class. :type wltp_class: str :return: WLTP class data. :rtype: dict """ return wltc_data['classes'][wltp_class]
[docs]@sh.add_function(dsp, outputs=['class_times', 'class_velocities'], weight=25) def get_class_velocities(class_data): """ Returns time and velocity profiles according to WLTP class data [s, km/h]. :param class_data: WLTP class data. :type class_data: dict :return: Class time and velocity vectors [s, km/h]. :rtype: tuple[numpy.array] """ vel = np.asarray(class_data['cycle'], dtype=float) return np.arange(vel.shape[0], dtype=float), vel
i = ['vehicle_mass', 'road_loads', 'inertial_factor'] calculate_class_powers = sh.SubDispatchPipe( _vehicle, function_id='calculate_class_powers', inputs=['times', 'velocities'] + i, outputs=['motive_powers'] ) dsp.add_function( function=calculate_class_powers, inputs=['class_times', 'class_velocities'] + i, outputs=['class_powers'] ) dsp.add_data( 'downscale_factor_threshold', dfl.values.downscale_factor_threshold )
[docs]@sh.add_function(dsp, outputs=['downscale_factor']) def calculate_downscale_factor( class_data, downscale_factor_threshold, max_velocity, engine_max_power, class_powers): """ Calculates velocity downscale factor [-]. :param class_data: WLTP class data. :type class_data: dict :param downscale_factor_threshold: Velocity downscale factor threshold [-]. :type downscale_factor_threshold: float :param max_velocity: Max vehicle velocity [km/h]. :type max_velocity: float :param engine_max_power: Maximum power [kW]. :type engine_max_power: float :param class_powers: Class motive power [kW]. :type class_powers: numpy.array :return: Velocity downscale factor [-]. :rtype: float """ from wltp.experiment import calcDownscaleFactor dsc_data = class_data['downscale'] p_max_values = dsc_data['p_max_values'] downsc_coeffs = dsc_data['factor_coeffs'] dsc_v_split = dsc_data.get('v_max_split', None) downscale_factor = calcDownscaleFactor( class_powers, p_max_values, downsc_coeffs, dsc_v_split, engine_max_power, max_velocity, downscale_factor_threshold ) return downscale_factor
[docs]@sh.add_function(dsp, outputs=['downscale_phases']) def get_downscale_phases(class_data): """ Returns downscale phases [s]. :param class_data: WLTP class data. :type class_data: dict :return: Downscale phases [s]. :rtype: list """ return class_data['downscale']['phases']
[docs]@sh.add_function(dsp, outputs=['theoretical_velocities']) def wltp_velocities( downscale_factor, class_times, class_velocities, downscale_phases, times): """ Returns the downscaled velocity profile [km/h]. :param downscale_factor: Velocity downscale factor [-]. :type downscale_factor: float :param class_times: Class time vector [s]. :type class_times: numpy.array :param class_velocities: Class velocity vector [km/h]. :type class_velocities: numpy.array :param downscale_phases: Downscale phases [s]. :type downscale_phases: list :param times: Time vector [s]. :type times: numpy.array :return: Theoretical velocity vector [km/h]. :rtype: numpy.array """ if downscale_factor > 0: from wltp.experiment import downscaleCycle downscale_phases = np.searchsorted(times, downscale_phases) v = downscaleCycle(class_velocities, downscale_factor, downscale_phases) else: v = class_velocities n = int(np.ceil(times[-1] / class_times[-1])) t = np.cumsum(np.tile(np.ediff1d(class_times, to_begin=[0]), (n,))) t += class_times[0] return np.interp(times, t, np.tile(v, (n,)))
dsp.add_function( function_id='calculate_theoretical_motive_powers', function=calculate_class_powers, inputs=['times', 'theoretical_velocities'] + i, outputs=['theoretical_motive_powers'] ) dsp.add_function( function=sh.bypass, inputs=['theoretical_velocities'], outputs=['velocities'] )