Этот пример демонстрирует процедуру уточнения передающего луча нисходящей линии связи с использованием опорного сигнала информации о состоянии канала (CSI-RS) от 5G Toolbox™. Пример показывает, как передавать множество ресурсов CSI-RS в разных направлениях в среде рассеяния и как выбирать оптимальный луч передачи на основе измерений принимаемой мощности опорного сигнала (RSRP).
В NR 5G частотный диапазон 2 (FR2) работает на миллиметровых частотах (от 24,25 ГГц до 52,6 ГГц). По мере увеличения частоты передаваемый сигнал подвержен высоким потерям в тракте и потерям проникновения, что влияет на бюджет линии связи. Для улучшения усиления и направленности передачи и приема сигналов на более высоких частотах необходимо формирование луча. Управление лучом представляет собой набор процедур уровня 1 (физический уровень) и уровня 2 (управление доступом к среде) для установления и сохранения оптимальной пары лучей (передающий луч и соответствующий принимающий луч) для хорошей связности. TR 38.802 Раздел 6.1.6.1 [1] определяет управление лучом как три процедуры:
Процедура 1 (P-1): Эта процедура фокусируется на первоначальном получении на основе блоков сигналов синхронизации (SSB). Во время начального обнаружения на передающем и приемном концах происходит подметка луча для выбора лучшей пары лучей на основе измерений RSRP. В общем случае выбранные лучи являются широкими и могут не быть оптимальной парой лучей для передачи и приема данных. Для получения дополнительной информации об этой процедуре см. NR SSB Beam Sweeping.
Процедура 2 (P-2): Эта процедура сосредоточена на уточнении луча на передающем конце, где свипирование луча происходит на передающем конце путем фиксации принимающего луча. Процедура основана на ненулевой мощности CSI-RS (NZP-CSI-RS) для уточнения передающего луча нисходящей линии связи и зондирующего опорного сигнала (SRS) для уточнения передающего луча восходящей линии связи.
После первоначального установления луча для получения одноадресной передачи данных с высокой направленностью и высоким усилением требуется луч, намного более тонкий, чем луч SSB. Поэтому набор ресурсов опорного сигнала конфигурируется и передается в различных направлениях с использованием более тонких лучей в пределах углового диапазона луча из процесса начального обнаружения. Затем пользовательское оборудование (UE) или узел сети доступа (gNB) измеряет все эти лучи путем захвата сигналов фиксированным приемным лучом. Наконец, наилучший передающий луч выбирается на основе измерений RSRP для всех передающих лучей.
Процедура 3 (P-3): Эта процедура фокусируется на корректировке луча на приемном конце, где свипирование луча происходит на приемном конце с учетом текущего передающего луча. Этот процесс направлен на поиск наилучшего принимающего луча, который может быть соседним лучом или усовершенствованным лучом. Для этой процедуры набор ресурсов опорного сигнала (NZP-CSI-RS для нисходящей линии связи и SRS для восходящей линии связи) передается одним и тем же передающим лучом, и UE или gNB принимает сигнал, используя различные лучи из разных направлений, охватывающих угловой диапазон. Наконец, наилучший принимаемый луч выбирается на основе измерений RSRP для всех принимаемых лучей.
В этом примере основное внимание уделяется уточнению луча нисходящей линии связи в передатчике. Пример работает и на частотный диапазон 1 (FR1) и на частотный диапазон 2 (FR2) НОМЕРА 5G. На этом рисунке показана процедура уточнения передающего луча с учетом четырех ресурсов NZP-CSI-RS, передаваемых в четырех различных направлениях.

На этом рисунке показаны основные этапы обработки этого примера с цветовыми этапами, связанными с процессом уточнения передающего луча.

Создайте объект конфигурации несущей, представляющий несущую 50 МГц с интервалом между поднесущими 30 кГц.
carrier = nrCarrierConfig;
% Maximum transmission bandwidth configuration for 50 MHz carrier with 30 kHz subcarrier spacing
carrier.NSizeGrid = 133;
carrier.SubcarrierSpacing = 30;
carrier.NSlot = 0;
carrier.NFrame = 0carrier =
nrCarrierConfig with properties:
NCellID: 1
SubcarrierSpacing: 30
CyclicPrefix: 'normal'
NSizeGrid: 133
NStartGrid: 0
NSlot: 0
NFrame: 0
Read-only properties:
SymbolsPerSlot: 14
SlotsPerSubframe: 2
SlotsPerFrame: 20
Создание объекта конфигурации CSI-RS, представляющего набор ресурсов NZP-CSI-RS с помощью numNZPRes количество ресурсов NZP-CSI-RS. Для измерений RSRP уровня 1 сконфигурируйте все ресурсы CSI-RS в наборе ресурсов с одинаковым количеством антенных портов (однопортовых или двухпортовых), как указано в TS 38.215 Раздел 5.1.2 [2] или TS 38.214 Раздел 5.1.6.1.2 [3]. В этом примере используется однопортовая плата CSI-RS.
numNZPRes = 12;
csirs = nrCSIRSConfig;
csirs.CSIRSType = repmat({'nzp'},1,numNZPRes);
csirs.CSIRSPeriod = 'on';
csirs.Density = repmat({'one'},1,numNZPRes);
csirs.RowNumber = repmat(2,1,numNZPRes);
csirs.SymbolLocations = {0,1,2,3,4,5,6,7,8,9,10,11};
csirs.SubcarrierLocations = repmat({0},1,numNZPRes);
csirs.NumRB = 25csirs =
nrCSIRSConfig with properties:
CSIRSType: {1x12 cell}
CSIRSPeriod: 'on'
RowNumber: [2 2 2 2 2 2 2 2 2 2 2 2]
Density: {1x12 cell}
SymbolLocations: {[0] [1] [2] [3] [4] [5] [6] [7] [8] [9] [10] [11]}
SubcarrierLocations: {[0] [0] [0] [0] [0] [0] [0] [0] [0] [0] [0] [0]}
NumRB: 25
RBOffset: 0
NID: 0
Read-only properties:
NumCSIRSPorts: [1 1 1 1 1 1 1 1 1 1 1 1]
CDMType: {1x12 cell}
% Validate CSI-RS antenna ports validateCSIRSPorts(csirs); % Get the binary vector to represent the presence of each CSI-RS resource % in a specified slot csirsTransmitted = getActiveCSIRSRes(carrier,csirs);
Сконфигурируйте масштабирование мощности всех ресурсов NZP-CSI-RS в децибелах (дБ).
powerCSIRS = 0;
Создание символов и индексов CSI-RS с помощью carrier и csirs объекты конфигурации. Чтобы различать каждый выход ресурса CSI-RS отдельно, укажите OutputResourceFormat,'cell' пара имя-значение.
csirsSym = nrCSIRS(carrier,csirs,'OutputResourceFormat','cell')
csirsSym=1×12 cell array
Columns 1 through 4
{25x1 double} {25x1 double} {25x1 double} {25x1 double}
Columns 5 through 8
{25x1 double} {25x1 double} {25x1 double} {25x1 double}
Columns 9 through 12
{25x1 double} {25x1 double} {25x1 double} {25x1 double}
csirsInd = nrCSIRSIndices(carrier,csirs,'OutputResourceFormat','cell')
csirsInd=1×12 cell array
Columns 1 through 4
{25x1 uint32} {25x1 uint32} {25x1 uint32} {25x1 uint32}
Columns 5 through 8
{25x1 uint32} {25x1 uint32} {25x1 uint32} {25x1 uint32}
Columns 9 through 12
{25x1 uint32} {25x1 uint32} {25x1 uint32} {25x1 uint32}
Сконфигурируйте несущую частоту и скорость распространения сигнала.
% Set the carrier frequency fc = 3.5e9; freqRange = validateFc(fc); % Set the propagation speed c = physconst('LightSpeed'); % Calculate wavelength lambda = c/fc;
Сконфигурируйте размер антенных решеток передачи и приема как двухэлементный вектор, где первый элемент представляет количество строк, а второй элемент представляет количество столбцов в антенной решетке.
txArySize = [8 8]; rxArySize = [2 2];
Вычислите общее количество антенных элементов передачи и приема.
nTx = prod(txArySize); nRx = prod(rxArySize);
Сконфигурируйте положения антенных решеток передачи и приема. Затем вычисляют потери в тракте свободного пространства на основе пространственного разделения между положениями антенной решетки передачи и приема.
% Configure antenna array positions txArrayPos = [0;0;0]; rxArrayPos = [100;50;0]; % Calculate the free space path loss toRxRange = rangeangle(txArrayPos,rxArrayPos); spLoss = fspl(toRxRange,lambda);
Сконфигурируйте однородный линейный массив (ULA) или однородный прямоугольный массив (URA) на основе размеров матриц антенн.
% Initialize the flags to choose between URA and ULA isTxRectArray = false; isRxRectArray = false; % Enable isTxRectArray if both the number of rows and columns of transmit % antenna array are greater than one if ~any(txArySize == 1) isTxRectArray = true; end % Enable isRxRectArray if both the number of rows and columns of receive % antenna array are greater than one if ~any(rxArySize == 1) isRxRectArray = true; end % Configure the transmit and receive antenna elements txAntenna = phased.IsotropicAntennaElement('BackBaffled',true); % To avoid transmission beyond +/- 90 % degrees from the broadside, baffle % the back of the transmit antenna % element by setting the BackBaffled % property to true rxAntenna = phased.IsotropicAntennaElement('BackBaffled',false); % To receive the signal from 360 degrees, % set the BackBaffled property to false % Configure transmit antenna array if isTxRectArray % Create a URA System object for signal transmission txArray = phased.URA('Element',txAntenna,'Size',txArySize,'ElementSpacing',lambda/2); else % Create a ULA System object for signal transmission txArray = phased.ULA('Element',txAntenna,'NumElements',nTx,'ElementSpacing',lambda/2); end % Configure receive antenna array if isRxRectArray % Create a URA System object for signal reception rxArray = phased.URA('Element',rxAntenna,'Size',rxArySize,'ElementSpacing',lambda/2); else % Create a ULA System object for signal reception rxArray = phased.ULA('Element',rxAntenna,'NumElements',nRx,'ElementSpacing',lambda/2); end
fixedScatMode = true; rng(42); if fixedScatMode % Fixed single scatterer location numScat = 1; scatPos = [60;10;15]; else % Generate scatterers at random positions numScat = 10; %#ok<UNRCH> azRange = -180:180; randAzOrder = randperm(length(azRange)); elRange = -90:90; randElOrder = randperm(length(elRange)); azAngInSph = deg2rad(azRange(randAzOrder(1:numScat))); elAngInSph = deg2rad(elRange(randElOrder(1:numScat))); r = 20; % Transform spherical coordinates to Cartesian coordinates [x,y,z] = sph2cart(azAngInSph,elAngInSph,r); scatPos = [x;y;z] + (txArrayPos + rxArrayPos)/2; end
Создайте управляющий вектор System object для передающей антенной решетки.
txArrayStv = phased.SteeringVector('SensorArray',txArray,'PropagationSpeed',c);
Вычислите угол положения рассеивателя относительно антенной решетки передачи.
[~,scatAng] = rangeangle(scatPos(:,1),txArrayPos); % Pointing towards the first scatterer position, in case of multiple scatterersСконфигурируйте азимут и высоту луча передачи SSB из начального процесса сбора данных (P-1).
azTxBeamWidth = 30; % In degrees elTxBeamWidth = 30; % In degrees
Получить направление луча передачи SSB, которое выровнено (частично или полностью) по положению рассеивателя, используя ширину луча в плоскостях азимута и возвышения.
ssbTxAng = getInitialBeamDir(scatAng,azTxBeamWidth,elTxBeamWidth);
Рассчитайте направления луча (пары азимута и угла места) для всех активных ресурсов CSI-RS в пределах углового диапазона, охватываемого лучом передачи SSB.
% Get the number of transmit beams based on the number of active CSI-RS resources in a slot numBeams = sum(csirsTransmitted); % Get the azimuthal sweep range based on the SSB transmit beam direction % and its beamwidth in azimuth plane azSweepRange = [ssbTxAng(1) - azTxBeamWidth/2 ssbTxAng(1) + azTxBeamWidth/2]; % Get the elevation sweep range based on the SSB transmit beam direction % and its beamwidth in elevation plane elSweepRange = [ssbTxAng(2) - elTxBeamWidth/2 ssbTxAng(2) + elTxBeamWidth/2]; % Get the azimuth and elevation angle pairs for all NZP-CSI-RS transmit beams azBW = beamwidth(txArray,fc,'Cut','Azimuth'); elBW = beamwidth(txArray,fc,'Cut','Elevation'); csirsBeamAng = hGetBeamSweepAngles(numBeams,azSweepRange,elSweepRange,azBW,elBW);
Вычислите векторы управления для всех активных ресурсов CSI-RS.
wT = zeros(nTx,numBeams); for beamIdx = 1:numBeams tempW = txArrayStv(fc,csirsBeamAng(:,beamIdx)); wT(:,beamIdx) = tempW; end
Выполните закольцовывание всех ресурсов NZP-CSI-RS и примените цифровое формирование луча ко всем активным ресурсам. Считается, что цифровое формирование луча обеспечивает частотно-избирательное формирование луча в пределах одного символа OFDM.
% Number of CSI-RS antenna ports ports = csirs.NumCSIRSPorts(1); % Initialize the beamformed grid bfGrid = nrResourceGrid(carrier,nTx); % Get the active NZP-CSI-RS resource indices activeRes = find(logical(csirsTransmitted)); for resIdx = 1:numNZPRes % Initialize the carrier resource grid for one slot and map NZP-CSI-RS symbols onto % the grid txSlotGrid = nrResourceGrid(carrier,ports); txSlotGrid(csirsInd{resIdx}) = db2mag(powerCSIRS)*csirsSym{resIdx}; reshapedSymb = reshape(txSlotGrid,[],ports); % Get the transmit beam index beamIdx = find(activeRes == resIdx); % Apply the digital beamforming if ~isempty(beamIdx) bfSymb = reshapedSymb * wT(:,beamIdx)'; bfGrid = bfGrid + reshape(bfSymb,size(bfGrid)); end end
Генерируют сигнал во временной области путем выполнения модуляции OFDM.
% Perform OFDM modulation [tbfWaveform,ofdmInfo] = nrOFDMModulate(carrier,bfGrid); % Normalize the beamformed time-domain waveform over the number of transmit % antennas tbfWaveform = tbfWaveform/sqrt(nTx);
Настройка канала распространения MIMO на основе рассеяния с помощью объекта System phased.ScatteringMIMOChannel(Панель инструментов системы фазированных массивов). Эта модель канала применяет временную задержку, усиление, доплеровский сдвиг, изменение фазы, потери на пути свободного пространства и, необязательно, другие атмосферные затухания на входе.
chan = phased.ScatteringMIMOChannel; chan.PropagationSpeed = c; chan.CarrierFrequency = fc; chan.Polarization = 'none'; chan.SpecifyAtmosphere = false; chan.SampleRate = ofdmInfo.SampleRate; chan.SimulateDirectPath = false; chan.ChannelResponseOutputPort = true; % Configure transmit array parameters chan.TransmitArray = txArray; chan.TransmitArrayMotionSource = 'property'; chan.TransmitArrayPosition = txArrayPos; % Configure receive array parameters chan.ReceiveArray = rxArray; chan.ReceiveArrayMotionSource = 'property'; chan.ReceiveArrayPosition = rxArrayPos; % Configure scatterers chan.ScattererSpecificationSource = 'property'; chan.ScattererPosition = scatPos; chan.ScattererCoefficient = ones(1,numScat); % Get the maximum channel delay by transmitting random signal [~,~,tau] = chan(complex(randn(chan.SampleRate*1e-3,nTx), ... randn(chan.SampleRate*1e-3,nTx))); maxChDelay = ceil(max(tau)*chan.SampleRate);
Добавьте нули в конце передаваемого сигнала, чтобы очистить содержимое канала и затем пропустить сигнал во временной области через канал MIMO рассеяния. Эти нули учитывают любую задержку, введенную в канале.
% Append zeros to the transmit waveform to account for channel delay tbfWaveform = [tbfWaveform; zeros(maxChDelay,nTx)]; % Pass the waveform through the channel fadWave = chan(tbfWaveform);
Сконфигурируйте и примените коэффициент усиления приема к затухшему сигналу для компенсации потерь в тракте. Затем примените AWGN к результирующему сигналу.
% Configure the receive gain rxGain = 10.^((spLoss)/20); % Gain in linear scale % Apply the gain fadWaveG = fadWave*rxGain; % Configure the SNR in dB SNRdB = 20; SNR = 10^(SNRdB/20); % SNR in linear scale % Calculate the standard deviation for AWGN N0 = 1/(sqrt(2.0*nRx*double(ofdmInfo.Nfft))*SNR); % Generate AWGN noise = N0*complex(randn(size(fadWaveG)),randn(size(fadWaveG))); % Apply AWGN to the waveform rxWaveform = fadWaveG + noise;
Выполните синхронизацию синхронизации путем кросс-корреляции принятых опорных символов с локальной копией символов NZP-CSI-RS.
% Generate reference symbols and indices refSym = nrCSIRS(carrier,csirs); refInd = nrCSIRSIndices(carrier,csirs); % Estimate timing offset offset = nrTimingEstimate(carrier,rxWaveform,refInd,refSym); if offset > maxChDelay offset = 0; end % Correct timing offset syncTdWaveform = rxWaveform(1+offset:end,:);
OFDM демодулируют синхронизированный сигнал временной области.
rxGrid = nrOFDMDemodulate(carrier,syncTdWaveform);
Создайте объект System вектора управления для приемной антенной решетки.
rxArrayStv = phased.SteeringVector('SensorArray',rxArray,'PropagationSpeed',c);
Вычисляют угол положения рассеивателя относительно приемной антенной решетки. Предположим, что это является направлением приема луча из процесса начального обнаружения с использованием SSB.
[~,scatRxAng] = rangeangle(scatPos(:,1),rxArrayPos); % Pointing towards the first scatterer position, in case of multiple scatterersСконфигурируйте азимут и ширину луча подъема приемного луча в процессе начального захвата (P-1).
azRxBeamWidth = 30; % In degrees elRxBeamWidth = 30; % In degrees
Получить начальное направление луча приема, которое выровнено (частично или полностью) по положению рассеивателя, используя ширину луча в плоскостях азимута и отметки от P-1.
rxAng = getInitialBeamDir(scatRxAng,azRxBeamWidth,elRxBeamWidth);
Вычислите рулевой вектор для угла приема.
wR = rxArrayStv(fc,rxAng);
Чтобы выполнить цифровое формирование луча на стороне приемника, примените веса рулевого управления к rxGrid, с предположением, что нет другого сигнала, присутствующего в rxGrid (сценарий одиночного UE). Объедините сигналы от всех приемных антенных элементов при FR2, как указано в ТУ 38.215 раздел 5.1.2 [2].
temp = rxGrid; if strcmpi(freqRange,'FR1') % Beamforming without combining rbfGrid = reshape(reshape(temp,[],nRx).*wR',size(temp,1),size(temp,2),[]); else % 'FR2' % Beamforming with combining rbfGrid = reshape(reshape(temp,[],nRx)*conj(wR),size(temp,1),size(temp,2),[]); end
Получение позиций элементов антенных решеток передачи и приема для построения графика.
% Get the positions of transmit antenna elements (in meters) txElemPos = getElementPosition(txArray); % Get the positions of receive antenna elements (in meters) rxElemPos = getElementPosition(rxArray);
Сконфигурируйте параметры сцены MIMO.
sceneParams.txElemPos = txElemPos; sceneParams.rxElemPos = rxElemPos; sceneParams.txArraySize = txArySize; sceneParams.rxArraySize = rxArySize; sceneParams.txArrayPos = txArrayPos; sceneParams.rxArrayPos = rxArrayPos; sceneParams.txAzAngles = -90:90; % Vector of azimuth angles, where the pattern of % transmit antenna array is calculated sceneParams.txElAngles = -90:90; % Vector of elevation angles, where the pattern of % transmit antenna array is calculated sceneParams.rxAzAngles = [90:180 -179:-90]; % Vector of azimuth angles, where the pattern of % receive antenna array is calculated sceneParams.rxElAngles = -90:90; % Vector of elevation angles, where the pattern of % receive antenna array is calculated sceneParams.scatPos = scatPos; sceneParams.lambda = lambda; sceneParams.arrayScaling = 100; % To enlarge antenna arrays in the plot sceneParams.maxBeamLength = 45; % Maximum length of transmit and receive beams in the plot
Постройте график сценария MIMO рассеяния (включая антенные решетки передачи и приема, положения рассеивателей и их пути, а также все диаграммы направленности антенной решетки передачи и приема) с помощью функции помощника hPlotSpatialMIMOScene.
hPlotSpatialMIMOScene(sceneParams,wT,wR); xlim([-20 120]); ylim([-50 100]); zlim([-50 50]); view([74 29]);

После демодуляции OFDM UE измеряет RSRP для всех ресурсов CSI-RS, передаваемых в различных лучах, учитывая текущий принимаемый луч. Выполните эти измерения с помощью функции помощника hCSIRSMeasurements.
% Perform RSRP measurements meas = hCSIRSMeasurements(carrier,csirs,rbfGrid); % Display the measurement quantities for all CSI-RS resources in dBm RSRPdBm = meas.RSRPdBm; disp(['RSRP measurements of all CSI-RS resources (in dBm):' 13 num2str(RSRPdBm)]);
RSRP measurements of all CSI-RS resources (in dBm): 42.3147 33.237 29.1999 45.1102 37.0922 31.4861 39.9414 33.5053 24.5859 17.5821 12.9908 -1.9296
Определите максимальное значение RSRP из измерений и найдите наилучший соответствующий луч.
% Get the transmit beam index with maximum RSRP value [~,maxRSRPIdx] = max(RSRPdBm(logical(csirsTransmitted))); % Get the CSI-RS resource index with maximum RSRP value [~,maxRSRPResIdx] = max(RSRPdBm);
Вычислите ширину луча, которая соответствует уточненному лучу передачи.
% Get the steering weights corresponding to refined transmit beam if numBeams == 0 disp('Refinement has not happened, as NZP-CSI-RS is not transmitted') else refBeamWts = wT(:,maxRSRPIdx); csirsAzBeamWidth = beamwidth(txArray,fc,'PropagationSpeed',c,'Weights',refBeamWts); csirsElBeamWidth = beamwidth(txArray,fc,'PropagationSpeed',c,'Weights',refBeamWts,'Cut','Elevation'); disp(['From initial beam acquisition:' 13 ' Beamwidth of initial SSB beam in azimuth plane is: '... num2str(azTxBeamWidth) ' degrees' 13 ... ' Beamwidth of initial SSB beam in elevation plane is: '... num2str(elTxBeamWidth) ' degrees' 13 13 ... 'With transmit-end beam refinement:' 13 ' Refined transmit beam ('... num2str(maxRSRPIdx) ') corresponds to CSI-RS resource '... num2str(maxRSRPResIdx) ' is selected in the direction ['... num2str(csirsBeamAng(1,maxRSRPIdx)) ';' num2str(csirsBeamAng(2,maxRSRPIdx))... ']' 13 ' Beamwidth of refined transmit beam in azimuth plane is: '... num2str(csirsAzBeamWidth) ' degrees' 13 ... ' Beamwidth of refined transmit beam in elevation plane is: '... num2str(csirsElBeamWidth) ' degrees']); end
From initial beam acquisition:
Beamwidth of initial SSB beam in azimuth plane is: 30 degrees
Beamwidth of initial SSB beam in elevation plane is: 30 degrees
With transmit-end beam refinement:
Refined transmit beam (4) corresponds to CSI-RS resource 4 is selected in the direction [10;15]
Beamwidth of refined transmit beam in azimuth plane is: 12.98 degrees
Beamwidth of refined transmit beam in elevation plane is: 13.25 degrees
В этом примере показана процедура уточнения балки (P-2) с использованием NZP-CSI-RS. Процедура идентифицирует передающий луч, который больше, чем луч от начального захвата.
Можно настроить несколько ресурсов CSI-RS, конфигурации антенной решетки передачи и приема и несколько рассеивателей, чтобы увидеть изменения в выборе усовершенствованного луча. Также можно сконфигурировать пары азимута и угла места для передачи и приема сигнала.
3GPP ТР 38.802. «Исследование аспектов физического уровня новой технологии радиодоступа». Техническая спецификация на сеть радиодоступа группы.
3GPP TS 38.215. "НР; измерение физического уровня. "Проект партнерства 3-го поколения; Техническая спецификация на сеть радиодоступа группы.
3GPP TS 38.214. "НР; Процедуры физического уровня для данных. "Проект партнерства третьего поколения; Техническая спецификация на сеть радиодоступа группы.
function validateCSIRSPorts(csirs) % validateCSIRSPorts validates the CSI-RS antenna ports, given the % CSI-RS configuration object CSIRS. numPorts = csirs.NumCSIRSPorts; if any(numPorts > 1) error('nr5g:PortsGreaterThan1','CSI-RS resources must be configured for single-port for RSRP measurements.'); end end function csirsTransmitted = getActiveCSIRSRes(carrier,csirs) % getActiveCSIRSRes returns a binary vector indicating the presence of % all CSI-RS resources in a specified slot, given the carrier % configuration object CARRIER and CSI-RS configuration object CSIRS. % Extract the following properties of carrier NSlotA = carrier.NSlot; % Absolute slot number NFrameA = carrier.NFrame; % Absolute frame number SlotsPerFrame = carrier.SlotsPerFrame; % Number of slots per frame % Calculate the appropriate frame number (0...1023) based on the % absolute slot number NFrameR = mod(NFrameA + fix(NSlotA/SlotsPerFrame),1024); % Relative slot number (0...slotsPerFrame-1) NSlotR = mod(NSlotA,SlotsPerFrame); % Loop over the number of CSI-RS resources numCSIRSRes = numel(csirs.CSIRSType); csirsTransmitted = zeros(1,numCSIRSRes); csirs_struct = validateConfig(csirs); for resIdx = 1:numCSIRSRes % Extract the CSI-RS slot periodicity and offset if isnumeric(csirs_struct.CSIRSPeriod{resIdx}) Tcsi_rs = csirs_struct.CSIRSPeriod{resIdx}(1); Toffset = csirs_struct.CSIRSPeriod{resIdx}(2); else if strcmpi(csirs_struct.CSIRSPeriod{resIdx},'on') Tcsi_rs = 1; else Tcsi_rs = 0; end Toffset = 0; end % Check for the presence of CSI-RS, based on slot periodicity and offset if (Tcsi_rs ~= 0) && (mod(SlotsPerFrame*NFrameR + NSlotR - Toffset, Tcsi_rs) == 0) csirsTransmitted(resIdx) = 1; end end end function freqRange = validateFc(fc) % validateFc validates the carrier frequency FC and returns the frequency % range as either 'FR1' or 'FR2'. if fc >= 410e6 && fc <= 7.125e9 freqRange = 'FR1'; elseif fc >= 24.25e9 && fc <= 52.6e9 freqRange = 'FR2'; else error('nr5g:invalidFreq',['Selected carrier frequency is outside '... 'FR1 (410 MHz to 7.125 GHz) and FR2 (24.25 GHz to 52.6 GHz).']); end end function beamDir = getInitialBeamDir(scatAng,azBeamWidth,elBeamWidth) % getInitialBeamDir returns the initial beam direction BEAMDIR, given the % angle of scatterer position with respect to transmit or receive antenna % array SCATANG, beamwidth of transmit or receive beam in azimuth plane % AZBEAMWIDTH, and beamwidth of transmit or receive beam in elevation % plane ELBEAMWIDTH. % Azimuth angle boundaries of all transmit/receive beams azSSBSweep = -180:azBeamWidth:180; % Elevation angle boundaries of all transmit/receive beams elSSBSweep = -90:elBeamWidth:90; % Get the azimuth angle of transmit/receive beam azIdx1 = find(azSSBSweep <= scatAng(1),1,'last'); azIdx2 = find(azSSBSweep >= scatAng(1),1,'first'); azAng = (azSSBSweep(azIdx1) + azSSBSweep(azIdx2))/2; % Get the elevation angle of transmit/receive beam elIdx1 = find(elSSBSweep <= scatAng(2),1,'last'); elIdx2 = find(elSSBSweep >= scatAng(2),1,'first'); elAng = (elSSBSweep(elIdx1) + elSSBSweep(elIdx2))/2; % Form the azimuth and elevation angle pair (in the form of [az;el]) % for transmit/receive beam beamDir = [azAng;elAng]; end