How to manually set SSPs in QuaDRiGa (Satellite Scenario)

Sometimes it is necessary to adjust the small-scale fading directly. This tutorial creates a simple satellite scenario. Then, a list of large-scale parameters (LSPs) and their corresponding small-scale parameters (SSPs) is given. It is also demonstrated how those parameters are adjusted and how they influence the resulting channel coefficients.

Contents

Setting general parameters

We set up some basic parameters such as center frequency and sample density.

close all
clear all

set(0,'defaultTextFontSize', 14)    % Set default font size for the plots
set(0,'defaultAxesFontSize', 14)

s = simulation_parameters;          % Basic simulation parameters
s.center_frequency      = 2.185e9;  % Center Frequency
s.sample_density        = 4;        % 4 samples / half wave length

Defining Antenna Arrays

We set up our antenna arrays for the transmitter at the satellite and the receiver. We use synthetic patch antennas for this case. Two elements are crossed by an angle of 90 degree. The signal is then split and fed with a 90 degree phase shift to both elements generating RHCP and LHCP signals.

% Create a patch antenna with 120 degree opening
a = array('custom',120,120,0);

% Copy element 1 to element 2.
a.copy_element(1,2);

% Rotate the second pattern by 90 degree around the x-axis.
a.rotate_pattern(90,'x',2);

Set the coupling between the elements. The Tx-signal for the first element is shifted by +90 degree out of phase and put on the second element. The signal for the second element is shifted by -90 degree and copied to the first element. Both antennas thus radiate a RHCP and a LHCP wave.

a.coupling = 1/sqrt(2) * [1 1;1j -1j];      % LHCP and RHCP

% Create a copy of the array for the receiver.
b = a.copy_objects;

% Rotate the receive antenna array to face sky-wards.
b.rotate_pattern(-90,'y');

Setting the satellite orbital position

In this step, we set the antennas and the position of the satellite into a simulation layout. A layout object contains all the geometric information that are necessary to run the simulation. First, we define the position of the satellite. Since the model uses Cartesian coordinates, we have to transform the position of the satellite first.

Choose a random satellite position (Astra 2, seen from Berlin). The distance only needs to be big enough to ensure insignificant changes in the reception angle on the ground.

sat_el      = 28.4;             % Elevation angle
sat_az      = 161.6;            % Azimuth angle (South = 180 degree)
rx_latitude = 51;               % Latitude of the Rx

% Approximate the satellite distance for GEO orbit
dist_x      = 35786 + rx_latitude/90 * 6384;    % [km]
dist_y      = (1-rx_latitude/90) * 6384;        % [km]
sat_dist    = sqrt(dist_x^2 + dist_y^2);        % [km]
sat_dist    = sat_dist*1e3;                     % [m]

% Transform angles to Cartesian coordinates
sat_x = sat_dist * cosd(sat_el) * cosd( -sat_az+90 );
sat_y = sat_dist * cosd(sat_el) * sind( -sat_az+90 );
sat_z = sat_dist * sind(sat_el);

% We also turn the antenna of the satellite so it points to the receiver.
a.rotate_pattern( sat_el , 'y' );
a.rotate_pattern( 270-sat_az , 'z' );

% Create a new layout
l = layout( s );

% Set the satellite position in the layout
l.tx_position = [ sat_x ; sat_y ; sat_z ];

% Set the transmit antenna in the layout
l.tx_array = a;

l.randomize_rx_positions( 500,0,0,0 );          % Random Rx position

Setting up a user track and assigning LSPs

Here, we create a track with one segment. We then assign LSPs and automatically calculate SSPs. Those parameters can then be edited.

t = track('linear',5);                          % Linear track, 20 m length
t.interpolate_positions( s.samples_per_meter);  % Interpolate to sample density
t.initial_position = l.rx_position;
t.scenario = 'MIMOSA_10-45_LOS';                % Set scenarios

t.generate_parameters;                          % Generate LSPs

l.track = t;                    % Set track
l.rx_array = b;                 % Set Rx-Antenna

[~,~,cb] = l.get_channels;      % Get SSPs
Parameters   [oooooooooooooooooooooooooooooooooooooooooooooooooo]     2 seconds
Channels     [oooooooooooooooooooooooooooooooooooooooooooooooooo]     1 seconds

The LSPs are stored in "t.par". The SSPs are stored in "cb". The parameter are as follows:

  t.par.ds
     The delay spread in [s]. This value is used to assign the powers
     "cb.pow" and the delays "cb.taus" of each SC. You can only change
     the value of "t.par.ds" before calling "[~,~,cb] = l.get_channels;".
  cb.taus
     The individual delays in [s] for each SC.
  t.par.kf
     A vector of values for temporal evolution of the Ricean K-factor in
     [dB] for each snapshot (sample point). The first value
     "t.par.kf(1)" is used to scale the power of the first SC. The
     vector is applied right before applying the antenna patterns.
     Hence, it overwrites any changes you make to the SC powers in
     "cb.pow". It should always be edited before scaling the individual
     SC powers, if needed.
  cb.pow
     The power of each SC normalized to a sum-power of 1. The initial
     Ricean K-factor is already applied. This is done in a way that the
     following variables are identical:
     cb.pow(1) / sum( cb.pow(2:end) )    % The KF in the SC powers
     10^( 0.1*t.par.kf(1) )              % The automatically generated value
     cb.par.kf                           % The initial value for the segment
     Any changes you make will be overwritten by "t.par.kf". Hence, if
     you edit "cb.pow", you must make sure to also correct the values in
     "t.par.kf" and "cb.par.kf". This is done as follows:
% Edit power values in cb.pow as you wish. Here, we scale the first and
% second SC.
cb.pow(1:2) = [0.5, 0.2];

% Make sure that the sum-power is 1
cb.pow = cb.pow / sum(cb.pow);

% Calcualte new KF
kf = 10*log10( cb.pow(1) / sum( cb.pow(2:end) ) );

% Correct KF in "t.par.kf" and "cb.par.kf"
t.par.kf = t.par.kf - ( t.par.kf(1) - kf );
cb.par.kf = 10.^( 0.1*t.par.kf(1) );
  t.par.pg
     A vector of values for total path gain in [dB] for each snapshot.
     This is equal to the sum-power (e.g. in [dBm]) minus the transmit
     power (also in [dBm]). This vector is applied after the KF-scaling
     and right before applying the antenna patterns.
  t.par.asA
     Azimuth angle spread of arrival in [deg]. You can only change
     the value of "t.par.asA" before calling "[~,~,cb] = l.get_channels;".
  cb.AoA
     Azimuth arrival angles for each SC in global spherical coordinates
     given in [rad]. The first angle corresponds to the satellite
     azimuth position. The following values are identical:
     -sat_az + 90            % Given in compass-coordinates
     cb.AoA(1)/pi*180        % Given in global spherical coordinates
  t.par.esA
     Elevation angle spread of arrival in [deg]. You can only change
     the value of "t.par.esA" before calling "[~,~,cb] = l.get_channels;".
  cb.EoA
     Elevation arrival angles for each SC in global spherical coordinates
     given in [rad]. The first angle corresponds to the satellite
     elevation position. The following values are identical:
     sat_el
     cb.EoA(1)/pi*180
  t.par.asD
     Azimuth angle spread of departure in [deg]. This value is
     irrelevant for satellite setups where the departure angle is almost
     the same for each SC. You can only change the value of "t.par.asD"
     before calling "[~,~,cb] = l.get_channels;".
  cb.AoD
     Azimuth departure angles for each SC in global spherical coordinates
     given in [rad]. All angles should point to the terminal position as
     seen from the satellite. The following values are identical:
     -sat_az + 90            % Given in compass-coordinates
     cb.AoD/pi*180-180       % Given spherical coordinates
  t.par.esD
     Elevation angle spread of departure in [deg]. This value is
     irrelavant for satellite setups where the departure angle is almost
     the same for each SC.You can only change the value of "t.par.esA"
     before calling "[~,~,cb] = l.get_channels;".
  cb.EoA
     Elevation departure angles for each SC in global spherical
     coordinates given in [rad]. All angles correspond roughly to the
     negative satellite elevation position. The following values are
     identical:
     -sat_el
     cb.EoD/pi*180

After making the required changes, you can combine the SC and the antenna patterns to calculate the channel coefficient by:

c = cb.get_channels;
Channels     [oooooooooooooooooooooooooooooooooooooooooooooooooo]     1 seconds

A narrow band time-series is calculated by:

h = squeeze( sum(c.coeff,3) );

Plot for the power on each MIMO sub-channel.

power = abs( reshape( h,4,[] ) ).^2;
power = 10*log10(power).';

figure
[~,dist] = t.get_length;
plot(dist,t.par.pg,'--k','Linewidth',2)
hold on
plot(dist,power)
hold off
title('Simulated Power')
xlabel('Distance from start point [m]')
ylabel('Received Power [dBm]')
axis([0,5,min( power(:) )-5,max( power(:) )+2])
grid on
legend('LSP: t.par.pg','LHCP-LHCP','LHCP-RHCP','RHCP-LHCP','RHCP-RHCP',4);
close all
disp(['QuaDRiGa Version: ',simulation_parameters.version])
QuaDRiGa Version: 1.2.3-307