Этот пример демонстрирует нисходящую процедуру уточнения луча передающего конца с использованием опорного сигнала информации о состоянии канала (CSI-RS) от 5G Toolbox™. Пример показывает, как передать несколько ресурсов CSI-RS в различных направлениях в среде рассеяния и как выбрать оптимальный передающий луч на основе измерений мощности приемника опорного сигнала (RSRP).
В NR 5G частота области значений 2 (FR2) работает на частотах миллиметровой волны (mmWave) (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) NR 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 = 0
carrier = 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 = 25
csirs = 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
Создайте вектор Системного объекта для антенной решетки передачи.
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 на основе рассеяния с помощью системного объекта phased.ScatteringMIMOChannel
(Phased Array System Toolbox). Эта модель канала применяет временную задержку, усиление, Допплеровский сдвиг, изменение фазы, потерь при распространении в свободном пространстве и, опционально, другие атмосферные ослабления к входу.
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);
Создайте вектор управления Системный объект для антенной решетки приема.
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 (включая передающие и приемные антенны, положения рассеяния и их пути, а также все диаграммы направленности передающая и приемная антенна) с помощью функции helper 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 TR 38.802. «Исследование по аспектам физического слоя новых технологий радиодоступа». 3-ья Генерация проект партнерства; Группа технических спецификаций Радиосеть доступ.
3GPP TS 38.215. "NR; Физический слой измерений ". 3-ья Генерация Партнерский проект; Группа технических спецификаций Радиосеть доступ.
3GPP TS 38.214. "NR; Процедуры физического слоя данных ". 3-ья Генерация проект Партнерства; Группа технических спецификаций Радиосеть доступ.
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