Exemplo n.º 1
0
    def __call__(self, schedule_entry_json, task_id, sensor_definition):
        """This is the entrypoint function called by the scheduler."""

        self.test_required_components()
        start_time = utils.get_datetime_str_now()
        measurement_result = self.acquire_data()
        end_time = utils.get_datetime_str_now()

        sigmf_builder = SigMFBuilder()
        self.set_base_sigmf_global(
            sigmf_builder,
            schedule_entry_json,
            sensor_definition,
            measurement_result,
            task_id,
            is_complex=False,
        )
        sigmf_builder.set_measurement(
            start_time,
            end_time,
            domain=Domain.FREQUENCY,
            measurement_type=MeasurementType.SINGLE_FREQUENCY,
            frequency=measurement_result["frequency"],
        )
        self.add_sigmf_capture(sigmf_builder, measurement_result)
        self.add_base_sigmf_annotations(sigmf_builder, measurement_result)
        self.add_fft_annotations(sigmf_builder, measurement_result)
        measurement_action_completed.send(
            sender=self.__class__,
            task_id=task_id,
            data=measurement_result["data"],
            metadata=sigmf_builder.metadata,
        )
Exemplo n.º 2
0
def status(request, version, format=None):
    """The status overview of the sensor."""
    return Response(
        {
            "scheduler": scheduler.thread.status,
            "location": serialize_location(),
            "system_time": get_datetime_str_now(),
            "last_calibration_time": last_calibration_time(),
        }
    )
    def __call__(self, schedule_entry_json, task_id, sensor_definition):
        """This is the entrypoint function called by the scheduler."""
        self.test_required_components()

        for recording_id, measurement_params in enumerate(
                self.sorted_measurement_parameters, start=1):
            start_time = utils.get_datetime_str_now()
            measurement_result = super().acquire_data(measurement_params)
            end_time = utils.get_datetime_str_now()
            received_samples = len(measurement_result["data"])
            sigmf_builder = SigMFBuilder()
            self.set_base_sigmf_global(
                sigmf_builder,
                schedule_entry_json,
                sensor_definition,
                measurement_result,
                task_id,
                recording_id,
            )
            sigmf_builder.set_measurement(
                start_time,
                end_time,
                domain=Domain.TIME,
                measurement_type=MeasurementType.SINGLE_FREQUENCY,
                frequency=measurement_result["frequency"],
            )
            self.add_sigmf_capture(sigmf_builder, measurement_result)
            self.add_base_sigmf_annotations(sigmf_builder, measurement_result)
            sigmf_builder.add_time_domain_detection(
                start_index=0,
                num_samples=received_samples,
                detector="sample_iq",
                units="volts",
                reference="preselector input",
            )
            measurement_action_completed.send(
                sender=self.__class__,
                task_id=task_id,
                data=measurement_result["data"],
                metadata=sigmf_builder.metadata,
            )
Exemplo n.º 4
0
    def acquire_time_domain_samples(self,
                                    num_samples,
                                    num_samples_skip=0,
                                    retries=5):
        self.sigan_overload = False
        self._capture_time = None
        self._num_samples_skip = num_samples_skip

        # Try to acquire the samples
        max_retries = retries
        data = []
        while True:
            if self.times_failed_recv < self.times_to_fail_recv:
                self.times_failed_recv += 1
                data = np.ones(0, dtype=np.complex64)
            else:
                self._capture_time = get_datetime_str_now()
                if self.randomize_values:
                    i = np.random.normal(0.5, 0.5, num_samples)
                    q = np.random.normal(0.5, 0.5, num_samples)
                    rand_iq = np.empty(num_samples, dtype=np.complex64)
                    rand_iq.real = i
                    rand_iq.imag = q
                    data = rand_iq
                else:
                    data = np.ones(num_samples, dtype=np.complex64)

            data_len = len(data)
            if not len(data) == num_samples:
                if retries > 0:
                    msg = "USRP error: requested {} samples, but got {}."
                    logger.warning(
                        msg.format(num_samples + num_samples_skip, data_len))
                    logger.warning("Retrying {} more times.".format(retries))
                    retries = retries - 1
                else:
                    err = "Failed to acquire correct number of samples "
                    err += "{} times in a row.".format(max_retries)
                    raise RuntimeError(err)
            else:
                logger.debug(
                    "Successfully acquired {} samples.".format(num_samples))
                return {
                    "data": data,
                    "overload": self._overload,
                    "frequency": self._frequency,
                    "gain": self._gain,
                    "sample_rate": self._sample_rate,
                    "capture_time": self._capture_time,
                    "calibration_annotation":
                    self.create_calibration_annotation(),
                }
Exemplo n.º 5
0
 def last_calibration_time(self):
     return get_datetime_str_now()
Exemplo n.º 6
0
    def acquire_time_domain_samples(self,
                                    num_samples,
                                    num_samples_skip=0,
                                    retries=5):
        """Acquire num_samples_skip+num_samples samples and return the last num_samples

        :type num_samples: int
        :param num_samples: Number of samples to acquire

        :type num_samples_skip: int
        :param num_samples_skip: Skip samples to allow signal analyzer DC offset and IQ imbalance algorithms to take effect

        :type retries: int
        :param retries: The number of retries to attempt when failing to acquire samples

        :rtype: dictionary containing the following:
            data - (list) measurement data
            overload - (boolean) True if overload occurred, otherwise False
            frequency - (float) Measurement center frequency in hertz
            gain - (float) Measurement signal analyzer gain setting in dB
            sample_rate - (float) Measurement sample rate in samples per second
            capture_time - (string) Measurement capture time
            calibration_annotation - (dict) SigMF calibration annotation
    """
        self._sigan_overload = False
        self._capture_time = None
        # Get the calibration data for the acquisition
        self.recompute_calibration_data()
        nsamps = int(num_samples)
        nskip = int(num_samples_skip)

        # Compute the linear gain
        db_gain = self.sensor_calibration_data["gain_sensor"]
        linear_gain = 10**(db_gain / 20.0)

        # Try to acquire the samples
        max_retries = retries
        while True:
            # No need to skip initial samples when simulating the radio
            if not settings.RUNNING_TESTS and not settings.MOCK_RADIO:
                nsamps += nskip

            self._capture_time = utils.get_datetime_str_now()
            samples = self.usrp.recv_num_samps(
                nsamps,  # number of samples
                self.frequency,  # center frequency in Hz
                self.sample_rate,  # sample rate in samples per second
                [0],  # channel list
                self.gain,  # gain in dB
            )
            # usrp.recv_num_samps returns a numpy array of shape
            # (n_channels, n_samples) and dtype complex64
            assert samples.dtype == np.complex64
            assert len(samples.shape) == 2 and samples.shape[0] == 1
            data = samples[0]  # isolate data for channel 0
            data_len = len(data)

            if not settings.RUNNING_TESTS and not settings.MOCK_RADIO:
                data = data[nskip:]

            if not len(data) == num_samples:
                if retries > 0:
                    msg = "USRP error: requested {} samples, but got {}."
                    logger.warning(
                        msg.format(num_samples + num_samples_skip, data_len))
                    logger.warning("Retrying {} more times.".format(retries))
                    retries = retries - 1
                else:
                    err = "Failed to acquire correct number of samples "
                    err += "{} times in a row.".format(max_retries)
                    raise RuntimeError(err)
            else:
                logger.debug(
                    "Successfully acquired {} samples.".format(num_samples))

                # Check IQ values versus ADC max for sigan compression
                self._sigan_overload = False
                i_samples = np.abs(np.real(data))
                q_samples = np.abs(np.imag(data))
                i_over_threshold = np.sum(
                    i_samples > self.ADC_FULL_RANGE_THRESHOLD)
                q_over_threshold = np.sum(
                    q_samples > self.ADC_FULL_RANGE_THRESHOLD)
                total_over_threshold = i_over_threshold + q_over_threshold
                ratio_over_threshold = float(
                    total_over_threshold) / num_samples
                if ratio_over_threshold > self.ADC_OVERLOAD_THRESHOLD:
                    self._sigan_overload = True

                # Scale the data back to RF power and return it
                data /= linear_gain
                self.check_sensor_overload(data)
                measurement_result = {
                    "data": data,
                    "overload": self.overload,
                    "frequency": self.frequency,
                    "gain": self.gain,
                    "sample_rate": self.sample_rate,
                    "capture_time": self._capture_time,
                    "calibration_annotation":
                    self.create_calibration_annotation(),
                }
                return measurement_result