%% NR Intercell Interference Modeling
% This example models the impact of intercell downlink (DL) interference caused by gNBs in a 5G New Radio (NR) network of multiple cells operating in the same frequency band and evaluates the network performance. Each cell has a gNB placed at the center of the cell that serves a set of user equipments (UEs). The network nodes in the example model the radio link control (RLC) layer, the medium access control (MAC) layer, and the physical (PHY) layer of the 5G NR stack.
%% Introduction
% The example considers the following operations within gNB and UEs that facilitate DL transmissions and receptions.
%
% The complete PDSCH packet is transmitted in the first symbol of its allocated symbol set. Receiver processes the packet in the symbol just after the last symbol in the allocated symbol set.
% This example models:
% Co-channel intercell interference.
% Slot-based DL scheduling of PDSCH resources. The time-domain granularity of the DL assignment is one slot.
% Configurable subcarrier spacing resulting in different slot durations.
% Noncontiguous allocation of frequency-domain resources in terms of resource block groups (RBGs).
% PDSCH demodulation reference signal (DM-RS).
% DL channel quality measurement by UEs based on the CSI-RS received from gNB. By default, the CSI-RS resource element is transmitted in each slot for each resource block (RB) in DL bandwidth, for all UEs. The same CSI-RS configuration is applicable to all the UEs in the cell.
% Free space path loss (FSPL), and additive white Gaussian noise (AWGN).
% Single input single output (SISO) antenna configuration.
% Single bandwidth part across the whole carrier.
% Control packets such as DL assignment, PDSCH feedback, and channel quality indicator (CQI) report, are assumed to be sent out of band, that is, without the need for resources for transmission and assured error-free reception.
%% Co-Channel Interference
% In cellular systems, each cell operates on a particular carrier frequency. The cells operating on the same carrier frequency are called co-channel cells. Co-channel cells can interfere in transmissions between them.
% Consider this sample network topology consisting of 3 cells. Cell-1 and cell-3 operate on the same frequency band. Cell-2 operates on a different frequency band and does not interfere with cell-1 or cell-3.
%
%% NR Protocol Stack
% A node (gNB or UE) consists of applications generating traffic, in addition to RLC, medium access control (MAC) and PHY. The helper classes hNRGNB.m and hNRUE.m create gNB and UE nodes respectively, containing RLC, MAC, and PHY layers. For more details on each layer, refer to the 'NR Protocol Stack' section in the NR Cell Performance Evaluation with Physical Layer Integration example.
%% Scenario Configuration
% For simulation, set the following key configuration parameters.
% Simulation time
% Number of cells
% Cell radius (all the UEs connected to a gNB are within this distance)
% Positions of gNBs
% Number of UEs in each cell
% Signal to interference and noise ratio (SINR) to CQI mapping table for 0.1 block error rate (BLER). The lookup table to map the received SINR to CQI index for 0.1 BLER. The lookup table corresponds to the CQI table as per 3GPP TS 38.214 Table 5.2.2.1-3. For more information about the process of generating this lookup table, refer to 5G NR CQI Reporting example.
% Transmit power of gNB
% DL carrier bandwidth in terms of number of resource blocks (RBs)
% DL carrier frequency
% Subcarrier spacing
% DL application traffic model

rng('default'); % Reset the random number generator
simParameters = []; % Clear the simParameters variable

simParameters.NumFramesSim = 30; % Simulation time in terms of number of 10 ms frames

% Number of cells in the simulation. Cells are assumed to have sequential cell identifiers (NCellIDs) from 0 to NumCells-1. If you change the number of cells, ensure that the number of rows in simParameters.GNBPosition is equal to NumCells.

simParameters.NumCells = 3; % Number of cells
simParameters.CellRadius = 500; % Radius of each cell (in meters)

% The N-by-2 matrix represents the position of gNBs in (X, Y)  coordinates, where 'N' is the number of cells in the simulation. The row number 'P' represents the X and Y coordinates of the gNB in the cell having cell ID 'P-1'. For example, the value [3000, 600] in the 2nd row represents the (X, Y) coordinates of the gNB in the cell having cell ID 1.

simParameters.GNBPosition = [1700 600;
    3000 600;
    2500 2000];

% Number of UEs in a cell. Each cell contains same number of UEs
simParameters.NumUEsCell = 4;

simParameters.GNBTxPower = 32; % Tx power for gNB (in dBm)

% Set the channel bandwidth to 10 MHz and subcarrier spacing (SCS) to 30 kHz
% as defined in 3GPP TS 38.104 Section 5.3.2.
simParameters.NumRBs = 24;
simParameters.SCS = 30; % kHz
simParameters.DLCarrierFreq = 2.635e9; % Hz
simParameters.DLBandwidth = 10e6; % Hz

% SINR to CQI mapping table for 0.1 BLER
simParameters.SINR90pc = [-5.46 -0.46 4.54 9.05 11.54 14.04 15.54 18.04 ...
    20.04 22.43 24.93 25.43 27.43 30.43 33.43];

% Maximum limit on the RBs allotted for PDSCH. Transmission limit is
% applicable for new PDSCH assignments and not for the retransmissions
simParameters.RBAllocationLimitDL = 15; % For PDSCH

%
% Logging and visualization configuration.

% Specify the ID of cell of interest. All the visualizations and metrics are shown for this cell
simParameters.CellOfInterest = 2; % Set a value from 0 to NumCells-1

% The parameters CQIVisualization and RBVisualization control the display
% of these visualizations: (i) CQI visualization of RBs (ii) RB assignment
% visualization. By default, the 'RBVisualization' plot is disabled. You
% can enable it by setting to 'true'
simParameters.CQIVisualization = true;
simParameters.RBVisualization = false;
% The output metrics plots are updated periodically NumMetricsSteps times within the
% simulation duration
simParameters.NumMetricsSteps = 20;
% MAT-files to write the logs into. They are used for post simulation analysis and visualization
simParameters.ParametersLogFile = 'simParameters'; % For logging the simulation parameters
simParameters.SimulationLogFile = 'simulationLogs'; % For logging the simulation logs

%
% Application traffic configuration.

% Set the periodic DL application traffic model for UEs. The following
% configuration applies for each cell
simParameters.DLPacketPeriodicityUEs = 10; % Periodicity (in ms) at which the DL packets are generated for UEs at gNB
simParameters.DLPacketSizesUEs = 2e4; % Size of the DL packets generated (in bytes) for UEs at gNB

% Validate the simulation configuration
hNRIntercellInterferenceValidateConfig(simParameters);

%
%% Derived Parameters
% Based on the primary configuration parameters, compute the derived parameters. Additionally, set some example specific constants.

simParameters.DuplexMode = 0; % FDD
simParameters.ULBandwidth = 10e6; % Hz
simParameters.ULCarrierFreq = 2.515e9; % Hz
simParameters.NumUEs = simParameters.NumUEsCell; % Number of UEs in a cell
simParameters.NCellIDList = 0:simParameters.NumCells-1; % List of physical cell IDs
% To store waveforms at the receiver, set the value to twice the number of transmitters
simParameters.UERxBufferSize = 2 * simParameters.NumCells; % Reception buffer size

% CSI-RS resource configuration. All UEs are assumed to measure channel quality on same CSI-RS resource
simParameters.CSIRSRowNumber = 2; % Possible row numbers for single transmit antenna case are 1 and 2
simParameters.SubbandSize = 8; % Size of sub-band for CQI reporting in terms of number of RBs

% Set the BSRPeriodicity to 'inf' as there is no UL traffic
simParameters.BSRPeriodicity = inf; % In ms

% Slot duration for the selected SCS and number of slots in a 10 ms frame
slotDuration = 1/(simParameters.SCS/15); % In ms
numSlotsFrame = 10/slotDuration; % Number of slots in a 10 ms frame
numSlotsSim = simParameters.NumFramesSim * numSlotsFrame; % Number of slots in the simulation

% Interval at which metrics visualization updates in terms of number of
% slots. As one slot is the finest time-granularity of the simulation, make
% sure that MetricsStepSize is an integer
simParameters.MetricsStepSize = ceil(numSlotsSim / simParameters.NumMetricsSteps);
if mod(numSlotsSim, simParameters.NumMetricsSteps) ~= 0
    % Update the NumMetricsSteps parameter if NumSlotsSim is not
    % completely divisible by it
    simParameters.NumMetricsSteps = floor(numSlotsSim / simParameters.MetricsStepSize);
end

% DL packet periodicity for UEs in terms of number of slots
appPeriodicityUEsSlotsDL = simParameters.DLPacketPeriodicityUEs / slotDuration;

simParameters.NumLogicalChannels = 1; % Only 1 logical channel is assumed in each UE in this example

% Logical channel configuration applies for all the nodes (UEs and gNBs) in the simulation
% Mapping between logical channel and logical channel group ID
simParameters.LCHConfig.LCGID = 1;
% Priority of each logical channel
simParameters.LCHConfig.Priority = 1;
% Prioritized bitrate (PBR) of each logical channel (in kilo bytes per second)
simParameters.LCHConfig.PBR = 8;
% Bucket size duration (BSD) of each logical channel (in ms). However, the priority,
% PBR and BSD for logical channel is not relevant in this example as single logical
% channel is assumed
simParameters.LCHConfig.BSD = 10;
% Logical channel ID (logical channel ID of data radio bearers starts from 4)
simParameters.LCHConfig.LCID = 4;

% RLC entity direction. Value 0 represents DL only, 1
% represents UL only and 2 represents both UL and DL
% directions. Setting entity direction to have both UL and DL
simParameters.RLCConfig.EntityDir = 0;

% Maximum RLC service data unit (SDU) length (in bytes) as per 3GPP TS 38.323
simParameters.maxRLCSDULength = 9000;

% Generate the positions of UEs in each cell
simParameters.UEPosition = generateUEPositions(simParameters);

% Total number of UEs in the simulation
simParameters.MaxReceivers = simParameters.NumCells * simParameters.NumUEsCell;

%
%% Multicell Setup
% Set up the cells with an individual cell consisting of one gNB and multiple UEs. For each cell, create the gNB and UE objects, initialize the channel quality information for UEs, and set up the logical channel at gNB and UEs. The helper classes hNRGNB.m and hNRUE.m create gNB and UE nodes respectively, containing the RLC, MAC, and PHY layers.

gNB = cell(simParameters.NumCells, 1);
UEs = cell(simParameters.NumCells, simParameters.NumUEsCell);
% Create DL packet distribution object
dlPacketDistributionObj = hNRPacketDistribution(simParameters, 0); % 0 for DL
% Create UL packet distribution object
ulPacketDistributionObj = hNRPacketDistribution(simParameters, 1); % 1 for UL

for cellIdx = 1:simParameters.NumCells % For each cell
    
    simParameters.NCellID = simParameters.NCellIDList(cellIdx); % Cell ID
    simParameters.Position = [simParameters.GNBPosition(cellIdx, :) 0]; % gNB position in (x,y,z) coordinates
    gNB{cellIdx} = hNRGNB(simParameters); % Create gNB node
    scheduler = hNRSchedulerProportionalFair(simParameters); % Create proportional fair scheduler
    addScheduler(gNB{cellIdx}, scheduler); % Add scheduler to gNB
    
    gNB{cellIdx}.PhyEntity = hNRGNBPhy(simParameters); % Create the PHY layer instance
    configurePhy(gNB{cellIdx}, simParameters); % Configure the PHY layer
    setPhyInterface(gNB{cellIdx}); % Set up the interface to PHY layer
    
    % For each cell, create the set of UE nodes and place them randomly within the cell radius
    for ueIdx = 1:simParameters.NumUEsCell
        simParameters.Position = [simParameters.UEPosition{cellIdx}(ueIdx, :) 0]; % Position of UE in (x,y,z) coordinates
        UEs{cellIdx, ueIdx} = hNRUE(simParameters, ueIdx);
        UEs{cellIdx, ueIdx}.PhyEntity = hNRUEPhy(simParameters, ueIdx); % Create the PHY layer instance
        configurePhy(UEs{cellIdx, ueIdx}, simParameters); % Configure the PHY layer
        setPhyInterface(UEs{cellIdx, ueIdx}); % Set up the interface to PHY
        
        % Create RLC channel configuration structure
        rlcChannelConfigStruct.EntityType = simParameters.RLCConfig.EntityDir;
        rlcChannelConfigStruct.LogicalChannelID = simParameters.LCHConfig.LCID;
        rlcChannelConfigStruct.LCGID = simParameters.LCHConfig.LCGID;
        rlcChannelConfigStruct.Priority = simParameters.LCHConfig.Priority;
        rlcChannelConfigStruct.PBR = simParameters.LCHConfig.PBR;
        rlcChannelConfigStruct.BSD = simParameters.LCHConfig.BSD;
        % Setup logical channel at gNB for the UE
        configureLogicalChannel(gNB{cellIdx}, ueIdx, rlcChannelConfigStruct);
        % Setup logical channel at UE
        configureLogicalChannel(UEs{cellIdx, ueIdx}, ueIdx, rlcChannelConfigStruct);
        
        % Add data traffic pattern generators to gNB node
        packetSize = simParameters.DLPacketSizesUEs;
        % Calculate the data rate (in kbps) of On-Off traffic pattern using
        % packet size (in bytes) and packet interval (in ms)
        dataRate = ceil(1000/simParameters.DLPacketPeriodicityUEs) * packetSize * 8e-3;
        % Limit the size of the generated application packet to the maximum
        % RLC SDU size. The maximum supported RLC SDU size is 9000 bytes
        if packetSize > simParameters.maxRLCSDULength
            packetSize = simParameters.maxRLCSDULength;
        end
        % Create an object for On-Off network traffic pattern for the specified
        % UE and add it to the gNB. This object generates the downlink data
        % traffic on the gNB for the UE
        app = networkTrafficOnOff('PacketSize', packetSize, 'GeneratePacket', true, ...
            'OnTime', simParameters.NumFramesSim/100, 'OffTime', 0, 'DataRate', dataRate);
        gNB{cellIdx}.addApplication(ueIdx, simParameters.LCHConfig.LCID, app);
    end
    
    % Setup the UL and DL packet distribution mechanism
    hNRSetUpPacketDistribution(simParameters, gNB{cellIdx}, UEs(cellIdx, :), dlPacketDistributionObj, ulPacketDistributionObj);
end

%
%% Processing Loop
% Simulation is run slot by slot. For each cell, in each slot, these operations are executed:
% Run the MAC and PHY layers of gNB
% Run the MAC and PHY layers of UEs
% Layer-specific logging and visualization
% Advance the timer for the nodes. Every 1 ms it also sends trigger to application and RLC layers. Application layer and RLC layer execute their scheduled operations based on 1 ms timer trigger.

% Display network topology
plotNetwork(simParameters);
% To store these UE metrics for each slot: throughput bytes
% transmitted, goodput bytes transmitted, and pending buffer amount bytes.
% The number of goodput bytes is calculated by excluding the
% retransmissions from the total transmissions
UESlotMetricsDL = zeros(simParameters.NumUEsCell, 3);

% To store last received new data indicator (NDI) values for DL HARQ process
HARQProcessStatusDL = zeros(simParameters.NumUEsCell, 16); % Max 16 HARQ process

% To store current DL CQI values on the RBs for different UEs
downlinkChannelQuality = zeros(simParameters.NumUEsCell, simParameters.NumRBs);

% Store the DL BLER for each UE
dlBLERStats = zeros(simParameters.NumUEsCell, 2);

simSchedulingLogger = cell(simParameters.NumCells, 1);
simPhyLogger = cell(simParameters.NumCells, 1);
for cellIdx = 1:simParameters.NumCells
    % Create an object for MAC DL scheduling information visualization and logging
    simParameters.NCellID = simParameters.NCellIDList(cellIdx);
    simSchedulingLogger{cellIdx} = hNRSchedulingLogger(simParameters, 0); % 0 for DL
    % Create an object for BLER visualization and PHY layer metrics logging
    simPhyLogger{cellIdx} = hNRPhyLogger(simParameters, 0); % 0 for DL
end

% Store the index of cell ID of interest
cellOfInterestIdx = find(simParameters.CellOfInterest == simParameters.NCellIDList);

symbolNum = 0;
% Run processing loop
for slotNum = 1:numSlotsSim
    
    % All the cells operating on same SCS hence slot durations are same
    for cellIdx = 1:simParameters.NumCells % For each cell
        
        % Run MAC and PHY layers of gNB
        run(gNB{cellIdx}.MACEntity);
        run(gNB{cellIdx}.PhyEntity);
        
        % Run MAC and PHY layers of UEs
        for ueIdx = 1:simParameters.NumUEsCell
            % Read the last received NDI flags for DL HARQ processes for
            % logging (Reading it before it gets overwritten by run function of MAC)
            HARQProcessStatusDL(ueIdx, :) = getLastNDIFlagHarq(UEs{cellIdx, ueIdx}.MACEntity, 0); % 0 for DL
            run(UEs{cellIdx, ueIdx}.MACEntity);
            run(UEs{cellIdx, ueIdx}.PhyEntity);
        end
        
        % MAC logging
        % Read DL assignments done by gNB MAC scheduler at current time.
        % Resource assignments returned by a scheduler is empty, if
        % scheduler was not scheduled to run at the current time or no
        % resources got scheduled
        [~, resourceAssignmentsDL] = getCurrentSchedulingAssignments(gNB{cellIdx}.MACEntity);
        % Read throughput and goodput bytes sent for each UE
        [UESlotMetricsDL(:, 1), UESlotMetricsDL(:, 2)] = getTTIBytes(gNB{cellIdx});
        UESlotMetricsDL(:, 3) = getBufferStatus(gNB{cellIdx}); % Read pending buffer (in bytes) on gNB, for all the UEs
        
        for ueIdx = 1:simParameters.NumUEsCell
            % Read the DL channel quality at gNB for each of the UEs for logging
            downlinkChannelQuality(ueIdx,:) = getChannelQuality(gNB{cellIdx}, 0, ueIdx); % 0 for DL
        end
        
        % Update DL scheduling logs based on the current slot run of UEs
        % and gNB. Logs are updated in each slot, RB grid visualizations
        % are updated every frame, and metrics plots are updated every
        % metricsStepSize slots
        logScheduling(simSchedulingLogger{cellIdx}, symbolNum + 1, resourceAssignmentsDL, UESlotMetricsDL, downlinkChannelQuality, HARQProcessStatusDL, 0); % 0 for DL
        
        % PHY logging
        for ueIdx = 1:simParameters.NumUEsCell
            dlBLERStats(ueIdx, :) = getDLBLER(UEs{cellIdx, ueIdx}.PhyEntity);
        end
        % Log the DL BLER statistics
        logBLERStats(simPhyLogger{cellIdx}, dlBLERStats, []);
    end
    
    for cellIdx = 1:simParameters.NumCells
        % Advance timer ticks for gNB and UEs by the number of symbols per slot
        advanceTimer(gNB{cellIdx}, 14);
        for ueIdx = 1:simParameters.NumUEsCell
            advanceTimer(UEs{cellIdx, ueIdx}, 14);
        end
    end
    
    % RB assignment visualization (if enabled)
    if simParameters.RBVisualization
        if mod(slotNum, numSlotsFrame) == 0
            plotRBGrids(simSchedulingLogger{cellOfInterestIdx});
        end
    end
    
    % CQI grid visualization (if enabled)
    if simParameters.CQIVisualization
        if mod(slotNum, numSlotsFrame) == 0
            plotCQIRBGrids(simSchedulingLogger{cellOfInterestIdx});
        end
    end
    
    % Plot scheduler metrics and PHY metrics visualization at slot
    % boundary, if the update periodicity is reached
    if mod(slotNum, simParameters.MetricsStepSize) == 0
        plotMetrics(simSchedulingLogger{cellOfInterestIdx});
        plotMetrics(simPhyLogger{cellOfInterestIdx});
    end
    
    % Symbol number in the simulation
    symbolNum = symbolNum + 14;
end

%
%% Simulation Visualization
% The five types of run-time visualization shown are:
% Display of Network Topology: The figure shows the configured cell topology. For each cell, it shows the position of the gNB and the connected UEs.
% Display of CQI values for UEs over the PDSCH bandwidth: For details, see the 'Channel Quality Visualization' figure description in NR PUSCH FDD Scheduling example.
% Display of resource grid assignment to UEs: The 2D time-frequency grid shows the resource allocation to the UEs. You can enable this visualization in the Logging and Visualization Configuration section. For details, see the 'Resource Grid Allocation' figure description in NR PUSCH FDD Scheduling example.
% Display of DL scheduling metrics plots: For details, see 'Downlink Scheduler Performance Metrics ' figure description in NR FDD Scheduling Performance Evaluation example.
% Display of DL Block Error Rates: For details, see 'Block Error Rate (BLER) Visualization' figure description in NR Cell Performance Evaluation with Physical Layer Integration example.
%% Simulation Logs
% The parameters used for simulation and the simulation logs are saved in MAT-files for post simulation analysis and visualization. The simulation parameters are saved in a MAT-file with the file name as the value of configuration parameter simParameters.ParametersLogFile. The per time step logs, scheduling assignment logs, and BLER logs are captured for each cell in the simulation and saved in the MAT-file simParameters.SimulationLogFile. After the simulation, open the file to load NCellID, DLTimeStepLogs, SchedulingAssignmentLogs, and BLERLogs in the workspace.
% NCellID: This stores the cell ID and represents cell to which the simulation logs belong.
% DL Time step logs: Stores the per slot logs of the simulation with each slot as one row in the simulation. For details of log format, see the 'Simulation Logs' section of NR PUSCH FDD Scheduling.
% Scheduling Assignment logs: Information of all the scheduling assignments and related information is logged in this file. For details of log format, see the 'Simulation Logs' section in the NR FDD Scheduling Performance Evaluation example.
% Block Error Rate logs: Information of all the scheduling assignments and related information is logged in this file. For details of log format, see the 'Simulation Logs' section in NR Cell Performance Evaluation with Physical Layer Integration example.
% You can run the script NRPostSimVisualization to get a post-simulation visualization of logs. For more details about the options to run this script, refer to the NR FDD Scheduling Performance Evaluation example.

% Get the logs
logInfo = struct('NCellID',[], 'DLTimeStepLogs',[], 'SchedulingAssignmentLogs',[] ,'BLERLogs',[]);
simulationLogs = cell(simParameters.NumCells, 1);
for cellIdx = 1:simParameters.NumCells
    logInfo.NCellID = simParameters.NCellIDList(cellIdx);
    [logInfo.DLTimeStepLogs, ~] = getSchedulingLogs(simSchedulingLogger{cellIdx});
    logInfo.SchedulingAssignmentLogs = getGrantLogs(simSchedulingLogger{cellIdx}); % Scheduling assignments log
    logInfo.BLERLogs = getBLERLogs(simPhyLogger{cellIdx}); % Block error rate logs
    simulationLogs{cellIdx, 1} = logInfo;
end
save(simParameters.ParametersLogFile, 'simParameters'); % Save simulation parameters in a MAT-file
save(simParameters.SimulationLogFile, 'simulationLogs'); % Save simulation logs in a MAT-file

%
%% Further Exploration
% You can use this example to further explore these options.
% Model the uplink interference between the nodes by configuring uplink-related configuration. For details, see the NR Cell Performance Evaluation with Physical Layer Integration example.
% Model the Aggressor-Victim scenarios: The aggressor is the source of interference and the victim suffers due to the interference. Consider the DL scenario in the following figure. The macro UE is far away from the macro base station (BS) and near to the small cell. The small cell BS interferes with macro BS transmission for macro UE in DL. Due to that macro UE suffers from interference by the small cell BS. The small cell BS is called the aggressor and macro UE is called the victim.
%
% To model multiple clusters, where each cluster consists of cells operating on different frequencies, and analyze the impact of interference on the cell edge users.
% Based on the described simulation parameters, the example evaluates the performance of the system measured in terms of various metrics. Different visualizations show the run time performance of the system. A more thorough post simulation analysis by using the saved logs gives a detailed picture of the operations happening on a per slot basis.
%% Appendix
% The example uses these helper functions and classes:
% hNRNode.m: NR node base class for both gNB and UE
% hNRGNB.m: gNB node functionality
% hNRUE.m: UE node functionality
% hNRRLCEntity.m: Base class for RLC UM and AM entities
% hNRUMEntity.m: RLC UM functionality
% hNRAMEntity.m: RLC AM functionality
% hNRRLCDataPDUInfo.m: Creates RLC PDU information object
% hNRRLCBufferStatus.m: Generates RLC buffer status information object
% hNRRLCDataReassembly.m: Create an RLC SDU reassembly information object
% hNRMAC.m: NR MAC base class functionality
% hNRGNBMAC.m: gNB MAC functionality
% hNRUEMAC.m: UE MAC functionality
% hNRScheduler.m: Core MAC scheduler functionality
% hNRSchedulerBestCQI.m: Implements best CQI scheduling strategy
% hNRSchedulerProportionalFair.m: Implements proportional fair scheduling strategy
% hNRSchedulerRoundRobin.m: Implements round robin scheduling strategy
% hNRMACBSR.m: Generates buffer status report
% hNRMACBSRParser.m: Parses buffer status report
% hNRMACSubPDU.m: Generates MAC subPDU
% hNRMACPaddingSubPDU.m: Generates MAC subPDU with padding
% hNRMACMultiplex.m: Generates MAC PDU
% hNRMACPDUParser.m: Parses MAC PDU
% hNewHARQProcesses.m: Creates new HARQ process
% hUpdateHARQProcess.m: Updates HARQ process
% hNRPhyInterface.m: NR PHY base class functionality
% hNRGNBPhy.m: gNB PHY functionality
% hNRUEPhy.m: UE PHY functionality
% hNRPUSCHInfo.m: PUSCH information structure passed by MAC to PHY layer
% hNRPDSCHInfo.m: PDSCH information structure passed by MAC to PHY layer
% hNRRxIndicationInfo.m: Information structure passed by PHY layer to MAC along with MAC PDU
% hNRUplinkGrantFormat.m: UL grant format
% hNRDownlinkGrantFormat.m: DL grant format
% hNRPacketDistribution.m: Creates packet distribution object
% hNRPhyRxBuffer.m: Creates PHY signal reception buffer object
% hSkipWeakTimingOffset.m: Skip timing offset estimates with weak correlation
% hNRRLCLogger.m: Implements RLC statistics logging and visualization functionality
% hNRSchedulingLogger.m: Implements scheduling information logging and visualization functionality
% hNRPhyLogger.m: Implements uplink and downlink block error rate logging and visualization functionality
% hNRIntercellInterferenceValidateConfig.m: Validates simulation configuration
% hNRSetUpPacketDistribution.m: Set up packet distribution functionality
% hNRPacketWriter.m: Captures MAC packets
% hNRPacketInfo.m: Metadata format for capturing MAC packets
% NRPostSimVisualization.m: Post simulation visualization script
%% Local functions

function plotNetwork(simParameters)
% Create the figure
figure('Name', 'Network Topology Visualization', 'units', 'normalized', 'outerposition', [0 0 1 1], 'Visible', "on");
title('Network Topology Visualization');
hold on;

for cellIdx = 1:simParameters.NumCells
    
    % Plot the circle
    th = 0:pi/60:2*pi;
    xunit = simParameters.CellRadius * cos(th) + simParameters.GNBPosition(cellIdx, 1);
    yunit = simParameters.CellRadius * sin(th) + simParameters.GNBPosition(cellIdx, 2);
    if simParameters.CellOfInterest == simParameters.NCellIDList(cellIdx)
        h1 =  plot(xunit, yunit, 'Color', 'green'); % Cell of interest
    else
        h2 =  plot(xunit, yunit, 'Color', 'red');
    end
    xlabel('X-Position (meters)')
    ylabel('Y-Position (meters)')
    % Add tool tip data for gNBs
    s1 = scatter(simParameters.GNBPosition(cellIdx, 1), simParameters.GNBPosition(cellIdx, 2), '^','MarkerEdgeColor', 'magenta');
    cellIdRow = dataTipTextRow('Cell - ',{num2str(simParameters.NCellIDList(cellIdx))});
    s1.DataTipTemplate.DataTipRows(1) = cellIdRow;
    posRow = dataTipTextRow('Position[X, Y]: ',{['[' num2str(simParameters.GNBPosition(cellIdx, :)) ']']});
    s1.DataTipTemplate.DataTipRows(2) = posRow;
    
    % Add tool tip data for UEs
    uePosition = simParameters.UEPosition{cellIdx};
    for ueIdx = 1:size(uePosition, 1)
        s2 = scatter(uePosition(ueIdx, 1), uePosition(ueIdx, 2), '.','MarkerEdgeColor', 'blue');
        ueIdRow = dataTipTextRow('UE - ',{num2str(ueIdx)});
        s2.DataTipTemplate.DataTipRows(1) = ueIdRow;
        posRow = dataTipTextRow('Position[X, Y]: ',{['[' num2str(uePosition(ueIdx, :)) ']']});
        s2.DataTipTemplate.DataTipRows(2) = posRow;
    end
end
% Create the legend
if simParameters.NumCells > 1
    legend([h1 h2 s1 s2], 'Cell of interest', 'Interfering cells', 'gNodeB', 'UE', 'Location', 'northeastoutside')
else
    legend([h1 s1 s2], 'Cell of interest', 'gNodeB', 'UE', 'Location', 'northeastoutside')
end
axis([0 4000 0 3000]); % Set axis limits
hold off;
daspect([1000,1000,1]); % Set data aspect ratio
end

function uePositions = generateUEPositions(simParameters)
% Return the position of UEs in each cell

uePositions = cell(simParameters.NumCells, 1);
for cellIdx=1:simParameters.NumCells
    gnbXCo = simParameters.GNBPosition(cellIdx, 1); % gNB X-coordinate
    gnbYCo = simParameters.GNBPosition(cellIdx, 2); % gNB Y-coordinate
    theta = rand(simParameters.NumUEsCell, 1)*(2*pi);
    % Expression to calculate position of UEs with in the cell. By default,
    % it will place the UEs randomly with in the cell
    r = sqrt(rand(simParameters.NumUEsCell, 1))*simParameters.CellRadius;
    x = round(gnbXCo + r.*cos(theta));
    y = round(gnbYCo + r.*sin(theta));
    uePositions{cellIdx} = [x y];
end
end

% Copyright 2020 The MathWorks, Inc.