联系方式

  • QQ:99515681
  • 邮箱:99515681@qq.com
  • 工作时间:8:00-23:00
  • 微信:codinghelp

您当前位置:首页 >> Java编程Java编程

日期:2023-10-20 11:40

Lab: Simulating and Sounding a Multi-Path Channel

Table of Contents

Visualizing the 3GPP TDL channel model..............................................................................................................1

Simulating the Multi-Path Channel.......................................................................................................................... 3

Creating the TX Channel Sounding Waveform.......................................................................................................6

Measuring the RX Channel Frequency Response..................................................................................................8

Compute the Time-Domain Channel Impulse Response........................................................................................9

Running the Channel Sounder over the SDR .....................................................................................................10

Create a Continuous Monitor.................................................................................................................................12

Further Enhancements...........................................................................................................................................14

Multi-path channel models are widely-used in the simulating wireless systems. In this lab, we will build a simple

simulator for a static multi-path channel. We will also show how to build a channel sounder, which is a device

that measures the channel response between a transmitter (TX) and receiver (RX). Channel sounders are key

for researchers studying wireless channel propagation. They are also useful in bringing up any SDR platform to

ensure the wideband response through the TX and RX chains is as expected. Indeed, after ensuring you can

receive a tone correctly, use a channel sounder to make sure the device works and correctly characterize the

TX and RX filters.

In going through this lab, you will learn to:

• Represent multi-path channels and download the 3GPP TDL multi-path model

• Simulate multi-path propagation with a fractional delay

• Measure the channel frequency response via frequency-domain correlation

• Compute the time-domain channel impulse response via an IFFT

• Align the channel impulse response via peak detection

• Build a continuous monitor for the channel

Files: You will need:

• chanSounder.mlx: This file, the main file for the lab

• SISOChan.m: Class file for the main simulator. You will use this in subsequent labs once done

• estChanResp.m: Function for estimating the channel

• TxFilt.m: Use the function that you created in the previous lab

Submissions: Run the lab with Pluto devices with either one or two hosts. Fill in all sections labeled TODO .

Print and submit the PDF. Do not submit the source code.

Visualizing the 3GPP TDL channel model

3GPP is an organization that designs common standards for wireless technologies such as 5G. Among many

other documents, 3GPP publishes channel models that can be used by designer for evaluating their products.

In this lab, we will use a simple tap delay line (TDL) model from 3GPP TR 38.900. In this model, the channel is

described as a number of "taps" or physical paths,

hchan(t) = \sum_k g(k) \delta(t-tau(k)),

2

where g(k) and tau(k) are the gain and delay of path k. MATLAB's excellent 5G Toolbox has a function to

retrieve these standard channels. The following code uses this function. We have set the delay spread to a

typical value for an outdoor suburban setting. The outputs are:

• dlyPath: A vector of delays of each path. Each value is in seconds.

• gainPath: A vector of relative gains of each path. Each value is in dB relative to the strongest path.

This channel would be considered an example of rich scattering, since it corresponds to a case of many paths,

posisbly from reflections, diffractions, and other paths. We will discuss channel modeling more in the wireless

class. For now, we will just use this channel.

tdl = nrTDLChannel('DelayProfile', 'TDL-A', 'DelaySpread', 1e-7);

chaninfo = info(tdl);

gainPath = chaninfo.AveragePathGains';

dlyPath = chaninfo.PathDelays';

To visualize the channel, plot gainPath vs. the delay.

• Use a stem pllot

• Set the BaseValue to -40 so that x-axis is well below the maximum path

• Put the delay in nanoseconds.

% Convert delay to nanoseconds for the stem plot.

dlyns = dlyPath * 1e9;

% Plot using stem

stem(dlyns, gainPath, 'filled');

xlabel('Delay (ns)');

ylabel('Gain (dB)');

title('3GPP TDL channel model');

grid on;

3

To simulate wireless multi-path channels, we need to implement a fractional delay. Suppose that, in

continuous-time, yc(t) = xc(t-tau) for some delay tau, and continuous-time signals xc(t) and yc(t),

Let x(n) = xc(nT) and y(n)=yc(nT) be discrete-time sampled versions of the signals. If the signals are

band-limited, we can write the discrete-time signals as:

y(n) = h(n)*x(n)

where h(n) is a filter that depends on the delay tau. As discussed in class, when tau=kT, so the delay is an

integer number of samples, we have y(n)=x(n-k) or equivalently, the filter h(n) = delta(n-k). When tau

is not an integer number of samples, it is called a fractional delay. MATLAB has excellent tools to implement

fractional delays. Complete and run the following code, which shift a ramp signal by a fractional delay. The

class dsp.VariableFractionalDelay is a bit of an over-kill for this task, but is simple to use. Under the

hood, the class creates a fractional FIR filter and then uses it to predict the delay signal.

% Create a fractional delay object fracDly =

dsp.VariableFractionalDelay(...

'InterpolationMethod', 'Farrow','FilterLength',8,...

'FarrowSmallDelayAction','Use off-centered kernel',...

'MaximumDelay', 1024);

% Create a ramp signal

nt = 100; x = (0:nt-1)'/nt;

Simulating the Multi-Path Channel

4

% Delay the signal by a fractional amount

dlySamp = 10.7;

y = fracDly(x, dlySamp);

% TODO: Plot x and y

plot(x, '-o', 'DisplayName', 'Original');

hold on;

plot(y, '-x', 'DisplayName', 'Delayed');

legend;

xlabel('Sample Number'); ylabel('Amplitude');

The class SISOChan uses dsp.VariableFractionalDelay class to implement the fractional delay along each

path. The constructor of the class creates the dsp.VariableFractionalDelay class objects. Complete the

code in SISOChan.stepImpl() method that:

• Computes the delays of each path in samples

• Computes the complex gain of each path

• Delay the input signal by the path delays using the fractional delay class

• Multiplies the delayed signals by the path gains and add them

% TODO: Complete the code in SISOChan.stepImpl() method

title('Fractional Delay of Ramp Signal');

5

To validate the channel model, we will send an impulse through the channel. Complete the following code which

creates an impulse signal, sends the impulse through the channel, and plots the output. You should see that

the observed impulse response mostly overlaps with the true impulse response. The difference arises from the

fact that we are sampling the paths at fractional delays.

% Create the channel object

fsamp = 30.72e6*2;

%chan = SISOChan(dlyPath == dlyPath, fsamp==fsamp, gainPath==gainPath);

% Create the channel object

fsamp = 30.72e6*2; %chan = SISOChan('dlyPath', dlyPath, 'fsamp', fsamp,

'gainPath', gainPath);

% Create a vector of times at the sample

rate. tmin = -0.5e-6; tmax = 2e-6;

t = (tmin:1/fsamp:tmax)';

nt = length(t);

% Create a signal ximp of length nt representing an impulse at zero.

ximp = zeros(nt, 1);

ximp(t == 0) = 1; % Set the value to 1 at the sample where time is zero

% Get the impulse response by sending ximp through the channel

%yimp = chan.stepImpl(ximp);

% Compute the energy in each output sample

%ypow = pow2db(max(abs(yimp).^2, 1e-8));

% Plot ypow vs. time using the stem plot

figure;

%stem(t*1e9, ypow); % Multiplying time by 1e9 to convert from seconds to nanoseconds

xlabel('Time (ns)');

ylabel('Energy (dB)');

title('Channel Impulse Response');

grid on;

6

Creating the TX Channel Sounding Waveform

The above code shows that, in principle, you could measure the channel by sending an impulse and looking

at the response. However, an impulse is typically not practical since it requires the transmitter to send a lot of

energy in a short period. Instead, most systems use a continuous wide band transmission. In this lab, we will

illustrate a very simple but effecitve frequency-domain channel sounding methd.

In frequency-domain channel sounding, we create the waveform in frequency domain. First, we create a vector

xfd of nfft QPSK symbols. Then, we take the IFFT to create the time-domain waveform.

% Parameters nfft

= 1024; fsamp =

30.72e6*2;

% Set the random number seed generator so that the TX and RX use the same

% random seed

rng(1, "twister");

% Flags

usePreRecorded = true; % Set to true to use pre-recorded data. Set to false to generate new

da saveData = true; % Set to true to save the generated data. Set to false to not save.

if usePreRecorded

try

load txData;

7

catch

warning('Could not find txData. Generating new data.');

usePreRecorded = false; % If the data cannot be loaded, generate new data. end

end

if ~usePreRecorded

% Generate a vector of nfft random QPSK symbols. xfd =

(randi(4, nfft, 1) - 2.5) + 1i * (randi(4, nfft, 1) - 2.5);

% Take the IFFT to obtain time-domain representation

x = ifft(xfd);

% Save frequency-domain TX data if the saveData flag is true

if saveData

save txData xfd;

end

end

% TODO: Take IFFT

x = ifft(xfd);

We next create a TX filter object that we built in the previous lab. Since we are not over-sampling (ovRatio =

1), we are just using the filter to scale the samples to the range of [-1,1].

% Create the TX filter object

backoffLev = 12; txFilt = TxFilt(vratio==1, rateIn==fsamp, backoffLev == backoffLev,

backoffAutoScale == true);

Not enough input arguments.

Error in vratio (line 12)

[s,c] = ellipj(u,mp);

% Filter the signal

x = txFilt(x);

In the real system, the TX will continuously transmit the signal x. For the simulation, we will create a signal

xrep with that is repeated nrep times. The resulting signal should be nrep*nfft x 1. You can use the

repmat function.

nrep = 4;

% TODO: Repeat the signal x, nrep times

% xrep

% Repeat the signal x, nrep times

xrep = repmat(x, [nrep, 1]);

Finally, we run the repeated signal through the channel. We will also add some noise 30 dB below the received

signal. We will discuss how to add noise later. For now, you can just run the provided code.

8

% Create the channel object

fsamp = 30.72e6*2;

chan = SISOChan(dlyPath == dlyPath, fsamp==fsamp, gainPath==gainPath);

% TODO: Run the input xrep through the channel

% r0 = ... r0

= chan(xrep);

% Add noise to r0

signalPower = mean(abs(r0).^2);

noisePower = signalPower / (10^(30/10));

noise = sqrt(noisePower/2) * (randn(size(r0)) + 1i*randn(size(r0)));

r0 = r0 + noise;

Measuring the RX Channel Frequency Response

Since the signal x is being repeatedly transmitted, the channel will act as a circular convolution. Therefore, the

channel frequency response can be estimated via:

hfd(k) = rfd(k) / xfd(k)

where rfd = fft(r). Complete the first two sections in the function estChanResp to estimate the frequency

response. You can ignore the other parts and outputs for now. After completing this section, run the following

code.

% Extract one FFT period of the data

r1 = r(nfft+1:2*nfft);

% TODO: Complete the TODO sections in estChanResp up to hfd = ...

% Then run:

% hfd = estChanResp(r1,xfd);

hfd = rfd ./ xfd;


The vector hfd from the previous part provides the sampled channel frequency response. Plot the power gain

in dB vs. frequency. The frequency should be in MHz and can be computed from the sample rate, fsamp. Use

the command fftshift to place the DC frequency in the center.

You should see the following:

• The channel has a lot of variation across frequency. This is due to the multi-path with high delay spread.

We will discuss in the wireless class.

• The channel starts to roll off after about |f| > 20 MHz. This is not from the physical channel, but the

filtering in the channel fractional delay.

• There is an arbitrary scaling we have scaled the signals in the TX.

9

% TODO: Compute the channel power gain and shift it using fftshift

and % plot against the frequency in MHz. Label your aees.

% hfddB = ...

% fMHz = ...

% plot(...)

% Estimate the channel frequency response

hfddB = 20 * log10(abs(hfd));

fMHz = fsamp * (-nfft/2:nfft/2-1) / nfft / 1e6;

plot(fMHz, fftshift(hfddB));

xlabel('Frequency (MHz)');

ylabel('Gain (dB)');

title('Estimated Channel Frequency Response');

grid on;

Compute the Time-Domain Channel Impulse Response

We can compute the channel impulse response by simply taking the IFFT of the channel frequency response. This

IFFT is performed in the function estChanResp. Note that we also shift the maximum peak to a fixed position and

normalize the channel response to the average energy. This last step is useful since the signals have an arbitrary

scaling at this point. In the wireless class, we will discuss how to measure the SNR.

Complete the TODO section of that code and run the following command.

% TODO: Complete the TODO sections in estChanResp up to h = ...

% Then run:

% [hfd, h] = estChanResp(r,xfd);

% TODO: Compute the estimated impulse responses

% hpow = pow2db(...);

% TODO: Plot hpow vs. time in

ns % tns = ...

% plot(tns, ...); hpow

= pow2db(abs(h).^2);

tns = (0:length(h)-1) / fsamp * 1e9; % convert to ns

plot(tns, hpow);

xlabel('Time (ns)');

ylabel('Gain (dB)');

title('Estimated Channel Impulse Response');

grid on;

The channel can have an arbitrary delay and gain relative to the true impulse response. Complete the code below

that scales and shifts the true and measures impulse response. You will see in this rich multipath environment the

channel esimator gets the rough locations of paths, but there is a lot of noise.

10

% Shift and scale the true path gains relative to the strongest path

[Pm, im] = max(gainPath);

relDlyTrue = dlyPath - dlyPath(im); % shift in time relative to strongest path

relDlyTrue = relDlyTrue*1e9; % convert to ns

gainTrue = gainPath - Pm; % shift in gain relative to strongest path

% TODO: Shift and scale the values in hpow and tns

% [Pm,im] =

max(hpow); %

relDlyMeas = ...

% relGainMeas = ...

% TODO: Plot the relative true and measured gains.

% Try to adjust the plot to get a good visualization.

Running the Channel Sounder over the SDR

We will now run the channel sounder over a real channel with the SDRs!

As before, set the mode to the desired configuration (loopback, two hosts with single host, or two hosts with two

hosts).

% TODO: Set parameters

% Set to true for loopback, else set to false

loopback = false;

% Select to run TX and RX

runTx = true;

runRx = true;

We a;sp set the parameters

• saveData: Indicates if the data is to be saved

• usePreRecorded: Indicates if the data is to use the pre-save data. This way, you will not need to run the

device

% Parameters saveData

= true; usePreRecorded

= false;

% Sample rate

fsamp = 30.72e6*2;

Plug one or two Plutos into the USB ports of your computer. If it is correctly working, in each device the Ready

light should be solid on and the LED1 light should be blinking. Next, run the following command that will detect

the devices and create the TX and RX ob

% clear previous instances

11

...

Transmit the data xrep repreatedly through the Pluto device.

if runTx && ~usePreRecorded

% TODO: Use the tx.release and tx.transmitRelease commands to

% continuously send xrep

end

% If not running the RX, stop the live script now

if ~runRx

return;

end

On the RX Pluto device, receive the data

nbits = 12; % number of ADC

bits fullScale = 2^(nbits-1); % full scale

if ~usePreRecorded

% TODO: Capture data for nfft samples

% r = rx.capture(...)


% TODO: Scale to floating

point % r = ...

% Save the data

if saveData

save rxDataSing r;

end

else

% Load pre-recorded

data load rxDataSing;

end

Estimate and plot the channel impulse response. You should a strong peak, but you will likely see no other

peaks since this system does not have sufficient bandwidth to resolve the multi-path in indoors (assuming you

are running the experiment indoors).

clear tx rx

% add path to the common directory where the function is found

addpath('..\..\common');

% Run the creation function. Skip this if we are using pre-recorded

% samples

if ~usePreRecorded

[tx, rx] = plutoCreateTxRx(createTx == runTx, createRx == runRx, loopback ==

loopback,

nsampsFrameRx == nfft, nsampsFrameTx == nfft, sampleRate == fsamp);

end

12

% Estimate the channel

[hfd,h] = estChanResp(r,xfd,'normToMean', true);

% Compute the estimated impulse responses

% hpow = pow2db(...);

hpow = pow2db(abs(h).^2);

% TODO: Plot hpow vs. time in

ns % tns = ...

% plot(tns, ...);

Create a Continuous Monitor

We will now continuously monitor and plot the channel impulse response and SNR.

if runTx && ~usePreRecorded

% TODO: Use the tx.release and tx.transmitRelease commands to

% continuously send xclip

end

% Number of captures

ncaptures = 100;

% Load pre-recorded data if required

if usePreRecorded load

rxDatMult; ncaptures =

size(rdat,2);

else

rdat = zeros(nfft, ncaptures);

end

if usePreRecorded

r = rdat(:,1);

else % TODO: Capture

initial data

% r = ...

end

% TODO: Get the channel response

% [hfd,h] = estChanResp(...);

% Re-compute the impulse response and impulse power

[hfd, h] = estChanResp(r, xfd, 'normToMean', true);

13

hpow1 = pow2db(abs(h(1:nplot)).^2);

% TODO: Get the initial impulse response as before.

%

% tus1 = relative delays in micro-seconds for the first nplot samples

% hpow1 = vector of impulse reponse

nplot = 256;

% Create the initial plot

clf;

p = plot(tus1,hpow1);

xlim([min(tus1),max(tus1)]);

ylim([-20, 40]);

xlabel('Time [us]');

ylabel('Path gain [dB]');

grid on;

% Set pointers to Y data for both plots

p.YDataSource = 'hpow1';

snr =

zeros(ncaptures,1); for

t = 1:ncaptures if

~usePreRecorded

% TODO: Capture data

% r = rx.capture(...);

% Save data if required

if saveData

rdat(:,t) = r;

end

else

% Load pre-recorded

r = rdat(:,t);

end

% TODO: Re-compute the impulse response

% [~,h] = estChanResp(...);

% TODO: Re-compute hpow1 = impulse response on the first nplot samples.

% hpow1 = ...

% Re-compute the impulse response

[~, h] = estChanResp(r, xfd, 'normToMean', true);

% Re-compute hpow1 = impulse response on the first nplot samples

hpow1 = pow2db(abs(h(1:nplot)).^2);

14

% Redraw plot

refreshdata(p);

drawnow

15


end

% Save data

if saveData

save rxDatMult rdat;

end

Further Enhancements

There are several ways we can improve the channel sounder. Feel free to take this code and modify it if you

are interested.

• We can integrate over multiple RX frames to average out the noise.

• Also, if we have multiple RX frames, we can estimate the carrier frequency offset (CFO). Estimating and

correcting the CFO is essential to integrate over multiple frames.

• Multiple frames will also allow us to measure fading, which is the variation of the channel over time. This

process is discussed in the wireless communications class

• We can use a wider band sounder (i.e., higher sample rate) to resolve closer multipath component

• A very similar method can be used for RADAR


相关文章

版权所有:留学生编程辅导网 2020 All Rights Reserved 联系方式:QQ:99515681 微信:codinghelp 电子信箱:99515681@qq.com
免责声明:本站部分内容从网络整理而来,只供参考!如有版权问题可联系本站删除。 站长地图

python代写
微信客服:codinghelp