Этот пример демонстрирует нисходящую процедуру улучшения луча конца передачи с помощью опорного сигнала информации о состоянии канала (CSI-RS) от 5G Toolbox™. Пример показывает, как передать несколько ресурсов CSI-RS в различных направлениях в рассеивающейся среде и как выбрать оптимальный луч передачи на основе измерений мощности приемника опорного сигнала (RSRP).
В 5G NR частотный диапазон 2 (FR2) работает с волной миллиметра (mmWave) частотами (от 24,25 ГГц до 52,6 ГГц). Когда частота увеличивается, переданный сигнал подвержен высокой потере пути и потере проникновения, которая влияет на бюджет ссылки. Чтобы улучшить усиление и направленность передачи и прием сигналов на более высоких частотах, beamforming важен. Управление лучом является набором Слоя 1 (физический уровень) и Слой 2 (среднее управление доступом) процедуры, чтобы установить и сохранить оптимальную пару луча (луч передачи, и соответствие получают луч) для хорошей возможности соединения. Раздел TR 38.802 6.1.6.1 [1] задает управление лучом как три процедуры:
Процедура 1 (p-1): Эта процедура фокусируется на начальном приобретении на основе блоков сигнала синхронизации (SSB). Во время начального приобретения развертка луча происходит и в передаче, и получите концы, чтобы выбрать лучшую пару луча на основе измерений RSRP. В общем случае выбранные лучи широки и не могут быть оптимальной парой луча для передачи данных и приема. Для получения дополнительной информации об этой процедуре смотрите, что Луч NR SSB Развертывается.
Процедура 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 NR. Этот рисунок изображает процедуру улучшения луча конца передачи, считая четыре ресурса 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 = 60;
carrier.NSlot = 0;
carrier.NFrame = 0
carrier = nrCarrierConfig with properties: NCellID: 1 SubcarrierSpacing: 60 CyclicPrefix: 'normal' NSizeGrid: 133 NStartGrid: 0 NSlot: 0 NFrame: 0 Read-only properties: SymbolsPerSlot: 14 SlotsPerSubframe: 4 SlotsPerFrame: 40
Создайте объект настройки CSI-RS представление набора ресурсов NZP-CSI-RS с numNZPRes
количество ресурсов NZP-CSI-RS. Для измерений Слоя 1 RSRP сконфигурируйте все ресурсы 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: {1x12 cell} SubcarrierLocations: {1x12 cell} 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 и применяет цифровой beamforming ко всем активным единицам. Цифровой beamforming, как рассматривается, предлагает частоте выборочный beamforming в том же символе 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
.
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);
% Append zeros to the transmit waveform to account for channel delay tbfWaveform = [tbfWaveform; zeros(maxChDelay,nTx)]; % Pass the signal through the channel fadWave = chan(tbfWaveform);
% Configure SNR SNRdB = 20; % in dB SNR = 10^(SNRdB/20); % Linear value % Calculate the standard deviation for AWGN N0 = 1/(sqrt(2.0*nRx*double(ofdmInfo.Nfft))*SNR); % Generate AWGN noise = N0*complex(randn(size(fadWave)),randn(size(fadWave))); % Apply AWGN to the waveform after accounting for free space path loss rxWaveform = fadWave*(10^(spLoss/20)) + 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);
Чтобы выполнить цифровой beamforming в стороне приемника, примените держащиеся веса к rxGrid
, учитывая, что нет никакого другого сигнала, существующего в rxGrid
(один сценарий UE). Объединитесь сигналы от всех получают антенные элементы в случае FR2, как задано в Разделе TS 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
Постройте рассеивающийся сценарий 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): 40.1313 31.0269 27.0399 42.9433 34.8756 29.2513 37.7758 31.3422 22.2327 15.931 11.258 -1.92416
Идентифицируйте максимальное значение 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. "Исследование Новых Радио-технологических аспектов физического уровня доступа". Проект Партнерства третьего поколения; Сеть радиодоступа Technical Specification Group.
3GPP TS 38.215. "NR; измерения Физического уровня". Проект Партнерства третьего поколения; Сеть радиодоступа Technical Specification Group.
3GPP TS 38.214. "NR; процедуры Физического уровня для данных". Проект Партнерства третьего поколения; Сеть радиодоступа Technical Specification Group.
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