예제 #1
0
파일: hard.py 프로젝트: tobenum/CO2MPAS-TA
def check_sign_currents(battery_currents, alternator_currents):
    """
    Checks if battery currents and alternator currents have the right signs.

    :param battery_currents:
        Low voltage battery current vector [A].
    :type battery_currents: numpy.array

    :param alternator_currents:
        Alternator currents [A].
    :type alternator_currents: numpy.array

    :return:
        If battery and alternator currents have the right signs.
    :rtype: (bool, bool)
    """
    #: Maximum allowed positive current for the alternator currents check [A].
    import co2mpas.utils as co2_utl
    max_pos_curr = 1.0
    b_c, a_c = battery_currents, alternator_currents

    a = co2_utl.reject_outliers(a_c, med=np.mean)[0]
    a = a <= max_pos_curr
    c = np.cov(a_c, b_c)[0][1]

    if c < 0:
        x = (a, a)
    elif c == 0:
        if any(b_c):
            x = (co2_utl.reject_outliers(b_c, med=np.mean)[0] <= 0, a)
        else:
            x = (True, a)
    else:
        x = (not a, a)
    return x
예제 #2
0
def check_sign_currents(battery_currents, alternator_currents):
    """
    Checks if battery currents and alternator currents have the right signs.

    :param battery_currents:
        Low voltage battery current vector [A].
    :type battery_currents: numpy.array

    :param alternator_currents:
        Alternator current vector [A].
    :type alternator_currents: numpy.array

    :return:
        If battery and alternator currents have the right signs.
    :rtype: (bool, bool)
    """

    b_c, a_c = battery_currents, alternator_currents

    a = co2_utl.reject_outliers(a_c, med=np.mean)[0]
    a = a <= con_vals.MAX_VALIDATE_POS_CURR
    c = np.cov(a_c, b_c)[0][1]

    if c < 0:
        x = (a, a)
    elif c == 0:
        if any(b_c):
            x = (co2_utl.reject_outliers(b_c, med=np.mean)[0] <= 0, a)
        else:
            x = (True, a)
    else:
        x = (not a, a)
    return x
예제 #3
0
def identify_service_battery_load(service_battery_loads, engine_powers_out,
                                  on_engine):
    """
    Identifies service electric load (engine off and on) [kW].

    :param service_battery_loads:
        Service battery load vector [kW].
    :type service_battery_loads: numpy.array

    :param engine_powers_out:
        Engine power vector [kW].
    :type engine_powers_out: numpy.array

    :param on_engine:
        If the engine is on [-].
    :type on_engine: numpy.array

    :return:
        Service electric load (engine off and on) [kW].
    :rtype: float, float
    """
    rjo, mae = co2_utl.reject_outliers, co2_utl.mae
    p, b = service_battery_loads, engine_powers_out >= -dfl.EPS
    on = min(0.0, co2_utl.reject_outliers(p[on_engine & b], med=np.mean)[0])
    off, b_off = on, b & ~on_engine & (p < 0)
    if b_off.any():
        off = rjo(p[b_off], med=np.mean)[0]
        if on > off:
            p = p[b]
            if mae(p, on) > mae(p, off):
                on = off
            else:
                off = on
    return off, on
예제 #4
0
def identify_r_dynamic(velocity_speed_ratios, gear_box_ratios,
                       final_drive_ratios):
    """
    Identifies the dynamic radius of the wheels [m].

    :param velocity_speed_ratios:
        Constant velocity speed ratios of the gear box [km/(h*RPM)].
    :type velocity_speed_ratios: dict[int | float]

    :param gear_box_ratios:
        Gear box ratios [-].
    :type gear_box_ratios: dict[int | float]

    :param final_drive_ratios:
        Final drive ratios [-].
    :type final_drive_ratios: dict[int | float]

    :return:
        Dynamic radius of the wheels [m].
    :rtype: float
    """

    svr = gb_mec.calculate_speed_velocity_ratios(gear_box_ratios,
                                                 final_drive_ratios, 1)

    r = [svr[k] * vs for k, vs in velocity_speed_ratios.items() if k]

    r_dynamic = co2_utl.reject_outliers(r)[0]

    return r_dynamic
예제 #5
0
def identify_r_dynamic(velocity_speed_ratios, gear_box_ratios,
                       final_drive_ratios):
    """
    Identifies the dynamic radius of the wheels [m].

    :param velocity_speed_ratios:
        Constant velocity speed ratios of the gear box [km/(h*RPM)].
    :type velocity_speed_ratios: dict[int | float]

    :param gear_box_ratios:
        Gear box ratios [-].
    :type gear_box_ratios: dict[int, float | int]

    :param final_drive_ratios:
        Final drive ratios [-].
    :type final_drive_ratios: dict[int, float | int]

    :return:
        Dynamic radius of the wheels [m].
    :rtype: float
    """
    from co2mpas.utils import reject_outliers
    from .gear_box.mechanical import calculate_speed_velocity_ratios
    svr = calculate_speed_velocity_ratios(gear_box_ratios, final_drive_ratios,
                                          1)

    r = [svr[k] * vs for k, vs in velocity_speed_ratios.items() if k]

    r_dynamic = reject_outliers(r)[0]

    return r_dynamic
예제 #6
0
def identify_service_battery_capacity(times, service_battery_currents,
                                      service_battery_state_of_charges):
    """
    Identify service battery capacity [Ah].

    :param times:
        Time vector [s].
    :type times: numpy.array

    :param service_battery_currents:
        Service battery current vector [A].
    :type service_battery_currents: numpy.array

    :param service_battery_state_of_charges:
        State of charge of the service battery [%].
    :type service_battery_state_of_charges: numpy.array

    :return:
        Service battery capacity [Ah].
    :rtype: float
    """
    soc = service_battery_state_of_charges
    ib = calculate_service_battery_currents_v1(1, times, soc)
    b = (ib < -dfl.EPS) | (ib > dfl.EPS)
    return co2_utl.reject_outliers(service_battery_currents[b] / ib[b])[0]
예제 #7
0
파일: drive.py 프로젝트: tobenum/CO2MPAS-TA
def identify_drive_battery_load(drive_battery_loads):
    """
    Identifies drive electric load [kW].

    :param drive_battery_loads:
        Drive battery load vector [kW].
    :type drive_battery_loads: numpy.array

    :return:
        Drive electric load [kW].
    :rtype: float
    """
    return co2_utl.reject_outliers(drive_battery_loads)[0]
예제 #8
0
def identify_clutch_tc_mean_efficiency(clutch_tc_efficiencies):
    """
    Identify clutch or torque converter mean efficiency [-].

    :param clutch_tc_efficiencies:
        Clutch or torque converter efficiency [-].
    :type clutch_tc_efficiencies: numpy.array

    :return:
        Clutch or torque converter mean efficiency [-].
    :rtype: float
    """
    from co2mpas.utils import reject_outliers
    return reject_outliers(clutch_tc_efficiencies)[0]
예제 #9
0
def identify_r_dynamic_v1(velocities, gears, gear_box_speeds_in,
                          gear_box_ratios, final_drive_ratios, stop_velocity):
    """
    Identifies the dynamic radius of the wheels [m].

    :param velocities:
        Vehicle velocity [km/h].
    :type velocities: numpy.array

    :param gears:
        Gear vector [-].
    :type gears: numpy.array

    :param gear_box_speeds_in:
        Gear box speed [RPM].
    :type gear_box_speeds_in: numpy.array

    :param gear_box_ratios:
        Gear box ratios [-].
    :type gear_box_ratios: dict[int, float | int]

    :param final_drive_ratios:
        Final drive ratios [-].
    :type final_drive_ratios: dict[int, float | int]

    :param stop_velocity:
        Maximum velocity to consider the vehicle stopped [km/h].
    :type stop_velocity: float

    :return:
        Dynamic radius of the wheels [m].
    :rtype: float
    """
    import numpy as np
    from co2mpas.utils import reject_outliers
    from .gear_box import mechanical as gb_mec
    svr = gb_mec.calculate_speed_velocity_ratios(gear_box_ratios,
                                                 final_drive_ratios, 1.0)

    vsr = gb_mec.calculate_velocity_speed_ratios(svr)

    speed_x_r_dyn_ratios = gb_mec.calculate_gear_box_speeds_in(
        gears, velocities, vsr, stop_velocity)
    with np.errstate(divide='ignore', invalid='ignore'):
        r_dynamic = speed_x_r_dyn_ratios / gear_box_speeds_in
    r_dynamic = r_dynamic[np.isfinite(r_dynamic)]
    r_dynamic = reject_outliers(r_dynamic)[0]
    return r_dynamic
예제 #10
0
def identify_r_dynamic_v1(velocities, gears, engine_speeds_out,
                          gear_box_ratios, final_drive_ratios, stop_velocity):
    """
    Identifies the dynamic radius of the wheels [m].

    :param velocities:
        Vehicle velocity [km/h].
    :type velocities: numpy.array

    :param gears:
        Gear vector [-].
    :type gears: numpy.array

    :param engine_speeds_out:
        Engine speed [RPM].
    :type engine_speeds_out: numpy.array

    :param gear_box_ratios:
        Gear box ratios [-].
    :type gear_box_ratios: dict[int | float]

    :param final_drive_ratios:
        Final drive ratios [-].
    :type final_drive_ratios: dict[int | float]

    :param stop_velocity:
        Maximum velocity to consider the vehicle stopped [km/h].
    :type stop_velocity: float

    :return:
        Dynamic radius of the wheels [m].
    :rtype: float
    """

    svr = gb_mec.calculate_speed_velocity_ratios(gear_box_ratios,
                                                 final_drive_ratios, 1.0)

    vsr = gb_mec.calculate_velocity_speed_ratios(svr)

    speed_x_r_dyn_ratios = gb_mec.calculate_gear_box_speeds_in(
        gears, velocities, vsr, stop_velocity)

    r_dynamic = speed_x_r_dyn_ratios / engine_speeds_out
    r_dynamic = r_dynamic[~np.isnan(r_dynamic)]
    r_dynamic = co2_utl.reject_outliers(r_dynamic)[0]

    return r_dynamic
예제 #11
0
파일: p4.py 프로젝트: tobenum/CO2MPAS-TA
def identify_motor_p4_speed_ratio(wheel_speeds, motor_p4_speeds):
    """
    Identifies motor P4 speed ratio.

    :param wheel_speeds:
        Rotating speed of the wheel [RPM].
    :type wheel_speeds: numpy.array | float

    :param motor_p4_speeds:
        Rotating speed of motor P4 [RPM].
    :type motor_p4_speeds: numpy.array | float

    :return:
        Motor P4 speed ratio [-].
    :rtype: float
    """
    b = wheel_speeds > 0
    return co2_utl.reject_outliers(motor_p4_speeds[b] / wheel_speeds[b])[0]
예제 #12
0
def identify_upper_bound_engine_speed(gears, engine_speeds_out,
                                      idle_engine_speed):
    """
    Identifies upper bound engine speed [RPM].

    It is used to correct the gear prediction for constant accelerations (see
    :func:`co2mpas.model.physical.at_gear.
    correct_gear_upper_bound_engine_speed`).

    This is evaluated as the median value plus 0.67 standard deviation of the
    filtered cycle engine speed (i.e., the engine speeds when engine speed >
    minimum engine speed plus 0.67 standard deviation and gear < maximum gear).

    :param gears:
        Gear vector [-].
    :type gears: numpy.array

    :param engine_speeds_out:
         Engine speed vector [RPM].
    :type engine_speeds_out: numpy.array

    :param idle_engine_speed:
        Idle engine speed and its standard deviation [RPM].
    :type idle_engine_speed: (float, float)

    :returns:
        Upper bound engine speed [RPM].
    :rtype: float

    .. note:: Assuming a normal distribution then about 68 percent of the data
       values are within 0.67 standard deviation of the mean.
    """

    max_gear = max(gears)

    idle_speed = idle_engine_speed[1]

    dom = (engine_speeds_out > idle_speed) & (gears < max_gear)

    m, sd = co2_utl.reject_outliers(engine_speeds_out[dom])

    return m + sd * 0.674490
예제 #13
0
def identify_alternator_current_threshold(alternator_currents, velocities,
                                          on_engine, stop_velocity,
                                          alternator_off_threshold):
    """
    Identifies the alternator current threshold [A] that identifies when the
    alternator is off.

    :param alternator_currents:
        Alternator current vector [A].
    :type alternator_currents: numpy.array

    :param velocities:
        Velocity vector [km/h].
    :type velocities: numpy.array

    :param on_engine:
        If the engine is on [-].
    :type on_engine: numpy.array

    :param stop_velocity:
        Maximum velocity to consider the vehicle stopped [km/h].
    :type stop_velocity: float

    :param alternator_off_threshold:
        Maximum negative current for being considered the alternator off [A].
    :type alternator_off_threshold: float

    :return:
        Alternator current threshold [A].
    :rtype: float
    """

    b, l = np.logical_not(on_engine), -float('inf')
    if not b.any():
        b, l = velocities < stop_velocity, alternator_off_threshold
        b &= alternator_currents < 0

    if b.any():
        return min(0.0,
                   max(co2_utl.reject_outliers(alternator_currents[b])[0], l))
    return 0.0
예제 #14
0
def identify_gear_box_mean_efficiency(gear_box_powers_in, gear_box_powers_out):
    """
    Identify gear box mean efficiency [-].

    :param gear_box_powers_in:
        Gear box power in vector [kW].
    :type gear_box_powers_in: numpy.array

    :param gear_box_powers_out:
        Gear box power out vector [kW].
    :type gear_box_powers_out: numpy.array

    :return:
        Gear box mean efficiency [-].
    :rtype: float
    """
    with np.errstate(divide='ignore', invalid='ignore'):
        eff = gear_box_powers_out / gear_box_powers_in
        b = eff > 1
        eff[b] = 1 / eff[b]
        return reject_outliers(eff[np.isfinite(eff) & (eff >= 0)])[0]
예제 #15
0
def identify_speed_velocity_ratios(gears, velocities, gear_box_speeds_in,
                                   stop_velocity):
    """
    Identifies speed velocity ratios from gear vector [h*RPM/km].

    :param gears:
        Gear vector [-].
    :type gears: numpy.array

    :param velocities:
        Velocity vector [km/h].
    :type velocities: numpy.array

    :param gear_box_speeds_in:
        Gear box speed vector [RPM].
    :type gear_box_speeds_in: numpy.array

    :param stop_velocity:
        Maximum velocity to consider the vehicle stopped [km/h].
    :type stop_velocity: float

    :return:
        Speed velocity ratios of the gear box [h*RPM/km].
    :rtype: dict
    """

    ratios = gear_box_speeds_in / velocities

    ratios[velocities < stop_velocity] = 0

    svr = {
        k: co2_utl.reject_outliers(ratios[gears == k])[0]
        for k in range(1,
                       int(max(gears)) + 1) if k in gears
    }
    svr[0] = INF

    return svr
예제 #16
0
    def fit(self, gears, velocities, velocity_speed_ratios, idle_engine_speed,
            stop_velocity):
        self.velocity_speed_ratios = velocity_speed_ratios
        idle = idle_engine_speed
        mvl = [np.array([idle[0] - idle[1], idle[0] + idle[1]])]
        for k in range(1, int(max(gears)) + 1):
            lm, on, vsr = [], None, velocity_speed_ratios[k]

            for i, b in enumerate(itertools.chain(gears == k, [False])):
                if not b and on is not None:
                    v = velocities[on:i]
                    lm.append([min(v), max(v)])
                    on = None

                elif on is None and b:
                    on = i

            if lm:
                min_v, max_v = zip(*lm)
                lm = [sum(co2_utl.reject_outliers(min_v)), max(max_v)]
                mvl.append(np.array([max(idle[0], l / vsr) for l in lm]))
            else:
                mvl.append(mvl[-1].copy())

        mvl = [[k, tuple(v * velocity_speed_ratios[k])]
               for k, v in reversed(list(enumerate(mvl[1:], 1)))]
        mvl[0][1] = (mvl[0][1][0], dfl.INF)
        mvl.append([0, (0, mvl[-1][1][0])])

        for i, v in enumerate(mvl[1:]):
            v[1] = (v[1][0], max(v[1][1], mvl[i][1][0] + stop_velocity))

        self.clear()
        # noinspection PyTypeChecker
        self.update(collections.OrderedDict(mvl))

        return self
예제 #17
0
def identify_planetary_ratio(planetary_speeds_in, engine_speeds_out,
                             final_drive_speeds_in):
    """
    Calculates final drive speed [RPM].

    :param planetary_speeds_in:
        Planetary speed vector [RPM].
    :type planetary_speeds_in: numpy.array

    :param engine_speeds_out:
        Engine speed vector [RPM].
    :type engine_speeds_out: numpy.array

    :param final_drive_speeds_in:
        Final drive speed in [RPM].
    :type final_drive_speeds_in: float

    :return:
        Fundamental planetary speed ratio [-].
    :rtype: numpy.array
    """
    r = planetary_speeds_in - engine_speeds_out
    r /= engine_speeds_out - final_drive_speeds_in
    return co2_utl.reject_outliers(r)
예제 #18
0
def identify_electric_loads(alternator_nominal_voltage, battery_currents,
                            alternator_currents, gear_box_powers_in, times,
                            on_engine, engine_starts,
                            alternator_start_window_width):
    """
    Identifies vehicle electric load and engine start demand [kW].

    :param alternator_nominal_voltage:
        Alternator nominal voltage [V].
    :type alternator_nominal_voltage: float

    :param battery_currents:
        Low voltage battery current vector [A].
    :type battery_currents: numpy.array

    :param alternator_currents:
        Alternator current vector [A].
    :type alternator_currents: numpy.array

    :param gear_box_powers_in:
        Gear box power vector [kW].
    :type gear_box_powers_in: numpy.array

    :param times:
        Time vector [s].
    :type times: numpy.array

    :param on_engine:
        If the engine is on [-].
    :type on_engine: numpy.array

    :param engine_starts:
        When the engine starts [-].
    :type engine_starts: numpy.array

    :param alternator_start_window_width:
        Alternator start window width [s].
    :type alternator_start_window_width: float

    :return:
        Vehicle electric load (engine off and on) [kW] and energy required to
        start engine [kJ].
    :rtype: ((float, float), float)
    """

    b_c, a_c = battery_currents, alternator_currents
    c = alternator_nominal_voltage / 1000.0

    b = gear_box_powers_in >= 0
    bL = b & np.logical_not(on_engine) & (b_c < 0)
    bH = b & on_engine

    off = min(0.0, c * co2_utl.reject_outliers(b_c[bL], med=np.mean)[0])
    on = min(off,
             c * co2_utl.reject_outliers(b_c[bH] + a_c[bH], med=np.mean)[0])

    loads = [off, on]
    start_demand = []
    dt = alternator_start_window_width / 2
    for i, j in _starts_windows(times, engine_starts, dt):
        p = b_c[i:j] * c
        # noinspection PyUnresolvedReferences
        p[p > 0] = 0.0
        # noinspection PyTypeChecker
        p = np.trapz(p, x=times[i:j])

        if p < 0:
            l = np.trapz(np.choose(on_engine[i:j], loads), x=times[i:j])
            if p < l:
                start_demand.append(p - l)

    start_demand = -co2_utl.reject_outliers(
        start_demand)[0] if start_demand else 0.0

    return (off, on), start_demand