I am currently working on a general python block that operates on data
between "start of burst" tags, and ignores all other data. As such, I only
want to output data that is part of the burst and the padded zeros actually
transmitted by the USRP, but the block actually outputs the burst data
along with a large number of zeros appended to the end by the block itself
(an example of the output is attached). How do I only get the data produced
by the USRP? The line that actually assigns the output is

out[:pulse_len] = in0[n - (pulse_len):n] * refl_gain * \
phase_shift * dopp_shift / prop_loss

If there's anything else I need to clarify please let me know. Thanks!

import math

import numpy as np
import pmt
import scipy.constants as sc
from gnuradio import gr


class mts_general(gr.basic_block):
    """
    docstring for block mts_general
    """

    def __init__(self, pos, vel, rcs, fc, fs):
        gr.basic_block.__init__(self,
                                name="mts_general",
                                in_sig=[np.complex64],
                                out_sig=[np.complex64]),
        # self.set_auto_consume(False)
        self.pos = np.array(pos)
        self.vel = np.array(vel)
        self.rcs = np.array(rcs)
        self.fc = fc
        self.lam = sc.c / self.fc
        self.fs = fs
        self.is_burst = False
        self.curr_pulse = 0
        # System parameters
        self.PRF = 1e4
        self.PRI = 1 / self.PRF
        self.burst_start, self.burst_end = 0, 0
        # self.set_history(5000)


    def forecast(self, noutput_items, ninput_items_required):
        # setup size of input_items[i] for work call
        for i in range(len(ninput_items_required)):
            ninput_items_required[i] = noutput_items

    def general_work(self, input_items, output_items):
        # Input and output data
        in0 = input_items[0][:len(output_items[0])]
        out = output_items[0]
        # Absolute start and end sample numbers
        start_n = self.nitems_read(0)
        end_n = start_n + len(in0)

        """
        Calculate all losses and shifts.

        Currently only take the radial position and velocity relative to the
        radar into account.
        """
        # Free space propagation loss
        R = math.sqrt(np.dot(np.transpose(self.pos), self.pos))
        prop_loss = (4 * sc.pi * R / self.lam) ** 2

        # Doppler shift (For now, using only the first velocity component)
        dopp_freq = 2 * self.vel[0] / self.lam
        dopp_shift = np.exp(
            1j * 2 * sc.pi * dopp_freq * self.PRI * self.curr_pulse)

        # Target reflection gain: The relation between the incident signal and
        # the reflected signal y can be expressed as y = sqrt(G)*x, where G =
        # (4*pi*rcs)/(lambda^2)
        refl_gain = math.sqrt(4 * sc.pi * self.rcs[0] / (self.lam ** 2))

        # Shift phase by -(4*pi*R) / ((1-(v/c))*lambda)
        phase_shift = np.exp(
            -(1j * 4 * sc.pi * R) / (1 - (self.vel[0] / sc.c)) *
            self.lam)
        # Delay sequence by fs*(R/c)
        self.delay_samps = int(round(2 * self.fs * (R / sc.c)))

        """
        Get all tags in the current call to the work function, and evaluate
        the tags indicating a start of burst (SOB). If the sample number for
        the burst start and end are the same (only happens on the first pulse
        and at the end of an already tagged pulse), assign the burst_start to
        the absolute offset of the tag and increment the current pulse number
        (used in the doppler shift exponential above)

        """
        tags = self.get_tags_in_range(0, start_n, end_n)
        for tag in tags:
            if pmt.symbol_to_string(tag.key) == "SOB":
                # Finds the start of a new burst. Barring a missed tag,
                # self.burst_start == self.burst_end only on the first burst
                # or a new burst
                if (self.burst_start == self.burst_end):
                    # Absolute sample number of the start of the burst
                    self.burst_start = tag.offset
                    # New pulse, so increment current pulse number
                    self.curr_pulse += 1
                else:
                    # Absolute sample number of the end of the burst. Since
                    # this tag.offset is the start of a new burst,
                    # must subtract 1
                    self.burst_end = tag.offset
                    # Relative sample number of the end of the burst
                    n = self.burst_end - start_n
                    # Length of the pulse (in samples)
                    pulse_len = self.burst_end - self.burst_start
                    # This solution captures the entire burst, but pads it
                    # with a variable number of zeros afterwards, so a better
                    # solution is necessary
                    out[:pulse_len] = in0[n - (pulse_len):n] * refl_gain * \
                                      phase_shift * dopp_shift / prop_loss
                    # Assign the next burst start to the end of the current
                    # burst (mostly necessary because of the above if statement)
                    self.burst_start = self.burst_end
                    return len(out)


        # output_items[0][:] = input_items[0][:len(out)]
        self.consume_each(len(input_items[0]))
        return len(output_items[0])

Reply via email to