Exemplo n.º 1
0
def _calibrate_gsm(
        velocity_speed_ratios, on_engine, anomalies, gear, velocities,
        stop_velocity, idle_engine_speed):
    # noinspection PyProtectedMember
    from .at_gear.cmv import CMV, _filter_gear_shifting_velocity as filter_gs
    idle = idle_engine_speed[0] - idle_engine_speed[1]
    _vsr = sh.combine_dicts(velocity_speed_ratios, base={0: 0})

    limits = {
        0: {False: [0]},
        1: {True: [stop_velocity]},
        max(_vsr): {True: [dfl.INF]}
    }
    shifts = np.unique(sum(map(_shift, (on_engine, anomalies)), []))
    for i, j in sh.pairwise(shifts):
        if on_engine[i:j].all() and not anomalies[i:j].any():
            for v in np.array(list(sh.pairwise(_shift(gear[i:j])))) + i:
                if j != v[1]:
                    v, (g, ng) = velocities[slice(*v)], gear[[v[1] - 1, v[1]]]
                    up = g < ng
                    sh.get_nested_dicts(limits, g, up, default=list).append(
                        v.max() if up else v.min()
                    )

    for k, v in list(limits.items()):
        limits[k] = v.get(False, [_vsr[k] * idle] * 2), v.get(True, [])
    d = {j: i for i, j in enumerate(sorted(limits))}
    gsm = CMV(filter_gs(sh.map_dict(d, limits), stop_velocity))
    gsm.velocity_speed_ratios = sh.selector(gsm, sh.map_dict(d, _vsr))
    gsm.convert(_vsr)
    return gsm
Exemplo n.º 2
0
    def fit(self, gears, velocities, motive_powers, velocity_speed_ratios,
            stop_velocity):
        self.clear()

        self.velocity_speed_ratios = velocity_speed_ratios

        it = zip(velocities, motive_powers, sh.pairwise(gears))

        for v, p, (g0, g1) in it:
            if v > stop_velocity and g0 != g1:
                x = self.get(g0, [[], [[], []]])
                if g0 < g1 and p >= 0:
                    x[1][0].append(p)
                    x[1][1].append(v)
                elif g0 > g1 and p <= 0:
                    x[0].append(v)
                else:
                    continue
                self[g0] = x

        self[0] = [[0.0], [[0.0], [stop_velocity]]]

        self[max(self)][1] = [[0, 1], [dfl.INF] * 2]

        self.cloud = {k: copy.deepcopy(v) for k, v in self.items()}

        self._fit_cloud()

        return self
Exemplo n.º 3
0
def _identify_gear_shifting_velocity_limits(gears, velocities, stop_velocity):
    """
    Identifies gear shifting velocity matrix.

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

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

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

    :return:
        Gear shifting velocity matrix.
    :rtype: dict
    """

    limits = {}

    for v, (g0, g1) in zip(velocities, sh.pairwise(gears)):
        if v >= stop_velocity and g0 != g1:
            limits[g0] = limits.get(g0, [[], []])
            limits[g0][int(g0 < g1)].append(v)
    return _filter_gear_shifting_velocity(limits, stop_velocity)
Exemplo n.º 4
0
def get_start_stop(vehicle_max_speed, speed_per_gear, poly_spline):
    """
    Calculate Speed boundaries for each gear.

    :param vehicle_max_speed:
        Vehicle maximum speed.
    :type vehicle_max_speed: int

    :param speed_per_gear:
        Speed per gear.
    :type speed_per_gear: numpy.array

    :param poly_spline:
        Poly spline.
    :type poly_spline: list

    :return:
        Start and Stop for each gear.
    :rtype: numpy.array, numpy.array
    """
    v = np.asarray(speed_per_gear)
    # Ensure that a higher gear starts from higher speed.
    assert (v[:-1, 0] < v[1:,
                          0]).all(), "Incoherent shifting point (vi < vi1)!"

    start, stop = v[:, 0].copy(), np.minimum(v[:, -1], vehicle_max_speed)
    start[0], index = 0, np.maximum(0, np.arange(v.shape[1]) - 1)

    # Find where the curve of each gear cuts the next one.
    b, _min = v[:-1] > v[1:, 0, None], lambda *a: np.min(a)
    for i, (_v, (ps0, ps1)) in enumerate(zip(v[:-1],
                                             sh.pairwise(poly_spline))):
        stop[i] = _min(stop[i], *_v[index[b[i] & (ps1(_v) > ps0(_v))]])

    return start, stop
Exemplo n.º 5
0
def select_phases_integration_times(cycle_type):
    """
    Selects the cycle phases integration times [s].

    :param cycle_type:
        Cycle type (WLTP or NEDC).
    :type cycle_type: str

    :return:
        Cycle phases integration times [s].
    :rtype: tuple
    """

    from co2mpas.defaults import dfl
    v = dfl.functions.select_phases_integration_times.INTEGRATION_TIMES
    return tuple(sh.pairwise(v[cycle_type.upper()]))
Exemplo n.º 6
0
def _correct_gsv(gsv, stop_velocity):
    """
    Corrects gear shifting velocity matrix from unreliable limits.

    :param gsv:
        Gear shifting velocity matrix.
    :type gsv: dict

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

    :return:
        Gear shifting velocity matrix corrected from unreliable limits.
    :rtype: dict
    """

    gsv[0] = [0, (stop_velocity, (dfl.INF, 0))]

    # noinspection PyMissingOrEmptyDocstring
    def func(x):
        return not x and float('inf') or 1 / x

    for v0, v1 in sh.pairwise(gsv.values()):
        up0, s0, down1, s1 = v0[1][0], v0[1][1][1], v1[0][0], v1[0][1][1]

        if down1 + s1 <= v0[0]:
            v0[1], v1[0] = up0 + s0, up0 - s0
        elif up0 >= down1:
            v0[1], v1[0] = up0 + s0, down1 - s1
            continue
        elif (v0[1][1][0], func(s0)) >= (v1[0][1][0], func(s1)):
            v0[1], v1[0] = up0 + s0, up0 - s0
        else:
            v0[1], v1[0] = down1 + s1, down1 - s1

        v0[1] += stop_velocity

    gsv[max(gsv)][1] = dfl.INF

    return gsv
Exemplo n.º 7
0
def identify_on_idle(
        times, velocities, engine_speeds_out_hot, gear_box_speeds_in, gears,
        stop_velocity, min_engine_on_speed, on_engine, idle_engine_speed):
    """
    Identifies when the engine is on idle [-].

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

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

    :param engine_speeds_out_hot:
        Engine speed at hot condition [RPM].
    :type engine_speeds_out_hot: numpy.array

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

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

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

    :param min_engine_on_speed:
        Minimum engine speed to consider the engine to be on [RPM].
    :type min_engine_on_speed: float

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

    :param idle_engine_speed:
        Engine speed idle median and std [RPM].
    :type idle_engine_speed: (float, float)

    :return:
        If the engine is on idle [-].
    :rtype: numpy.array
    """
    # noinspection PyProtectedMember
    from .gear_box.mechanical import _shift
    b = engine_speeds_out_hot > min_engine_on_speed
    b &= (gears == 0) | (velocities <= stop_velocity)

    on_idle = np.zeros_like(times, int)
    i = np.where(on_engine)[0]
    ds = np.abs(gear_box_speeds_in[i] - engine_speeds_out_hot[i])
    on_idle[i[ds > idle_engine_speed[1]]] = 1
    on_idle = co2_utl.median_filter(times, on_idle, 4)
    on_idle[b] = 1
    for i, j in sh.pairwise(_shift(on_idle)):
        if not on_idle[i] and times[j - 1] - times[i] <= 2:
            on_idle[i:j] = 1
    return co2_utl.clear_fluctuations(times, on_idle, 4).astype(bool)
Exemplo n.º 8
0
def identify_gears_v1(
        times, velocities, accelerations, motive_powers, on_engine,
        engine_speeds_out, velocity_speed_ratios, stop_velocity,
        plateau_acceleration, change_gear_window_width, idle_engine_speed,
        correct_gear):
    """
    Identifies gear time series [-].

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

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

    :param accelerations:
        Acceleration vector [m/s2].
    :type accelerations: numpy.array

    :param motive_powers:
        Motive power [kW].
    :type motive_powers: numpy.array

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

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

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

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

    :param plateau_acceleration:
        Maximum acceleration to be at constant velocity [m/s2].
    :type plateau_acceleration: float

    :param change_gear_window_width:
        Time window used to apply gear change filters [s].
    :type change_gear_window_width: float

    :param idle_engine_speed:
        Engine speed idle median and std [RPM].
    :type idle_engine_speed: (float, float)

    :param correct_gear:
        A function to correct the gear predicted.
    :type correct_gear: callable

    :return:
        Gear vector identified [-].
    :rtype: numpy.array
    """
    n = [k for k in velocity_speed_ratios if k != 0]
    if len(n) == 1:
        gears = np.ones_like(times, int) * n[0]
        gears[velocities <= stop_velocity] = 0
        return gears
    with np.errstate(divide='ignore', invalid='ignore'):
        r = velocities / engine_speeds_out

    idle = (idle_engine_speed[0] - idle_engine_speed[1],
            idle_engine_speed[0] + idle_engine_speed[1])
    r[engine_speeds_out <= idle[0]] = 0

    _vsr = sh.combine_dicts(velocity_speed_ratios, base={0: 0})
    g, vsr = np.array([(k, v) for k, v in sorted(_vsr.items())]).T
    dr = np.abs(vsr[:, None] - r)
    i, j = np.argmin(dr, 0), np.arange(times.shape[0])
    b = velocities <= vsr[i] * idle[0]
    if idle[1]:
        b |= np.abs(velocities / idle[1] - r) < dr[i, j]
    b = (velocities <= stop_velocity) | (b & (accelerations < 0))
    gears = np.where(b, 0, g[i]).astype(int)
    gears = co2_utl.median_filter(times, gears, change_gear_window_width)
    gears = _correct_gear_shifts(times, r, gears, velocity_speed_ratios)
    gears = co2_utl.clear_fluctuations(times, gears, change_gear_window_width)
    anomalies = velocities > stop_velocity
    anomalies &= (accelerations > 0) | ~on_engine
    anomalies |= accelerations > plateau_acceleration
    anomalies &= gears == 0
    from ..control.conventional import calculate_engine_speeds_out_hot
    ds = calculate_engine_speeds_out_hot(calculate_gear_box_speeds_in(
        gears, velocities, velocity_speed_ratios, stop_velocity
    ), on_engine, idle_engine_speed) - engine_speeds_out
    i = np.where(on_engine & ~anomalies)[0]
    med = np.nanmedian(ds[i])
    std = 3 * max(50, co2_utl.mad(ds[i], med=med))
    anomalies[i] |= np.abs(ds[i] - med) >= std
    b = (gears == 0) & (velocities <= stop_velocity)
    anomalies[b] = False
    anomalies = co2_utl.clear_fluctuations(
        times, anomalies.astype(int), change_gear_window_width
    )
    for i, j in sh.pairwise(_shift(gears)):
        anomalies[i:j] = anomalies[i:j].mean() > .3

    gsm = _calibrate_gsm(
        velocity_speed_ratios, on_engine, anomalies, gears, velocities,
        stop_velocity, idle_engine_speed
    ).init_gear(
        gears, times, velocities, accelerations, motive_powers,
        correct_gear=correct_gear
    )
    for i, v in enumerate(anomalies):
        if v:
            gears[i] = gsm(i)
    gears = co2_utl.median_filter(times, gears, change_gear_window_width)
    gears = co2_utl.clear_fluctuations(times, gears, change_gear_window_width)
    return gears.astype(int)
Exemplo n.º 9
0
def _is_sorted(iterable, key=lambda a, b: a <= b):
    return all(key(a, b) for a, b in sh.pairwise(iterable))
Exemplo n.º 10
0
 def test_pairwise(self):
     self.assertEqual(list(sh.pairwise([1, 2, 3])), [(1, 2), (2, 3)])
     sh.pairwise([1, 2, 3, 4])
     self.assertEqual(list(sh.pairwise([1])), [])