Null Steering Beamformer

Inheritance diagram of hermespy.beamforming.nullsteeringbeamformer

The following section provides an example for the usage of the nullsteeringbeamformer. A digital antenna array consisting of ideal isotropic antenna elements spaced at half wavelength intervals is created in the following code snippet.

 1sampling_rate = 1e6
 2carrier_frequency = 70e9
 3wavelength = speed_of_light / carrier_frequency
 4
 5# Initialize a new simulation
 6simulation = Simulation(seed=42)
 7
 8# Create a new device and assign it the antenna array
 9base_station_device = simulation.new_device(
10    antennas=SimulatedUniformArray(SimulatedIdealAntenna, .5 * wavelength, (5, 5, 1)),
11    carrier_frequency=carrier_frequency,

To investigate how the radiation pattern of the antenna array changes with respect to its topology. For this a new simulation environment is initialised and the custom antenna array is assigned to a device representing a transmitting base station.

1)
2
3# Configure a probong signal to be transmitted from the base station
4waveform = RootRaisedCosineWaveform(
5    symbol_rate=sampling_rate//2,
6    oversampling_factor=2,
7    num_preamble_symbols=32,
8    num_data_symbols=128,
9    roll_off=.9,

To probe the characterestics a cosine waveform is generated as the transmit waveform.

 1waveform.synchronization = SingleCarrierCorrelationSynchronization()
 2waveform.channel_estimation = SingleCarrierLeastSquaresChannelEstimation()
 3waveform.channel_equalization = SingleCarrierZeroForcingChannelEqualization()
 4
 5# Configure the base station device to transmit the beamformed probing signal
 6beamformer = NullSteeringBeamformer()
 7base_station_device.transmit_coding[0] = beamformer
 8
 9base_station_transmitter = TransmittingModem(waveform=deepcopy(waveform))
10base_station_device.add_dsp(base_station_transmitter)
11

The nullsteeringbeamformer is assigned to the custom array to transmit beamformed probing signal.

1user_equipment_device_1 = simulation.new_device(
2    carrier_frequency=carrier_frequency,
3    pose=Transformation.From_Translation(np.array([100., 100., 100.])),
4)
5
6user_equipment_device_2 = simulation.new_device(

The radiation pattern of the array can be visualised by specifiying the beamformer’s transmitting focus point and calling the plot_pattern method.

1# Render the beamformer's characteristics
2_ = uniform_array.plot_pattern(carrier_frequency, beamformer, title="Null Steering Beamformer")
3plt.show()
images/nullsteeringbeamformer_radiation_pattern.PNG

Now the simulation can be extended to evalaute the performance in a real world communication scenario. For this three devices representing the UEs are added, to be illuminated by the BS.

 1    pose=Transformation.From_Translation(np.array([-100., 100., 100.])),
 2)
 3
 4user_equipment_device_3 = simulation.new_device(
 5    carrier_frequency=carrier_frequency,
 6    pose=Transformation.From_Translation(np.array([100., -100., 100.])),
 7)
 8
 9# Configure the user equipments to receive the signal
10ue_receiver_1 = ReceivingModem(waveform=deepcopy(waveform))
11ue_receiver_2 = ReceivingModem(waveform=deepcopy(waveform))
12ue_receiver_3 = ReceivingModem(waveform=deepcopy(waveform))
13user_equipment_device_1.add_dsp(ue_receiver_1)
14user_equipment_device_2.add_dsp(ue_receiver_2)
15user_equipment_device_3.add_dsp(ue_receiver_3)
16
17# Focus the base station's main lobe on the desired user equipment and nulls on the others
18beamformer.transmit_focus = [
19    DeviceFocus(user_equipment_device_1),  # Focus on UE1
20    DeviceFocus(user_equipment_device_2),  # Null on UE2

Now as defined the nullsteeringbeamformer illuminates the maximum radiation on one UE whereas the nulls on the others. This can be realised by configuring the transmit foucs of the Beamformer.

1]
2
3# Configure a channel between base station and the UEs
4simulation.set_channel(

The propgation characterestics between the BS and the UEs can be modelled using the SpatialDelayChannel Model.

 1    user_equipment_device_1,
 2    SpatialDelayChannel(model_propagation_loss=False),
 3)
 4
 5simulation.set_channel(
 6    base_station_device,
 7    user_equipment_device_2,
 8    SpatialDelayChannel(model_propagation_loss=False),
 9)
10
11simulation.set_channel(
12    base_station_device,
13    user_equipment_device_3,
14    SpatialDelayChannel(model_propagation_loss=False),
15)
16
17# Configure a simulation scenario and analyze the power received by the 3 UEs by adding an evaluator.
18simulation.add_evaluator(ReceivePowerEvaluator(ue_receiver_1))

Now hermespy can be instructed to conduct a simulation campaign to evaluate the received signal power at the UEs by adding the evaluator.

1simulation.add_evaluator(ReceivePowerEvaluator(ue_receiver_3))
2result = simulation.run()
class NullSteeringBeamformer[source]

Bases: Serializable, TransmitBeamformer, ReceiveBeamformer

Implementation of the Null Steering Beamformer. Null-steering [1] transmit beamformers aim to maximize the received signal power in the direction of the intended receiver while substantially reducing the power impinging on the unintended receivers located in other directions. Let us introduce

\[\mathbf{a}_{\psi_{\bullet}} \triangleq \left[e^{j \frac{2\pi}{\lambda} r_1 \cos(\phi - \psi_1)}, \dots, e^{j \frac{2\pi}{\lambda} r_K \cos(\phi - \psi_K)} \right]^T\]

and

\[\mathbf{w} \triangleq \left[ w_1 \dots w_K \right]^T\]

Where \(\mathbf{a}_{\psi_{\bullet}}\) is the array propagation matrix and the vector W corresponds to the beamforming weights. Let

\[\mathbf{A} \triangleq \left[ \mathbf{a}_{\phi_1} \dots \mathbf{a}_{\phi_L} \right]\]

where A is the matrix that contains the array propagation vectors of all AoAs and \(P_T\) denote the maximum admissible total transmission power. The beamformer has maximized power in the intended direction and nulls at the unintended directions when:

\[\begin{split}\max_{\mathbf{w}} & \quad |\mathbf{w}^H \mathbf{a}_0|^2 \\ \text{subject to} & \quad \mathbf{w}^H \mathbf{A} = 0 \\ & \quad \mathbf{w}^H \mathbf{w} \leq P_T.\end{split}\]

The optimal solution to the above expression can be derived as:

\[\mathbf{w}_{\text{ns}} = \frac{\sqrt{P_T}}{\|(\mathbf{I} - \mathbf{P_A})\mathbf{a}_0\|} \cdot (\mathbf{I} - \mathbf{P_A})\mathbf{a}_0\]

where

\[\mathbf{P_A} \triangleq \mathbf{A}(\mathbf{A}^H\mathbf{A})^{-1}\mathbf{A}^H\]

is the orthogonal projection matrix onto the subspace spanned by the columns of A. As such, \(W_{\text{ns}}\) is in fact the orthogonal projection of onto the null space of \(a_0\). Thus, \(W_{\text{ns}}\) is the null steering beamformer.

_encode(samples, carrier_frequency, focus_angles, array)[source]

Encode signal streams for transmit beamforming.

Parameters:
  • samples (numpy.ndarray) – Signal samples, first dimension being the number of transmit antennas, second the number of samples.

  • carrier_frequency (float) – The assumed central carrier frequency of the samples generated RF signal after mixing in Hz.

  • focus_angles (numpy.ndarray) – Focused angles of departure in radians. Two-dimensional numpy array with the first dimension representing the number of focus points and the second dimension of magnitude two being the azimuth and elevation angles, respectively.

  • array (AntennaArrayState) – The assumed antenna array.

Return type:

ndarray

Returns:

The encoded signal samples. Two-dimensional complex-valued numpy array with the first dimension representing the number of transmit antennas streams and the second dimension the number of samples.

num_receive_output_streams(num_input_streams)[source]

Get required number of output streams during decoding.

Parameters:

num_input_streams (int) – Number of input streams.

Return type:

int

Returns: The number of output streams. Negative numbers indicate infeasible configurations.

property num_receive_focus_points: int

Number of required receive focus points.

If this is \(1\), the beamformer is considered to be a single focus point beamformer and receive_focus will return a single focus point. Otherwise, the beamformer is considered a multi focus point beamformer and receive_focus will return a Sequence of focus points.

Returns: Number of focus points.

property num_transmit_focus_points: int

Number of required transmit focus points.

If this is \(1\), the beamformer is considered to be a single focus point beamformer and transmit_focus will return a single focus point. Otherwise, the beamformer is considered a multi focus point beamformer and transmit_focus will return a Sequence of focus points.