def report(): """ Defines and returns a function that produces a vehicle report from CO2MPAS outputs. .. dispatcher:: d >>> d = report() :return: The reporting model. :rtype: SubDispatchFunction """ # Initialize a dispatcher. d = dsp.Dispatcher( name='make_report', description='Produces a vehicle report from CO2MPAS outputs.' ) d.add_function( function=get_report_output_data, inputs=['output_data'], outputs=['report'] ) d.add_function( function=extract_summary, inputs=['report', 'vehicle_name'], outputs=['summary'] ) inputs = ['output_data', 'vehicle_name'] outputs = ['report', 'summary'] return dsp_utl.SubDispatchFunction(d, d.name, inputs, outputs)
def write_outputs(): """ Defines a module to write on files the outputs of the CO2MPAS model. .. dispatcher:: d >>> d = write_outputs() :return: The write outputs module. :rtype: SubDispatchFunction """ d = dsp.Dispatcher( name='write_outputs', description='Writes on files the outputs of the CO2MPAS model.') d.add_function(function=convert2df, inputs=['output_data', 'start_time', 'main_flags'], outputs=['dfs']) d.add_function(function=excel.write_to_excel, inputs=['dfs', 'output_file_name', 'template_file_name']) inp = [ 'output_file_name', 'template_file_name', 'output_data', 'start_time', 'main_flags' ] return dsp_utl.SubDispatchFunction(d, d.name, inp)
def _selector(name, data_in, data_out, setting): d = dsp.Dispatcher( name='%s selector' % name, description='Select the calibrated %s.' % name, ) errors, setting = [], setting or {} _sort_models = setting.pop('sort_models', sort_models) if 'weights' in setting: _weights = dsp_utl.map_list(setting['targets'], *setting.pop('weights')) else: _weights = None _get_best_model = functools.partial( setting.pop('get_best_model', get_best_model), models_wo_err=setting.pop('models_wo_err', None), selector_id=d.name ) d.add_data( data_id='selector_settings', default_value={}) node_ids = ['error_settings', 'best_model_settings'] d.add_function( function=functools.partial(define_selector_settings, node_ids=node_ids), inputs=['selector_settings'], outputs=node_ids ) for i in data_in: e = 'error/%s' % i errors.append(e) d.add_function( function=_errors(name, i, data_out, setting), inputs=['error_settings', i] + [k for k in data_out if k != i], outputs=[e] ) d.add_function( function_id='sort_models', function=functools.partial(_sort_models, weights=_weights), inputs=errors, outputs=['rank'] ) d.add_function( function_id='get_best_model', function=_get_best_model, inputs=['rank', 'best_model_settings'], outputs=['model', 'errors'] ) return dsp_utl.SubDispatch(d, outputs=['model', 'errors'], output_type='list')
def _errors(name, data_id, data_out, setting): name = ''.join(k[0].upper() for k in name.split('_')) d = dsp.Dispatcher( name='%s-%s errors' % (name, data_id), description='Calculates the error of calibrated model.', ) setting = setting.copy() d.add_data( data_id='models', default_value=setting.pop('models', []) ) select_data = functools.partial(dsp_utl.selector, allow_miss=True) d.add_function( function_id='select_models', function=setting.pop('select_models', select_data), inputs=['models', data_id], outputs=['calibrated_models'] ) d.add_data( data_id='data_in', default_value=data_id ) d.add_data( data_id='error_settings', default_value={} ) for o in data_out: d.add_function( function=functools.partial( dsp_utl.map_list, ['calibrated_models', 'data'] ), inputs=['calibrated_models', o], outputs=['input/%s' % o] ) d.add_function( function=_error(name, data_id, o, setting), inputs=['input/%s' % o, 'error_settings'], outputs=['error/%s' % o] ) i = ['error_settings', data_id] + [k for k in data_out if k != data_id] func = dsp_utl.SubDispatchFunction( dsp=d, function_id=d.name, inputs=i ) return func
def thermal(): """ Defines the engine thermal model. .. dispatcher:: d >>> d = thermal() :return: The engine thermal model. :rtype: co2mpas.dispatcher.Dispatcher """ d = dsp.Dispatcher(name='thermal', description='Models the engine thermal behaviour.') d.add_function(function=calculate_engine_temperature_derivatives, inputs=['times', 'engine_coolant_temperatures'], outputs=['engine_temperature_derivatives']) d.add_function(function=identify_max_engine_coolant_temperature, inputs=['engine_coolant_temperatures'], outputs=['max_engine_coolant_temperature']) d.add_function(function=calibrate_engine_temperature_regression_model, inputs=[ 'idle_engine_speed', 'on_engine', 'engine_temperature_derivatives', 'engine_coolant_temperatures', 'final_drive_powers_in', 'engine_speeds_out_hot', 'accelerations' ], outputs=['engine_temperature_regression_model']) d.add_function(function=predict_engine_coolant_temperatures, inputs=[ 'engine_temperature_regression_model', 'times', 'final_drive_powers_in', 'engine_speeds_out_hot', 'accelerations', 'initial_engine_temperature', 'max_engine_coolant_temperature' ], outputs=['engine_coolant_temperatures']) d.add_function(function=identify_engine_thermostat_temperature, inputs=['engine_temperature_regression_model'], outputs=['engine_thermostat_temperature']) d.add_function(function=identify_engine_thermostat_temperature_window, inputs=[ 'engine_thermostat_temperature', 'engine_coolant_temperatures' ], outputs=['engine_thermostat_temperature_window']) d.add_function(function=identify_initial_engine_temperature, inputs=['engine_coolant_temperatures'], outputs=['initial_engine_temperature']) return d
def load_inputs(): """ Defines a module to load the input file of the CO2MPAS model. .. dispatcher:: d >>> d = load_inputs() :return: The load input module. :rtype: SubDispatchFunction """ d = dsp.Dispatcher( name='load_inputs', description='Loads from files the inputs for the CO2MPAS model.') d.add_function(function=get_cache_fpath, inputs=['input_file_name'], outputs=['cache_file_name']) d.add_data(data_id='overwrite_cache', default_value=False) d.add_function( function_id='load_data_from_cache', function=dsp_utl.add_args(dill.load_from_dill, n=2), inputs=['overwrite_cache', 'input_file_name', 'cache_file_name'], outputs=['raw_data'], input_domain=check_cache_fpath_exists) d.add_function(function=excel.parse_excel_file, inputs=['input_file_name'], outputs=['raw_data'], input_domain=functools.partial(check_file_format, extensions=('.xlsx', '.xls')), weight=5) d.add_function(function=dill.load_from_dill, inputs=['input_file_name'], outputs=['raw_data'], input_domain=functools.partial(check_file_format, extensions=('.dill', )), weight=5) d.add_function(function_id='load_from_xlasso', function=xleash.lasso, inputs=['input_file_name'], outputs=['raw_data'], input_domain=check_xlasso, weight=5) d.add_function(function_id='cache_parsed_data', function=dill.save_dill, inputs=['raw_data', 'cache_file_name']) return d
def nedc_cycle(): """ Defines the wltp cycle model. .. dispatcher:: d >>> d = nedc_cycle() :return: The wltp cycle model. :rtype: co2mpas.dispatcher.Dispatcher """ d = dsp.Dispatcher( name='NEDC cycle model', description='Returns the theoretical times, velocities, and gears of ' 'NEDC.') from ..defaults import dfl d.add_data(data_id='initial_temperature', default_value=dfl.values.initial_temperature_NEDC, description='Initial temperature of the test cell [°C].') d.add_data(data_id='max_time', default_value=dfl.values.max_time_NEDC, description='Maximum time [s].', initial_dist=5) d.add_data(data_id='k1', default_value=dfl.values.k1) d.add_data(data_id='k2', default_value=dfl.values.k2) d.add_function(function_id='set_max_gear_as_default_k5', function=dsp_utl.bypass, inputs=['max_gear'], outputs=['k5']) d.add_data(data_id='k5', default_value=dfl.values.k5, initial_dist=10) d.add_data(data_id='time_sample_frequency', default_value=dfl.values.time_sample_frequency) d.add_function( function_id='nedc_gears', function=dsp_utl.add_args(nedc_gears), inputs=['gear_box_type', 'times', 'max_gear', 'k1', 'k2', 'k5'], outputs=['gears'], input_domain=lambda *args: args[0] == 'manual') d.add_function(function=nedc_velocities, inputs=['times', 'gear_box_type'], outputs=['velocities']) return d
def cold_start(): """ Defines the engine cold start model. .. dispatcher:: d >>> d = cold_start() :return: The engine start/stop model. :rtype: co2mpas.dispatcher.Dispatcher """ d = dsp.Dispatcher(name='cold_start', description='Models the engine cold start strategy.') d.add_function(function=identify_cold_start_speeds_phases, inputs=[ 'engine_coolant_temperatures', 'engine_thermostat_temperature', 'on_idle' ], outputs=['cold_start_speeds_phases']) d.add_function(function=identify_cold_start_speeds_delta, inputs=[ 'cold_start_speeds_phases', 'engine_speeds_out', 'engine_speeds_out_hot' ], outputs=['cold_start_speeds_delta']) d.add_function(function=calibrate_cold_start_speed_model, inputs=[ 'cold_start_speeds_phases', 'cold_start_speeds_delta', 'idle_engine_speed', 'on_engine', 'engine_coolant_temperatures', 'engine_speeds_out_hot' ], outputs=['cold_start_speed_model']) d.add_function(function=calculate_cold_start_speeds_delta, inputs=[ 'cold_start_speed_model', 'on_engine', 'engine_coolant_temperatures', 'engine_speeds_out_hot', 'idle_engine_speed' ], outputs=['cold_start_speeds_delta']) return d
def run_plan(): """ Defines the plan model. .. dispatcher:: d >>> d = run_plan() :return: The plan model. :rtype: Dispatcher """ d = dsp.Dispatcher(name='run_plan', description='Processes a vehicle plan.') d.add_data(data_id='engineering_mode', default_value=False) d.add_data(data_id='use_selector', default_value=False) d.add_data(data_id='soft_validation', default_value=False) d.add_function(function=dsp_utl.add_args(schema.validate_plan), inputs=[ 'run_plan', 'data', 'engineering_mode', 'soft_validation', 'use_selector' ], outputs=['validated_plan'], input_domain=check_first_arg) d.add_function(function=default_start_time, outputs=['start_time']) d.add_function(function=default_timestamp, inputs=['start_time'], outputs=['timestamp']) from .plan import make_simulation_plan d.add_function(function=make_simulation_plan, inputs=['validated_plan', 'timestamp', 'variation', 'flag'], outputs=['summary']) return dsp_utl.SubDispatch(d)
def cvt_model(): """ Defines the gear box model. .. dispatcher:: d >>> d = cvt_model() :return: The gear box model. :rtype: co2mpas.dispatcher.Dispatcher """ d = dsp.Dispatcher(name='CVT model', description='Models the gear box.') d.add_function(function=calibrate_cvt, inputs=[ 'on_engine', 'engine_speeds_out', 'velocities', 'accelerations', 'gear_box_powers_out' ], outputs=['CVT']) d.add_function( function=predict_gear_box_speeds_in__gears_and_max_gear, inputs=['CVT', 'velocities', 'accelerations', 'gear_box_powers_out'], outputs=['gear_box_speeds_in', 'gears', 'max_gear'], out_weight={'gear_box_speeds_in': 10}) from ..defaults import dfl d.add_data(data_id='stop_velocity', default_value=dfl.values.stop_velocity) d.add_function(function=identify_max_speed_velocity_ratio, inputs=[ 'velocities', 'engine_speeds_out', 'idle_engine_speed', 'stop_velocity' ], outputs=['max_speed_velocity_ratio']) return d
def electrics(): """ Defines the electrics model. .. dispatcher:: d >>> d = electrics() :return: The electrics model. :rtype: co2mpas.dispatcher.Dispatcher """ d = dsp.Dispatcher(name='Electrics', description='Models the vehicle electrics.') from ..defaults import dfl d.add_data(data_id='alternator_efficiency', default_value=dfl.values.alternator_efficiency) d.add_data(data_id='delta_time_engine_starter', default_value=dfl.values.delta_time_engine_starter) d.add_function(function=calculate_engine_start_demand, inputs=[ 'engine_moment_inertia', 'idle_engine_speed', 'alternator_efficiency', 'delta_time_engine_starter' ], outputs=['start_demand'], weight=100) d.add_function(function=identify_electric_loads, inputs=[ 'alternator_nominal_voltage', 'battery_currents', 'alternator_currents', 'gear_box_powers_in', 'times', 'on_engine', 'engine_starts', 'alternator_start_window_width' ], outputs=['electric_load', 'start_demand']) d.add_function(function=default_initial_state_of_charge, inputs=['cycle_type'], outputs=['initial_state_of_charge']) d.add_function(function=identify_charging_statuses, inputs=[ 'times', 'alternator_currents', 'gear_box_powers_in', 'on_engine', 'alternator_current_threshold', 'starts_windows', 'alternator_initialization_time' ], outputs=['alternator_statuses']) d.add_function( function=identify_charging_statuses_and_alternator_initialization_time, inputs=[ 'times', 'alternator_currents', 'gear_box_powers_in', 'on_engine', 'alternator_current_threshold', 'starts_windows', 'state_of_charges', 'accelerations' ], outputs=['alternator_statuses', 'alternator_initialization_time'], weight=1) d.add_function(function=identify_alternator_initialization_time, inputs=[ 'alternator_currents', 'gear_box_powers_in', 'on_engine', 'accelerations', 'state_of_charges', 'alternator_statuses', 'times', 'alternator_current_threshold' ], outputs=['alternator_initialization_time']) d.add_function(function=calculate_state_of_charges, inputs=[ 'battery_capacity', 'times', 'initial_state_of_charge', 'battery_currents', 'max_battery_charging_current' ], outputs=['state_of_charges']) d.add_data(data_id='stop_velocity', default_value=dfl.values.stop_velocity) d.add_data(data_id='alternator_off_threshold', default_value=dfl.values.alternator_off_threshold) d.add_function(function=identify_alternator_current_threshold, inputs=[ 'alternator_currents', 'velocities', 'on_engine', 'stop_velocity', 'alternator_off_threshold' ], outputs=['alternator_current_threshold']) d.add_data(data_id='alternator_start_window_width', default_value=dfl.values.alternator_start_window_width) d.add_function(function=identify_alternator_starts_windows, inputs=[ 'times', 'engine_starts', 'alternator_currents', 'alternator_start_window_width', 'alternator_current_threshold' ], outputs=['starts_windows']) d.add_function(function=calculate_alternator_powers_demand, inputs=[ 'alternator_nominal_voltage', 'alternator_currents', 'alternator_efficiency' ], outputs=['alternator_powers_demand']) d.add_function( function=define_alternator_status_model, inputs=['state_of_charge_balance', 'state_of_charge_balance_window'], outputs=['alternator_status_model']) d.add_function( function=identify_state_of_charge_balance_and_window, inputs=['alternator_status_model'], outputs=['state_of_charge_balance', 'state_of_charge_balance_window']) d.add_data(data_id='has_energy_recuperation', default_value=dfl.values.has_energy_recuperation) d.add_function(function=calibrate_alternator_status_model, inputs=[ 'times', 'alternator_statuses', 'state_of_charges', 'gear_box_powers_in' ], outputs=['alternator_status_model'], weight=10) d.add_function(function=identify_max_battery_charging_current, inputs=['battery_currents'], outputs=['max_battery_charging_current']) d.add_function(function=define_alternator_current_model, inputs=['alternator_charging_currents'], outputs=['alternator_current_model']) d.add_function(function=calibrate_alternator_current_model, inputs=[ 'alternator_currents', 'on_engine', 'times', 'state_of_charges', 'alternator_statuses', 'gear_box_powers_in', 'accelerations', 'alternator_initialization_time' ], outputs=['alternator_current_model']) d.add_function(function=define_electrics_model, inputs=[ 'battery_capacity', 'alternator_status_model', 'max_alternator_current', 'alternator_current_model', 'max_battery_charging_current', 'alternator_nominal_voltage', 'start_demand', 'electric_load', 'has_energy_recuperation', 'alternator_initialization_time', 'times' ], outputs=['electrics_model']) d.add_function(function=predict_vehicle_electrics, inputs=[ 'electrics_model', 'initial_state_of_charge', 'times', 'gear_box_powers_in', 'on_engine', 'engine_starts', 'accelerations' ], outputs=[ 'alternator_currents', 'battery_currents', 'state_of_charges', 'alternator_statuses' ]) d.add_function(function_id='identify_alternator_nominal_power', function=lambda x: max(x), inputs=['alternator_powers_demand'], outputs=['alternator_nominal_power']) d.add_function(function=calculate_max_alternator_current, inputs=[ 'alternator_nominal_voltage', 'alternator_nominal_power', 'alternator_efficiency' ], outputs=['max_alternator_current']) return d
def gear_box(): """ Defines the gear box model. .. dispatcher:: d >>> d = gear_box() :return: The gear box model. :rtype: co2mpas.dispatcher.Dispatcher """ d = dsp.Dispatcher(name='Gear box model', description='Models the gear box.') d.add_function(function=calculate_gear_shifts, inputs=['gears'], outputs=['gear_shifts']) d.add_function( function=get_gear_box_efficiency_constants, inputs=['has_torque_converter'], outputs=['gear_box_efficiency_constants'], ) d.add_function( function=calculate_gear_box_efficiency_parameters_cold_hot, inputs=['gear_box_efficiency_constants', 'engine_max_torque'], outputs=['gear_box_efficiency_parameters_cold_hot'], ) d.add_data(data_id='min_engine_on_speed', default_value=defaults.dfl.values.min_engine_on_speed) d.add_function( function=calculate_gear_box_torques, inputs=[ 'gear_box_powers_out', 'gear_box_speeds_in', 'gear_box_speeds_out', 'min_engine_on_speed' ], outputs=['gear_box_torques'], ) d.add_data( data_id='gear_box_temperature_references', default_value=defaults.dfl.values.gear_box_temperature_references) d.add_function(function=calculate_gear_box_torques_in, inputs=[ 'gear_box_torques', 'gear_box_speeds_in', 'gear_box_speeds_out', 'gear_box_temperatures', 'gear_box_efficiency_parameters_cold_hot', 'gear_box_temperature_references', 'min_engine_on_speed' ], outputs=['gear_box_torques_in<0>']) d.add_function( function=correct_gear_box_torques_in, inputs=[ 'gear_box_torques', 'gear_box_torques_in<0>', 'gears', 'gear_box_ratios' ], outputs=['gear_box_torques_in'], ) d.add_function( function=dsp_utl.bypass, inputs=['gear_box_torques_in<0>'], outputs=['gear_box_torques_in'], weight=100, ) d.add_function( function=calculate_gear_box_efficiencies_v2, inputs=[ 'gear_box_powers_out', 'gear_box_speeds_in', 'gear_box_torques', 'gear_box_torques_in', 'min_engine_on_speed' ], outputs=['gear_box_efficiencies'], ) d.add_function( function=calculate_torques_losses, inputs=['gear_box_torques_in', 'gear_box_torques'], outputs=['gear_box_torque_losses'], ) d.add_function(function=define_gear_box_loss_model, inputs=[ 'gear_box_efficiency_parameters_cold_hot', 'equivalent_gear_box_heat_capacity', 'engine_thermostat_temperature', 'gear_box_temperature_references', 'gear_box_ratios' ], outputs=['gear_box_loss_model']) d.add_function(function=define_gear_box_loss_model, inputs=[ 'gear_box_efficiency_parameters_cold_hot', 'equivalent_gear_box_heat_capacity', 'engine_thermostat_temperature', 'gear_box_temperature_references' ], outputs=['gear_box_loss_model'], weight=10) d.add_function( function=calculate_gear_box_efficiencies_torques_temperatures, inputs=[ 'gear_box_loss_model', 'gear_box_powers_out', 'gear_box_speeds_in', 'gear_box_speeds_out', 'gear_box_torques', 'initial_gear_box_temperature', 'gears' ], outputs=[ 'gear_box_temperatures', 'gear_box_torques_in', 'gear_box_efficiencies' ], weight=40) d.add_function( function=calculate_gear_box_efficiencies_torques_temperatures, inputs=[ 'gear_box_loss_model', 'gear_box_powers_out', 'gear_box_speeds_in', 'gear_box_speeds_out', 'gear_box_torques', 'initial_gear_box_temperature' ], outputs=[ 'gear_box_temperatures', 'gear_box_torques_in', 'gear_box_efficiencies' ], weight=90) d.add_function(function=calculate_gear_box_powers_in, inputs=['gear_box_torques_in', 'gear_box_speeds_in'], outputs=['gear_box_powers_in']) d.add_data( data_id='has_gear_box_thermal_management', default_value=defaults.dfl.values.has_gear_box_thermal_management) d.add_function(function=calculate_equivalent_gear_box_heat_capacity, inputs=['engine_mass', 'has_gear_box_thermal_management'], outputs=['equivalent_gear_box_heat_capacity']) from .mechanical import mechanical d.add_dispatcher(include_defaults=True, dsp=mechanical(), inputs={ 'n_gears': 'n_gears', 'times': 'times', 'velocities': 'velocities', 'accelerations': 'accelerations', 'velocity_speed_ratios': 'velocity_speed_ratios', 'engine_speeds_out': 'engine_speeds_out', 'final_drive_ratio': 'final_drive_ratio', 'gear_box_speeds_out': 'gear_box_speeds_out', 'gear_box_ratios': 'gear_box_ratios', 'gear_box_type': dsp_utl.SINK, 'gears': 'gears', 'idle_engine_speed': 'idle_engine_speed', 'r_dynamic': 'r_dynamic', 'stop_velocity': 'stop_velocity', 'plateau_acceleration': 'plateau_acceleration', 'change_gear_window_width': 'change_gear_window_width' }, outputs={ 'n_gears': 'n_gears', 'gears': 'gears', 'gear_box_ratios': 'gear_box_ratios', 'velocity_speed_ratios': 'velocity_speed_ratios', 'speed_velocity_ratios': 'speed_velocity_ratios', 'gear_box_speeds_in': 'gear_box_speeds_in', 'max_gear': 'max_gear', }, input_domain=not_cvt) from .at_gear import at_gear d.add_dispatcher( include_defaults=True, dsp=at_gear(), dsp_id='at_gear_shifting', inputs={ 'fuel_saving_at_strategy': 'fuel_saving_at_strategy', 'MVL': 'MVL', 'CMV': 'CMV', 'CMV_Cold_Hot': 'CMV_Cold_Hot', 'DT_VA': 'DT_VA', 'DT_VAT': 'DT_VAT', 'DT_VAP': 'DT_VAP', 'DT_VATP': 'DT_VATP', 'GSPV': 'GSPV', 'GSPV_Cold_Hot': 'GSPV_Cold_Hot', 'accelerations': 'accelerations', 'use_dt_gear_shifting': 'use_dt_gear_shifting', 'specific_gear_shifting': 'specific_gear_shifting', 'engine_speeds_out': 'engine_speeds_out', 'full_load_curve': 'full_load_curve', 'gears': 'gears', 'motive_powers': 'motive_powers', 'gear_box_type': dsp_utl.SINK, 'idle_engine_speed': 'idle_engine_speed', 'engine_max_power': 'engine_max_power', 'engine_max_speed_at_max_power': 'engine_max_speed_at_max_power', 'road_loads': 'road_loads', 'engine_coolant_temperatures': 'engine_coolant_temperatures', 'time_cold_hot_transition': 'time_cold_hot_transition', 'times': 'times', 'vehicle_mass': 'vehicle_mass', 'velocities': 'velocities', 'velocity_speed_ratios': 'velocity_speed_ratios', 'stop_velocity': 'stop_velocity', 'plateau_acceleration': 'plateau_acceleration', 'change_gear_window_width': 'change_gear_window_width', 'max_velocity_full_load_correction': 'max_velocity_full_load_correction', 'cycle_type': 'cycle_type' }, outputs={ 'specific_gear_shifting': 'specific_gear_shifting', 'gears': 'gears', 'MVL': 'MVL', 'CMV': 'CMV', 'CMV_Cold_Hot': 'CMV_Cold_Hot', 'DT_VA': 'DT_VA', 'DT_VAT': 'DT_VAT', 'DT_VAP': 'DT_VAP', 'DT_VATP': 'DT_VATP', 'GSPV': 'GSPV', 'GSPV_Cold_Hot': 'GSPV_Cold_Hot', }, input_domain=is_automatic) from .cvt import cvt_model d.add_dispatcher(include_defaults=True, dsp=cvt_model(), dsp_id='cvt_model', inputs={ 'on_engine': 'on_engine', 'gear_box_type': dsp_utl.SINK, 'engine_speeds_out': 'engine_speeds_out', 'velocities': 'velocities', 'accelerations': 'accelerations', 'gear_box_powers_out': 'gear_box_powers_out', 'CVT': 'CVT', 'idle_engine_speed': 'idle_engine_speed', 'stop_velocity': 'stop_velocity' }, outputs={ 'CVT': 'CVT', 'gear_box_speeds_in': 'gear_box_speeds_in', 'gears': 'gears', 'max_gear': 'max_gear', 'max_speed_velocity_ratio': 'max_speed_velocity_ratio' }, input_domain=is_cvt) return d
def mechanical(): """ Defines the mechanical gear box model. .. dispatcher:: d >>> d = mechanical() :return: The gear box mechanical model. :rtype: co2mpas.dispatcher.Dispatcher """ d = dsp.Dispatcher(name='mechanical model', description='Models the gear box mechanical.') d.add_data(data_id='stop_velocity', default_value=defaults.dfl.values.stop_velocity) d.add_data(data_id='plateau_acceleration', default_value=defaults.dfl.values.plateau_acceleration) d.add_data(data_id='change_gear_window_width', default_value=defaults.dfl.values.change_gear_window_width) d.add_function(function=identify_gears, inputs=[ 'times', 'velocities', 'accelerations', 'engine_speeds_out', 'velocity_speed_ratios', 'stop_velocity', 'plateau_acceleration', 'change_gear_window_width', 'idle_engine_speed' ], outputs=['gears']) d.add_function(function=calculate_gear_box_speeds_in, inputs=[ 'gears', 'velocities', 'velocity_speed_ratios', 'stop_velocity' ], outputs=['gear_box_speeds_in'], weight=25) d.add_function(function=calculate_gear_box_speeds_in_v1, inputs=['gears', 'gear_box_speeds_out', 'gear_box_ratios'], outputs=['gear_box_speeds_in']) d.add_function( function=calculate_speed_velocity_ratios, inputs=['gear_box_ratios', 'final_drive_ratio', 'r_dynamic'], outputs=['speed_velocity_ratios']) d.add_function( function=identify_speed_velocity_ratios, inputs=['gears', 'velocities', 'gear_box_speeds_in', 'stop_velocity'], outputs=['speed_velocity_ratios'], weight=5) d.add_function( function=identify_speed_velocity_ratios, inputs=['gears', 'velocities', 'engine_speeds_out', 'stop_velocity'], outputs=['speed_velocity_ratios'], weight=10) d.add_function(function=calculate_velocity_speed_ratios, inputs=['speed_velocity_ratios'], outputs=['velocity_speed_ratios']) d.add_function(function=identify_n_gears, inputs=['gear_box_ratios'], outputs=['n_gears']) d.add_function(function=identify_velocity_speed_ratios, inputs=[ 'n_gears', 'engine_speeds_out', 'velocities', 'idle_engine_speed', 'stop_velocity' ], outputs=['velocity_speed_ratios'], weight=49) d.add_function(function=identify_velocity_speed_ratios, inputs=[ 'engine_speeds_out', 'velocities', 'idle_engine_speed', 'stop_velocity' ], outputs=['velocity_speed_ratios'], weight=50) d.add_function( function=calculate_gear_box_ratios, inputs=['velocity_speed_ratios', 'final_drive_ratio', 'r_dynamic'], outputs=['gear_box_ratios']) d.add_function(function=identify_max_gear, inputs=['speed_velocity_ratios'], outputs=['max_gear']) return d
def clutch(): """ Defines the clutch model. .. dispatcher:: d >>> d = clutch() :return: The clutch model. :rtype: co2mpas.dispatcher.Dispatcher """ d = dsp.Dispatcher(name='Clutch', description='Models the clutch.') d.add_function(function=calculate_clutch_phases, inputs=['times', 'gear_shifts', 'clutch_window'], outputs=['clutch_phases']) d.add_function(function=calculate_clutch_speed_threshold, inputs=['clutch_speeds_delta'], outputs=['clutch_speed_threshold']) from ..defaults import dfl d.add_data(data_id='max_clutch_window_width', default_value=dfl.values.max_clutch_window_width) d.add_function(function=identify_clutch_window, inputs=[ 'times', 'accelerations', 'gear_shifts', 'engine_speeds_out', 'engine_speeds_out_hot', 'cold_start_speeds_delta', 'max_clutch_window_width' ], outputs=['clutch_window']) d.add_function(function=identify_clutch_speeds_delta, inputs=[ 'clutch_phases', 'engine_speeds_out', 'engine_speeds_out_hot', 'cold_start_speeds_delta' ], outputs=['clutch_speeds_delta']) d.add_function( function=calibrate_clutch_prediction_model, inputs=['clutch_phases', 'accelerations', 'clutch_speeds_delta'], outputs=['clutch_model']) d.add_function(function=predict_clutch_speeds_delta, inputs=['clutch_model', 'clutch_phases', 'accelerations'], outputs=['clutch_speeds_delta']) from . import define_k_factor_curve d.add_function(function=define_k_factor_curve, inputs=['stand_still_torque_ratio', 'lockup_speed_ratio'], outputs=['k_factor_curve']) d.add_function(function=default_clutch_k_factor_curve, outputs=['k_factor_curve'], weight=2) return d
def thermal(): """ Defines the gear box thermal sub model. .. dispatcher:: d >>> d = thermal() :return: The gear box thermal sub model. :rtype: co2mpas.dispatcher.Dispatcher """ d = dsp.Dispatcher( name='Gear box thermal sub model', description='Calculates temperature, efficiency, ' 'torque loss of gear box' ) from ..defaults import dfl d.add_data( data_id='gear_box_temperature_references', default_value=dfl.values.gear_box_temperature_references ) d.add_function( function=calculate_gear_box_torque_in, inputs=['gear_box_torque_out', 'gear_box_speed_in', 'gear_box_speed_out', 'gear_box_temperature', 'gear_box_efficiency_parameters_cold_hot', 'gear_box_temperature_references'], outputs=['gear_box_torque_in<0>'] ) d.add_function( function=correct_gear_box_torque_in, inputs=['gear_box_torque_out', 'gear_box_torque_in<0>', 'gear', 'gear_box_ratios'], outputs=['gear_box_torque_in'] ) d.add_function( function=dsp_utl.bypass, inputs=['gear_box_torque_in<0>'], outputs=['gear_box_torque_in'], weight=100, ) d.add_function( function=calculate_gear_box_efficiency, inputs=['gear_box_power_out', 'gear_box_speed_in', 'gear_box_torque_out', 'gear_box_torque_in'], outputs=['gear_box_efficiency'], ) d.add_function( function=calculate_gear_box_heat, inputs=['gear_box_efficiency', 'gear_box_power_out'], outputs=['gear_box_heat'] ) d.add_function( function=calculate_gear_box_temperature, inputs=['gear_box_heat', 'gear_box_temperature', 'equivalent_gear_box_heat_capacity', 'thermostat_temperature'], outputs=['gear_box_temperature'] ) return d
def final_drive(): """ Defines the final drive model. .. dispatcher:: d >>> d = final_drive() :return: The final drive model. :rtype: co2mpas.dispatcher.Dispatcher """ d = dsp.Dispatcher(name='Final drive', description='Models the final drive.') from .defaults import dfl d.add_data(data_id='final_drive_ratio', default_value=dfl.values.final_drive_ratio) d.add_function(function=calculate_final_drive_speeds_in, inputs=['final_drive_speeds_out', 'final_drive_ratio'], outputs=['final_drive_speeds_in']) d.add_data(data_id='final_drive_efficiency', default_value=dfl.values.final_drive_efficiency) d.add_data(data_id='n_wheel_drive', default_value=dfl.values.n_wheel_drive) d.add_function( function=calculate_final_drive_torque_losses, inputs=['final_drive_torques_out', 'final_drive_torque_loss'], outputs=['final_drive_torque_losses']) d.add_function( function=dsp_utl.add_args(calculate_final_drive_torque_losses_v1), inputs=[ 'n_dyno_axes', 'n_wheel_drive', 'final_drive_torques_out', 'final_drive_ratio', 'final_drive_efficiency' ], outputs=['final_drive_torque_losses'], weight=5, input_domain=domain_final_drive_torque_losses_v1) d.add_function(function=calculate_final_drive_torques_in, inputs=[ 'final_drive_torques_out', 'final_drive_ratio', 'final_drive_torque_losses' ], outputs=['final_drive_torques_in']) d.add_function(function=calculate_final_drive_efficiencies, inputs=[ 'final_drive_torques_out', 'final_drive_ratio', 'final_drive_torques_in' ], outputs=['final_drive_efficiencies']) d.add_function( function=calculate_final_drive_powers_in, inputs=['final_drive_powers_out', 'final_drive_efficiencies'], outputs=['final_drive_powers_in']) return d
def selector(*data, pred_cyl_ids=('nedc_h', 'nedc_l', 'wltp_h', 'wltp_l')): """ Defines the models' selector model. .. dispatcher:: d >>> d = selector() :return: The models' selector model. :rtype: SubDispatchFunction """ data = data or ('wltp_h', 'wltp_l') d = dsp.Dispatcher( name='Models selector', description='Select the calibrated models.', ) d.add_function( function=functools.partial(dsp_utl.map_list, data), inputs=data, outputs=['CO2MPAS_results'] ) d.add_data( data_id='models', function=combine_outputs, wait_inputs=True ) d.add_data( data_id='scores', function=combine_outputs, wait_inputs=True ) setting = sub_models() d.add_data( data_id='selector_settings', default_value={} ) m = list(setting) d.add_function( function=functools.partial(split_selector_settings, m), inputs=['selector_settings'], outputs=['selector_settings/%s' % k for k in m] ) for k, v in setting.items(): v['dsp'] = v.pop('define_sub_model', define_sub_model)(**v) v['metrics'] = dsp_utl.map_list(v['targets'], *v['metrics']) d.add_function( function=v.pop('model_selector', _selector)(k, data, data, v), function_id='%s selector' % k, inputs=['CO2MPAS_results', 'selector_settings/%s' % k], outputs=['models', 'scores'] ) pred_mdl_ids = ['models_%s' % k for k in pred_cyl_ids] d.add_function( function=functools.partial(split_prediction_models, cycle_ids=pred_cyl_ids), inputs=['scores', 'models', 'default_models'], outputs=['selections'] + pred_mdl_ids ) func = dsp_utl.SubDispatchFunction( dsp=d, function_id='models_selector', inputs=('selector_settings', 'default_models') + data, outputs=['selections'] + pred_mdl_ids ) return func
def run_base(): """ Defines the vehicle-processing model. .. dispatcher:: d >>> d = run_base() :return: The vehicle-processing model. :rtype: Dispatcher """ d = dsp.Dispatcher( name='run_base', description='Processes a vehicle from the file path to the write of its' ' outputs.') d.add_data(data_id='engineering_mode', default_value=False) d.add_data(data_id='output_folder', default_value='.') d.add_data(data_id='use_selector', default_value=False) d.add_data(data_id='soft_validation', default_value=False) d.add_function(function=dsp_utl.add_args(schema.validate_base), inputs=[ 'run_base', 'data', 'engineering_mode', 'soft_validation', 'use_selector' ], outputs=['validated_base'], input_domain=check_first_arg, weight=10) d.add_data(data_id='only_summary', default_value=False) d.add_function(function=default_vehicle_name, inputs=['input_file_name'], outputs=['vehicle_name']) d.add_function(function=default_start_time, outputs=['start_time']) d.add_function(function=default_timestamp, inputs=['start_time'], outputs=['timestamp']) d.add_function(function=default_output_file_name, inputs=['output_folder', 'vehicle_name', 'timestamp'], outputs=['output_file_name']) from .model import model d.add_function( function=dsp_utl.SubDispatch(model()), inputs=['validated_base'], outputs=['dsp_solution'], ) d.add_function(function=parse_dsp_solution, inputs=['dsp_solution'], outputs=['output_data']) from .report import report d.add_function( function=report(), inputs=['output_data', 'vehicle_name'], outputs=['report', 'summary'], ) d.add_function(function=get_template_file_name, inputs=['output_template', 'input_file_name'], outputs=['template_file_name']) d.add_data(data_id='output_template', default_value=_get_co2mpas_output_template_fpath(), initial_dist=10) from .io import write_outputs d.add_function(function=dsp_utl.add_args(write_outputs()), inputs=[ 'only_summary', 'output_file_name', 'template_file_name', 'report', 'start_time', 'flag' ], outputs=[dsp_utl.SINK], input_domain=lambda *args: not args[0]) d.add_function( function=dsp_utl.add_args(plot_model_workflow), inputs=['plot_workflow', 'output_file_name', 'vehicle_name'], outputs=[dsp_utl.PLOT], weight=30, input_domain=check_first_arg) return dsp_utl.SubDispatch(d)
def vehicle_processing_model(): """ Defines the vehicle-processing model. .. dispatcher:: d >>> d = vehicle_processing_model() :return: The vehicle-processing model. :rtype: Dispatcher """ d = dsp.Dispatcher( name='CO2MPAS vehicle_processing_model', description='Processes a vehicle from the file path to the write of its' ' outputs.') from .io import load_inputs d.add_dispatcher(include_defaults=True, dsp=load_inputs(), inputs={ 'input_file_name': 'input_file_name', 'overwrite_cache': 'overwrite_cache' }, outputs={ 'raw_data': 'raw_data', dsp_utl.SINK: dsp_utl.SINK }) d.add_data(data_id='variation', default_value={}) d.add_data(data_id='overwrite_cache', default_value=False) d.add_data(data_id='output_folder', default_value='.') d.add_data(data_id='timestamp', default_value=None) d.add_data(data_id='type_approval_mode', default_value=False) d.add_data(data_id='modelconf', default_value=None) d.add_function(function=prepare_data, inputs=[ 'raw_data', 'variation', 'input_file_name', 'overwrite_cache', 'output_folder', 'timestamp', 'type_approval_mode', 'modelconf' ], outputs=['base_data', 'plan_data']) d.add_function(function=run_base(), inputs=['base_data'], outputs=['solution'], input_domain=check_run_base) d.add_function(function=run_plan(), inputs=['plan_data'], outputs=['solution'], input_domain=check_run_plan) return d
def electrics_prediction(): """ Defines the electric sub model to predict the alternator loads. .. dispatcher:: d >>> d = electrics_prediction() :return: The electric sub model. :rtype: SubDispatchPipe """ d = dsp.Dispatcher( name='Electric sub model', description='Electric sub model to predict the alternator loads') d.add_function(function=calculate_battery_current, inputs=[ 'electric_load', 'alternator_current', 'alternator_nominal_voltage', 'on_engine', 'max_battery_charging_current' ], outputs=['battery_current']) d.add_function(function=calculate_alternator_current, inputs=[ 'alternator_status', 'on_engine', 'gear_box_power_in', 'max_alternator_current', 'alternator_current_model', 'engine_start_current', 'prev_battery_current', 'acceleration' ], outputs=['alternator_current']) d.add_function(function=calculate_battery_state_of_charge, inputs=[ 'battery_state_of_charge', 'battery_capacity', 'delta_time', 'battery_current', 'prev_battery_current' ], outputs=['battery_state_of_charge']) d.add_function(function=predict_alternator_status, inputs=[ 'alternator_status_model', 'prev_alternator_status', 'battery_state_of_charge', 'gear_box_power_in' ], outputs=['alternator_status']) d.add_function(function=calculate_engine_start_current, inputs=[ 'engine_start', 'start_demand', 'alternator_nominal_voltage', 'delta_time' ], outputs=['engine_start_current']) func = dsp_utl.SubDispatchPipe( dsp=d, function_id='electric_sub_model', inputs=[ 'battery_capacity', 'alternator_status_model', 'max_alternator_current', 'alternator_current_model', 'max_battery_charging_current', 'alternator_nominal_voltage', 'start_demand', 'electric_load', 'delta_time', 'gear_box_power_in', 'acceleration', 'on_engine', 'engine_start', 'prev_alternator_status', 'prev_battery_current', 'battery_state_of_charge' ], outputs=[ 'alternator_current', 'alternator_status', 'battery_current', 'battery_state_of_charge' ]) return func
def vehicle(): """ Defines the vehicle model. .. dispatcher:: d >>> d = vehicle() :return: The vehicle model. :rtype: co2mpas.dispatcher.Dispatcher """ d = dsp.Dispatcher( name='Vehicle free body diagram', description='Calculates forces and power acting on the vehicle.') d.add_function(function=calculate_velocities, inputs=['times', 'obd_velocities'], outputs=['velocities']) d.add_function(function=calculate_accelerations, inputs=['times', 'velocities'], outputs=['accelerations']) d.add_function(function=calculate_aerodynamic_resistances, inputs=['f2', 'velocities'], outputs=['aerodynamic_resistances']) from .defaults import dfl d.add_data( data_id='air_density', default_value=dfl.values.air_density, ) d.add_function( function=calculate_f2, inputs=['air_density', 'aerodynamic_drag_coefficient', 'frontal_area'], outputs=['f2'], weight=5) d.add_function(function=calculate_f0, inputs=['vehicle_mass', 'rolling_resistance_coeff'], outputs=['f0'], weight=5) d.add_data( data_id='angle_slope', default_value=dfl.values.angle_slope, ) d.add_function(function=calculate_angle_slopes, inputs=['times', 'angle_slope'], outputs=['angle_slopes']) d.add_function(function=calculate_rolling_resistance, inputs=['f0', 'angle_slopes'], outputs=['rolling_resistance']) d.add_function(function=calculate_velocity_resistances, inputs=['f1', 'velocities'], outputs=['velocity_resistances']) d.add_function(function=calculate_climbing_force, inputs=['vehicle_mass', 'angle_slopes'], outputs=['climbing_force']) d.add_function(function=select_default_n_dyno_axes, inputs=['cycle_type'], outputs=['n_dyno_axes']) d.add_function(function=select_inertial_factor, inputs=['n_dyno_axes'], outputs=['inertial_factor']) d.add_function(function=calculate_rotational_inertia_forces, inputs=['vehicle_mass', 'inertial_factor', 'accelerations'], outputs=['rotational_inertia_forces']) d.add_function(function=calculate_motive_forces, inputs=[ 'vehicle_mass', 'accelerations', 'climbing_force', 'aerodynamic_resistances', 'rolling_resistance', 'velocity_resistances', 'rotational_inertia_forces' ], outputs=['motive_forces']) d.add_function(function=calculate_motive_powers, inputs=['motive_forces', 'velocities'], outputs=['motive_powers']) d.add_function(function_id='grouping', function=dsp_utl.bypass, inputs=['f0', 'f1', 'f2'], outputs=['road_loads']) d.add_data(data_id='road_loads', description='Cycle road loads [N, N/(km/h), N/(km/h)^2].') d.add_function(function_id='splitting', function=dsp_utl.bypass, inputs=['road_loads'], outputs=['f0', 'f1', 'f2']) d.add_data(data_id='correct_f0', default_value=dfl.values.correct_f0) d.add_function(function=apply_f0_correction, inputs=['f0_uncorrected', 'correct_f0'], outputs=['f0']) return d
def physical(): """ Defines the CO2MPAS physical model. .. dispatcher:: d >>> d = physical() :return: The CO2MPAS physical model. :rtype: co2mpas.dispatcher.Dispatcher """ d = dsp.Dispatcher( name='CO2MPAS physical model', description='Wraps all functions needed to calibrate and predict ' 'light-vehicles\' CO2 emissions.') from .cycle import cycle d.add_dispatcher(include_defaults=True, dsp_id='cycle_model', dsp=cycle(), inputs={ 'wltp_base_model': 'wltp_base_model', 'cycle_type': 'cycle_type', 'k1': 'k1', 'k2': 'k2', 'k5': 'k5', 'max_gear': 'max_gear', 'time_sample_frequency': 'time_sample_frequency', 'gear_box_type': 'gear_box_type', 'times': 'times', 'velocities': 'velocities', 'accelerations': 'accelerations', 'motive_powers': 'motive_powers', 'speed_velocity_ratios': 'speed_velocity_ratios', 'idle_engine_speed': 'idle_engine_speed', 'inertial_factor': 'inertial_factor', 'downscale_phases': 'downscale_phases', 'climbing_force': 'climbing_force', 'full_load_curve': 'full_load_curve', 'downscale_factor': 'downscale_factor', 'downscale_factor_threshold': 'downscale_factor_threshold', 'vehicle_mass': 'vehicle_mass', 'driver_mass': 'driver_mass', 'road_loads': 'road_loads', 'engine_max_power': 'engine_max_power', 'engine_max_speed_at_max_power': 'engine_max_speed_at_max_power', 'max_velocity': 'max_velocity', 'wltp_class': 'wltp_class', 'max_speed_velocity_ratio': 'max_speed_velocity_ratio', 'gears': 'gears', 'max_time': 'max_time', 'bag_phases': 'bag_phases' }, outputs={ 'times': 'times', 'velocities': 'velocities', 'gears': 'gears', 'initial_temperature': 'initial_temperature', 'phases_integration_times': 'phases_integration_times', }) from .vehicle import vehicle d.add_dispatcher(include_defaults=True, dsp_id='vehicle_model', dsp=vehicle(), inputs={ 'obd_velocities': 'obd_velocities', 'n_dyno_axes': 'n_dyno_axes', 'aerodynamic_drag_coefficient': 'aerodynamic_drag_coefficient', 'frontal_area': 'frontal_area', 'air_density': 'air_density', 'angle_slope': 'angle_slope', 'cycle_type': 'cycle_type', 'f0_uncorrected': 'f0_uncorrected', 'correct_f0': 'correct_f0', 'f0': 'f0', 'f1': 'f1', 'f2': 'f2', 'inertial_factor': 'inertial_factor', 'rolling_resistance_coeff': 'rolling_resistance_coeff', 'times': 'times', 'vehicle_mass': 'vehicle_mass', 'velocities': 'velocities', 'road_loads': 'road_loads', 'angle_slopes': 'angle_slopes' }, outputs={ 'f0': 'f0', 'velocities': 'velocities', 'climbing_force': 'climbing_force', 'inertial_factor': 'inertial_factor', 'accelerations': 'accelerations', 'motive_powers': 'motive_powers', 'road_loads': 'road_loads', 'n_dyno_axes': 'n_dyno_axes', 'angle_slopes': 'angle_slopes' }) from .wheels import wheels d.add_dispatcher(include_defaults=True, dsp_id='wheels_model', dsp=wheels(), inputs={ 'times': 'times', 'idle_engine_speed': 'idle_engine_speed', 'accelerations': 'accelerations', 'tyre_code': 'tyre_code', 'tyre_dimensions': 'tyre_dimensions', 'r_wheels': 'r_wheels', 'tyre_dynamic_rolling_coefficient': 'tyre_dynamic_rolling_coefficient', 'r_dynamic': 'r_dynamic', 'velocities': 'velocities', 'gears': 'gears', 'engine_speeds_out': 'engine_speeds_out', 'gear_box_ratios': 'gear_box_ratios', 'final_drive_ratio': 'final_drive_ratio', 'velocity_speed_ratios': 'velocity_speed_ratios', 'motive_powers': 'motive_powers', 'stop_velocity': 'stop_velocity', 'plateau_acceleration': 'plateau_acceleration', 'change_gear_window_width': 'change_gear_window_width' }, outputs={ 'tyre_code': 'tyre_code', 'tyre_dynamic_rolling_coefficient': 'tyre_dynamic_rolling_coefficient', 'r_wheels': 'r_wheels', 'r_dynamic': 'r_dynamic', 'wheel_powers': 'wheel_powers', 'wheel_speeds': 'wheel_speeds', 'wheel_torques': 'wheel_torques' }, inp_weight={'r_dynamic': 3}) from .final_drive import final_drive d.add_dispatcher(include_defaults=True, dsp_id='final_drive_model', dsp=final_drive(), inputs={ 'n_dyno_axes': 'n_dyno_axes', 'n_wheel_drive': 'n_wheel_drive', 'final_drive_efficiency': 'final_drive_efficiency', 'final_drive_ratio': 'final_drive_ratio', 'final_drive_torque_loss': 'final_drive_torque_loss', 'wheel_powers': 'final_drive_powers_out', 'wheel_speeds': 'final_drive_speeds_out', 'wheel_torques': 'final_drive_torques_out' }, outputs={ 'final_drive_powers_in': 'final_drive_powers_in', 'final_drive_speeds_in': 'final_drive_speeds_in', 'final_drive_torques_in': 'final_drive_torques_in', }) from .gear_box import gear_box d.add_dispatcher( include_defaults=True, dsp_id='gear_box_model', dsp=gear_box(), inputs={ 'has_gear_box_thermal_management': 'has_gear_box_thermal_management', 'engine_mass': 'engine_mass', 'on_engine': 'on_engine', 'CVT': 'CVT', 'fuel_saving_at_strategy': 'fuel_saving_at_strategy', 'MVL': 'MVL', 'CMV': 'CMV', 'CMV_Cold_Hot': 'CMV_Cold_Hot', 'DT_VA': 'DT_VA', 'DT_VAT': 'DT_VAT', 'DT_VAP': 'DT_VAP', 'DT_VATP': 'DT_VATP', 'GSPV': 'GSPV', 'GSPV_Cold_Hot': 'GSPV_Cold_Hot', 'cycle_type': 'cycle_type', 'use_dt_gear_shifting': 'use_dt_gear_shifting', 'specific_gear_shifting': 'specific_gear_shifting', 'full_load_curve': 'full_load_curve', 'engine_max_power': 'engine_max_power', 'engine_max_speed_at_max_power': 'engine_max_speed_at_max_power', 'road_loads': 'road_loads', 'engine_coolant_temperatures': 'engine_coolant_temperatures', 'time_cold_hot_transition': 'time_cold_hot_transition', 'vehicle_mass': 'vehicle_mass', 'accelerations': 'accelerations', 'motive_powers': 'motive_powers', 'engine_max_torque': 'engine_max_torque', 'engine_speeds_out': 'engine_speeds_out', 'final_drive_ratio': 'final_drive_ratio', 'final_drive_powers_in': 'gear_box_powers_out', 'final_drive_speeds_in': 'gear_box_speeds_out', 'gear_box_efficiency_constants': 'gear_box_efficiency_constants', 'gear_box_efficiency_parameters_cold_hot': 'gear_box_efficiency_parameters_cold_hot', 'gear_box_ratios': 'gear_box_ratios', 'initial_temperature': 'initial_gear_box_temperature', 'initial_engine_temperature': 'initial_gear_box_temperature', 'initial_gear_box_temperature': 'initial_gear_box_temperature', 'gear_box_type': 'gear_box_type', 'gears': 'gears', 'idle_engine_speed': 'idle_engine_speed', 'r_dynamic': 'r_dynamic', 'gear_box_temperature_references': 'gear_box_temperature_references', 'engine_thermostat_temperature': 'engine_thermostat_temperature', 'times': 'times', 'velocities': 'velocities', 'velocity_speed_ratios': 'velocity_speed_ratios', 'stop_velocity': 'stop_velocity', 'plateau_acceleration': 'plateau_acceleration', 'change_gear_window_width': 'change_gear_window_width', 'min_engine_on_speed': 'min_engine_on_speed', 'max_velocity_full_load_correction': 'max_velocity_full_load_correction', 'has_torque_converter': 'has_torque_converter', 'n_gears': 'n_gears', }, outputs={ 'CVT': 'CVT', 'MVL': 'MVL', 'CMV': 'CMV', 'CMV_Cold_Hot': 'CMV_Cold_Hot', 'DT_VA': 'DT_VA', 'DT_VAT': 'DT_VAT', 'DT_VAP': 'DT_VAP', 'DT_VATP': 'DT_VATP', 'GSPV': 'GSPV', 'GSPV_Cold_Hot': 'GSPV_Cold_Hot', 'equivalent_gear_box_heat_capacity': 'equivalent_gear_box_heat_capacity', 'gears': 'gears', 'gear_box_ratios': 'gear_box_ratios', 'speed_velocity_ratios': 'speed_velocity_ratios', 'gear_box_efficiencies': 'gear_box_efficiencies', 'gear_box_speeds_in': 'gear_box_speeds_in', 'gear_box_temperatures': 'gear_box_temperatures', 'gear_box_torque_losses': 'gear_box_torque_losses', 'gear_box_torques_in': 'gear_box_torques_in', 'gear_box_powers_in': 'gear_box_powers_in', 'max_gear': 'max_gear', 'gear_shifts': 'gear_shifts', 'velocity_speed_ratios': 'velocity_speed_ratios', 'max_speed_velocity_ratio': 'max_speed_velocity_ratio', 'specific_gear_shifting': 'specific_gear_shifting', 'n_gears': 'n_gears', }, inp_weight={'initial_temperature': 5}) from .clutch_tc import clutch_torque_converter d.add_dispatcher(include_defaults=True, dsp=clutch_torque_converter(), dsp_id='clutch_torque_converter_model', inputs={ 'times': 'times', 'velocities': 'velocities', 'accelerations': 'accelerations', 'gear_box_type': 'gear_box_type', 'clutch_model': 'clutch_model', 'clutch_window': 'clutch_window', 'gears': 'gears', 'gear_shifts': 'gear_shifts', 'engine_speeds_out': 'engine_speeds_out', 'engine_speeds_out_hot': 'engine_speeds_out_hot', 'cold_start_speeds_delta': 'cold_start_speeds_delta', 'torque_converter_model': 'torque_converter_model', 'stand_still_torque_ratio': 'stand_still_torque_ratio', 'lockup_speed_ratio': 'lockup_speed_ratio', 'gear_box_speeds_in': 'gear_box_speeds_in', 'gear_box_powers_in': 'gear_box_powers_in', 'lock_up_tc_limits': 'lock_up_tc_limits', 'calibration_tc_speed_threshold': 'calibration_tc_speed_threshold', 'stop_velocity': 'stop_velocity', 'has_torque_converter': 'has_torque_converter' }, outputs={ 'clutch_tc_speeds_delta': 'clutch_tc_speeds_delta', 'clutch_window': 'clutch_window', 'clutch_model': 'clutch_model', 'torque_converter_model': 'torque_converter_model', 'stand_still_torque_ratio': 'stand_still_torque_ratio', 'lockup_speed_ratio': 'lockup_speed_ratio', 'clutch_tc_powers': 'clutch_tc_powers', 'has_torque_converter': 'has_torque_converter' }) from .electrics import electrics d.add_dispatcher(include_defaults=True, dsp_id='electric_model', dsp=electrics(), inputs={ 'cycle_type': 'cycle_type', 'delta_time_engine_starter': 'delta_time_engine_starter', 'alternator_charging_currents': 'alternator_charging_currents', 'alternator_current_model': 'alternator_current_model', 'alternator_currents': 'alternator_currents', 'alternator_efficiency': 'alternator_efficiency', 'alternator_nominal_voltage': 'alternator_nominal_voltage', 'alternator_nominal_power': 'alternator_nominal_power', 'accelerations': 'accelerations', 'state_of_charge_balance': 'state_of_charge_balance', 'state_of_charge_balance_window': 'state_of_charge_balance_window', 'has_energy_recuperation': 'has_energy_recuperation', 'alternator_status_model': 'alternator_status_model', 'idle_engine_speed': 'idle_engine_speed', 'battery_capacity': 'battery_capacity', 'battery_currents': 'battery_currents', 'electric_load': 'electric_load', 'engine_moment_inertia': 'engine_moment_inertia', 'engine_starts': 'engine_starts', 'gear_box_powers_in': 'gear_box_powers_in', 'initial_state_of_charge': 'initial_state_of_charge', 'max_battery_charging_current': 'max_battery_charging_current', 'on_engine': 'on_engine', 'start_demand': 'start_demand', 'times': 'times', 'velocities': 'velocities', 'alternator_statuses': 'alternator_statuses', 'state_of_charges': 'state_of_charges', 'stop_velocity': 'stop_velocity', 'alternator_start_window_width': 'alternator_start_window_width', 'alternator_off_threshold': 'alternator_off_threshold', 'alternator_initialization_time': 'alternator_initialization_time' }, outputs={ 'initial_state_of_charge': 'initial_state_of_charge', 'alternator_current_model': 'alternator_current_model', 'alternator_nominal_power': 'alternator_nominal_power', 'alternator_currents': 'alternator_currents', 'alternator_statuses': 'alternator_statuses', 'alternator_powers_demand': 'alternator_powers_demand', 'alternator_status_model': 'alternator_status_model', 'battery_currents': 'battery_currents', 'electric_load': 'electric_load', 'max_battery_charging_current': 'max_battery_charging_current', 'state_of_charges': 'state_of_charges', 'start_demand': 'start_demand', 'electrics_model': 'electrics_model', 'alternator_initialization_time': 'alternator_initialization_time', 'state_of_charge_balance': 'state_of_charge_balance', 'state_of_charge_balance_window': 'state_of_charge_balance_window' }) from .engine import engine d.add_dispatcher(include_defaults=True, dsp_id='engine_model', dsp=engine(), inputs={ 'has_selective_catalytic_reduction': 'has_selective_catalytic_reduction', 'has_lean_burn': 'has_lean_burn', 'engine_mass': 'engine_mass', 'is_hybrid': 'is_hybrid', 'state_of_charges': 'state_of_charges', 'auxiliaries_torque_loss': 'auxiliaries_torque_loss', 'auxiliaries_power_loss': 'auxiliaries_power_loss', 'alternator_powers_demand': 'alternator_powers_demand', 'on_engine': 'on_engine', 'on_idle': 'on_idle', 'correct_start_stop_with_gears': 'correct_start_stop_with_gears', 'is_cycle_hot': 'is_cycle_hot', 'engine_capacity': 'engine_capacity', 'engine_is_turbo': 'engine_is_turbo', 'engine_max_power': 'engine_max_power', 'engine_max_speed_at_max_power': 'engine_max_speed_at_max_power', 'engine_max_torque': 'engine_max_torque', 'engine_speeds_out': 'engine_speeds_out', 'engine_coolant_temperatures': 'engine_coolant_temperatures', 'engine_temperature_regression_model': 'engine_temperature_regression_model', 'cold_start_speed_model': 'cold_start_speed_model', 'ignition_type': 'ignition_type', 'fuel_type': 'fuel_type', 'full_load_speeds': 'full_load_speeds', 'full_load_torques': 'full_load_torques', 'full_load_powers': 'full_load_powers', 'idle_engine_speed_median': 'idle_engine_speed_median', 'idle_engine_speed_std': 'idle_engine_speed_std', 'initial_temperature': 'initial_engine_temperature', 'initial_engine_temperature': 'initial_engine_temperature', 'velocities': 'velocities', 'accelerations': 'accelerations', 'co2_emission_low': 'co2_emission_low', 'co2_emission_medium': 'co2_emission_medium', 'co2_emission_high': 'co2_emission_high', 'co2_emission_extra_high': 'co2_emission_extra_high', 'co2_params': 'co2_params', 'co2_params_calibrated': 'co2_params_calibrated', 'engine_fuel_lower_heating_value': 'engine_fuel_lower_heating_value', 'engine_idle_fuel_consumption': 'engine_idle_fuel_consumption', 'engine_powers_out': 'engine_powers_out', 'engine_stroke': 'engine_stroke', 'engine_thermostat_temperature_window': 'engine_thermostat_temperature_window', 'engine_thermostat_temperature': 'engine_thermostat_temperature', 'engine_type': 'engine_type', 'fuel_carbon_content_percentage': 'fuel_carbon_content_percentage', 'fuel_carbon_content': 'fuel_carbon_content', 'gear_box_speeds_in': 'gear_box_speeds_in', 'final_drive_powers_in': 'final_drive_powers_in', 'gear_box_type': 'gear_box_type', 'clutch_tc_powers': 'clutch_tc_powers', 'gears': 'gears', 'idle_engine_speed': 'idle_engine_speed', 'start_stop_model': 'start_stop_model', 'start_stop_activation_time': 'start_stop_activation_time', 'times': 'times', 'clutch_tc_speeds_delta': 'clutch_tc_speeds_delta', 'calibration_status': 'calibration_status', 'co2_normalization_references': 'co2_normalization_references', 'fuel_density': 'fuel_density', 'phases_integration_times': 'phases_integration_times', 'enable_phases_willans': 'enable_phases_willans', 'enable_willans': 'enable_willans', 'motive_powers': 'motive_powers', 'engine_starts': 'engine_starts', 'engine_speeds_out_hot': 'engine_speeds_out_hot', 'stop_velocity': 'stop_velocity', 'plateau_acceleration': 'plateau_acceleration', 'min_time_engine_on_after_start': 'min_time_engine_on_after_start', 'min_engine_on_speed': 'min_engine_on_speed', 'initial_friction_params': 'initial_friction_params', 'use_basic_start_stop': 'use_basic_start_stop', 'has_start_stop': 'has_start_stop', 'max_engine_coolant_temperature': 'max_engine_coolant_temperature', 'angle_slopes': 'angle_slopes', 'engine_max_speed': 'engine_max_speed', 'active_cylinder_ratios': 'active_cylinder_ratios', 'engine_has_cylinder_deactivation': 'engine_has_cylinder_deactivation', 'engine_has_variable_valve_actuation': 'engine_has_variable_valve_actuation', 'has_periodically_regenerating_systems': 'has_periodically_regenerating_systems', 'ki_factor': 'ki_factor', 'has_exhausted_gas_recirculation': 'has_exhausted_gas_recirculation' }, outputs={ 'engine_mass': 'engine_mass', 'engine_heat_capacity': 'engine_heat_capacity', 'ignition_type': 'ignition_type', 'has_sufficient_power': 'has_sufficient_power', 'idle_engine_speed_median': 'idle_engine_speed_median', 'idle_engine_speed_std': 'idle_engine_speed_std', 'fuel_carbon_content_percentage': 'fuel_carbon_content_percentage', 'fuel_carbon_content': 'fuel_carbon_content', 'auxiliaries_torque_losses': 'auxiliaries_torque_losses', 'auxiliaries_power_losses': 'auxiliaries_power_losses', 'calibration_status': 'calibration_status', 'correct_start_stop_with_gears': 'correct_start_stop_with_gears', 'co2_emissions_model': 'co2_emissions_model', 'co2_emission_value': 'co2_emission_value', 'co2_emissions': 'co2_emissions', 'identified_co2_emissions': 'identified_co2_emissions', 'co2_error_function_on_emissions': 'co2_error_function_on_emissions', 'co2_error_function_on_phases': 'co2_error_function_on_phases', 'co2_params_calibrated': 'co2_params_calibrated', 'co2_params_initial_guess': 'co2_params_initial_guess', 'cold_start_speed_model': 'cold_start_speed_model', 'engine_max_torque': 'engine_max_torque', 'engine_moment_inertia': 'engine_moment_inertia', 'engine_powers_out': 'engine_powers_out', 'engine_speeds_out': 'engine_speeds_out', 'engine_speeds_out_hot': 'engine_speeds_out_hot', 'cold_start_speeds_delta': 'cold_start_speeds_delta', 'engine_starts': 'engine_starts', 'engine_coolant_temperatures': 'engine_coolant_temperatures', 'engine_thermostat_temperature': 'engine_thermostat_temperature', 'engine_type': 'engine_type', 'engine_thermostat_temperature_window': 'engine_thermostat_temperature_window', 'engine_temperature_regression_model': 'engine_temperature_regression_model', 'fuel_consumptions': 'fuel_consumptions', 'idle_engine_speed': 'idle_engine_speed', 'initial_engine_temperature': 'initial_engine_temperature', 'on_engine': 'on_engine', 'on_idle': 'on_idle', 'phases_co2_emissions': 'phases_co2_emissions', 'start_stop_model': 'start_stop_model', 'full_load_curve': 'full_load_curve', 'engine_max_power': 'engine_max_power', 'engine_max_speed_at_max_power': 'engine_max_speed_at_max_power', 'willans_factors': 'willans_factors', 'optimal_efficiency': 'optimal_efficiency', 'extended_phases_integration_times': 'extended_phases_integration_times', 'extended_phases_co2_emissions': 'extended_phases_co2_emissions', 'after_treatment_temperature_threshold': 'after_treatment_temperature_threshold', 'phases_fuel_consumptions': 'phases_fuel_consumptions', 'fuel_density': 'fuel_density', 'phases_willans_factors': 'phases_willans_factors', 'missing_powers': 'missing_powers', 'brake_powers': 'brake_powers', 'initial_friction_params': 'initial_friction_params', 'use_basic_start_stop': 'use_basic_start_stop', 'max_engine_coolant_temperature': 'max_engine_coolant_temperature', 'engine_temperature_derivatives': 'engine_temperature_derivatives', 'engine_fuel_lower_heating_value': 'engine_fuel_lower_heating_value', 'cold_start_speeds_phases': 'cold_start_speeds_phases', 'full_load_speeds': 'full_load_speeds', 'full_load_powers': 'full_load_powers', 'engine_max_speed': 'engine_max_speed', 'engine_idle_fuel_consumption': 'engine_idle_fuel_consumption', 'active_cylinders': 'active_cylinders', 'active_variable_valves': 'active_variable_valves', 'active_lean_burns': 'active_lean_burns', 'ki_factor': 'ki_factor', 'declared_co2_emission_value': 'declared_co2_emission_value', 'active_exhausted_gas_recirculations': 'active_exhausted_gas_recirculations', 'has_exhausted_gas_recirculation': 'has_exhausted_gas_recirculation' }, inp_weight={'initial_temperature': 5}) d.add_function( function=predict_vehicle_electrics_and_engine_behavior, inputs=[ 'electrics_model', 'start_stop_model', 'engine_temperature_regression_model', 'initial_engine_temperature', 'initial_state_of_charge', 'idle_engine_speed', 'times', 'final_drive_powers_in', 'gear_box_speeds_in', 'gear_box_powers_in', 'velocities', 'accelerations', 'gears', 'start_stop_activation_time', 'correct_start_stop_with_gears', 'min_time_engine_on_after_start', 'has_start_stop', 'use_basic_start_stop', 'max_engine_coolant_temperature' ], outputs=[ 'alternator_currents', 'battery_currents', 'state_of_charges', 'alternator_statuses', 'on_engine', 'engine_starts', 'engine_speeds_out_hot', 'engine_coolant_temperatures' ], weight=10) return d
def cycle(): """ Defines the cycle model. .. dispatcher:: d >>> d = cycle() :return: The cycle model. :rtype: co2mpas.dispatcher.Dispatcher """ d = dsp.Dispatcher( name='Cycle model', description='Returns the theoretical times, velocities, and gears.') from .NEDC import nedc_cycle d.add_dispatcher(include_defaults=True, dsp=nedc_cycle(), inputs={ 'cycle_type': dsp_utl.SINK, 'k1': 'k1', 'k2': 'k2', 'k5': 'k5', 'max_gear': 'max_gear', 'gear_box_type': 'gear_box_type', 'times': 'times', 'time_sample_frequency': 'time_sample_frequency', 'gears': 'gears' }, outputs={ 'velocities': 'velocities', 'gears': 'gears', 'max_time': 'max_time', 'initial_temperature': 'initial_temperature' }, input_domain=is_nedc) from .WLTP import wltp_cycle d.add_dispatcher(include_defaults=True, dsp=wltp_cycle(), inputs={ 'cycle_type': dsp_utl.SINK, 'gear_box_type': 'gear_box_type', 'times': 'times', 'wltp_base_model': 'wltp_base_model', 'velocities': 'velocities', 'accelerations': 'accelerations', 'motive_powers': 'motive_powers', 'speed_velocity_ratios': 'speed_velocity_ratios', 'idle_engine_speed': 'idle_engine_speed', 'inertial_factor': 'inertial_factor', 'downscale_phases': 'downscale_phases', 'climbing_force': 'climbing_force', 'full_load_curve': 'full_load_curve', 'downscale_factor': 'downscale_factor', 'downscale_factor_threshold': 'downscale_factor_threshold', 'vehicle_mass': 'vehicle_mass', 'driver_mass': 'driver_mass', 'road_loads': 'road_loads', 'engine_max_power': 'engine_max_power', 'engine_max_speed_at_max_power': 'engine_max_speed_at_max_power', 'max_velocity': 'max_velocity', 'wltp_class': 'wltp_class', 'max_speed_velocity_ratio': 'max_speed_velocity_ratio', 'time_sample_frequency': 'time_sample_frequency', 'gears': 'gears' }, outputs={ 'velocities': 'velocities', 'gears': 'gears', 'max_time': 'max_time', 'initial_temperature': 'initial_temperature' }, input_domain=is_wltp) d.add_function(function=calculate_time_length, inputs=['time_sample_frequency', 'max_time'], outputs=['time_length']) d.add_function(function=cycle_times, inputs=['time_sample_frequency', 'time_length'], outputs=['times']) d.add_function(function=len, inputs=['velocities'], outputs=['time_length']) d.add_function(function=len, inputs=['gears'], outputs=['time_length'], weight=1) d.add_function(function=extract_phases_integration_times, inputs=['times', 'bag_phases'], outputs=['phases_integration_times']) d.add_function(function=select_phases_integration_times, inputs=['cycle_type'], outputs=['phases_integration_times'], weight=10) return d
def wheels(): """ Defines the wheels model. .. dispatcher:: d >>> d = wheels() :return: The wheels model. :rtype: co2mpas.dispatcher.Dispatcher """ d = dsp.Dispatcher(name='Wheel model', description='It models the wheel dynamics.') d.add_function(function=calculate_wheel_torques, inputs=['wheel_powers', 'wheel_speeds'], outputs=['wheel_torques']) d.add_function(function=calculate_wheel_powers, inputs=['wheel_torques', 'wheel_speeds'], outputs=['wheel_powers']) d.add_function(function=calculate_wheel_speeds, inputs=['velocities', 'r_dynamic'], outputs=['wheel_speeds']) d.add_function(function=identify_r_dynamic, inputs=[ 'velocity_speed_ratios', 'gear_box_ratios', 'final_drive_ratio' ], outputs=['r_dynamic']) d.add_function(function=identify_r_dynamic_v1, inputs=[ 'velocities', 'gears', 'engine_speeds_out', 'gear_box_ratios', 'final_drive_ratio', 'stop_velocity' ], outputs=['r_dynamic'], weight=10) from .defaults import dfl d.add_data(data_id='stop_velocity', default_value=dfl.values.stop_velocity) d.add_data(data_id='plateau_acceleration', default_value=dfl.values.plateau_acceleration) d.add_data(data_id='change_gear_window_width', default_value=dfl.values.change_gear_window_width) d.add_function(function=calculate_tyre_dimensions, inputs=['tyre_code'], outputs=['tyre_dimensions']) d.add_function(function=calculate_r_wheels, inputs=['tyre_dimensions'], outputs=['r_wheels']) d.add_function(function=define_tyre_code, inputs=['tyre_dimensions'], outputs=['tyre_code']) d.add_function(function=default_tyre_code, inputs=['r_dynamic'], outputs=['tyre_code'], weight=5) d.add_data(data_id='tyre_dynamic_rolling_coefficient', default_value=dfl.values.tyre_dynamic_rolling_coefficient, initial_dist=50) d.add_function(function=calculate_r_dynamic, inputs=['r_wheels', 'tyre_dynamic_rolling_coefficient'], outputs=['r_dynamic']) d.add_function(function=identify_tyre_dynamic_rolling_coefficient, inputs=['r_wheels', 'r_dynamic'], outputs=['tyre_dynamic_rolling_coefficient']) d.add_function(function=identify_r_dynamic_v2, inputs=[ 'times', 'velocities', 'accelerations', 'r_wheels', 'engine_speeds_out', 'gear_box_ratios', 'final_drive_ratio', 'idle_engine_speed', 'stop_velocity', 'plateau_acceleration', 'change_gear_window_width' ], outputs=['r_dynamic'], weight=11) d.add_function(function=dsp_utl.bypass, inputs=['motive_powers'], outputs=['wheel_powers']) return d
def start_stop(): """ Defines the engine start/stop model. .. dispatcher:: d >>> d = start_stop() :return: The engine start/stop model. :rtype: co2mpas.dispatcher.Dispatcher """ d = dsp.Dispatcher(name='start_stop', description='Models the engine start/stop strategy.') d.add_function(function=identify_on_engine, inputs=[ 'times', 'engine_speeds_out', 'idle_engine_speed', 'min_time_engine_on_after_start' ], outputs=['on_engine']) d.add_function(function=identify_engine_starts, inputs=['on_engine'], outputs=['engine_starts']) d.add_data(data_id='start_stop_activation_time', default_value=defaults.dfl.values.start_stop_activation_time) d.add_function(function=calibrate_start_stop_model, inputs=[ 'on_engine', 'velocities', 'accelerations', 'engine_coolant_temperatures', 'state_of_charges' ], outputs=['start_stop_model']) d.add_function(function=default_correct_start_stop_with_gears, inputs=['gear_box_type'], outputs=['correct_start_stop_with_gears']) d.add_data( data_id='min_time_engine_on_after_start', default_value=defaults.dfl.values.min_time_engine_on_after_start) d.add_data(data_id='has_start_stop', default_value=defaults.dfl.values.has_start_stop) d.add_data(data_id='is_hybrid', default_value=defaults.dfl.values.is_hybrid) d.add_function(function=default_use_basic_start_stop_model, inputs=['is_hybrid'], outputs=['use_basic_start_stop']) d.add_function( function=predict_engine_start_stop, inputs=[ 'start_stop_model', 'times', 'velocities', 'accelerations', 'engine_coolant_temperatures', 'state_of_charges', 'gears', 'correct_start_stop_with_gears', 'start_stop_activation_time', 'min_time_engine_on_after_start', 'has_start_stop', 'use_basic_start_stop' ], outputs=['on_engine', 'engine_starts']) return d
def model(): """ Defines the CO2MPAS model. .. dispatcher:: d >>> d = model() :return: The CO2MPAS model. :rtype: co2mpas.dispatcher.Dispatcher """ from .physical import physical d = dsp.Dispatcher( name='CO2MPAS model', description='Calibrates the models with WLTP data and predicts NEDC ' 'cycle.') ############################################################################ # PRECONDITIONING CYCLE ############################################################################ d.add_data( data_id='input.precondition.wltp_p', description='Dictionary that has all inputs of the calibration cycle.', default_value={}) d.add_function( function_id='calculate_precondition_output', function=dsp_utl.SubDispatch(physical()), inputs=['input.precondition.wltp_p'], outputs=['output.precondition.wltp_p'], description='Wraps all functions needed to calculate the precondition ' 'outputs.') ############################################################################ # WLTP - HIGH CYCLE ############################################################################ d.add_data(data_id='input.calibration.wltp_h', default_value={}) d.add_function( function=select_calibration_data, inputs=['input.calibration.wltp_h', 'output.precondition.wltp_p'], outputs=['data.calibration.wltp_h'], ) d.add_function( function_id='calibrate_with_wltp_h', function=dsp_utl.SubDispatch(physical()), inputs=['data.calibration.wltp_h'], outputs=['output.calibration.wltp_h'], description='Wraps all functions needed to calibrate the models to ' 'predict light-vehicles\' CO2 emissions.') d.add_data(data_id='input.prediction.wltp_h', default_value={}) d.add_function( function=select_prediction_data, inputs=['output.calibration.wltp_h', 'input.prediction.wltp_h'], outputs=['data.prediction.wltp_h']) d.add_function( function_id='predict_wltp_h', function=dsp_utl.SubDispatch(physical()), inputs=['data.prediction.models_wltp_h', 'data.prediction.wltp_h'], outputs=['output.prediction.wltp_h'], description='Wraps all functions needed to predict CO2 emissions.') ############################################################################ # WLTP - LOW CYCLE ############################################################################ d.add_data(data_id='input.calibration.wltp_l', default_value={}) d.add_function( function=select_calibration_data, inputs=['input.calibration.wltp_l', 'output.precondition.wltp_p'], outputs=['data.calibration.wltp_l'], ) d.add_function( function_id='calibrate_with_wltp_l', function=dsp_utl.SubDispatch(physical()), inputs=['data.calibration.wltp_l'], outputs=['output.calibration.wltp_l'], description='Wraps all functions needed to calibrate the models to ' 'predict light-vehicles\' CO2 emissions.') d.add_data(data_id='input.prediction.wltp_l', default_value={}) d.add_function( function=select_prediction_data, inputs=['output.calibration.wltp_l', 'input.prediction.wltp_l'], outputs=['data.prediction.wltp_l']) d.add_function( function_id='predict_wltp_l', function=dsp_utl.SubDispatch(physical()), inputs=['data.prediction.models_wltp_l', 'data.prediction.wltp_l'], outputs=['output.prediction.wltp_l'], description='Wraps all functions needed to predict CO2 emissions.') ############################################################################ # MODEL SELECTOR ############################################################################ from .selector import selector pred_cyl_ids = ('nedc_h', 'nedc_l', 'wltp_h', 'wltp_l') sel = selector('wltp_h', 'wltp_l', pred_cyl_ids=pred_cyl_ids) d.add_data(data_id='config.selector.all', default_value={}) d.add_data(data_id='input.prediction.models', default_value={}) d.add_function(function_id='extract_calibrated_models', function=sel, inputs=[ 'config.selector.all', 'input.prediction.models', 'output.calibration.wltp_h', 'output.calibration.wltp_l' ], outputs=['data.calibration.model_scores'] + ['data.prediction.models_%s' % k for k in pred_cyl_ids]) ############################################################################ # NEDC - HIGH CYCLE ############################################################################ d.add_function( function_id='predict_nedc_h', function=dsp_utl.SubDispatch(physical()), inputs=['data.prediction.models_nedc_h', 'input.prediction.nedc_h'], outputs=['output.prediction.nedc_h'], ) ############################################################################ # NEDC - LOW CYCLE ############################################################################ d.add_function( function_id='predict_nedc_l', function=dsp_utl.SubDispatch(physical()), inputs=['data.prediction.models_nedc_l', 'input.prediction.nedc_l'], outputs=['output.prediction.nedc_l'], ) return d
def wltp_cycle(): """ Defines the wltp cycle model. .. dispatcher:: d >>> d = wltp_cycle() :return: The wltp cycle model. :rtype: co2mpas.dispatcher.Dispatcher """ d = dsp.Dispatcher( name='WLTP cycle model', description='Returns the theoretical times, velocities, and gears of ' 'WLTP.' ) from ..defaults import dfl d.add_data( data_id='initial_temperature', default_value=dfl.values.initial_temperature_WLTP, description='Initial temperature of the test cell [°C].' ) d.add_data( data_id='max_time', default_value=dfl.values.max_time_WLTP, description='Maximum time [s].', initial_dist=5 ) d.add_data( data_id='wltp_base_model', default_value=copy.deepcopy(dfl.values.wltp_base_model) ) d.add_function( function=define_wltp_base_model, inputs=['wltp_base_model'], outputs=['base_model'] ) d.add_data( data_id='time_sample_frequency', default_value=dfl.values.time_sample_frequency ) d.add_dispatcher( dsp=calculate_wltp_velocities(), inputs={ 'times': 'times', 'base_model': 'base_model', 'velocities': 'velocities', 'speed_velocity_ratios': 'speed_velocity_ratios', 'inertial_factor': 'inertial_factor', 'downscale_phases': 'downscale_phases', 'climbing_force': 'climbing_force', 'downscale_factor': 'downscale_factor', 'downscale_factor_threshold': 'downscale_factor_threshold', 'vehicle_mass': 'vehicle_mass', 'driver_mass': 'driver_mass', 'road_loads': 'road_loads', 'engine_max_power': 'engine_max_power', 'engine_max_speed_at_max_power': 'engine_max_speed_at_max_power', 'max_velocity': 'max_velocity', 'wltp_class': 'wltp_class', 'max_speed_velocity_ratio': 'max_speed_velocity_ratio' }, outputs={ 'velocities': 'velocities' } ) d.add_function( function=dsp_utl.add_args(wltp_gears), inputs=['gear_box_type', 'full_load_curve', 'velocities', 'accelerations', 'motive_powers', 'speed_velocity_ratios', 'idle_engine_speed', 'engine_max_speed_at_max_power', 'engine_max_power', 'base_model'], outputs=['gears'], input_domain=lambda *args: args[0] == 'manual', weight=10 ) return d
def calculate_wltp_velocities(): """ Defines the wltp cycle model. .. dispatcher:: d >>> d = calculate_wltp_velocities() :return: The wltp cycle model. :rtype: co2mpas.dispatcher.Dispatcher """ d = dsp.Dispatcher( name='WLTP velocities model', description='Returns the theoretical velocities of WLTP.' ) d.add_function( function=get_dfl, inputs=['base_model'], outputs=['driver_mass', 'resistance_coeffs_regression_curves', 'wltc_data'] ) d.add_function( function=calculate_unladen_mass, inputs=['vehicle_mass', 'driver_mass'], outputs=['unladen_mass'] ) d.add_function( function=wltp_exp.calc_default_resistance_coeffs, inputs=['vehicle_mass', 'resistance_coeffs_regression_curves'], outputs=['road_loads'], weight=15 ) d.add_function( function=calculate_max_speed_velocity_ratio, inputs=['speed_velocity_ratios'], outputs=['max_speed_velocity_ratio'] ) d.add_function( function=calculate_max_velocity, inputs=['engine_max_speed_at_max_power', 'max_speed_velocity_ratio'], outputs=['max_velocity'] ) d.add_function( function=calculate_wltp_class, inputs=['wltc_data', 'engine_max_power', 'unladen_mass', 'max_velocity'], outputs=['wltp_class'] ) d.add_function( function=get_class_data, inputs=['wltc_data', 'wltp_class'], outputs=['class_data'] ) d.add_function( function=get_class_velocities, inputs=['class_data', 'times'], outputs=['class_velocities'], weight=25 ) from ..vehicle import vehicle func = dsp_utl.SubDispatchFunction( dsp=vehicle(), function_id='calculate_class_powers', inputs=['vehicle_mass', 'velocities', 'climbing_force', 'road_loads', 'inertial_factor', 'times'], outputs=['motive_powers'] ) d.add_function( function=func, inputs=['vehicle_mass', 'class_velocities', 'climbing_force', 'road_loads', 'inertial_factor', 'times'], outputs=['class_powers'] ) from ..defaults import dfl d.add_data( data_id='downscale_factor_threshold', default_value=dfl.values.downscale_factor_threshold ) d.add_function( function=calculate_downscale_factor, inputs=['class_data', 'downscale_factor_threshold', 'max_velocity', 'engine_max_power', 'class_powers', 'times'], outputs=['downscale_factor'] ) d.add_function( function=get_downscale_phases, inputs=['class_data'], outputs=['downscale_phases'] ) d.add_function( function=wltp_velocities, inputs=['downscale_factor', 'class_velocities', 'downscale_phases', 'times'], outputs=['velocities'] ) return d
def _error(name, data_id, data_out, setting): d = dsp.Dispatcher( name='%s-%s error vs %s' % (name, data_id, data_out), description='Calculates the error of calibrated model of a reference.', ) default_settings = { 'inputs_map': {}, 'targets': [], 'metrics_inputs': {}, 'up_limit': None, 'dn_limit': None } default_settings.update(setting) it = dsp_utl.selector(['up_limit', 'dn_limit'], default_settings).items() for k, v in it: if v is not None: default_settings[k] = dsp_utl.map_list(setting['targets'], *v) d.add_function( function_id='select_inputs', function=dsp_utl.map_dict, inputs=['inputs_map', 'data'], outputs=['inputs<0>'] ) d.add_function( function_id='select_inputs', function=functools.partial(dsp_utl.selector, allow_miss=True), inputs=['inputs', 'inputs<0>'], outputs=['inputs<1>'] ) d.add_function( function=dsp_utl.combine_dicts, inputs=['calibrated_models', 'inputs<1>'], outputs=['prediction_inputs'] ) d.add_function( function_id='select_targets', function=functools.partial(dsp_utl.selector, allow_miss=True), inputs=['targets', 'data'], outputs=['references'] ) d.add_function( function=functools.partial( default_settings.pop('dsp', lambda x: x), {} ), inputs=['prediction_inputs', 'calibrated_models'], outputs=['results'] ) d.add_function( function_id='select_outputs', function=select_outputs, inputs=['outputs', 'targets', 'results'], outputs=['predictions'] ) d.add_function( function_id='select_metrics_inputs', function=functools.partial(dsp_utl.selector, allow_miss=True), inputs=['metrics_inputs', 'data'], outputs=['metrics_args'] ) d.add_function( function=make_metrics, inputs=['metrics', 'references', 'predictions', 'metrics_args'], outputs=['errors'] ) d.add_function( function=check_limits, inputs=['errors', 'up_limit', 'dn_limit'], outputs=['status'] ) for k, v in default_settings.items(): d.add_data(k, v) func = dsp_utl.SubDispatch( dsp=d, outputs=['errors', 'status'], output_type='list' ) return func
def clutch_torque_converter(): """ Defines the clutch and torque-converter model. .. dispatcher:: d >>> d = clutch_torque_converter() :return: The clutch and torque-converter model. :rtype: co2mpas.dispatcher.Dispatcher """ d = dsp.Dispatcher(name='Clutch and torque-converter', description='Models the clutch and torque-converter.') d.add_function(function=default_has_torque_converter, inputs=['gear_box_type'], outputs=['has_torque_converter']) d.add_function(function=calculate_clutch_tc_powers, inputs=[ 'clutch_tc_speeds_delta', 'k_factor_curve', 'gear_box_speeds_in', 'gear_box_powers_in', 'engine_speeds_out' ], outputs=['clutch_tc_powers']) from .clutch import clutch d.add_dispatcher(include_defaults=True, input_domain=clutch_domain, dsp=clutch(), dsp_id='clutch', inputs={ 'times': 'times', 'accelerations': 'accelerations', 'has_torque_converter': dsp_utl.SINK, 'clutch_model': 'clutch_model', 'clutch_window': 'clutch_window', 'clutch_tc_speeds_delta': 'clutch_speeds_delta', 'gear_shifts': 'gear_shifts', 'stand_still_torque_ratio': 'stand_still_torque_ratio', 'lockup_speed_ratio': 'lockup_speed_ratio', 'max_clutch_window_width': 'max_clutch_window_width', 'engine_speeds_out': 'engine_speeds_out', 'engine_speeds_out_hot': 'engine_speeds_out_hot', 'cold_start_speeds_delta': 'cold_start_speeds_delta' }, outputs={ 'clutch_speeds_delta': 'clutch_tc_speeds_delta', 'clutch_window': 'clutch_window', 'clutch_model': 'clutch_model', 'k_factor_curve': 'k_factor_curve' }) from .torque_converter import torque_converter d.add_dispatcher(include_defaults=True, input_domain=torque_converter_domain, dsp=torque_converter(), dsp_id='torque_converter', inputs={ 'lock_up_tc_limits': 'lock_up_tc_limits', 'calibration_tc_speed_threshold': 'calibration_tc_speed_threshold', 'stop_velocity': 'stop_velocity', 'velocities': 'velocities', 'accelerations': 'accelerations', 'has_torque_converter': dsp_utl.SINK, 'gears': 'gears', 'clutch_tc_speeds_delta': 'torque_converter_speeds_delta', 'engine_speeds_out_hot': ('gear_box_speeds_in', 'engine_speeds_out_hot'), 'torque_converter_model': 'torque_converter_model', 'stand_still_torque_ratio': 'stand_still_torque_ratio', 'lockup_speed_ratio': 'lockup_speed_ratio', 'engine_speeds_out': 'engine_speeds_out', 'cold_start_speeds_delta': 'cold_start_speeds_delta' }, outputs={ 'torque_converter_speeds_delta': 'clutch_tc_speeds_delta', 'torque_converter_model': 'torque_converter_model', 'k_factor_curve': 'k_factor_curve' }) return d