Exemplo n.º 1
0
def equalize_frame(sframe, x_preamble, fft_len, cp_len, cs_len):
    rx_preamble = sframe[cp_len:cp_len + len(x_preamble)]
    agc_factor = calculate_agc_factor(rx_preamble, x_preamble)
    # print('AGC values:', ref_e, rx_e, agc_factor)
    sframe *= agc_factor

    frame_start = cp_len + 2 * fft_len + cs_len + cp_len
    H, e0, e1 = preamble_estimate(rx_preamble, x_preamble, fft_len)
    H_estimate = estimate_frame_channel(H, fft_len, len(sframe))

    H_p = estimate_frame_channel(H, fft_len, fft_len * 9)
    p = sframe[frame_start:frame_start + fft_len * 9]

    P = np.fft.fft(p)
    P *= np.fft.fftshift(np.conj(H_p))
    p = np.fft.ifft(P)
    print('equalize p:', utils.calculate_signal_energy(p))

    F = np.fft.fft(sframe)
    F *= np.fft.fftshift(np.conj(H_estimate))
    sframe = np.fft.ifft(F)

    s = sframe[frame_start:frame_start + fft_len * 9]
    print('equalize s:', utils.calculate_signal_energy(s))
    # plt.plot(s.real)
    # plt.plot(p.real)
    # plt.plot(s.imag)
    # plt.plot(p.imag)
    # plt.plot(np.abs(P))
    # plt.plot(np.abs(F))
    # # plt.plot(np.abs(P - F))
    # plt.show()

    return sframe
Exemplo n.º 2
0
def check_preamble_properties(preamble, x_preamble):
    x_1st = x_preamble[0:len(x_preamble) // 2]
    x_2nd = x_preamble[-len(x_preamble) // 2:]
    if not np.all(np.abs(x_1st - x_2nd) < 1e-12):
        print np.abs(x_1st - x_2nd)
        raise ValueError('preamble timeslots do not repeat!')
    from correlation import cross_correlate_naive, auto_correlate_halfs
    from utils import calculate_signal_energy
    x_ampl = np.sqrt(calculate_signal_energy(x_preamble))
    preamble *= x_ampl
    x_preamble *= x_ampl
    x_energy = calculate_signal_energy(x_preamble)
    if np.abs(2. * auto_correlate_halfs(x_preamble) / x_energy) -1. > 1e-10:
        raise ValueError('auto correlating halfs of preamble fails!')

    print 'normalized preamble xcorr val: ', np.correlate(x_preamble, x_preamble) / x_energy
    print 'windowed normalized preamble: ', np.correlate(preamble[-len(x_preamble):], x_preamble) / x_energy
    fxc = np.correlate(preamble, x_preamble, 'full') / x_energy
    vxc = np.correlate(preamble, x_preamble, 'valid') / x_energy
    nxc = cross_correlate_naive(preamble, x_preamble) / x_energy
    import matplotlib.pyplot as plt

    plt.plot(np.abs(fxc))
    plt.plot(np.abs(vxc))
    plt.plot(np.abs(nxc))
    plt.show()
Exemplo n.º 3
0
def equalize_frame(sframe, x_preamble, fft_len, cp_len, cs_len):
    rx_preamble = sframe[cp_len:cp_len + len(x_preamble)]
    agc_factor = calculate_agc_factor(rx_preamble, x_preamble)
    # print('AGC values:', ref_e, rx_e, agc_factor)
    sframe *= agc_factor

    frame_start = cp_len + 2 * fft_len + cs_len + cp_len
    H, e0, e1 = preamble_estimate(rx_preamble, x_preamble, fft_len)
    H_estimate = estimate_frame_channel(H, fft_len, len(sframe))

    H_p = estimate_frame_channel(H, fft_len, fft_len * 9)
    p = sframe[frame_start:frame_start + fft_len * 9]

    P = np.fft.fft(p)
    P *= np.fft.fftshift(np.conj(H_p))
    p = np.fft.ifft(P)
    print('equalize p:', utils.calculate_signal_energy(p))

    F = np.fft.fft(sframe)
    F *= np.fft.fftshift(np.conj(H_estimate))
    sframe = np.fft.ifft(F)

    s = sframe[frame_start:frame_start + fft_len * 9]
    print('equalize s:', utils.calculate_signal_energy(s))
    # plt.plot(s.real)
    # plt.plot(p.real)
    # plt.plot(s.imag)
    # plt.plot(p.imag)
    # plt.plot(np.abs(P))
    # plt.plot(np.abs(F))
    # # plt.plot(np.abs(P - F))
    # plt.show()

    return sframe
Exemplo n.º 4
0
def demodulate_frame(rx_data_frame,
                     modulated_frame,
                     rx_kernel,
                     demapper,
                     data,
                     timeslots,
                     fft_len,
                     H_estimate=None):
    ref_data = demodulate_data_frame(modulated_frame, rx_kernel, demapper,
                                     len(data))
    rx_data = demodulate_data_frame(rx_data_frame, rx_kernel, demapper,
                                    len(data))

    if H_estimate is None:
        d = np.array([1 + 1j, -1 + 1j, -1 - 1j, 1 - 1j]) / np.sqrt(2.)
    else:
        d = rx_kernel.demodulate_equalize(
            rx_data_frame.astype(dtype=np.complex64),
            H_estimate.astype(dtype=np.complex64))
        d = demapper.demap_from_resources(d.astype(dtype=np.complex64),
                                          len(data))

    mse = np.sum(np.abs(rx_data - ref_data)**2) / len(ref_data)
    print('frame EQ demodulated energy',
          utils.calculate_signal_energy(rx_data),
          utils.calculate_signal_energy(rx_data) / len(rx_data),
          utils.calculate_signal_energy(ref_data) / len(ref_data))

    # calculate_avg_phase(rx_data, ref_data)

    fber = calculate_frame_ber(ref_data, rx_data)
    print('Frame BER: ', fber, 'with MSE: ', mse)

    plot_constellation(ref_data, rx_data, d, 0, timeslots * fft_len)
    plt.show()
Exemplo n.º 5
0
def check_preamble_properties(preamble, x_preamble):
    x_1st = x_preamble[0:len(x_preamble) // 2]
    x_2nd = x_preamble[-len(x_preamble) // 2:]
    if not np.all(np.abs(x_1st - x_2nd) < 1e-12):
        print(np.abs(x_1st - x_2nd))
        raise ValueError("preamble timeslots do not repeat!")
    from correlation import cross_correlate_naive, auto_correlate_halfs
    from utils import calculate_signal_energy

    x_ampl = np.sqrt(calculate_signal_energy(x_preamble))
    preamble *= x_ampl
    x_preamble *= x_ampl
    x_energy = calculate_signal_energy(x_preamble)
    if np.abs(2.0 * auto_correlate_halfs(x_preamble) / x_energy) - 1.0 > 1e-10:
        raise ValueError("auto correlating halfs of preamble fails!")

    print(
        "normalized preamble xcorr val: ",
        np.correlate(x_preamble, x_preamble) / x_energy,
    )
    print(
        "windowed normalized preamble: ",
        np.correlate(preamble[-len(x_preamble):], x_preamble) / x_energy,
    )
    fxc = np.correlate(preamble, x_preamble, "full") / x_energy
    vxc = np.correlate(preamble, x_preamble, "valid") / x_energy
    nxc = cross_correlate_naive(preamble, x_preamble) / x_energy
    import matplotlib.pyplot as plt

    plt.plot(np.abs(fxc))
    plt.plot(np.abs(vxc))
    plt.plot(np.abs(nxc))
    plt.show()
Exemplo n.º 6
0
def synchronize_time(frame,
                     ref_frame,
                     x_preamble,
                     fft_len,
                     cp_len,
                     samp_rate=12.e6):
    kframe = kernel_synchronize_time(frame, x_preamble, fft_len, cp_len,
                                     len(ref_frame))

    ac = sync.auto_correlate_signal(frame, fft_len)
    nm = np.argmax(np.abs(ac))
    print('AC start: ', nm)
    # cfo = 2 * np.angle(ac[nm]) / (2. * np.pi)
    cfo = np.angle(ac[nm]) / (2. * np.pi)
    print('CFO:', cfo, cfo * samp_rate / fft_len)

    phase_inc = sync.cfo_to_phase_increment(-cfo, fft_len)
    wave = sync.complex_sine(phase_inc, len(frame), 0.0)
    # print(len(wave), len(frame))
    # frame *= wave

    ac = sync.auto_correlate_signal(frame, fft_len)
    cfo = np.angle(ac[nm]) / (2. * np.pi)
    print('CFO:', cfo, cfo * samp_rate / fft_len)

    xc = np.correlate(frame, x_preamble, 'valid')
    cc = sync.multiply_valid(np.abs(ac), np.abs(xc))
    nc = np.argmax(np.abs(cc))
    print('correlation frame start:', nc)
    cfo = np.angle(ac[nc]) / (2. * np.pi)
    print('CFO:', cfo, cfo * samp_rate / fft_len)
    sample_nc = nc - cp_len
    print('sample frame start:     ', sample_nc)
    p_len = cp_len + 2 * fft_len + cp_len // 2 + cp_len
    print('data frame start:       ', sample_nc + p_len)
    phase = np.angle(xc[nc])
    # phase = 0.0
    print('phase:', phase)
    # frame *= np.exp(-1j * phase)

    ref_e = utils.calculate_signal_energy(x_preamble)
    rx_e = utils.calculate_signal_energy(frame[nc:nc + len(x_preamble)])
    agc_factor = np.sqrt(ref_e / rx_e)
    print('AGC values:', ref_e, rx_e, agc_factor)
    frame *= agc_factor
    sframe = frame[sample_nc:sample_nc + len(ref_frame)]
    # plt.plot(np.abs(ref_frame))
    # plt.plot(np.abs(frame))
    # plt.plot(np.abs(ac))
    # plt.plot(np.abs(xc))
    # plt.plot(cc)
    # # # plt.axvline(sample_nc, color='y')
    # print(np.abs(kframe - sframe) < 1e-4)
    # plt.plot(np.abs(kframe))
    # plt.plot(np.abs(sframe))
    # plt.show()
    return sframe
Exemplo n.º 7
0
def synchronize_time(frame, ref_frame, x_preamble, fft_len, cp_len, samp_rate=12.e6):
    kframe = kernel_synchronize_time(frame, x_preamble, fft_len, cp_len, len(ref_frame))

    ac = sync.auto_correlate_signal(frame, fft_len)
    nm = np.argmax(np.abs(ac))
    print('AC start: ', nm)
    # cfo = 2 * np.angle(ac[nm]) / (2. * np.pi)
    cfo = np.angle(ac[nm]) / (2. * np.pi)
    print('CFO:', cfo, cfo * samp_rate / fft_len)

    phase_inc = sync.cfo_to_phase_increment(-cfo, fft_len)
    wave = sync.complex_sine(phase_inc, len(frame), 0.0)
    # print(len(wave), len(frame))
    # frame *= wave

    ac = sync.auto_correlate_signal(frame, fft_len)
    cfo = np.angle(ac[nm]) / (2. * np.pi)
    print('CFO:', cfo, cfo * samp_rate / fft_len)

    xc = np.correlate(frame, x_preamble, 'valid')
    cc = sync.multiply_valid(np.abs(ac), np.abs(xc))
    nc = np.argmax(np.abs(cc))
    print('correlation frame start:', nc)
    cfo = np.angle(ac[nc]) / (2. * np.pi)
    print('CFO:', cfo, cfo * samp_rate / fft_len)
    sample_nc = nc - cp_len
    print('sample frame start:     ', sample_nc)
    p_len = cp_len + 2 * fft_len + cp_len // 2 + cp_len
    print('data frame start:       ', sample_nc + p_len)
    phase = np.angle(xc[nc])
    # phase = 0.0
    print('phase:', phase)
    # frame *= np.exp(-1j * phase)

    ref_e = utils.calculate_signal_energy(x_preamble)
    rx_e = utils.calculate_signal_energy(frame[nc:nc + len(x_preamble)])
    agc_factor = np.sqrt(ref_e / rx_e)
    print('AGC values:', ref_e, rx_e, agc_factor)
    frame *= agc_factor
    sframe = frame[sample_nc:sample_nc + len(ref_frame)]
    # plt.plot(np.abs(ref_frame))
    # plt.plot(np.abs(frame))
    # plt.plot(np.abs(ac))
    # plt.plot(np.abs(xc))
    # plt.plot(cc)
    # # # plt.axvline(sample_nc, color='y')
    # print(np.abs(kframe - sframe) < 1e-4)
    # plt.plot(np.abs(kframe))
    # plt.plot(np.abs(sframe))
    # plt.show()
    return sframe
Exemplo n.º 8
0
def gfdm_modulate_fft(data, alpha, M, K, overlap):
    # this function aims to reproduce [0] Section IIIA

    H = get_frequency_domain_filter('rrc', alpha, M, K, overlap)
    filter_energy = calculate_signal_energy(H)
    scaling_factor = 1. / np.sqrt(filter_energy / M)
    H *= scaling_factor
    D = get_data_matrix(data, K, group_by_subcarrier=False)
    return gfdm_modulate_block(D, H, M, K, overlap, False)
Exemplo n.º 9
0
def modulate_mapped_gfdm_block(data, ts, sc, active_sc, overlap, alpha, dc_free=False):
    # const gfdm_complex scaling_factor = gfdm_complex(1. / std::sqrt(std::abs(res) / n_timeslots), 0.0f);
    smap = get_subcarrier_map(sc, active_sc, dc_free=dc_free)
    dm = map_to_waveform_resource_grid(data, active_sc, sc, smap).T
    H = get_frequency_domain_filter('rrc', alpha, ts, sc, overlap)
    filter_energy = calculate_signal_energy(H)
    scaling_factor = 1. / np.sqrt(filter_energy / ts)
    H = H * scaling_factor
    # print filter_energy, scaling_factor, calculate_signal_energy(H)
    return gfdm_modulate_block(dm, H, ts, sc, overlap, False)
Exemplo n.º 10
0
def demodulate_frame(rx_data_frame, modulated_frame, rx_kernel, demapper, data, timeslots, fft_len, H_estimate=None):
    ref_data = demodulate_data_frame(modulated_frame, rx_kernel, demapper, len(data))
    rx_data = demodulate_data_frame(rx_data_frame, rx_kernel, demapper, len(data))

    if H_estimate is None:
        d = np.array([1+1j, -1+1j, -1-1j, 1-1j]) / np.sqrt(2.)
    else:
        d = rx_kernel.demodulate_equalize(rx_data_frame.astype(dtype=np.complex64), H_estimate.astype(dtype=np.complex64))
        d = demapper.demap_from_resources(d.astype(dtype=np.complex64), len(data))

    mse = np.sum(np.abs(rx_data - ref_data) ** 2) / len(ref_data)
    print('frame EQ demodulated energy', utils.calculate_signal_energy(rx_data), utils.calculate_signal_energy(rx_data) / len(rx_data), utils.calculate_signal_energy(ref_data) / len(ref_data))

    # calculate_avg_phase(rx_data, ref_data)

    fber = calculate_frame_ber(ref_data, rx_data)
    print('Frame BER: ', fber, 'with MSE: ', mse)

    plot_constellation(ref_data, rx_data, d, 0, timeslots * fft_len)
    plt.show()
Exemplo n.º 11
0
def auto_correlate_signal(signal, K):
    plen = K * 2
    slen = len(signal)
    ac = np.zeros(slen - plen, dtype=np.complex)

    for i in range(slen - plen):
        # calc auto-correlation
        c = signal[i:i+plen]
        #normalize value
        p = calculate_signal_energy(c)
        ac[i] = 2 * auto_correlate_halfs(c) / p
    return ac
Exemplo n.º 12
0
def auto_correlate_signal(signal, K):
    plen = K * 2
    slen = len(signal)
    ac = np.zeros(slen - plen, dtype=np.complex)

    for i in range(slen - plen):
        # calc auto-correlation
        c = signal[i:i + plen]
        #normalize value
        p = calculate_signal_energy(c)
        ac[i] = 2 * auto_correlate_halfs(c) / p
    return ac
Exemplo n.º 13
0
def generate_sync_symbol(pn_symbols,
                         filtertype,
                         alpha,
                         K,
                         L,
                         cp_len,
                         ramp_len,
                         cyclic_shift=0):
    H = get_frequency_domain_filter(filtertype, alpha, 2, K, L)
    filter_energy = calculate_signal_energy(H)
    scaling_factor = 1.0 / np.sqrt(filter_energy / 2)
    H = H * scaling_factor
    return get_sync_symbol(pn_symbols, H, K, L, cp_len, ramp_len, cyclic_shift)
Exemplo n.º 14
0
def estimate_frame_channel(H, fft_len, frame_len):
    used_sc = 52
    # subcarrier_map = mapping.get_subcarrier_map(fft_len, used_sc, dc_free=True)
    # subcarrier_map = np.roll(subcarrier_map, len(subcarrier_map) // 2)
    # ts = time.time()
    H[0] = (H[1] + H[-1]) / 2.
    # plt.plot(subcarrier_map, np.angle(H[subcarrier_map]))
    H = np.fft.fftshift(H)
    active_sc = np.arange((fft_len - used_sc)//2, (fft_len + used_sc)//2+1)
    active_sc = active_sc[3:-3]
    g = signal.gaussian(9, 1.0)
    g_factor = 1.
    g /= np.sqrt(g_factor * g.dot(g))
    Ha = H[active_sc]
    Hb = np.concatenate((np.repeat(Ha[0], 4), Ha, np.repeat(Ha[-1], 4)))
    Hg = np.correlate(Hb, g)

    # print('channel averaging error:', utils.calculate_signal_energy(Ha), utils.calculate_signal_energy(Hg), utils.calculate_signal_energy(Ha) / utils.calculate_signal_energy(Hg))
    Hg *= np.sqrt(utils.calculate_signal_energy(Ha) / utils.calculate_signal_energy(Hg))

    freqs = np.fft.fftfreq(len(H))
    freqs = np.fft.fftshift(freqs)

    fr_freqs = np.fft.fftfreq(frame_len)
    fr_freqs = np.fft.fftshift(fr_freqs)
    H_frame = np.interp(fr_freqs, freqs[active_sc], Hg.real) + 1j * np.interp(fr_freqs, freqs[active_sc], Hg.imag)
    # te = time.time()
    # print('interpolation timing:', te - ts)

    A = np.array([freqs[active_sc], np.ones(len(active_sc))])
    # print(np.shape(A))

    m, c = np.linalg.lstsq(A.T, H[active_sc])[0]
    Hl = m * freqs[active_sc] + c


    # plt.plot(freqs[active_sc], Ha.real)
    # plt.plot(freqs[active_sc], Ha.imag)
    # plt.plot(freqs[active_sc], Hg.real, marker='x', ms=10)
    # plt.plot(freqs[active_sc], Hl.real)

    # Hg = Ha

    fr_freqs = np.fft.fftfreq(frame_len)
    fr_freqs = np.fft.fftshift(fr_freqs)
    H_frame = np.interp(fr_freqs, freqs[active_sc], Hg.real) + 1j * np.interp(fr_freqs, freqs[active_sc], Hg.imag)
    # plt.plot(fr_freqs, H_frame.real)

    p_freqs = np.fft.fftfreq(fft_len * 9)
    p_freqs = np.fft.fftshift(p_freqs)
    H_p = np.interp(p_freqs, freqs[active_sc], Hg.real) + 1j * np.interp(p_freqs, freqs[active_sc], Hg.imag)
    # plt.plot(p_freqs, H_p.real)

    Hlf = m * fr_freqs + c
    # plt.plot(fr_freqs, Hlf.real)

    # plt.show()

    # plt.plot(xp, Hg.real, marker='x')
    # plt.plot(x, H_frame.real)
    # plt.plot(xf, H_p.real)

    # phase_m = m * fft_len / len(sframe)
    # p = np.arange(-frame_len, frame_len)
    # plt.plot(np.angle(H_p))
    # plt.plot(np.angle(H_frame))
    #
    # plt.plot(np.angle(Ha))
    # plt.plot(np.angle(Hg))
    # plt.plot(np.abs(Ha))
    # plt.plot(np.abs(Hg))
    # plt.show()
    return H_frame
Exemplo n.º 15
0
def calculate_agc_factor(rx_preamble, x_preamble):
    ref_e = utils.calculate_signal_energy(x_preamble)
    rx_e = utils.calculate_signal_energy(rx_preamble)
    # print('AGC factor', np.sqrt(ref_e / rx_e))
    return np.sqrt(ref_e / rx_e)
Exemplo n.º 16
0
def calculate_agc_factor(rx_preamble, x_preamble):
    ref_e = utils.calculate_signal_energy(x_preamble)
    rx_e = utils.calculate_signal_energy(rx_preamble)
    # print('AGC factor', np.sqrt(ref_e / rx_e))
    return np.sqrt(ref_e / rx_e)
Exemplo n.º 17
0
def rx_demodulate(frames, ref_frame, modulated_frame, x_preamble, data, rx_kernel, demapper, timeslots, fft_len, cp_len, cs_len):
    f_start = cp_len + 2 * fft_len + cs_len
    d_start = f_start + cp_len
    print('data start: ', d_start)
    sync_kernel = cgfdm.py_auto_cross_corr_multicarrier_sync_cc(64, 32, x_preamble)

    estimator = validation_utils.frame_estimator(x_preamble, fft_len, timeslots, 52)
    c_est = cgfdm.py_preamble_channel_estimator_cc(9, 64, 52, True, x_preamble)
    p_filter_taps = c_est.preamble_filter_taps()
    print(estimator._p_filter)
    print(p_filter_taps)
    print(np.abs(p_filter_taps - estimator._p_filter) < 1e-6)

    for f in frames[0:30]:
        rxs = time.time()
        rx_preamble = f[cp_len:cp_len + 2 * fft_len]
        agc_factor = sync_kernel.calculate_preamble_attenuation(rx_preamble.astype(dtype=np.complex64))
        f = sync_kernel.normalize_power_level(f, agc_factor)

        rx_preamble = f[cp_len:cp_len + 2 * fft_len]
        H_estimate = estimator.estimate_frame(rx_preamble)

        rx_t_frame = f[d_start:d_start + fft_len * timeslots]

        kde = rx_kernel.demodulate_equalize(rx_t_frame.astype(dtype=np.complex64), H_estimate.astype(dtype=np.complex64))
        de = demapper.demap_from_resources(kde.astype(dtype=np.complex64), len(data))
        rxe = time.time()
        print('receiver chain time: ', 1e6 * (rxe - rxs), 'us')

        # p_active = np.concatenate((np.arange(1, 27), np.arange(37, 64)))
        # cp_est = c_est.estimate_preamble_channel(rx_preamble)
        # p_est = estimator._estimate_preamble(rx_preamble)
        # print('Python vs C Preamble channel correct:', np.all(np.abs(cp_est[p_active] - p_est[p_active]) < 1e-4), np.all(np.angle(cp_est[p_active]) - np.angle(p_est[p_active]) < 1e-6))

        # pf = estimator._filter_preamble_estimate(p_est)
        # cf = c_est.filter_preamble_estimate(p_est.astype(dtype=np.complex64))
        # print(np.all(np.angle(pf) - np.angle(cf) < 1e-6))

        # frame_estimate = c_est.interpolate_frame(pf.astype(dtype=np.complex64))
        rxs = time.time()
        frame_estimate = c_est.estimate_frame(rx_preamble)
        rxe = time.time()
        print('CPP channel estimator duration: ', 1e6 * (rxe - rxs), 'us')
        print('Python vs C Preamble channel correct:', np.all(np.abs(frame_estimate - H_estimate) < 1e-6))
        H_estimate = frame_estimate
        # plt.plot(H_estimate.real)
        # plt.plot(H_estimate.imag)
        # plt.plot(frame_estimate.real)
        # plt.plot(frame_estimate.imag)
        #
        # # plt.plot(pf.real)
        # # plt.plot(pf.imag)
        # # plt.plot(cf.real)
        # # plt.plot(cf.imag)
        # plt.show()


        P = np.fft.fft(rx_t_frame)
        P *= np.conj(H_estimate)
        rx_t_frame = np.fft.ifft(P)
        # kd = rx_kernel.demodulate(rx_t_frame.astype(dtype=np.complex64))
        # d = demapper.demap_from_resources(kd.astype(dtype=np.complex64), len(data))

        print('kernel FER: ', calculate_frame_ber(data, de))

        sframe = equalize_frame(f, x_preamble, fft_len, cp_len, cs_len)

        # rx_preamble = sframe[cp_len:cp_len + 2 * fft_len]
        # avg_phase = calculate_avg_phase(rx_preamble, x_preamble)
        # sframe *= np.exp(-1j * avg_phase)
        rx_data_frame = sframe[d_start:d_start + fft_len * timeslots]

        ekd = utils.calculate_signal_energy(rx_t_frame - rx_data_frame)
        print('MSE for kernel vs Python demod', ekd, ekd / len(rx_data_frame))
        plt.show()
        # plt.scatter(d.real, d.imag, label='kernel')
        plt.scatter(de.real, de.imag, label='EQ kern')
        H_estimate = np.ones(len(H_estimate))

        # demodulate_frame(rx_data_frame, modulated_frame, rx_kernel, demapper, data, timeslots, fft_len, H_estimate)
        demodulate_frame(rx_t_frame, modulated_frame, rx_kernel, demapper, data, timeslots, fft_len, H_estimate)
Exemplo n.º 18
0
def rx_demodulate(frames, ref_frame, modulated_frame, x_preamble, data, rx_kernel, demapper, timeslots, fft_len, cp_len, cs_len):
    f_start = cp_len + 2 * fft_len + cs_len
    d_start = f_start + cp_len
    print('data start: ', d_start)
    sync_kernel = cgfdm.py_auto_cross_corr_multicarrier_sync_cc(64, 32, x_preamble)

    estimator = validation_utils.frame_estimator(x_preamble, fft_len, timeslots, 52)
    c_est = cgfdm.py_preamble_channel_estimator_cc(9, 64, 52, True, x_preamble)
    p_filter_taps = c_est.preamble_filter_taps()
    print(estimator._p_filter)
    print(p_filter_taps)
    print(np.abs(p_filter_taps - estimator._p_filter) < 1e-6)

    for f in frames[0:30]:
        rxs = time.time()
        rx_preamble = f[cp_len:cp_len + 2 * fft_len]
        agc_factor = sync_kernel.calculate_preamble_attenuation(rx_preamble.astype(dtype=np.complex64))
        f = sync_kernel.normalize_power_level(f, agc_factor)

        rx_preamble = f[cp_len:cp_len + 2 * fft_len]
        H_estimate = estimator.estimate_frame(rx_preamble)

        rx_t_frame = f[d_start:d_start + fft_len * timeslots]

        kde = rx_kernel.demodulate_equalize(rx_t_frame.astype(dtype=np.complex64), H_estimate.astype(dtype=np.complex64))
        de = demapper.demap_from_resources(kde.astype(dtype=np.complex64), len(data))
        rxe = time.time()
        print('receiver chain time: ', 1e6 * (rxe - rxs), 'us')

        # p_active = np.concatenate((np.arange(1, 27), np.arange(37, 64)))
        # cp_est = c_est.estimate_preamble_channel(rx_preamble)
        # p_est = estimator._estimate_preamble(rx_preamble)
        # print('Python vs C Preamble channel correct:', np.all(np.abs(cp_est[p_active] - p_est[p_active]) < 1e-4), np.all(np.angle(cp_est[p_active]) - np.angle(p_est[p_active]) < 1e-6))

        # pf = estimator._filter_preamble_estimate(p_est)
        # cf = c_est.filter_preamble_estimate(p_est.astype(dtype=np.complex64))
        # print(np.all(np.angle(pf) - np.angle(cf) < 1e-6))

        # frame_estimate = c_est.interpolate_frame(pf.astype(dtype=np.complex64))
        rxs = time.time()
        frame_estimate = c_est.estimate_frame(rx_preamble)
        rxe = time.time()
        print('CPP channel estimator duration: ', 1e6 * (rxe - rxs), 'us')
        print('Python vs C Preamble channel correct:', np.all(np.abs(frame_estimate - H_estimate) < 1e-6))
        H_estimate = frame_estimate
        # plt.plot(H_estimate.real)
        # plt.plot(H_estimate.imag)
        # plt.plot(frame_estimate.real)
        # plt.plot(frame_estimate.imag)
        #
        # # plt.plot(pf.real)
        # # plt.plot(pf.imag)
        # # plt.plot(cf.real)
        # # plt.plot(cf.imag)
        # plt.show()


        P = np.fft.fft(rx_t_frame)
        P *= np.conj(H_estimate)
        rx_t_frame = np.fft.ifft(P)
        # kd = rx_kernel.demodulate(rx_t_frame.astype(dtype=np.complex64))
        # d = demapper.demap_from_resources(kd.astype(dtype=np.complex64), len(data))

        print('kernel FER: ', calculate_frame_ber(data, de))

        sframe = equalize_frame(f, x_preamble, fft_len, cp_len, cs_len)

        # rx_preamble = sframe[cp_len:cp_len + 2 * fft_len]
        # avg_phase = calculate_avg_phase(rx_preamble, x_preamble)
        # sframe *= np.exp(-1j * avg_phase)
        rx_data_frame = sframe[d_start:d_start + fft_len * timeslots]

        ekd = utils.calculate_signal_energy(rx_t_frame - rx_data_frame)
        print('MSE for kernel vs Python demod', ekd, ekd / len(rx_data_frame))
        plt.show()
        # plt.scatter(d.real, d.imag, label='kernel')
        plt.scatter(de.real, de.imag, label='EQ kern')
        H_estimate = np.ones(len(H_estimate))

        # demodulate_frame(rx_data_frame, modulated_frame, rx_kernel, demapper, data, timeslots, fft_len, H_estimate)
        demodulate_frame(rx_t_frame, modulated_frame, rx_kernel, demapper, data, timeslots, fft_len, H_estimate)
Exemplo n.º 19
0
def estimate_frame_channel(H, fft_len, frame_len):
    used_sc = 52
    # subcarrier_map = mapping.get_subcarrier_map(fft_len, used_sc, dc_free=True)
    # subcarrier_map = np.roll(subcarrier_map, len(subcarrier_map) // 2)
    # ts = time.time()
    H[0] = (H[1] + H[-1]) / 2.
    # plt.plot(subcarrier_map, np.angle(H[subcarrier_map]))
    H = np.fft.fftshift(H)
    active_sc = np.arange((fft_len - used_sc)//2, (fft_len + used_sc)//2+1)
    active_sc = active_sc[3:-3]
    g = signal.gaussian(9, 1.0)
    g_factor = 1.
    g /= np.sqrt(g_factor * g.dot(g))
    Ha = H[active_sc]
    Hb = np.concatenate((np.repeat(Ha[0], 4), Ha, np.repeat(Ha[-1], 4)))
    Hg = np.correlate(Hb, g)

    # print('channel averaging error:', utils.calculate_signal_energy(Ha), utils.calculate_signal_energy(Hg), utils.calculate_signal_energy(Ha) / utils.calculate_signal_energy(Hg))
    Hg *= np.sqrt(utils.calculate_signal_energy(Ha) / utils.calculate_signal_energy(Hg))

    freqs = np.fft.fftfreq(len(H))
    freqs = np.fft.fftshift(freqs)

    fr_freqs = np.fft.fftfreq(frame_len)
    fr_freqs = np.fft.fftshift(fr_freqs)
    H_frame = np.interp(fr_freqs, freqs[active_sc], Hg.real) + 1j * np.interp(fr_freqs, freqs[active_sc], Hg.imag)
    # te = time.time()
    # print('interpolation timing:', te - ts)

    A = np.array([freqs[active_sc], np.ones(len(active_sc))])
    # print(np.shape(A))

    m, c = np.linalg.lstsq(A.T, H[active_sc])[0]
    Hl = m * freqs[active_sc] + c


    # plt.plot(freqs[active_sc], Ha.real)
    # plt.plot(freqs[active_sc], Ha.imag)
    # plt.plot(freqs[active_sc], Hg.real, marker='x', ms=10)
    # plt.plot(freqs[active_sc], Hl.real)

    # Hg = Ha

    fr_freqs = np.fft.fftfreq(frame_len)
    fr_freqs = np.fft.fftshift(fr_freqs)
    H_frame = np.interp(fr_freqs, freqs[active_sc], Hg.real) + 1j * np.interp(fr_freqs, freqs[active_sc], Hg.imag)
    # plt.plot(fr_freqs, H_frame.real)

    p_freqs = np.fft.fftfreq(fft_len * 9)
    p_freqs = np.fft.fftshift(p_freqs)
    H_p = np.interp(p_freqs, freqs[active_sc], Hg.real) + 1j * np.interp(p_freqs, freqs[active_sc], Hg.imag)
    # plt.plot(p_freqs, H_p.real)

    Hlf = m * fr_freqs + c
    # plt.plot(fr_freqs, Hlf.real)

    # plt.show()

    # plt.plot(xp, Hg.real, marker='x')
    # plt.plot(x, H_frame.real)
    # plt.plot(xf, H_p.real)

    # phase_m = m * fft_len / len(sframe)
    # p = np.arange(-frame_len, frame_len)
    # plt.plot(np.angle(H_p))
    # plt.plot(np.angle(H_frame))
    #
    # plt.plot(np.angle(Ha))
    # plt.plot(np.angle(Hg))
    # plt.plot(np.abs(Ha))
    # plt.plot(np.abs(Hg))
    # plt.show()
    return H_frame
Exemplo n.º 20
0
def generate_sync_symbol(pn_symbols, filtertype, alpha, K, L, cp_len, ramp_len):
    H = get_frequency_domain_filter(filtertype, alpha, 2, K, L)
    filter_energy = calculate_signal_energy(H)
    scaling_factor = 1. / np.sqrt(filter_energy / 2)
    H = H * scaling_factor
    return get_sync_symbol(pn_symbols, H, K, L, cp_len, ramp_len)