def setUp(self) -> None:

        self.carrier_frequency = 10e9
        self.sampling_rate = 1e3
        self.frequency = .25 * self.sampling_rate

        self.array_dimensions = (30, 30, 1)
        self.antenna_spacing = .5 * speed_of_light / self.carrier_frequency
        self.antennas = UniformArray(IdealAntenna(), self.antenna_spacing, self.array_dimensions)

        self.simulation = Simulation()
        self.device_a = self.simulation.scenario.new_device()
        self.device_b = self.simulation.scenario.new_device()

        self.device_a.antennas = self.antennas
        self.device_b.antennas = UniformArray(IdealAntenna(), self.antenna_spacing, [1, 1, 1])
        self.device_a.position = np.array([0., 0., 0.])
        self.device_b.position = np.array([0., 0., 100.])
        self.device_a.orientation = np.array([0., 0., 0.])
        self.device_b.orientation = np.array([0., 0., 0.])
        self.device_a.carrier_frequency = self.carrier_frequency
        self.device_b.carrier_frequency = self.carrier_frequency

        self.channel = RuralMacrocellsLineOfSight()
        self.simulation.scenario.set_channel(self.device_a, self.device_b, self.channel)
        self.channel.set_seed(123456)
示例#2
0
    def test_spatial_properties(self) -> None:
        """Direction of arrival estimation should result in the correct angle estimation of impinging devices"""

        self.channel.num_clusters = 1

        self.transmitter.antennas = UniformArray(
            IdealAntenna(), .5 * speed_of_light / self.carrier_frequency,
            (1, ))
        self.transmitter.orientation = np.zeros(3, dtype=float)
        self.receiver.position = np.zeros(3, dtype=float)
        self.receiver.antennas = UniformArray(
            IdealAntenna(), .5 * speed_of_light / self.carrier_frequency,
            (8, 8))

        angle_candidates = [
            (.25 * pi, 0),
            (.25 * pi, .25 * pi),
            (.25 * pi, .5 * pi),
            (.5 * pi, 0),
            (.5 * pi, .25 * pi),
            (.5 * pi, .5 * pi),
        ]
        range = 1e3

        steering_codebook = np.empty((8**2, len(angle_candidates)),
                                     dtype=complex)
        for a, (zenith, azimuth) in enumerate(angle_candidates):
            steering_codebook[:,
                              a] = self.receiver.antennas.spherical_response(
                                  self.carrier_frequency, azimuth, zenith)

        probing_signal = Signal(np.exp(2j * pi * .25 * np.arange(100)),
                                sampling_rate=1e3,
                                carrier_frequency=self.carrier_frequency)

        for a, (zenith, azimuth) in enumerate(angle_candidates):

            self.channel.set_seed(1)
            self.transmitter.position = range * np.array([
                cos(azimuth) * sin(zenith),
                sin(azimuth) * sin(zenith),
                cos(zenith)
            ],
                                                         dtype=float)

            received_signal, _, _ = self.channel.propagate(probing_signal)

            beamformer = np.linalg.norm(
                steering_codebook.T.conj() @ received_signal[0].samples,
                2,
                axis=1,
                keepdims=False)
            self.assertEqual(a, np.argmax(beamformer))
示例#3
0
    def test_num_streams(self) -> None:
        """Number of streams property should return proper number of streams."""

        self.device.antennas = UniformArray(IdealAntenna(),
                                            spacing=1.,
                                            dimensions=(3, ))
        self.assertEqual(3, self.modem.num_streams)

        self.device.antennas = UniformArray(IdealAntenna(),
                                            spacing=1.,
                                            dimensions=(2, ))
        self.assertEqual(2, self.modem.num_streams)
示例#4
0
    def setUp(self) -> None:

        self.rng = default_rng(42)
        self.random_node = Mock()
        self.random_node._rng = self.rng

        self.carrier_frequency = 1e9
        self.antennas = UniformArray(IdealAntenna(), 1, (1, ))

        self.receiver = Mock()
        self.receiver.position = np.array([100., 0., 0.])
        self.receiver.antennas = self.antennas
        self.receiver.orientation = np.array([0, 0, 0])
        self.receiver.velocity = np.array([0., 0., 0.], dtype=float)
        self.receiver.carrier_frequency = self.carrier_frequency

        self.transmitter = Mock()
        self.transmitter.position = np.array([-100., 0., 0.])
        self.transmitter.orientation = np.array([0, 0, 0])
        self.transmitter.antennas = self.antennas
        self.transmitter.velocity = np.array([0., 0., 0.], dtype=float)
        self.transmitter.carrier_frequency = 1e9

        self.channel = StreetCanyonNoLineOfSight(receiver=self.receiver,
                                                 transmitter=self.transmitter)
        self.channel.random_mother = self.random_node
示例#5
0
    def setUp(self) -> None:

        self.rng = np.random.default_rng(42)

        self.operator = Mock()
        self.operator.device = Mock()
        self.operator.device.antennas = UniformArray(IdealAntenna(), .01,
                                                     (5, 1, 1))

        self.beamformer = ConventionalBeamformer(operator=self.operator)
示例#6
0
    def setUp(self) -> None:

        self.seed = 12345

        self.num_clusters = 3
        self.delay_spread_mean = -7.49
        self.delay_spread_std = 0.55
        self.delay_scaling = 3.8
        self.carrier_frequency = 1e9

        self.antennas = UniformArray(
            IdealAntenna(), .5 * speed_of_light / self.carrier_frequency,
            (2, 2))

        self.receiver = Mock()
        self.receiver.num_antennas = self.antennas.num_antennas
        self.receiver.antennas = self.antennas
        self.receiver.position = np.array([100., 0., 0.])
        self.receiver.orientation = np.array([0., 0., 0.])
        self.receiver.antenna_positions = np.array([[100., 0., 0.]],
                                                   dtype=float)
        self.receiver.velocity = np.zeros(3, dtype=float)
        self.receiver.carrier_frequency = self.carrier_frequency

        self.transmitter = Mock()
        self.transmitter.num_antennas = self.antennas.num_antennas
        self.transmitter.antennas = self.antennas
        self.transmitter.position = np.array([-100., 0., 0.])
        self.transmitter.orientation = np.array([0., 0., pi])
        self.transmitter.antenna_positions = np.array([[-100., 0., 0.]],
                                                      dtype=float)
        self.transmitter.velocity = np.array([0., 0., 0.], dtype=float)
        self.transmitter.carrier_frequency = self.carrier_frequency

        self.channel = ClusterDelayLine(
            delay_spread_mean=self.delay_spread_mean,
            delay_spread_std=self.delay_spread_std,
            delay_scaling=self.delay_scaling,
            num_clusters=self.num_clusters,
            receiver=self.receiver,
            transmitter=self.transmitter,
            seed=1234)
    def setUp(self) -> None:

        self.simulation = Simulation()
        self.device = self.simulation.scenario.new_device()
        self.device.carrier_frequency = 1e8
        self.device.antennas = UniformArray(IdealAntenna(), .5 * speed_of_light / self.device.carrier_frequency, (3, 3))

        self.waveform = FMCW()
        self.beamformer = ConventionalBeamformer()

        self.radar = Radar()
        self.radar.waveform = self.waveform
        self.radar.transmit_beamformer = self.beamformer
        self.radar.receive_beamformer = self.beamformer

        self.radar.device = self.device
        self.device.sampling_rate = self.radar.sampling_rate

        self.channel = RadarChannel(target_range=.5*self.waveform.max_range,
                                    radar_cross_section=1.)
        self.simulation.scenario.set_channel(self.device, self.device, self.channel)
示例#8
0
    def setUp(self) -> None:

        # Configure a 2x2 link scenario
        antennas = UniformArray(IdealAntenna(), 5e-3, [2, 1, 1])
        self.tx_device = SimulatedDevice(antennas=antennas)
        self.rx_device = SimulatedDevice(antennas=antennas)

        scenario = Scenario()
        scenario.add_device(self.tx_device)
        scenario.add_device(self.rx_device)

        # Define a transmit operation on the first device
        self.tx_operator = Modem()
        self.tx_operator.precoding[0] = SpatialMultiplexing()
        self.tx_operator.device = self.tx_device

        # Define a receive operation on the second device
        self.rx_operator = Modem()
        self.rx_operator.precoding[0] = SpatialMultiplexing()
        self.rx_operator.device = self.rx_device
        self.rx_operator.reference_transmitter = self.tx_operator

        self.ber = BitErrorEvaluator(self.tx_operator, self.rx_operator)
示例#9
0
    def setUp(self) -> None:

        self.antenna = IdealAntenna()
示例#10
0
class TestIdealAntenna(TestCase):
    """Test the ideal antenna model"""
    def setUp(self) -> None:

        self.antenna = IdealAntenna()

    def test_array_setget(self) -> None:
        """Array property getter should return setter argument."""

        array = Mock()
        self.antenna.array = array

        self.assertIs(array, self.antenna.array)

        self.antenna.array = array
        self.assertIs(array, self.antenna.array)

    def test_array_removal(self) -> None:
        """Removing an array should envoke the callback."""

        array = Mock()
        self.antenna.array = array
        self.antenna.array = None

        self.assertEqual(1, array.remove_antenna.call_count)

    def test_pos_set(self) -> None:
        """Setting an antenna element position should call the respective array callback"""

        array = Mock()
        self.antenna.array = array
        self.antenna.pos = [1, 2, 3]

        self.assertEqual(1, array.set_antenna_position.call_count)

    def test_pos_set_validation(self) -> None:
        """Setting the position of a floating antenna should raise an exception"""

        with self.assertRaises(RuntimeError):
            self.antenna.pos = np.array([1, 2, 3])

    def test_transmit(self) -> None:
        """Transmitting should just be a stub returning the argument."""

        signal = Mock()
        self.assertIs(signal, self.antenna.transmit(signal))

    def test_receive(self) -> None:
        """Receiving should just be a stub returning the argument."""

        signal = Mock()
        self.assertIs(signal, self.antenna.receive(signal))

    def test_polarization(self) -> None:
        """Polarization should return unit polarization."""

        self.assertCountEqual((2**-.5, 2**-.5),
                              self.antenna.polarization(0., 0.))

    def test_plot_polarization(self) -> None:
        """Calling the plot routine should return a figure object."""

        self.assertIsInstance(self.antenna.plot_polarization(), plt.Figure)

    def test_plot_gain(self) -> None:
        """Calling the plot routine should return a figure object."""

        self.assertIsInstance(self.antenna.plot_gain(), plt.Figure)