From 8d1b816db91621cc97ceac3e8429ebffe924e075 Mon Sep 17 00:00:00 2001 From: Chester Koh Date: Wed, 27 Sep 2023 20:53:38 +0800 Subject: [PATCH 01/11] add output parameter to suppress printing to main file, and add option to manually specify simID --- MatFilesInit/initiateOutParameters.m | 47 +++++++++++++++++----------- WiLabV2Xsim.m | 4 ++- 2 files changed, 32 insertions(+), 19 deletions(-) diff --git a/MatFilesInit/initiateOutParameters.m b/MatFilesInit/initiateOutParameters.m index 7d53c0c..3a7c0ef 100644 --- a/MatFilesInit/initiateOutParameters.m +++ b/MatFilesInit/initiateOutParameters.m @@ -20,26 +20,36 @@ outParams.outputFolder = s.path; fprintf('Full path of the output folder = %s\n',outParams.outputFolder); -% Name of the file that summarizes the inputs and outputs of the simulation -% Each simulation adds a line in append -% The file is a xls file -% The name of the file cannot be changed -outParams.outMainFile = 'MainOut.xls'; -fprintf('Main output file = %s/%s\n',outParams.outputFolder,outParams.outMainFile); - -% Simulation ID -mainFileName = sprintf('%s/%s',outParams.outputFolder,outParams.outMainFile); -fid = fopen(mainFileName); -if fid==-1 - simID = 0; + +% [printToXLSMainFile] +[outParams,varargin]= addNewParam(outParams,'printToXLSMainFile', true, 'Write some result info into a main xls file','bool',fileCfg,varargin{1}); +if outParams.printToXLSMainFile + % Name of the file that summarizes the inputs and outputs of the simulation + % Each simulation adds a line in append + % The file is a xls file + % The name of the file cannot be changed + [outParams,varargin]= addNewParam(outParams,'outMainFile','MainOut.xls','Output Main File','string',fileCfg,varargin{1}); + fprintf('Main output file = %s/%s\n',outParams.outputFolder,outParams.outMainFile); + % Simulation ID + [outParams,varargin]= addNewParam(outParams,'simID',0,'Sim ID - leave 0 for auto increment from main file','integer',fileCfg,varargin{1}); + if outParams.simID == 0 + mainFileName = sprintf('%s/%s',outParams.outputFolder,outParams.outMainFile); + fid = fopen(mainFileName); + if fid==-1 + simID = 0; + else + % use recommended function textscan + C = textscan(fid,'%s %*[^\n]'); + simID = str2double(C{1}{end}); + fclose(fid); + end + outParams.simID = simID+1; + end + fprintf('Simulation ID = %.0f\n',outParams.simID); else - % use recommended function textscan - C = textscan(fid,'%s %*[^\n]'); - simID = str2double(C{1}{end}); - fclose(fid); + % Simulation ID + [outParams,varargin]= addNewParam(outParams,'simID',1,'Sim ID - default 1 if printToXLSMainFile','integer',fileCfg,varargin{1}); end -outParams.simID = simID+1; -fprintf('Simulation ID = %.0f\n',outParams.simID); % [printNeighbors] % Boolean to activate the print to file of the number of neighbors @@ -164,4 +174,5 @@ [outParams,varargin]= addNewParam(outParams,'message', 'None', 'Message during simulation','string',fileCfg,varargin{1}); fprintf('\n'); % + %%%%%%%%% diff --git a/WiLabV2Xsim.m b/WiLabV2Xsim.m index 737cd65..63c8baf 100644 --- a/WiLabV2Xsim.m +++ b/WiLabV2Xsim.m @@ -376,7 +376,9 @@ function WiLabV2Xsim(varargin) end % Print to XLS file -outputToFiles(stationManagement,simParams,appParams,phyParams,sinrManagement,outParams,outputValues); +if outParams.printToXLSMainFile + outputToFiles(stationManagement,simParams,appParams,phyParams,sinrManagement,outParams,outputValues); +end %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% %% Print To Video From 09f55f073a6320ad0d4dc75ddcb49b571f72e636 Mon Sep 17 00:00:00 2001 From: Chester Koh Date: Thu, 28 Sep 2023 15:29:16 +0800 Subject: [PATCH 02/11] make the main function return output and used params --- WiLabV2Xsim.m | 9 ++++++++- 1 file changed, 8 insertions(+), 1 deletion(-) diff --git a/WiLabV2Xsim.m b/WiLabV2Xsim.m index 737cd65..2decced 100644 --- a/WiLabV2Xsim.m +++ b/WiLabV2Xsim.m @@ -1,4 +1,4 @@ -function WiLabV2Xsim(varargin) +function [outputValues, allParams] = WiLabV2Xsim(varargin) % The function WiLabV2Xsim() is the main function of the simulator % ============== @@ -77,6 +77,13 @@ function WiLabV2Xsim(varargin) % Update PHY structure with the ranges [phyParams] = deriveRanges(phyParams,simParams); +% Save all the params to return later +allParams = struct(); +allParams.simParams = simParams; +allParams.appParams = appParams; +allParams.phyParams = phyParams; +allParams.outParams = outParams; + % Simulator output inizialization outputValues = struct('computationTime',-1,... 'blockingRateCV2X',-1*ones(1,length(phyParams.Raw)),'blockingRate11p',-1*ones(1,length(phyParams.Raw)),'blockingRateTOT',-1*ones(1,length(phyParams.Raw)),... From c7bfb1b7a46e05062d33775000e44df233b83ae5 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E5=90=B4=E5=8D=93=E9=9C=8F=5FFelix?= Date: Mon, 2 Oct 2023 10:52:15 +0800 Subject: [PATCH 03/11] update for parallel task based on pr/24 1. When writing the "mainout" file, using a "marker file" to indicate that the "mainout" file is writing now. In case of multiple processes write the file simultaneously. 2. If the outputs of different simulations are in one folder, the auto-set simIDs could not support "parfor". We may need another effective way to fix this promble. --- MatFilesInit/initiateOutParameters.m | 21 +++++++++++++------- MatFilesOut/outputToFiles.m | 29 +++++++++++++++++++++++++--- README.md | 2 +- 3 files changed, 41 insertions(+), 11 deletions(-) diff --git a/MatFilesInit/initiateOutParameters.m b/MatFilesInit/initiateOutParameters.m index 3a7c0ef..3282b7e 100644 --- a/MatFilesInit/initiateOutParameters.m +++ b/MatFilesInit/initiateOutParameters.m @@ -30,20 +30,27 @@ % The name of the file cannot be changed [outParams,varargin]= addNewParam(outParams,'outMainFile','MainOut.xls','Output Main File','string',fileCfg,varargin{1}); fprintf('Main output file = %s/%s\n',outParams.outputFolder,outParams.outMainFile); - % Simulation ID + + % Two ways to use the "parfor" + % 1. Using different output folder. + % 2. At the same output folder, the simID should be set one by one + % before starting simulation. + % Note: with the 2nd method, if not set simID before the simulation, + % there might be some errors multiple processes have the same + % simID [outParams,varargin]= addNewParam(outParams,'simID',0,'Sim ID - leave 0 for auto increment from main file','integer',fileCfg,varargin{1}); - if outParams.simID == 0 - mainFileName = sprintf('%s/%s',outParams.outputFolder,outParams.outMainFile); - fid = fopen(mainFileName); - if fid==-1 - simID = 0; + if outParams.simID == 0 % fixme: auto increment does not support parallel tasks. The IDs would be a mess + mainFileName = fullfile(outParams.outputFolder, outParams.outMainFile); + if exist(mainFileName, "file") ~= 2 + outParams.simID = 1; else + fid = fopen(mainFileName); % use recommended function textscan C = textscan(fid,'%s %*[^\n]'); simID = str2double(C{1}{end}); + outParams.simID = simID+1; fclose(fid); end - outParams.simID = simID+1; end fprintf('Simulation ID = %.0f\n',outParams.simID); else diff --git a/MatFilesOut/outputToFiles.m b/MatFilesOut/outputToFiles.m index 199f83a..c407021 100644 --- a/MatFilesOut/outputToFiles.m +++ b/MatFilesOut/outputToFiles.m @@ -6,8 +6,26 @@ function outputToFiles(stationManagement,simParams,appParams,phyParams,sinrManag mkdir(outputFolder) end -fileNameMain = sprintf('%s/%s',outputFolder,outParams.outMainFile); -fileMainID = fopen(fileNameMain,'at'); +% Due to parfor function, it is possible that multiple tasks try to open +% this file at the same time. If one of them can not open it, try within 120 s +fileNameMain = fullfile(outputFolder, outParams.outMainFile); +fileWriteMarker = fullfile(outputFolder, "MainFileIsWriting.txt"); +startLogTime = toc; +while true + currentTime = toc; + if currentTime - startLogTime < 120 + if exist(fileWriteMarker, "file") == 2 % check if file is being written now + openFileDelay = rand(); + pause(openFileDelay); + else + IsWritingFile = fopen(fileWriteMarker,"w"); + fileMainID = fopen(fileNameMain,'at'); + break; + end + else + error("Could not open file: %s", fileNameMain); + end +end if fseek(fileMainID, 1, 'bof') == -1 %1 Main settings @@ -686,4 +704,9 @@ function outputToFiles(stationManagement,simParams,appParams,phyParams,sinrManag fprintf(fileMainID,','); end end -fprintf(fileMainID,'\n'); \ No newline at end of file +fprintf(fileMainID,'\n'); + +% close file and delete fileWriteMarker +fclose(fileMainID); +fclose(IsWritingFile); +delete(fileWriteMarker); diff --git a/README.md b/README.md index 4acbf9d..e3ec696 100644 --- a/README.md +++ b/README.md @@ -33,7 +33,7 @@ Alessandro Bazzi (alessandro.bazzi@unibo.it) Vittorio Todisco (vittorio.todisco@unibo.it, vittorio.todisco@ieiit.cnr.it) -Wu Zhuofei, also called Felix (wu.zhuofei@unibo.it) +Wu Zhuofei, also called Felix (wzfhrb.cn@gmail.com) ***** ***** From d7ad5bad7449d7c03274ed62481f1e2e689087df Mon Sep 17 00:00:00 2001 From: Chester Koh Date: Fri, 13 Oct 2023 18:10:14 +0800 Subject: [PATCH 04/11] add support for counting hidden node events, and add unit tests --- MainFilesCV2X/updateKPICV2X.m | 8 ++- MatFilesInit/initiateOutParameters.m | 5 +- MatFilesOut/countHiddenNodeEvents.m | 30 +++++++++ MatFilesOut/printHiddenNodeEvents.m | 17 +++++ .../+unit/+out/test_countHiddenNodeEvents.m | 66 +++++++++++++++++++ WiLabV2Xsim.m | 10 ++- 6 files changed, 132 insertions(+), 4 deletions(-) create mode 100644 MatFilesOut/countHiddenNodeEvents.m create mode 100644 MatFilesOut/printHiddenNodeEvents.m create mode 100644 Tests/+v2xsim_tests/+unit/+out/test_countHiddenNodeEvents.m diff --git a/MainFilesCV2X/updateKPICV2X.m b/MainFilesCV2X/updateKPICV2X.m index 56bf9ea..47feecd 100644 --- a/MainFilesCV2X/updateKPICV2X.m +++ b/MainFilesCV2X/updateKPICV2X.m @@ -83,11 +83,15 @@ if simParams.typeOfScenario==constants.SCENARIO_TRACE && outParams.printPRRmap simValues = counterMap(iPhyRaw,simValues,stationManagement.activeIDsCV2X,indexInActiveIDsOnlyLTE,activeIDsTXLTE,awarenessID_LTE(:,:,iPhyRaw),errorMatrix); end - + + if outParams.printHiddenNodeEvents + hiddenNodeEvents = countHiddenNodeEvents(errorRxList=errorRxList, awarenessIDLTE=stationManagement.awarenessIDLTE(:,:,iPhyRaw), BRid=stationManagement.BRid, NbeaconsT=appParams.NbeaconsT, duplexCV2X=phyParams.duplexCV2X); + outputValues.hiddenNodeEvents(iPhyRaw) = outputValues.hiddenNodeEvents(iPhyRaw) + hiddenNodeEvents; + end end % Count distance details for distances up to the maximum awareness range (if enabled) if outParams.printPacketReceptionRatio %outputValues.distanceDetailsCounterCV2X = countDistanceDetails(indexInActiveIDsOnlyLTE,activeIDsTXLTE,neighborsID_LTE,stationManagement.neighborsDistanceLTE,errorMatrixRawMax,outputValues.distanceDetailsCounterCV2X,stationManagement,outParams,appParams,phyParams); outputValues.distanceDetailsCounterCV2X = countDistanceDetails(fateRxListRawMax(fateRxListRawMax(:,5)==1,:),fateRxListRawMax(fateRxListRawMax(:,5)==0,:),outputValues.distanceDetailsCounterCV2X,stationManagement,outParams,appParams,phyParams); -end \ No newline at end of file +end diff --git a/MatFilesInit/initiateOutParameters.m b/MatFilesInit/initiateOutParameters.m index 7d53c0c..0cde56f 100644 --- a/MatFilesInit/initiateOutParameters.m +++ b/MatFilesInit/initiateOutParameters.m @@ -163,5 +163,8 @@ % [message] [outParams,varargin]= addNewParam(outParams,'message', 'None', 'Message during simulation','string',fileCfg,varargin{1}); fprintf('\n'); -% + +% [printHiddenNodeEvents] +[outParams,varargin] = addNewParam(outParams,'printHiddenNodeEvents', false, 'Count the number of errors due to hidden node problem', 'bool', fileCfg, varargin{1}); + %%%%%%%%% diff --git a/MatFilesOut/countHiddenNodeEvents.m b/MatFilesOut/countHiddenNodeEvents.m new file mode 100644 index 0000000..eee94de --- /dev/null +++ b/MatFilesOut/countHiddenNodeEvents.m @@ -0,0 +1,30 @@ +function hiddenNodeEvents = countHiddenNodeEvents(args) + arguments + args.errorRxList (:, 5) double + args.awarenessIDLTE (:, :) double {mustBeInteger} + args.BRid (1, :) double {mustBeInteger} + args.NbeaconsT double {mustBeInteger} + args.duplexCV2X string + end + errorRxList = args.errorRxList; + hiddenNodeEvents = 0; + for error_rx_list_i = 1:size(errorRxList, 1) + tx = errorRxList(error_rx_list_i, 1); + rx = errorRxList(error_rx_list_i, 2); + tx_brid = errorRxList(error_rx_list_i, 3); + % Find who else is within rx's awareness range + rx_neighbors = setdiff(nonzeros(args.awarenessIDLTE(rx,:)), tx); + if args.duplexCV2X == "HD" + % If half duplex, the interferers are the rx's neighbors + % using the same BRT + tx_bridT = mod(tx_brid, args.NbeaconsT); + ix = rx_neighbors(mod(args.BRid(rx_neighbors), args.NbeaconsT) == tx_bridT); + else + % If full duplex, the interferers are the rx's neighbors + % using the exact same BR + ix = rx_neighbors(args.BRid(rx_neighbors) == tx_brid); + end + % If the ix is not within tx's awareness range, is hidden node + hiddenNodeEvents = hiddenNodeEvents + nnz(~ismember(ix, args.awarenessIDLTE(tx, :))); + end +end diff --git a/MatFilesOut/printHiddenNodeEvents.m b/MatFilesOut/printHiddenNodeEvents.m new file mode 100644 index 0000000..e47360c --- /dev/null +++ b/MatFilesOut/printHiddenNodeEvents.m @@ -0,0 +1,17 @@ +function [] = printHiddenNodeEvents(args) + % Prints the hiddenNodeEvents member (of the outputValue struct) to a + % csv file + % Format is just n rows of events, each row corresponds to number of + % events counted in a specified awareness range + arguments + args.outputFolder string + args.simId (1, 1) double + args.hiddenNodeEvents (:, 1) double + end + base_filename = sprintf("hiddennode-%d.csv", args.simId); + outputFolder = args.outputFolder; + if isfolder(outputFolder) == false + mkdir(outputFolder) + end + writematrix(args.hiddenNodeEvents, sprintf('%s/%s', outputFolder, base_filename)); +end diff --git a/Tests/+v2xsim_tests/+unit/+out/test_countHiddenNodeEvents.m b/Tests/+v2xsim_tests/+unit/+out/test_countHiddenNodeEvents.m new file mode 100644 index 0000000..ed0f53a --- /dev/null +++ b/Tests/+v2xsim_tests/+unit/+out/test_countHiddenNodeEvents.m @@ -0,0 +1,66 @@ +function tests = test_countHiddenNodeEvents +tests = functiontests(localfunctions); +end + +function testSimpleCaseHDSameBRF(testCase) +% test the simple case in HD mode where there is only one BRF +% let 1 be tx, 2 be rx, 3 be interferer +% let the BRid in contention be 9 +errorRxList = [1 2 9 100 0]; +% 1 can see 2, cannot see 3 +% 2 can see 1 and 3 +% 3 can only see 2 +awarenessIDLTE = [ + 2 0 0; + 1 3 0; + 2 0 0; + ]; +% 1 and 3 share the same BR, don't care about 2 +BRid = [9 -1 9]; +actual = countHiddenNodeEvents(errorRxList=errorRxList, awarenessIDLTE=awarenessIDLTE, BRid=BRid, NbeaconsT=100, duplexCV2X="HD"); +expected = 1; +verifyEqual(testCase, actual, expected); +end + +function testCaseHDSameBRTDiffBRF(testCase) +% a slightly more complex case, test if the tx and ix are in the same BRT, +% even if diff BRF, in HD mode we consider this hidden node +% let 1 be tx, 2 be rx, 3 be interferer +% let the BRid in contention be 9 +errorRxList = [1 2 9 100 0]; +% 1 can see 2, cannot see 3 +% 2 can see 1 and 3 +% 3 can only see 2 +awarenessIDLTE = [ + 2 0 0; + 1 3 0; + 2 0 0; + ]; +% 1 and 3 share the same BRT but diff BRF, don't care about 2 +BRid = [3 -1 9]; +NbeaconsT = 3; +actual = countHiddenNodeEvents(errorRxList=errorRxList, awarenessIDLTE=awarenessIDLTE, BRid=BRid, NbeaconsT=NbeaconsT, duplexCV2X="HD"); +expected = 1; +verifyEqual(testCase, actual, expected); +end + +function testCaseFDSameBRTSameBRF(testCase) +% in FD mode, tx and ix must be sharing the same BRT and BRF +% let 1 be tx, 2 be rx, 3 be interferer +% let the BRid in contention be 9 +errorRxList = [1 2 9 100 0]; +% 1 can see 2, cannot see 3 +% 2 can see 1 and 3 +% 3 can only see 2 +awarenessIDLTE = [ + 2 0 0; + 1 3 0; + 2 0 0; + ]; +% 1 and 3 share the same BRT and same BRF, don't care about 2 +BRid = [9 -1 9]; +NbeaconsT = 3; +actual = countHiddenNodeEvents(errorRxList=errorRxList, awarenessIDLTE=awarenessIDLTE, BRid=BRid, NbeaconsT=NbeaconsT, duplexCV2X="HD"); +expected = 1; +verifyEqual(testCase, actual, expected); +end diff --git a/WiLabV2Xsim.m b/WiLabV2Xsim.m index 737cd65..97c3569 100644 --- a/WiLabV2Xsim.m +++ b/WiLabV2Xsim.m @@ -229,6 +229,10 @@ function WiLabV2Xsim(varargin) %outputValues.hiddenNodeProbEvents = zeros(floor(phyParams.RawMax)+1,1); end +if outParams.printHiddenNodeEvents + outputValues.hiddenNodeEvents = zeros(length(phyParams.Raw), 1); +end + %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% %% Start Simulation [simValues,outputValues,appParams,simParams,phyParams,sinrManagement,outParams,stationManagement] = mainV2X(appParams,simParams,phyParams,outParams,simValues,outputValues,positionManagement); @@ -375,6 +379,10 @@ function WiLabV2Xsim(varargin) printHiddenNodeProb(outputValues,outParams); end +if outParams.printHiddenNodeEvents + printHiddenNodeEvents(outputFolder=outParams.outputFolder, simId=outParams.simID, hiddenNodeEvents=outputValues.hiddenNodeEvents); +end + % Print to XLS file outputToFiles(stationManagement,simParams,appParams,phyParams,sinrManagement,outParams,outputValues); @@ -406,4 +414,4 @@ function WiLabV2Xsim(varargin) %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% -end \ No newline at end of file +end From ad5de7556163bf64f259c744b63219abba563d1d Mon Sep 17 00:00:00 2001 From: Chester Koh Date: Fri, 13 Oct 2023 18:20:08 +0800 Subject: [PATCH 05/11] fix typo in test case for hiddenNode, should be FD not HD --- Tests/+v2xsim_tests/+unit/+out/test_countHiddenNodeEvents.m | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Tests/+v2xsim_tests/+unit/+out/test_countHiddenNodeEvents.m b/Tests/+v2xsim_tests/+unit/+out/test_countHiddenNodeEvents.m index ed0f53a..8862739 100644 --- a/Tests/+v2xsim_tests/+unit/+out/test_countHiddenNodeEvents.m +++ b/Tests/+v2xsim_tests/+unit/+out/test_countHiddenNodeEvents.m @@ -60,7 +60,7 @@ function testCaseFDSameBRTSameBRF(testCase) % 1 and 3 share the same BRT and same BRF, don't care about 2 BRid = [9 -1 9]; NbeaconsT = 3; -actual = countHiddenNodeEvents(errorRxList=errorRxList, awarenessIDLTE=awarenessIDLTE, BRid=BRid, NbeaconsT=NbeaconsT, duplexCV2X="HD"); +actual = countHiddenNodeEvents(errorRxList=errorRxList, awarenessIDLTE=awarenessIDLTE, BRid=BRid, NbeaconsT=NbeaconsT, duplexCV2X="FD"); expected = 1; verifyEqual(testCase, actual, expected); end From 5d86130e9ce879eb0147c7f25dcd5951b258bfc8 Mon Sep 17 00:00:00 2001 From: Chester Koh Date: Fri, 13 Oct 2023 20:13:38 +0800 Subject: [PATCH 06/11] attempt to support a configurable buffer size --- MainFilesCV2X/mainCV2XttiEnds.m | 4 ++-- MainFilesCV2X/mainCV2XttiStarts.m | 6 ++++-- MainFilesIEEE802.11p/updateVehicleEndingTx11p.m | 2 +- MatFilesInit/initiateApplicationParameters.m | 8 +++++++- 4 files changed, 14 insertions(+), 6 deletions(-) diff --git a/MainFilesCV2X/mainCV2XttiEnds.m b/MainFilesCV2X/mainCV2XttiEnds.m index d8feaaa..8aacd58 100644 --- a/MainFilesCV2X/mainCV2XttiEnds.m +++ b/MainFilesCV2X/mainCV2XttiEnds.m @@ -8,7 +8,7 @@ % geneated in a subframe during which the station is transmitting is % not correctly managed for idLte = stationManagement.activeIDsCV2X' - if stationManagement.pckBuffer(idLte)>1 + if stationManagement.pckBuffer(idLte) > appParams.bufferLength [stationManagement,outputValues] = bufferOverflowLTE(idLte,timeManagement,positionManagement,stationManagement,phyParams,appParams,outputValues,outParams); stationManagement.pckNextAttempt(idLte) = 1; end @@ -48,7 +48,7 @@ stationManagement.BRid(stationManagement.activeIDsCV2X(hasNewPacketThisTbeacon),:) = BRidModified; end -elseif mod(timeManagement.elapsedTime_TTIs,appParams.NbeaconsT)==0 +elseif timeManagement.elapsedTime_TTIs == 1 || mod(timeManagement.elapsedTime_TTIs,appParams.NbeaconsT) == 0 % All other algorithms except standard Mode 4 % TODO not checked in version 5.X diff --git a/MainFilesCV2X/mainCV2XttiStarts.m b/MainFilesCV2X/mainCV2XttiStarts.m index a3de990..14c039c 100644 --- a/MainFilesCV2X/mainCV2XttiStarts.m +++ b/MainFilesCV2X/mainCV2XttiStarts.m @@ -30,7 +30,9 @@ currentT = (mod((timeManagement.elapsedTime_TTIs-1),appParams.NbeaconsT)+1); idLteHasPck = stationManagement.activeIDsCV2X(stationManagement.pckBuffer(stationManagement.activeIDsCV2X) >= 1); for idLte = idLteHasPck' - attemptToDo = stationManagement.pckNextAttempt(idLte); + % attemptToDo = stationManagement.pckNextAttempt(idLte); + % was BRid ever going to have more than one column...? + attemptToDo = 1; if ceil((stationManagement.BRid(idLte,attemptToDo))/appParams.NbeaconsF)==currentT stationManagement.transmittingIDsCV2X(iTransmitting) = idLte; stationManagement.transmittingFusedLTE(iTransmitting) = mod((stationManagement.BRid(idLte,attemptToDo))-1,appParams.NbeaconsF)+1; @@ -71,7 +73,7 @@ % This has been done to allow the possibility of allowing the possibility % of triggering retransmissions if ~isempty(stationManagement.transmittingIDsCV2X) - stationManagement.pckTxOccurring(stationManagement.transmittingIDsCV2X) = stationManagement.pckNextAttempt(stationManagement.transmittingIDsCV2X); + stationManagement.pckTxOccurring(stationManagement.transmittingIDsCV2X) = logical(stationManagement.pckNextAttempt(stationManagement.transmittingIDsCV2X)); stationManagement.pckNextAttempt(stationManagement.transmittingIDsCV2X) = stationManagement.pckNextAttempt(stationManagement.transmittingIDsCV2X) + 1; txIDlastTx = stationManagement.transmittingIDsCV2X(stationManagement.pckNextAttempt(stationManagement.transmittingIDsCV2X)>stationManagement.cv2xNumberOfReplicas(stationManagement.transmittingIDsCV2X)); stationManagement.pckBuffer(txIDlastTx) = stationManagement.pckBuffer(txIDlastTx)-1; diff --git a/MainFilesIEEE802.11p/updateVehicleEndingTx11p.m b/MainFilesIEEE802.11p/updateVehicleEndingTx11p.m index 45b6a95..7c58931 100644 --- a/MainFilesIEEE802.11p/updateVehicleEndingTx11p.m +++ b/MainFilesIEEE802.11p/updateVehicleEndingTx11p.m @@ -42,7 +42,7 @@ % in idle state stationManagement.vehicleState(idEvent) = constants.V_STATE_11P_IDLE; % idle timeManagement.timeNextTxRx11p(idEvent) = Inf; - elseif stationManagement.pckBuffer(idEvent) >= 1 + elseif stationManagement.pckBuffer(idEvent) >= appParams.bufferLength % If there are other packets in the queue, a new % backoff is initialized and started % in this case is retransmission, because the queue only has one diff --git a/MatFilesInit/initiateApplicationParameters.m b/MatFilesInit/initiateApplicationParameters.m index a377eb5..5a24d58 100644 --- a/MatFilesInit/initiateApplicationParameters.m +++ b/MatFilesInit/initiateApplicationParameters.m @@ -153,7 +153,13 @@ % if simParams.mco_nVehInterf<0 % error('Error: "simParams.mco_nVehInterf" cannot be < 0'); % end - + +% [bufferLength] +[appParams,varargin]= addNewParam(appParams,'bufferLength',1,'Length of the vehicle packet buffer','integer',fileCfg,varargin{1}); +if appParams.bufferLength<1 + error('bufferLength must be >= 1'); +end + fprintf('\n'); % %%%%%%%%% From 6f48040c38c8b8038c82d1103d4d33f393c8fd66 Mon Sep 17 00:00:00 2001 From: Chester Koh Date: Fri, 20 Oct 2023 21:20:19 +0800 Subject: [PATCH 07/11] enhance usage of posDelay, add posPacketLoss param --- MainFiles/mainInit.m | 22 +- MainFiles/mainPositionUpdate.m | 13 +- MainFilesCV2X/mainCV2XttiEnds.m | 6 +- MatFilesInit/constants.m | 9 +- MatFilesInit/initiateBRAssignmentAlgorithm.m | 514 ++++++++---------- MatFilesPosition/addPosDelay.m | 97 +++- MatFilesUtility/computeDistance.m | 19 +- MatFilesUtility/computeNeighbors.m | 10 +- .../+unit/+position/test_addPosDelay.m | 94 ++++ 9 files changed, 443 insertions(+), 341 deletions(-) create mode 100644 Tests/+v2xsim_tests/+unit/+position/test_addPosDelay.m diff --git a/MainFiles/mainInit.m b/MainFiles/mainInit.m index effe15e..3a28430 100644 --- a/MainFiles/mainInit.m +++ b/MainFiles/mainInit.m @@ -68,6 +68,7 @@ outputValues.NvehiclesTOT = outputValues.NvehiclesTOT + outputValues.Nvehicles; outputValues.NvehiclesLTE = outputValues.NvehiclesLTE + length(stationManagement.activeIDsCV2X); outputValues.Nvehicles11p = outputValues.Nvehicles11p + length(stationManagement.activeIDs11p); +outputValues.meanPositionError = zeros(outputValues.Nvehicles, 1); %% Initialization of packets management % Number of packets in the queue of each node @@ -201,15 +202,22 @@ end % Copy real coordinates into estimated coordinates at eNodeB (no positioning error) -simValues.XvehicleEstimated = positionManagement.XvehicleReal; -simValues.YvehicleEstimated = positionManagement.YvehicleReal; +positionManagement.XvehicleEstimated = positionManagement.XvehicleReal; +positionManagement.YvehicleEstimated = positionManagement.YvehicleReal; % Call function to compute distances -% computeDistance(i,j): computeDistance from vehicle with index i to vehicle with index j -% positionManagement.distance matrix has dimensions equal to simValues.IDvehicle x simValues.IDvehicle in order to -% speed up the computation (only vehicles present at the considered instant) -% positionManagement.distance(i,j): positionManagement.distance from vehicle with index i to vehicle with index j -[positionManagement,stationManagement] = computeDistance (simParams,simValues,stationManagement,positionManagement); +[positionManagement] = computeDistance (positionManagement); + +% Position Delay +% timetables of old positions +n_vehicles = length(positionManagement.XvehicleReal); +positionManagement.XvehicleHistory = cell(n_vehicles, 1); +positionManagement.YvehicleHistory = cell(n_vehicles, 1); +for i = 1:n_vehicles + positionManagement.XvehicleHistory{i} = timetable(Size=[0 1], VariableTypes={'double'}, TimeStep=seconds(simParams.positionTimeResolution)); + positionManagement.YvehicleHistory{i} = timetable(Size=[0 1], VariableTypes={'double'}, TimeStep=seconds(simParams.positionTimeResolution)); +end + % Save positionManagement.distance matrix positionManagement.XvehicleRealOld = positionManagement.XvehicleReal; diff --git a/MainFiles/mainPositionUpdate.m b/MainFiles/mainPositionUpdate.m index f696ac7..29ca675 100644 --- a/MainFiles/mainPositionUpdate.m +++ b/MainFiles/mainPositionUpdate.m @@ -68,15 +68,20 @@ end % Add LTE positioning delay (if selected) - [simValues.XvehicleEstimated,simValues.YvehicleEstimated,PosUpdateIndex] = addPosDelay(simValues.XvehicleEstimated,simValues.YvehicleEstimated,positionManagement.XvehicleReal,positionManagement.YvehicleReal,stationManagement.activeIDs,indexNewVehicles,indexOldVehicles,indexOldVehiclesToOld,positionManagement.posUpdateAllVehicles,simParams.positionTimeResolution); - + [positionManagement.XvehicleEstimated, positionManagement.YvehicleEstimated,... + positionManagement.XvehicleHistory, positionManagement.YvehicleHistory] = addPosDelay(positionManagement.XvehicleReal, positionManagement.YvehicleReal, positionManagement.XvehicleHistory, positionManagement.YvehicleHistory, timeManagement.timeNow, simParams.posDelay, simParams.posPacketLoss); + % Add LTE positioning error (if selected) % (Xvehicle, Yvehicle): fictitious vehicles' position seen by the eNB - [simValues.XvehicleEstimated(PosUpdateIndex),simValues.YvehicleEstimated(PosUpdateIndex)] = addPosError(positionManagement.XvehicleReal(PosUpdateIndex),positionManagement.YvehicleReal(PosUpdateIndex),simParams.sigmaPosError); + [positionManagement.XvehicleEstimated,positionManagement.YvehicleEstimated] = addPosError(positionManagement.XvehicleEstimated, positionManagement.YvehicleEstimated,simParams.sigmaPosError); + + % Record the cumulative mean of positioning error + this_instance_error = sqrt((positionManagement.XvehicleReal - positionManagement.XvehicleEstimated).^2 + (positionManagement.YvehicleReal - positionManagement.YvehicleEstimated).^2); + outputValues.meanPositionError = (this_instance_error + positionManagement.NposUpdates*outputValues.meanPositionError)/(positionManagement.NposUpdates+1); end % Call function to compute the distances -[positionManagement,stationManagement] = computeDistance (simParams,simValues,stationManagement,positionManagement); +[positionManagement] = computeDistance(positionManagement); % Call function to update positionManagement.distance matrix where D(i,j) is the % change in positionManagement.distance of link i to j from time n-1 to time n and used diff --git a/MainFilesCV2X/mainCV2XttiEnds.m b/MainFilesCV2X/mainCV2XttiEnds.m index d8feaaa..9d83377 100644 --- a/MainFilesCV2X/mainCV2XttiEnds.m +++ b/MainFilesCV2X/mainCV2XttiEnds.m @@ -53,7 +53,7 @@ % TODO not checked in version 5.X %% Radio Resources Reassignment - if simParams.BRAlgorithm==constants.REASSIGN_BR_REUSE_DIS_SCHEDULED_VEH || simParams.BRAlgorithm==constants.REASSIGN_BR_MAX_REUSE_DIS || simParams.BRAlgorithm==constants.REASSIGN_BR_MIN_REUSE_POW + if ismember(simParams.BRAlgorithm, constants.CONTROLLED_ALGORITHMS) if timeManagement.elapsedTime_TTIs > 0 % Current scheduled reassign period @@ -79,7 +79,7 @@ % BRs reassignment (CONTROLLED with MAXIMUM REUSE DISTANCE) %[stationManagement.BRid,Nreassign] = BRreassignmentControlledMaxReuse(stationManagement.activeIDsCV2X,stationManagement.BRid,scheduledID,stationManagement.neighborsIDLTE,appParams.NbeaconsT,appParams.NbeaconsF); - [stationManagement.BRid,Nreassign] = BRreassignmentControlledMaxReuse(stationManagement.activeIDsCV2X,stationManagement.BRid,scheduledID,stationManagement.allNeighborsID,appParams.NbeaconsT,appParams.NbeaconsF); + [stationManagement.BRid,Nreassign] = BRreassignmentControlledMaxReuse(stationManagement.activeIDsCV2X,stationManagement.BRid,scheduledID,stationManagement.allNeighborsIDEstimated,appParams.NbeaconsT,appParams.NbeaconsF); elseif simParams.BRAlgorithm == constants.REASSIGN_BR_MIN_REUSE_POW @@ -113,7 +113,7 @@ elseif simParams.BRAlgorithm==constants.REASSIGN_BR_ORDERED_ALLOCATION % Call Benchmark Algorithm 102 (ORDERED ALLOCATION) - [stationManagement.BRid,Nreassign] = BRreassignmentOrdered(positionManagement.XvehicleReal,stationManagement.activeIDsCV2X,stationManagement.BRid,appParams.NbeaconsT,appParams.NbeaconsF); + [stationManagement.BRid,Nreassign] = BRreassignmentOrdered(positionManagement.XvehicleEstimated,stationManagement.activeIDsCV2X,stationManagement.BRid,appParams.NbeaconsT,appParams.NbeaconsF); end diff --git a/MatFilesInit/constants.m b/MatFilesInit/constants.m index eed80b3..2fb3b97 100644 --- a/MatFilesInit/constants.m +++ b/MatFilesInit/constants.m @@ -151,9 +151,14 @@ % ORDERED ALLOCATION (following X coordinate) REASSIGN_BR_ORDERED_ALLOCATION = 102; - % ***** this two Algorithms used as benchmarks ***** - + REASSIGN_BR_ALGORITHMS_CONTROLLED = [constants.REASSIGN_BR_REUSE_DIS_SCHEDULED_VEH + constants.REASSIGN_BR_MAX_REUSE_DIS + constants.REASSIGN_BR_POW_CONTROL + constants.REASSIGN_BR_MIN_REUSE_POW + constants.REASSIGN_BR_ORDERED_ALLOCATION]; + REASSIGN_BR_ALOGRITHMS_AUTONOMOUS = [constants.REASSIGN_BR_STD_MODE_4 + constants.REASSIGN_BR_RAND_ALLOCATION]; %% **************************************** %% CHANNEL MODEL diff --git a/MatFilesInit/initiateBRAssignmentAlgorithm.m b/MatFilesInit/initiateBRAssignmentAlgorithm.m index a3b536f..07faacc 100644 --- a/MatFilesInit/initiateBRAssignmentAlgorithm.m +++ b/MatFilesInit/initiateBRAssignmentAlgorithm.m @@ -1,324 +1,276 @@ -function [simParams,phyParams,varargin] = initiateBRAssignmentAlgorithm(simParams,phyParams,Tbeacon,fileCfg,varargin) -% function [simParams,varargin]= initiateBRAssignmentAlgorithm(simParams,fileCfg,varargin) -% -% Main settings of the simulation -% It takes in input the structure simParams, the name of the (possible) file config and the inputs -% of the main function -% It returns the structure "simParams" - -fprintf('Settings of resource assignement algorithm\n'); - -% [BRAlgorithm] -% Selects the BR reassignment algorithm: -% Check .../MatFilesInit/constants.m for details -% 2 -> CONTROLLED with REUSE DISTANCE and scheduled vehicles -% 7 -> CONTROLLED with MAXIMUM REUSE DISTANCE (MRD) -% 8 -> AUTONOMOUS with SENSING (3GPP STANDARD MODE 4) - ON A BEACON PERIOD BASIS -% 18 -> AUTONOMOUS with SENSING (3GPP STANDARD LTE-MODE-4 or NR-MODE-2) - ON A SLOT BASIS -% -% 9 -> CONTROLLED with POWER CONTROL -% 10 -> CONTROLLED with MINIMUM REUSE POWER (MRP) - -% [BENCHMARKS Algorithms] -% Algorithms used as benchmarks -% 101 -> RANDOM ALLOCATION -% 102 -> ORDERED ALLOCATION (following X coordinate) - -[simParams,varargin] = addNewParam(simParams,'BRAlgorithm',constants.REASSIGN_BR_STD_MODE_4,'Assignment algorithm','integer',fileCfg,varargin{1}); -switch simParams.BRAlgorithm - case constants.REASSIGN_BR_REUSE_DIS_SCHEDULED_VEH % CONTROLLED with REUSE DISTANCE and scheduled vehicles +function [simParams, phyParams, varargin] = initiateBRAssignmentAlgorithm(simParams, phyParams, Tbeacon, fileCfg, varargin) + % function [simParams,varargin]= initiateBRAssignmentAlgorithm(simParams,fileCfg,varargin) + % + % Main settings of the simulation + % It takes in input the structure simParams, the name of the (possible) file config and the inputs + % of the main function + % It returns the structure "simParams" + + fprintf('Settings of resource assignement algorithm\n'); + + % [BRAlgorithm] + % Selects the BR reassignment algorithm: + % Check .../MatFilesInit/constants.m for details + % 2 -> CONTROLLED with REUSE DISTANCE and scheduled vehicles + % 7 -> CONTROLLED with MAXIMUM REUSE DISTANCE (MRD) + % 8 -> AUTONOMOUS with SENSING (3GPP STANDARD MODE 4) - ON A BEACON PERIOD BASIS + % 18 -> AUTONOMOUS with SENSING (3GPP STANDARD LTE-MODE-4 or NR-MODE-2) - ON A SLOT BASIS + % + % 9 -> CONTROLLED with POWER CONTROL + % 10 -> CONTROLLED with MINIMUM REUSE POWER (MRP) + + % [BENCHMARKS Algorithms] + % Algorithms used as benchmarks + % 101 -> RANDOM ALLOCATION + % 102 -> ORDERED ALLOCATION (following X coordinate) + + implementedAlgorithms = [constants.REASSIGN_BR_ALGORITHMS_CONTROLLED ; constants.REASSIGN_BR_ALOGRITHMS_AUTONOMOUS]; + + [simParams, varargin] = addNewParam(simParams, 'BRAlgorithm', constants.REASSIGN_BR_STD_MODE_4, 'Assignment algorithm', 'integer', fileCfg, varargin{1}); + if ~ismember(simParams.BRAlgorithm, implementedAlgorithms) + error('Error: "simParams.BRAlgorithm" not valid. Algorithm not implemented.'); + end + + % Add parameters common to all controlled algorithms + if ismember(simParams.BRAlgorithm, constants.REASSIGN_BR_ALGORITHMS_CONTROLLED) + % [posDelay] + % LTE position delay + [simParams, varargin] = addNewParam(simParams, 'posDelay', 0, 'V2NB Positioning Delay (only controlled BR algorithms) (s)', 'double', fileCfg, varargin{1}); + if simParams.posDelay < 0 + error('Error: "simParams.posDelay" cannot be negative'); + end + % [posError95] % LTE Positioning Accuracy (Gaussian model): 95th percentile of the error (m) - [simParams,varargin] = addNewParam(simParams,'posError95',0,'LTE positioning error - 95th percentile (only controlled) (m)','double',fileCfg,varargin{1}); - simParams.sigmaPosError = simParams.posError95/1.96; % Standard deviation of the error (m) - + [simParams, varargin] = addNewParam(simParams, 'posError95', 0, 'V2NB Positioning error - 95th percentile (only controlled BR algorithms) (m)', 'double', fileCfg, varargin{1}); + if simParams.posError95 < 0 + error('Error: "simParams.posError95" cannot be negative'); + end + simParams.sigmaPosError = simParams.posError95 / 1.96; % Standard deviation of the error (m) + + % [posPacketLoss] + [simParams, varargin] = addNewParam(simParams, 'posPacketLoss', 0, 'V2NB Positioning Signal Packet Loss Probability (only controlled BR algorithms)', 'double', fileCfg, varargin{1}); + if simParams.posPacketLoss <= 0 || simParams.posPacketLoss < 1 + error('Error: "simParams.posPacketLoss must be 0 <= p < 1'); + end + % [Tupdate] % Time interval between each position update at the eNodeBs (s) - [simParams,varargin]= addNewParam(simParams,'Tupdate',Tbeacon,'Time interval between position updates at the eNodeBs (s)','double',fileCfg,varargin{1}); - if simParams.Tupdate<=0 + [simParams, varargin] = addNewParam(simParams, 'Tupdate', Tbeacon, 'Time interval between position updates at the eNodeBs (s)', 'double', fileCfg, varargin{1}); + if simParams.Tupdate <= 0 error('Error: "simParams.Tupdate" cannot <= 0'); end - - % [Mreuse] - % Reuse margin (m) (only valid for controlled LTE-V2V with reuse distance [BRAlgorithm 2]) - [simParams,varargin]= addNewParam(simParams,'Mreuse',0,'Reuse margin (m)','integer',fileCfg,varargin{1}); - - % [Treassign] - % Time interval between each scheduled BR reassignment (BRAlgorithm 2,7,9,10) (s) - % By default it is set equal to the beacon period - [simParams,varargin]= addNewParam(simParams,'Treassign',Tbeacon,'Interval of scheduled reassignment (BRAlgorithm 2,7,9,10) (s)','double',fileCfg,varargin{1}); - if simParams.Treassign<=0 - error('Error: "simParams.Treassign" cannot be <= 0.'); - end - case constants.REASSIGN_BR_MAX_REUSE_DIS % CONTROLLED with MAXIMUM REUSE DISTANCE (MRD) - simParams.posError95 = 0; - simParams.sigmaPosError = 0; - simParams.Tupdate = Tbeacon; - simParams.Mreuse=0; % [Treassign] - % Time interval between each scheduled BR reassignment (BRAlgorithm 2,7,9,10) (s) + % Time interval between each scheduled BR reassignment (Controlled BR algorithms) (s) % By default it is set equal to the beacon period - [simParams,varargin]= addNewParam(simParams,'Treassign',Tbeacon,'Interval of scheduled reassignment (BRAlgorithm 2,7,9,10) (s)','double',fileCfg,varargin{1}); - if simParams.Treassign<=0 + [simParams, varargin] = addNewParam(simParams, 'Treassign', Tbeacon, 'Interval of scheduled reassignment (Controlled BR algorithms) (s)', 'double', fileCfg, varargin{1}); + if simParams.Treassign <= 0 error('Error: "simParams.Treassign" cannot be <= 0.'); end - case constants.REASSIGN_BR_POW_CONTROL % CONTROLLED with POWER CONTROL + else + simParams.posDelay = 0; simParams.posError95 = 0; + simParams.posPacketLoss = 0; simParams.sigmaPosError = 0; simParams.Tupdate = Tbeacon; - simParams.Mreuse=0; + simParams.Mreuse = 0; + end - % [Treassign] - % Time interval between each scheduled BR reassignment (BRAlgorithm 2,7,9,10) (s) - % By default it is set equal to the beacon period - [simParams,varargin]= addNewParam(simParams,'Treassign',Tbeacon,'Interval of scheduled reassignment (BRAlgorithm 2,7,9,10) (s)','double',fileCfg,varargin{1}); - if simParams.Treassign<=0 - error('Error: "simParams.Treassign" cannot be <= 0.'); - end - case constants.REASSIGN_BR_MIN_REUSE_POW % CONTROLLED with MINIMUM REUSE POWER (MRP) - simParams.posError95 = 0; - simParams.sigmaPosError = 0; - simParams.Tupdate = Tbeacon; - simParams.Mreuse=0; + % Initalize BRAlgorithm-specific parameters + switch simParams.BRAlgorithm + case constants.REASSIGN_BR_REUSE_DIS_SCHEDULED_VEH % CONTROLLED with REUSE DISTANCE and scheduled vehicles + % [Mreuse] + % Reuse margin (m) (only valid for controlled LTE-V2V with reuse distance [BRAlgorithm 2]) + [simParams, varargin] = addNewParam(simParams, 'Mreuse', 0, 'Reuse margin (m)', 'integer', fileCfg, varargin{1}); + case constants.REASSIGN_BR_MIN_REUSE_POW % CONTROLLED with MINIMUM REUSE POWER (MRP) + % [knownShadowing] + % Selects if shadowing is estimated at the eNB side + [simParams, varargin] = addNewParam(simParams, 'knownShadowing', false, 'if shadowing is estimated at the eNB side', 'bool', fileCfg, varargin{1}); + case constants.REASSIGN_BR_STD_MODE_4 % AUTONOMOUS with SENSING (3GPP STANDARD MODE 4) - ON A SUBFRAME BASIS + simParams.posError95 = 0; + simParams.sigmaPosError = 0; + simParams.Tupdate = Tbeacon; + simParams.Mreuse = 0; - % [Treassign] - % Time interval between each scheduled BR reassignment (BRAlgorithm 2,7,9,10) (s) - % By default it is set equal to the beacon period - [simParams,varargin]= addNewParam(simParams,'Treassign',Tbeacon,'Interval of scheduled reassignment (BRAlgorithm 2,7,9,10) (s)','double',fileCfg,varargin{1}); - if simParams.Treassign<=0 - error('Error: "simParams.Treassign" cannot be <= 0.'); - end + % [resourceReEvaluation] + % Enables the the resource re-evaluation in 5G + [simParams, varargin] = addNewParam(simParams, 'resourceReEvaluation', false, 'Activates the resource re-evaluation in NR-V2X', 'bool', fileCfg, varargin{1}); + if simParams.resourceReEvaluation == true && simParams.mode5G ~= 1 + error('Error: "simParams.mode5G" must be equal to: 5G-V2X when resource re-evaluation is active'); + end - % [knownShadowing] - % Selects if shadowing is estimated at the eNB side - [simParams,varargin]= addNewParam(simParams,'knownShadowing',false,'if shadowing is estimated at the eNB side','bool',fileCfg,varargin{1}); + % [reEvalAfterEmptyResource] + % Enables the the resource re-evaluation after a user has not transmitted in a previously reserved resource + [simParams, varargin] = addNewParam(simParams, 'reEvalAfterEmptyResource', false, 'Activates the resource re-evaluation in NR-V2X after empty transmission', 'bool', fileCfg, varargin{1}); + if simParams.reEvalAfterEmptyResource == true && simParams.mode5G ~= 1 + error('Error: "simParams.mode5G" must be equal to: 5G-V2X when resource re-evaluation is active'); + end + if simParams.reEvalAfterEmptyResource == true && simParams.resourceReEvaluation == false + error('Error: "simParams.reEvalAfterEmptyResource" cannot be true when resourceReEvaluation is false'); + end - case constants.REASSIGN_BR_STD_MODE_4 % AUTONOMOUS with SENSING (3GPP STANDARD MODE 4) - ON A SUBFRAME BASIS - simParams.posError95 = 0; - simParams.sigmaPosError = 0; - simParams.Tupdate = Tbeacon; - simParams.Mreuse=0; + % [dynamicScheduling] + % Enables the dynamic scheduling: resources are changed at each generation + [simParams, varargin] = addNewParam(simParams, 'dynamicScheduling', false, 'Probability to keep the previously selected BR', 'bool', fileCfg, varargin{1}); - % [resourceReEvaluation] - % Enables the the resource re-evaluation in 5G - [simParams,varargin]= addNewParam(simParams,'resourceReEvaluation',false,'Activates the resource re-evaluation in NR-V2X','bool',fileCfg,varargin{1}); - if simParams.resourceReEvaluation == true && simParams.mode5G ~=1 - error('Error: "simParams.mode5G" must be equal to: 5G-V2X when resource re-evaluation is active'); - end + % [probResKeep] + % Probability to keep the previously selected BR + [simParams, varargin] = addNewParam(simParams, 'probResKeep', 0.8 * (~simParams.dynamicScheduling), 'Probability to keep the previously selected BR', 'double', fileCfg, varargin{1}); + if simParams.probResKeep < 0 || simParams.probResKeep > 1 + error('Error: "simParams.probResKeep" must be within 0 and 0.8. In this version it can take also values bigger than 0.8'); + elseif simParams.probResKeep > 0.8 && simParams.probResKeep <= 1 + warning('Warning: "simParams.probResKeep" must be within 0 and 0.8 according to specifications. A value bigger than 0.8 has been inserted'); + end + if simParams.dynamicScheduling == true && simParams.probResKeep ~= 0 + error('Error: "simParams.probResKeep" must be 0 when Dynamic Scheduling is selected'); + end - % [reEvalAfterEmptyResource] - % Enables the the resource re-evaluation after a user has not transmitted in a previously reserved resource - [simParams,varargin]= addNewParam(simParams,'reEvalAfterEmptyResource',false,'Activates the resource re-evaluation in NR-V2X after empty transmission','bool',fileCfg,varargin{1}); - if simParams.reEvalAfterEmptyResource == true && simParams.mode5G ~=1 - error('Error: "simParams.mode5G" must be equal to: 5G-V2X when resource re-evaluation is active'); - end - if simParams.reEvalAfterEmptyResource == true && simParams.resourceReEvaluation == false - error('Error: "simParams.reEvalAfterEmptyResource" cannot be true when resourceReEvaluation is false'); - end + % [ratioSelectedAutonomousMode] + % Percentage of resources to be considered for random selection + [simParams, varargin] = addNewParam(simParams, 'ratioSelectedAutonomousMode', 0.2, 'Percentage of resources to be considered for random selection', 'double', fileCfg, varargin{1}); + if simParams.ratioSelectedAutonomousMode < 0.2 || simParams.ratioSelectedAutonomousMode > 1 + error('Error: "simParams.ratioSelectedAutonomousMode" must be more than 0.2 and not more than 1 (specs: 0.2)'); + end - % [dynamicScheduling] - % Enables the dynamic scheduling: resources are changed at each generation - [simParams,varargin]= addNewParam(simParams,'dynamicScheduling',false,'Probability to keep the previously selected BR','bool',fileCfg,varargin{1}); - - % [probResKeep] - % Probability to keep the previously selected BR - [simParams,varargin]= addNewParam(simParams,'probResKeep',0.8*(~simParams.dynamicScheduling),'Probability to keep the previously selected BR','double',fileCfg,varargin{1}); - if simParams.probResKeep<0 || simParams.probResKeep>1 - error('Error: "simParams.probResKeep" must be within 0 and 0.8. In this version it can take also values bigger than 0.8'); - elseif simParams.probResKeep>0.8 && simParams.probResKeep<=1 - warning('Warning: "simParams.probResKeep" must be within 0 and 0.8 according to specifications. A value bigger than 0.8 has been inserted'); - end - if simParams.dynamicScheduling == true && simParams.probResKeep~=0 - error('Error: "simParams.probResKeep" must be 0 when Dynamic Scheduling is selected'); - end + % [L2active] + % Parameter that gives the possibility to reintroduce L2 in mode2 + % By default (and specifications) is active in LTE and disabled in 5G + [simParams, varargin] = addNewParam(simParams, 'L2active', ~simParams.mode5G, 'Activate or De-activate L2 in mode2/mode4', 'bool', fileCfg, varargin{1}); - % [ratioSelectedAutonomousMode] - % Percentage of resources to be considered for random selection - [simParams,varargin]= addNewParam(simParams,'ratioSelectedAutonomousMode',0.2,'Percentage of resources to be considered for random selection','double',fileCfg,varargin{1}); - if simParams.ratioSelectedAutonomousMode<0.2 || simParams.ratioSelectedAutonomousMode>1 - error('Error: "simParams.ratioSelectedAutonomousMode" must be more than 0.2 and not more than 1 (specs: 0.2)'); - end + % [averageSensingActive] + % Parameter that gives the possibility to reintroduce the average sensing in mode2 + % By default (and specifications) is active in LTE and disabled in 5G + [simParams, varargin] = addNewParam(simParams, 'averageSensingActive', ~simParams.mode5G, 'Activate or De-activate the average sensing mode2/mode4', 'bool', fileCfg, varargin{1}); - % [L2active] - % Parameter that gives the possibility to reintroduce L2 in mode2 - % By default (and specifications) is active in LTE and disabled in 5G - [simParams,varargin]= addNewParam(simParams,'L2active',(~simParams.mode5G),'Activate or De-activate L2 in mode2/mode4','bool',fileCfg,varargin{1}); - - % [averageSensingActive] - % Parameter that gives the possibility to reintroduce the average sensing in mode2 - % By default (and specifications) is active in LTE and disabled in 5G - [simParams,varargin] = addNewParam(simParams,'averageSensingActive',(~simParams.mode5G),'Activate or De-activate the average sensing mode2/mode4','bool',fileCfg,varargin{1}); - - - % This can be used with same effect as averageSensingActive to unify the two conditions - % % [NsensingPeriod] - % % Number of beacon periods during which performing sensing - % [simParams,varargin{1}{1}]= addNewParam(simParams,'NsensingPeriod',10,'Number of beacon periods during which performing sensing','integer',fileCfg,varargin{1}{1}); - % if simParams.NsensingPeriod<=0 - % error('Error: "simParams.NsensingPeriod" must be larger than 0'); - % end - - % [TsensingPeriod] - % Duration of the sensing period, in seconds - [simParams,varargin]= addNewParam(simParams,'TsensingPeriod',1,'Duration of the sensing period, in seconds','double',fileCfg,varargin{1}); - if simParams.TsensingPeriod<=0 - error('Error: "simParams.TsensingPeriod" must be larger than 0'); - end + % This can be used with same effect as averageSensingActive to unify the two conditions + % % [NsensingPeriod] + % % Number of beacon periods during which performing sensing + % [simParams,varargin{1}{1}]= addNewParam(simParams,'NsensingPeriod',10,'Number of beacon periods during which performing sensing','integer',fileCfg,varargin{1}{1}); + % if simParams.NsensingPeriod<=0 + % error('Error: "simParams.NsensingPeriod" must be larger than 0'); + % end - % [minRandValueMode4] - % Minimum duration keeping the same allocation - [simParams,varargin]= addNewParam(simParams,'minRandValueMode4',-1,'Minimum duration keeping the same allocation','integer',fileCfg,varargin{1}); - if simParams.minRandValueMode4~=-1 && simParams.minRandValueMode4<=0 - error('Error: "simParams.minRandValueMode4" must be more than 0'); - end + % [TsensingPeriod] + % Duration of the sensing period, in seconds + [simParams, varargin] = addNewParam(simParams, 'TsensingPeriod', 1, 'Duration of the sensing period, in seconds', 'double', fileCfg, varargin{1}); + if simParams.TsensingPeriod <= 0 + error('Error: "simParams.TsensingPeriod" must be larger than 0'); + end - % [maxRandValueMode4] - % Maximum duration keeping the same allocation - [simParams,varargin]= addNewParam(simParams,'maxRandValueMode4',-1,'Maximum duration keeping the same allocation','integer',fileCfg,varargin{1}); - if simParams.maxRandValueMode4~=-1 && simParams.maxRandValueMode4<=simParams.minRandValueMode4 - error('Error: "simParams.maxRandValueMode4" must be larger than "simParams.minRandValueMode4"'); - end - - % [powerThresholdAutonomous] - % Minimum power threshold to consider a BR as occupied in dBm - [simParams,varargin]= addNewParam(simParams,'powerThresholdAutonomous',-110,'Minimum power threshold to consider a BR as occupied in Mode 4, in dBm','double',fileCfg,varargin{1}); - if simParams.powerThresholdAutonomous/2<-64 || simParams.powerThresholdAutonomous/2>-1 || mod(simParams.powerThresholdAutonomous,2)~=0 - error('Error: "simParams.powerThresholdAutonomous" must be between -128 and -2, step 2 dB'); - end - % From dBm to linear - simParams.powerThresholdAutonomous = db2pow(simParams.powerThresholdAutonomous-30); - - % [minSCIsinr] - % Minimum SINR for a SCI to be correctly decoded - [phyParams,varargin] = addNewParam(phyParams,'minSCIsinr',0,'Minimum SINR for a SCI to be correctly decoded, in dB','double',fileCfg,varargin{1}); - phyParams.minSCIsinr = db2pow(phyParams.minSCIsinr); - - % [asynMode] - % Enables Asynchronous transmitters - [simParams,varargin]= addNewParam(simParams,'asynMode',0,'Enables/Desable Asynchronous transmitters','integer',fileCfg,varargin{1}); - if (simParams.asynMode ~=0 && simParams.asynMode ~= 1) - error('Error: "simParams.asynMode" cannot different from 0 or 1'); - end - - % [percAsynUser] - % TODO - % if Asynchronous transmitters is active -> sets the percentage of - % Asynchronous users - if simParams.asynMode == 1 - [simParams,varargin]= addNewParam(simParams,'percAsynUser',0.2,'Percentage of asynchronous users','double',fileCfg,varargin{1}); - if simParams.percAsynUser<0 || simParams.percAsynUser>1 - error('Error: "simParams.percAsynUser" must be within 0 and 1'); + % [minRandValueMode4] + % Minimum duration keeping the same allocation + [simParams, varargin] = addNewParam(simParams, 'minRandValueMode4', -1, 'Minimum duration keeping the same allocation', 'integer', fileCfg, varargin{1}); + if simParams.minRandValueMode4 ~= -1 && simParams.minRandValueMode4 <= 0 + error('Error: "simParams.minRandValueMode4" must be more than 0'); end - end - % [FDalgorithm] - % Enables different FD algorithm - [simParams,varargin]= addNewParam(simParams,'FDalgorithm',0,'Enables FD algorithm','integer',fileCfg,varargin{1}); - if simParams.FDalgorithm~=0 && phyParams.PDelta==Inf - error('Error: "phyParams.PDelta" must be defined'); - end - if simParams.FDalgorithm~=0 && phyParams.duplexCV2X~="FD" - error('Error: "phyParams.duplexCV2X" must be "FD"'); - end - if ismember(simParams.FDalgorithm,[1,2]) && phyParams.cv2xNumberOfReplicasMax==2 - error('Error: "phyParams.cv2xNumberOfReplicasMax" must be equal to 1'); - end - if ismember(simParams.FDalgorithm,[3,4,5,6,7,8]) && phyParams.cv2xNumberOfReplicasMax~=2 - error('Error: "phyParams.cv2xNumberOfReplicasMax" must be equal to 2'); - end - if simParams.FDalgorithm~=0 && simParams.mode5G ~=1 - error('Error: "simParams.mode5G" must be equal to: 5G-V2X'); - end + % [maxRandValueMode4] + % Maximum duration keeping the same allocation + [simParams, varargin] = addNewParam(simParams, 'maxRandValueMode4', -1, 'Maximum duration keeping the same allocation', 'integer', fileCfg, varargin{1}); + if simParams.maxRandValueMode4 ~= -1 && simParams.maxRandValueMode4 <= simParams.minRandValueMode4 + error('Error: "simParams.maxRandValueMode4" must be larger than "simParams.minRandValueMode4"'); + end - % [dynamicPDelta] - % Enables dynamic setting of PDelta - [simParams,varargin]= addNewParam(simParams,'dynamicPDelta',0,'Enables dynamic setting of PDelta','integer',fileCfg,varargin{1}); - if (simParams.dynamicPDelta==1 && phyParams.duplexCV2X~="FD") || (simParams.dynamicPDelta==1 && simParams.FDalgorithm==0) - error('Error: "phyParams.duplexCV2X" must be "FD" or incompatible settings'); - end + % [powerThresholdAutonomous] + % Minimum power threshold to consider a BR as occupied in dBm + [simParams, varargin] = addNewParam(simParams, 'powerThresholdAutonomous', -110, 'Minimum power threshold to consider a BR as occupied in Mode 4, in dBm', 'double', fileCfg, varargin{1}); + if simParams.powerThresholdAutonomous / 2 < -64 || simParams.powerThresholdAutonomous / 2 > -1 || mod(simParams.powerThresholdAutonomous, 2) ~= 0 + error('Error: "simParams.powerThresholdAutonomous" must be between -128 and -2, step 2 dB'); + end + % From dBm to linear + simParams.powerThresholdAutonomous = db2pow(simParams.powerThresholdAutonomous - 30); + + % [minSCIsinr] + % Minimum SINR for a SCI to be correctly decoded + [phyParams, varargin] = addNewParam(phyParams, 'minSCIsinr', 0, 'Minimum SINR for a SCI to be correctly decoded, in dB', 'double', fileCfg, varargin{1}); + phyParams.minSCIsinr = db2pow(phyParams.minSCIsinr); - % [T1autonomousMode] - % Minimum time for the next allocation in ms - % For 5G, T1 is modelled as the sum of Tproc,0 and Tproc,1 - % Tproc,1 must be smaller to 3, 2.5, or 2.25 ms for a SCS of 15, 30, 60 kHz, respectively. - % Tproc,0 is equivalent to 1 ms for a SCS of 15 kHz and 0.50 ms for the rest of SCS configurations. - - if phyParams.muNumerology==0 % 4G and 5G SCS=15 - [simParams,varargin]= addNewParam(simParams,'T1autonomousMode',1,'Minimum time for the next allocation in Autonomous Mode','integer',fileCfg,varargin{1}); - if simParams.T1autonomousMode<1 || simParams.T1autonomousMode>4 - error('Error: "simParams.T1autonomousMode" must be between 1 and 4 in LTE and 5G SCS=15'); + % [asynMode] + % Enables Asynchronous transmitters + [simParams, varargin] = addNewParam(simParams, 'asynMode', 0, 'Enables/Desable Asynchronous transmitters', 'integer', fileCfg, varargin{1}); + if simParams.asynMode ~= 0 && simParams.asynMode ~= 1 + error('Error: "simParams.asynMode" cannot different from 0 or 1'); end - elseif phyParams.muNumerology==1 || phyParams.muNumerology==2 % 5G SCS=30 and 5G SCS=60 - [simParams,varargin]= addNewParam(simParams,'T1autonomousMode',0.5,'Minimum time for the next allocation in Autonomous Mode','double',fileCfg,varargin{1}); - if (simParams.T1autonomousMode<0.5 || simParams.T1autonomousMode>3)&&(phyParams.muNumerology==1) - error('Error: "simParams.T1autonomousMode" must be between 0.5 and 3 in 5G with SCS=30'); - elseif (simParams.T1autonomousMode<0.5 || simParams.T1autonomousMode>2.75)&&(phyParams.muNumerology==2) - error('Error: "simParams.T1autonomousMode" must be between 0.5 and 2.75 in 5G with SCS=60'); + + % [percAsynUser] + % TODO + % if Asynchronous transmitters is active -> sets the percentage of + % Asynchronous users + if simParams.asynMode == 1 + [simParams, varargin] = addNewParam(simParams, 'percAsynUser', 0.2, 'Percentage of asynchronous users', 'double', fileCfg, varargin{1}); + if simParams.percAsynUser < 0 || simParams.percAsynUser > 1 + error('Error: "simParams.percAsynUser" must be within 0 and 1'); + end end - end - - % [T2autonomousMode] - % Maximum time for the next allocation in ms - [simParams,varargin]= addNewParam(simParams,'T2autonomousMode',100,'Maximum time for the next allocation in autonomous mode','integer',fileCfg,varargin{1}); - if simParams.T2autonomousMode<20 || simParams.T2autonomousMode>100 - error('Error: "simParams.T2autonomousMode" must be between 20 and 100 ms in LTE and 5G'); + + % [FDalgorithm] + % Enables different FD algorithm + [simParams, varargin] = addNewParam(simParams, 'FDalgorithm', 0, 'Enables FD algorithm', 'integer', fileCfg, varargin{1}); + if simParams.FDalgorithm ~= 0 && phyParams.PDelta == Inf + error('Error: "phyParams.PDelta" must be defined'); end - - simParams.T1autonomousModeTTIs = simParams.T1autonomousMode*(2^phyParams.muNumerology); % T1 in terms of TTIs - simParams.T2autonomousModeTTIs = simParams.T2autonomousMode*(2^phyParams.muNumerology); % T2 in terms of TTIs - case constants.REASSIGN_BR_RAND_ALLOCATION % RANDOM ALLOCATION - simParams.posError95 = 0; - simParams.sigmaPosError = 0; - simParams.Tupdate = Tbeacon; - simParams.Mreuse=0; - - % [T1autonomousMode] - % Minimum time for the next allocation in ms - % For 5G, T1 is modelled as the sum of Tproc,0 and Tproc,1 - % Tproc,1 must be smaller to 3, 2.5, or 2.25 ms for a SCS of 15, 30, 60 kHz, respectively. - % Tproc,0 is equivalent to 1 ms for a SCS of 15 kHz and 0.50 ms for the rest of SCS configurations. - if hyParams.muNumerologyp == 0 % 4G and 5G SCS=15 - [simParams,varargin]= addNewParam(simParams,'T1autonomousMode',1,'Minimum time for the next allocation in Autonomous Mode','integer',fileCfg,varargin{1}); - if simParams.T1autonomousMode < 1 || simParams.T1autonomousMode > 4 - error('Error: "simParams.T1autonomousMode" must be between 1 and 4 in LTE and 5G SCS=15'); + if simParams.FDalgorithm ~= 0 && phyParams.duplexCV2X ~= "FD" + error('Error: "phyParams.duplexCV2X" must be "FD"'); end - elseif phyParams.muNumerology == 1 || phyParams.muNumerology == 2 % 5G SCS=30 and 5G SCS=60 - [simParams,varargin]= addNewParam(simParams,'T1autonomousMode',0.5,'Minimum time for the next allocation in Autonomous Mode','double',fileCfg,varargin{1}); - if (simParams.T1autonomousMode < 0.5 || simParams.T1autonomousMode > 3)&&(phyParams.muNumerology == 1) - error('Error: "simParams.T1autonomousMode" must be between 0.5 and 3 in 5G with SCS=30'); - elseif (simParams.T1autonomousMode < 0.5 || simParams.T1autonomousMode > 2.75)&&(phyParams.muNumerology == 2) - error('Error: "simParams.T1autonomousMode" must be between 0.5 and 2.75 in 5G with SCS=60'); + if ismember(simParams.FDalgorithm, [1, 2]) && phyParams.cv2xNumberOfReplicasMax == 2 + error('Error: "phyParams.cv2xNumberOfReplicasMax" must be equal to 1'); end - end - - % [T2autonomousMode] - % Maximum time for the next allocation in ms - [simParams,varargin]= addNewParam(simParams,'T2autonomousMode',100,'Maximum time for the next allocation in autonomous mode','integer',fileCfg,varargin{1}); - if simParams.T2autonomousMode<20 || simParams.T2autonomousMode>100 + if ismember(simParams.FDalgorithm, [3, 4, 5, 6, 7, 8]) && phyParams.cv2xNumberOfReplicasMax ~= 2 + error('Error: "phyParams.cv2xNumberOfReplicasMax" must be equal to 2'); + end + if simParams.FDalgorithm ~= 0 && simParams.mode5G ~= 1 + error('Error: "simParams.mode5G" must be equal to: 5G-V2X'); + end + + % [dynamicPDelta] + % Enables dynamic setting of PDelta + [simParams, varargin] = addNewParam(simParams, 'dynamicPDelta', 0, 'Enables dynamic setting of PDelta', 'integer', fileCfg, varargin{1}); + if (simParams.dynamicPDelta == 1 && phyParams.duplexCV2X ~= "FD") || (simParams.dynamicPDelta == 1 && simParams.FDalgorithm == 0) + error('Error: "phyParams.duplexCV2X" must be "FD" or incompatible settings'); + end + + % [T1autonomousMode] + % Minimum time for the next allocation in ms + % For 5G, T1 is modelled as the sum of Tproc,0 and Tproc,1 + % Tproc,1 must be smaller to 3, 2.5, or 2.25 ms for a SCS of 15, 30, 60 kHz, respectively. + % Tproc,0 is equivalent to 1 ms for a SCS of 15 kHz and 0.50 ms for the rest of SCS configurations. + + if phyParams.muNumerology == 0 % 4G and 5G SCS=15 + [simParams, varargin] = addNewParam(simParams, 'T1autonomousMode', 1, 'Minimum time for the next allocation in Autonomous Mode', 'integer', fileCfg, varargin{1}); + if simParams.T1autonomousMode < 1 || simParams.T1autonomousMode > 4 + error('Error: "simParams.T1autonomousMode" must be between 1 and 4 in LTE and 5G SCS=15'); + end + elseif phyParams.muNumerology == 1 || phyParams.muNumerology == 2 % 5G SCS=30 and 5G SCS=60 + [simParams, varargin] = addNewParam(simParams, 'T1autonomousMode', 0.5, 'Minimum time for the next allocation in Autonomous Mode', 'double', fileCfg, varargin{1}); + if (simParams.T1autonomousMode < 0.5 || simParams.T1autonomousMode > 3) && (phyParams.muNumerology == 1) + error('Error: "simParams.T1autonomousMode" must be between 0.5 and 3 in 5G with SCS=30'); + elseif (simParams.T1autonomousMode < 0.5 || simParams.T1autonomousMode > 2.75) && (phyParams.muNumerology == 2) + error('Error: "simParams.T1autonomousMode" must be between 0.5 and 2.75 in 5G with SCS=60'); + end + end + + % [T2autonomousMode] + % Maximum time for the next allocation in ms + [simParams, varargin] = addNewParam(simParams, 'T2autonomousMode', 100, 'Maximum time for the next allocation in autonomous mode', 'integer', fileCfg, varargin{1}); + if simParams.T2autonomousMode < 20 || simParams.T2autonomousMode > 100 error('Error: "simParams.T2autonomousMode" must be between 20 and 100 ms in LTE and 5G'); end - simParams.T1autonomousModeTTIs = simParams.T1autonomousMode*(2^phyParams.muNumerology); % T1 in terms of TTIs - simParams.T2autonomousModeTTIs = simParams.T2autonomousMode*(2^phyParams.muNumerology); % T2 in terms of TTIs - case constants.REASSIGN_BR_ORDERED_ALLOCATION % ORDERED ALLOCATION (following X coordinate) - simParams.posError95 = 0; - simParams.sigmaPosError = 0; - simParams.Tupdate = Tbeacon; - simParams.Mreuse=0; - otherwise - error('Error: "simParams.BRAlgorithm" not valid. Algorithm not implemented.'); -end -if ~ismember(simParams.BRAlgorithm, [constants.REASSIGN_BR_STD_MODE_4, constants.REASSIGN_BR_RAND_ALLOCATION]) - if phyParams.BRoverlapAllowed - error('Partial overlap in the frequency domain implemented only for Mode 4 (alg. 18) or Random (101)'); + simParams.T1autonomousModeTTIs = simParams.T1autonomousMode * (2^phyParams.muNumerology); % T1 in terms of TTIs + simParams.T2autonomousModeTTIs = simParams.T2autonomousMode * (2^phyParams.muNumerology); % T2 in terms of TTIs end - if phyParams.cv2xNumberOfReplicasMax > 1 - error('HHARQ implemented only for Mode 4 (alg. 18 and alg. 101)'); + if ~ismember(simParams.BRAlgorithm, [constants.REASSIGN_BR_STD_MODE_4, constants.REASSIGN_BR_RAND_ALLOCATION]) + if phyParams.BRoverlapAllowed + error('Partial overlap in the frequency domain implemented only for Mode 4 (alg. 18) or Random (101)'); + end + + if phyParams.cv2xNumberOfReplicasMax > 1 + error('HHARQ implemented only for Mode 4 (alg. 18 and alg. 101)'); + end end -end -fprintf('\n'); + fprintf('\n'); end diff --git a/MatFilesPosition/addPosDelay.m b/MatFilesPosition/addPosDelay.m index 52c18ce..2f362bc 100644 --- a/MatFilesPosition/addPosDelay.m +++ b/MatFilesPosition/addPosDelay.m @@ -1,29 +1,70 @@ -function [Xvehicle,Yvehicle,PosUpdateIndex] = addPosDelay(Xvehicle,Yvehicle,XvehicleReal,YvehicleReal,IDvehicle,indexNewVehicles,... - indexOldVehicles,indexOldVehiclesToOld,posUpdateAllVehicles,PosUpdatePeriod) -% Update positions of vehicles in the current positioning update period -% (PosUpdatePeriod) - -% Initialize temporary Xvehicle and Yvehicle -Nvehicles = length(IDvehicle); -XvehicleTemp = zeros(Nvehicles,1); -YvehicleTemp = zeros(Nvehicles,1); - -% Position of new vehicles in the scenario immediately updated -XvehicleTemp(indexNewVehicles) = XvehicleReal(indexNewVehicles); -YvehicleTemp(indexNewVehicles) = YvehicleReal(indexNewVehicles); - -% Copy old coordinates to temporary Xvehicle and Yvehicle -XvehicleTemp(indexOldVehicles) = Xvehicle(indexOldVehiclesToOld); -YvehicleTemp(indexOldVehicles) = Yvehicle(indexOldVehiclesToOld); -Xvehicle = XvehicleTemp; -Yvehicle = YvehicleTemp; - -% Find index of vehicles in the scenario whose position will be updated -PosUpdateIndex = find(posUpdateAllVehicles(IDvehicle)==PosUpdatePeriod); - -% Update positions -Xvehicle(PosUpdateIndex) = XvehicleReal(PosUpdateIndex); -Yvehicle(PosUpdateIndex) = YvehicleReal(PosUpdateIndex); - +function [XVehicleEstimated, YVehicleEstimated, XVehicleHistory, YVehicleHistory] = addPosDelay(XVehicle, YVehicle, XVehicleHistory, YVehicleHistory, timeNow, posDelay, posPacketLoss) + arguments (Input) + XVehicle (:, 1) double {mustBeNonNan, mustBeReal} + YVehicle (:, 1) double {mustBeNonNan, mustBeReal} + XVehicleHistory (:, :) cell + YVehicleHistory (:, :) cell + timeNow (1, 1) double {mustBeNonnegative} + posDelay (1, 1) double {mustBeNonnegative} + posPacketLoss (1, 1) double {mustBeNonnegative, mustBeLessThan(posPacketLoss, 1)} + end + arguments (Output) + XVehicleEstimated (:, 1) double {mustBeNonNan, mustBeReal} + YVehicleEstimated (:, 1) double {mustBeNonNan, mustBeReal} + XVehicleHistory (:, :) cell + YVehicleHistory (:, :) cell + end + % preconditions: inputs are equal length + % histories are cells of timetable (not timeseries, because timeseries + % will no longer be viewable in variable editor in a future release) + n_vehicles = numel(YVehicle); + assert(numel(XVehicle) == numel(YVehicle)); + assert(numel(XVehicleHistory) == numel(YVehicleHistory)); + assert(numel(XVehicle) == numel(XVehicleHistory)); + time_now = seconds(timeNow); + % operations on cell arrays unfortunately cannot be vectorized + % it is faster to use forloop than to use cellfun + % initialise output + XVehicleEstimated = zeros(n_vehicles, 1); + YVehicleEstimated = zeros(n_vehicles, 1); + for i = 1:n_vehicles + % copy the data out first to avoid repeated indexing + this_vehicle_x_history = XVehicleHistory{i}; + this_vehicle_y_history = YVehicleHistory{i}; + % just in case + assert(isa(this_vehicle_x_history, 'timetable')); + assert(isa(this_vehicle_y_history, 'timetable')); + % there should only be one variable + assert(width(this_vehicle_x_history) == 1); + assert(width(this_vehicle_y_history) == 1); + % if the timetables are empty, always append + % else, flip coin for packet loss probability, if the inverse case is + % true, add to the history timetable + if isempty(this_vehicle_x_history) || binornd(1, 1 - posPacketLoss) + this_vehicle_x_history{time_now, 1} = XVehicle(i); + this_vehicle_y_history{time_now, 1} = YVehicle(i); + % timetables are value types, so we have to insert it back into the + % cell array + XVehicleHistory{i} = this_vehicle_x_history; + YVehicleHistory{i} = this_vehicle_y_history; + end + % find the best position snapshot + % for simplicity we find the index using the X position table + oldest_valid_snapshot_time = max(this_vehicle_x_history.Properties.RowTimes(this_vehicle_x_history.Properties.RowTimes <= seconds(timeNow - posDelay))); + if isempty(oldest_valid_snapshot_time) + oldest_snapshot = min(this_vehicle_x_history.Properties.RowTimes); + XVehicleEstimated(i) = table2array(this_vehicle_x_history(oldest_snapshot, 1)); + YVehicleEstimated(i) = table2array(this_vehicle_y_history(oldest_snapshot, 1)); + else + XVehicleEstimated(i) = table2array(this_vehicle_x_history(oldest_valid_snapshot_time, 1)); + YVehicleEstimated(i) = table2array(this_vehicle_y_history(oldest_valid_snapshot_time, 1)); + % delete rows that are older than the oldest valid snapshot + this_vehicle_x_history(this_vehicle_x_history.Properties.RowTimes < oldest_valid_snapshot_time, :) = []; + this_vehicle_y_history(this_vehicle_y_history.Properties.RowTimes < oldest_valid_snapshot_time, :) = []; + % timetables are value types, so we have to insert it back into the + % cell array + XVehicleHistory{i} = this_vehicle_x_history; + YVehicleHistory{i} = this_vehicle_y_history; + end + end end - diff --git a/MatFilesUtility/computeDistance.m b/MatFilesUtility/computeDistance.m index 23c8f48..de0ed0d 100644 --- a/MatFilesUtility/computeDistance.m +++ b/MatFilesUtility/computeDistance.m @@ -1,16 +1,7 @@ -function [positionManagement,stationManagement] = computeDistance (simParams,simValues,stationManagement,positionManagement) -% Function derived dividing previous version in computeDistance and -% computeNeighbors (version 5.6.0) - - -% Compute distance matrix +function [positionManagement] = computeDistance (positionManagement) +% Operates on struct members XvehicleReal, YvehicleReal, XvehicleEstimated, +% YvehiclesEstimated to populate struct members distanceReal, +% distanceEstimated positionManagement.distanceReal = sqrt((positionManagement.XvehicleReal - positionManagement.XvehicleReal').^2+(positionManagement.YvehicleReal - positionManagement.YvehicleReal').^2); -%if simParams.technology ~= 2 && ... % not only 11p -if sum(stationManagement.vehicleState(stationManagement.activeIDs)==constants.V_STATE_LTE_TXRX)>0 && ... - (simParams.posError95 || positionManagement.NgroupPosUpdate~=1) %LTE - positionManagement.distanceEstimated = sqrt((simValues.XvehicleEstimated - simValues.XvehicleEstimated').^2+(simValues.YvehicleEstimated - simValues.YvehicleEstimated').^2); -else - positionManagement.distanceEstimated = positionManagement.distanceReal; +positionManagement.distanceEstimated = sqrt((positionManagement.XvehicleEstimated - positionManagement.XvehicleEstimated').^2+(positionManagement.YvehicleEstimated - positionManagement.YvehicleEstimated').^2); end - -end \ No newline at end of file diff --git a/MatFilesUtility/computeNeighbors.m b/MatFilesUtility/computeNeighbors.m index 393bf3f..3d01e96 100644 --- a/MatFilesUtility/computeNeighbors.m +++ b/MatFilesUtility/computeNeighbors.m @@ -14,23 +14,29 @@ if sum(stationManagement.vehicleState(stationManagement.activeIDs)==constants.V_STATE_LTE_TXRX)>0 %if simParams.technology~=2 % Not only 11p distanceReal_LTE = positionManagement.distanceReal; + distanceEstimated_LTE = positionManagement.distanceEstimated; % Vehicles from which the received power is below a minimum are set to an infinite distance %distanceReal_LTE(stationManagement.activeIDs,stationManagement.activeIDs) = distanceReal_LTE(stationManagement.activeIDs,stationManagement.activeIDs)./nonNegligibleReceivedPower; % Vehciles that are not LTE are set to an infinite distance distanceReal_LTE(:,(stationManagement.vehicleState(stationManagement.activeIDs)~=100))=Inf; + distanceEstimated_LTE(:,(stationManagement.vehicleState(stationManagement.activeIDs)~=100))=Inf; % The diagonal must be set to 0 distanceReal_LTE(1:1+length(distanceReal_LTE(1,:)):end) = 0; + distanceEstimated_LTE(1:1+length(distanceEstimated_LTE(1,:)):end) = 0; % sort [neighborsDistanceLTE, neighborsIndexLTE] = sort(distanceReal_LTE,2); + [~, neighborsIndexLTE_Estimated] = sort(distanceEstimated_LTE,2); % remove the first element per each raw, which is self neighborsDistanceLTE(:,1) = []; - neighborsIndexLTE(:,1) = []; + neighborsIndexLTE(:,1) = []; + neighborsIndexLTE_Estimated(:,1) = []; neighborsDistanceLTE_ofLTE = neighborsDistanceLTE(stationManagement.vehicleState(stationManagement.activeIDs)==100,:); neighborsIndexLTE_ofLTE = neighborsIndexLTE(stationManagement.vehicleState(stationManagement.activeIDs)==100,:); % Vehicles in order of distance %allNeighborsID = IDvehicle(neighborsIndexLTE); stationManagement.allNeighborsID = stationManagement.activeIDs(neighborsIndexLTE); + stationManagement.allNeighborsIDEstimated = stationManagement.activeIDs(neighborsIndexLTE_Estimated); % Vehicles in the maximum awareness range stationManagement.neighborsIDLTE = (neighborsDistanceLTE_ofLTE < phyParams.RawMaxCV2X) .*stationManagement.activeIDs(neighborsIndexLTE_ofLTE); @@ -102,4 +108,4 @@ end %% -end \ No newline at end of file +end diff --git a/Tests/+v2xsim_tests/+unit/+position/test_addPosDelay.m b/Tests/+v2xsim_tests/+unit/+position/test_addPosDelay.m new file mode 100644 index 0000000..7fc44f9 --- /dev/null +++ b/Tests/+v2xsim_tests/+unit/+position/test_addPosDelay.m @@ -0,0 +1,94 @@ +function tests = test_addPosDelay + % only include functions that begin with the name "test" + idx = cellfun(@(f) startsWith(func2str(f), 'test'), localfunctions); + fs = localfunctions; + tests = functiontests(fs(idx)); +end + +function testNoDelay(testCase) + % test that if the posDelay is 0, the positions should not be delayed at + % all, regardless of the time + for time_now = [0 1 100] + [X_real, Y_real] = mockVehiclePositionData(100); + [X_history, Y_history] = mockVehiclePositionHistory(100); + [X_est, Y_est, ~, ~] = addPosDelay(X_real, Y_real, X_history, Y_history, time_now, 0, 0); + verifyEqual(testCase, X_est, X_real); + verifyEqual(testCase, Y_est, Y_real); + end +end + +function testFiniteDelayReturnsOldestDataForTimesBeforeDelay(testCase) + % for the edge case where posDelay > 0 and timeNow <= posDelay, assert that + % the positions returned is always the oldest one + posDelay = 3; + [X_init, Y_init] = mockVehiclePositionData(100); + [X_history, Y_history] = mockVehiclePositionHistory(100); + [~, ~, X_history, Y_history] = addPosDelay(X_init, Y_init, X_history, Y_history, 0, 3, 0); + for time_now = linspace(0.1, 2.9, 10) + [X_real, Y_real] = mockVehiclePositionData(100); + [X_est, Y_est, X_history, Y_history] = addPosDelay(X_real, Y_real, X_history, Y_history, time_now, posDelay, 0); + verifyEqual(testCase, X_est, X_init); + verifyEqual(testCase, Y_est, Y_init); + end +end + +function testFiniteDelayReturnsDelayedData(testCase) + % eventually, when timeNow > posDelay, return snapshots of positions at least posDelay + % seconds ago + posDelay = 3; + X_real_cell = cell(6, 1); + Y_real_cell = cell(6, 1); + for i = 1:6 + [X_t, Y_t] = mockVehiclePositionData(100); + X_real_cell{i} = X_t; + Y_real_cell{i} = Y_t; + end + [X_history, Y_history] = mockVehiclePositionHistory(100); + for time_now = 1:6 + X_real = X_real_cell{time_now}; + Y_real = Y_real_cell{time_now}; + [X_est, Y_est, X_history, Y_history] = addPosDelay(X_real, Y_real, X_history, Y_history, time_now, posDelay, 0); + if time_now > 3 + X_pos_delay_ago = X_real_cell{time_now - posDelay}; + Y_pos_delay_ago = Y_real_cell{time_now - posDelay}; + verifyEqual(testCase, X_est, X_pos_delay_ago); + verifyEqual(testCase, Y_est, Y_pos_delay_ago); + end + end +end + +function testNonzeroPacketLossResultsInTimetablesOfVaryingHeights(testCase) + % When there is packet loss, the height of the history tables should not be + % the same. Test with 100 vehicles, 50% loss chance, 10 position updates. + % This test has a very, very small chance of producing a false failure. + % P(Binomial(100*10, 0.5)=0) = 9.33E-302 + % If this test fails on you, you should probably take a break and ponder + % what did you do to offend the RNG machines of the universe. + posDelay = 3; + [X_history, Y_history] = mockVehiclePositionHistory(100); + for time_now = linspace(0, 5, 10) + [X_real, Y_real] = mockVehiclePositionData(100); + [~, ~, X_history, Y_history] = addPosDelay(X_real, Y_real, X_history, Y_history, time_now, posDelay, 0.5); + end + history_table_heights = unique(cellfun(@height, X_history)); + verifyEqual(testCase, numel(history_table_heights) ~= 1, true); +end + +function [X, Y] = mockVehiclePositionData(n_vehicles) + % creates a mock vehicle position data + arguments + n_vehicles (1, 1) double {mustBeInteger mustBePositive} + end + X = rand(n_vehicles, 1) .* 1000; + Y = rand(n_vehicles, 1) .* 1000; +end + +function [X_history, Y_history] = mockVehiclePositionHistory(n_vehicles) + % creates mock vehicle position timetable (empty) + X_history = cell(n_vehicles, 1); + Y_history = cell(n_vehicles, 1); + for i = 1:n_vehicles + X_history{i} = timetable(Size = [0 1], VariableTypes = {'double'}, TimeStep = seconds(0.1)); + Y_history{i} = timetable(Size = [0 1], VariableTypes = {'double'}, TimeStep = seconds(0.1)); + end +end From 4e99b43d3e66b000c0926eb57a4f342b9e2651bc Mon Sep 17 00:00:00 2001 From: Chester Koh Date: Fri, 20 Oct 2023 21:35:54 +0800 Subject: [PATCH 08/11] fix typo in class member of constants class --- MatFilesInit/constants.m | 2 +- MatFilesInit/initiateBRAssignmentAlgorithm.m | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/MatFilesInit/constants.m b/MatFilesInit/constants.m index 2fb3b97..9111aab 100644 --- a/MatFilesInit/constants.m +++ b/MatFilesInit/constants.m @@ -157,7 +157,7 @@ constants.REASSIGN_BR_POW_CONTROL constants.REASSIGN_BR_MIN_REUSE_POW constants.REASSIGN_BR_ORDERED_ALLOCATION]; - REASSIGN_BR_ALOGRITHMS_AUTONOMOUS = [constants.REASSIGN_BR_STD_MODE_4 + REASSIGN_BR_ALGORITHMS_AUTONOMOUS = [constants.REASSIGN_BR_STD_MODE_4 constants.REASSIGN_BR_RAND_ALLOCATION]; %% **************************************** %% CHANNEL MODEL diff --git a/MatFilesInit/initiateBRAssignmentAlgorithm.m b/MatFilesInit/initiateBRAssignmentAlgorithm.m index 07faacc..a42db9a 100644 --- a/MatFilesInit/initiateBRAssignmentAlgorithm.m +++ b/MatFilesInit/initiateBRAssignmentAlgorithm.m @@ -24,7 +24,7 @@ % 101 -> RANDOM ALLOCATION % 102 -> ORDERED ALLOCATION (following X coordinate) - implementedAlgorithms = [constants.REASSIGN_BR_ALGORITHMS_CONTROLLED ; constants.REASSIGN_BR_ALOGRITHMS_AUTONOMOUS]; + implementedAlgorithms = [constants.REASSIGN_BR_ALGORITHMS_CONTROLLED ; constants.REASSIGN_BR_ALGORITHMS_AUTONOMOUS]; [simParams, varargin] = addNewParam(simParams, 'BRAlgorithm', constants.REASSIGN_BR_STD_MODE_4, 'Assignment algorithm', 'integer', fileCfg, varargin{1}); if ~ismember(simParams.BRAlgorithm, implementedAlgorithms) From 651156641c87685222f4715cb50266144cd9043a Mon Sep 17 00:00:00 2001 From: Chester Koh Date: Mon, 23 Oct 2023 13:20:00 +0800 Subject: [PATCH 09/11] fix wrong bounds check for simParams.posPacketLoss --- MatFilesInit/initiateBRAssignmentAlgorithm.m | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/MatFilesInit/initiateBRAssignmentAlgorithm.m b/MatFilesInit/initiateBRAssignmentAlgorithm.m index a42db9a..da1c146 100644 --- a/MatFilesInit/initiateBRAssignmentAlgorithm.m +++ b/MatFilesInit/initiateBRAssignmentAlgorithm.m @@ -50,7 +50,7 @@ % [posPacketLoss] [simParams, varargin] = addNewParam(simParams, 'posPacketLoss', 0, 'V2NB Positioning Signal Packet Loss Probability (only controlled BR algorithms)', 'double', fileCfg, varargin{1}); - if simParams.posPacketLoss <= 0 || simParams.posPacketLoss < 1 + if simParams.posPacketLoss < 0 || simParams.posPacketLoss > 1 error('Error: "simParams.posPacketLoss must be 0 <= p < 1'); end From 8fa1a46a291ebb142162c4d9e95d4d569eaf4cdb Mon Sep 17 00:00:00 2001 From: Chester Koh Date: Mon, 23 Oct 2023 13:59:40 +0800 Subject: [PATCH 10/11] fix wrong constant name --- MainFilesCV2X/mainCV2XttiEnds.m | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/MainFilesCV2X/mainCV2XttiEnds.m b/MainFilesCV2X/mainCV2XttiEnds.m index 9d83377..96b37a0 100644 --- a/MainFilesCV2X/mainCV2XttiEnds.m +++ b/MainFilesCV2X/mainCV2XttiEnds.m @@ -53,7 +53,7 @@ % TODO not checked in version 5.X %% Radio Resources Reassignment - if ismember(simParams.BRAlgorithm, constants.CONTROLLED_ALGORITHMS) + if ismember(simParams.BRAlgorithm, constants.REASSIGN_BR_ALGORITHMS_CONTROLLED) if timeManagement.elapsedTime_TTIs > 0 % Current scheduled reassign period From 8dcbdcb81a1a3a6984498b8b3f6d35f8cc783242 Mon Sep 17 00:00:00 2001 From: Chester Koh Date: Mon, 22 Apr 2024 14:54:00 +0800 Subject: [PATCH 11/11] rudimentary support for dynamic vehicle entry and exit in traffic trace --- MainFiles/mainInit.m | 23 +-- MainFiles/mainPositionUpdate.m | 42 +++-- MainFiles/mainV2X.m | 7 +- MainFilesCV2X/elaborateFateRxCV2X.m | 16 +- MainFilesCV2X/initLastPowerCV2X.m | 4 +- MainFilesCV2X/mainCV2XttiStarts.m | 2 +- .../initiateMainSimulationParameters.m | 12 -- MatFilesPosition/checkVehicleBounds.m | 23 +++ MatFilesPosition/initVehiclePositions.m | 25 ++- MatFilesPosition/interpolateTrace.m | 123 --------------- MatFilesPosition/loadTrafficTrace.m | 146 +++--------------- .../updateDistanceChangeForShadowing.m | 35 +++-- MatFilesPosition/updatePositionFile.m | 80 +++------- .../BRreassignmentRandom.m | 6 +- .../CV2XsensingProcedure.m | 8 +- MatFilesSINR/computeChannelGain.m | 67 +++++--- MatFilesUtility/computeNeighbors.m | 83 +++++----- Simulations_test_trace.m | 36 +---- 18 files changed, 252 insertions(+), 486 deletions(-) create mode 100644 MatFilesPosition/checkVehicleBounds.m delete mode 100644 MatFilesPosition/interpolateTrace.m diff --git a/MainFiles/mainInit.m b/MainFiles/mainInit.m index 3a28430..76fcc98 100644 --- a/MainFiles/mainInit.m +++ b/MainFiles/mainInit.m @@ -4,8 +4,7 @@ %% Init of active vehicles and states % Move IDvehicle from simValues to station Management -stationManagement.activeIDs = simValues.IDvehicle; -simValues = rmfield(simValues,'IDvehicle'); +stationManagement.activeIDs = []; % The simulation starts at time '0' timeManagement.timeNow = 0; @@ -54,6 +53,8 @@ stationManagement.activeIDsCV2X = stationManagement.activeIDsCV2X(stationManagement.activeIDsCV2X>0); stationManagement.activeIDs11p = stationManagement.activeIDs.*(stationManagement.vehicleState(stationManagement.activeIDs)~=constants.V_STATE_LTE_TXRX); stationManagement.activeIDs11p = stationManagement.activeIDs11p(stationManagement.activeIDs11p>0); +stationManagement.activeIDsEnter = []; +stationManagement.activeIDsExit = []; stationManagement.indexInActiveIDs_ofLTEnodes = zeros(length(stationManagement.activeIDsCV2X),1); for i=1:length(stationManagement.activeIDsCV2X) stationManagement.indexInActiveIDs_ofLTEnodes(i) = find(stationManagement.activeIDs==stationManagement.activeIDsCV2X(i)); @@ -64,7 +65,7 @@ end %% Number of vehicles at the current time -outputValues.Nvehicles = length(stationManagement.activeIDs); +outputValues.Nvehicles = simValues.maxID; outputValues.NvehiclesTOT = outputValues.NvehiclesTOT + outputValues.Nvehicles; outputValues.NvehiclesLTE = outputValues.NvehiclesLTE + length(stationManagement.activeIDsCV2X); outputValues.Nvehicles11p = outputValues.Nvehicles11p + length(stationManagement.activeIDs11p); @@ -227,7 +228,7 @@ % Computation of the channel gain % 'dUpdate': vector used for the calculation of correlated shadowing -dUpdate = zeros(outputValues.Nvehicles,outputValues.Nvehicles); +dUpdate = zeros(0, 0); [sinrManagement,simValues.Xmap,simValues.Ymap,phyParams.LOS] = computeChannelGain(sinrManagement,stationManagement,positionManagement,phyParams,simParams,dUpdate); % Update of the neighbors @@ -405,7 +406,7 @@ timeManagement.timeNextCV2X = inf; % if not only 11p -if ismember(constants.V_STATE_LTE_TXRX, stationManagement.vehicleState(stationManagement.activeIDs)) +if ismember(constants.V_STATE_LTE_TXRX, stationManagement.vehicleState) % Initialization of resouce allocation algorithms in LTE-V2X if ismember(simParams.BRAlgorithm, [constants.REASSIGN_BR_REUSE_DIS_SCHEDULED_VEH,... constants.REASSIGN_BR_MAX_REUSE_DIS, constants.REASSIGN_BR_MIN_REUSE_POW]) @@ -453,11 +454,11 @@ % Must be ordered with respect to the packet generation instant % (Vittorio 5.5.3) % subframeGen = ceil(timeManagement.timeNextPacket/phyParams.Tsf); - TTIGen = ceil(timeManagement.timeNextPacket/phyParams.TTI); - TTI_BR = ceil(stationManagement.BRid/appParams.NbeaconsF); - stationManagement.BRid = stationManagement.BRid + (TTI_BR<=TTIGen) * appParams.Nbeacons; - stationManagement.BRid = sort(stationManagement.BRid,2); - stationManagement.BRid = stationManagement.BRid - (stationManagement.BRid>appParams.Nbeacons) * appParams.Nbeacons; + TTIGen = ceil(timeManagement.timeNextPacket(stationManagement.activeIDs)/phyParams.TTI); + TTI_BR = ceil(stationManagement.BRid(stationManagement.activeIDs)/appParams.NbeaconsF); + stationManagement.BRid(stationManagement.activeIDs) = stationManagement.BRid(stationManagement.activeIDs) + (TTI_BR<=TTIGen) * appParams.Nbeacons; + stationManagement.BRid(stationManagement.activeIDs) = sort(stationManagement.BRid(stationManagement.activeIDs),2); + stationManagement.BRid(stationManagement.activeIDs) = stationManagement.BRid(stationManagement.activeIDs) - (stationManagement.BRid(stationManagement.activeIDs)>appParams.Nbeacons) * appParams.Nbeacons; % vector correctSCImatrixCV2X created stationManagement.correctSCImatrixCV2X = []; @@ -491,7 +492,7 @@ % of the first TTI in 0 timeManagement.timeNextCV2X = 0; timeManagement.ttiCV2Xstarts = true; - + % The channel busy ratio of C-V2X is initialized sinrManagement.cbrCV2X = zeros(simValues.maxID,1); sinrManagement.cbrLTE_coexLTEonly = zeros(simValues.maxID,1); diff --git a/MainFiles/mainPositionUpdate.m b/MainFiles/mainPositionUpdate.m index 29ca675..15d706b 100644 --- a/MainFiles/mainPositionUpdate.m +++ b/MainFiles/mainPositionUpdate.m @@ -6,20 +6,28 @@ % Call function to update vehicles positions [indexNewVehicles,indexOldVehicles,indexOldVehiclesToOld,stationManagement.activeIDsExit,positionManagement] = updatePosition(timeManagement.timeNow,stationManagement.activeIDs,simParams.positionTimeResolution,positionManagement,simValues,outParams,simParams); else - % Store IDs of vehicles at the previous beacon period and update positions - [positionManagement.XvehicleReal,positionManagement.YvehicleReal,stationManagement.activeIDs,indexNewVehicles,indexOldVehicles,indexOldVehiclesToOld,stationManagement.activeIDsExit,positionManagement.v,positionManagement.direction] = updatePositionFile( ... - round(timeManagement.timeNextPosUpdate,2), ... - simValues.dataTrace,stationManagement.activeIDs, ... - positionManagement.XvehicleReal,positionManagement.YvehicleReal, ... - round(timeManagement.timeNextPosUpdate,2)-simParams.positionTimeResolution,simValues,outParams); - %% ONLY LTE - if sum(stationManagement.vehicleState(stationManagement.activeIDs)==100)>0 - %if simParams.technology ~= 2 % not only 11p - % Update stationManagement.BRid vector (variable number of vehicles in the scenario) - [stationManagement.BRid] = updateBRidFile(stationManagement.BRid,stationManagement.activeIDs,indexNewVehicles); - end + % Interpolate position of all vehicles from current trace file + [positions] = updatePositionFile(simValues.trafficTraceTimetable, timeManagement.timeNow, simValues.IDvehicle); + positionManagement.XvehicleReal = positions.X; + positionManagement.YvehicleReal = positions.Y; + positionManagement.v = positions.V; + positionManagement.direction = NaN(height(positions)); + + old_active_ids = stationManagement.activeIDs; + % Mark vehicles coming in and out of bounds as active/inactive + [activeIds, enteredVehicles, exitedVehicles] = checkVehicleBounds(positions, stationManagement.activeIDs, ... + "XMin", simParams.XminTrace, "XMax", simParams.XmaxTrace, "YMin", simParams.YminTrace, "YMax", simParams.YmaxTrace); + indexNewVehicles = find(ismember(activeIds, enteredVehicles)); + indexOldVehicles = find(~ismember(activeIds, enteredVehicles)); + oldVehicles = activeIds(indexOldVehicles); + [~ , indexOldVehiclesToOld] = ismember(oldVehicles, old_active_ids); + stationManagement.activeIDs = activeIds; + stationManagement.activeIDsExit = exitedVehicles; + stationManagement.activeIDsEnter = enteredVehicles; + stationManagement.indexOldVehiclesToOld = indexOldVehiclesToOld; end + % Vectors IDvehicleLTE and IDvehicle11p are updated stationManagement.activeIDsCV2X = stationManagement.activeIDs.*(stationManagement.vehicleState(stationManagement.activeIDs)==100); stationManagement.activeIDsCV2X = stationManagement.activeIDsCV2X(stationManagement.activeIDsCV2X>0); @@ -86,7 +94,7 @@ % Call function to update positionManagement.distance matrix where D(i,j) is the % change in positionManagement.distance of link i to j from time n-1 to time n and used % for updating Shadowing matrix -[dUpdate,sinrManagement.Shadowing_dB,positionManagement.distanceRealOld] = updateDistanceChangeForShadowing(positionManagement.distanceReal,positionManagement.distanceRealOld,indexOldVehicles,indexOldVehiclesToOld,sinrManagement.Shadowing_dB,phyParams.stdDevShadowLOS_dB); +[dUpdate,sinrManagement.Shadowing_dB,positionManagement.distanceRealOld] = updateDistanceChangeForShadowing(positionManagement.distanceReal,positionManagement.distanceRealOld,phyParams.stdDevShadowLOS_dB, activeIds, enteredVehicles, exitedVehicles); % Calculation of channel and then received power [sinrManagement,simValues.Xmap,simValues.Ymap,phyParams.LOS] = computeChannelGain(sinrManagement,stationManagement,positionManagement,phyParams,simParams,dUpdate); @@ -237,6 +245,14 @@ stationManagement.pckNextAttempt(stationManagement.activeIDsExit) = 1; stationManagement.pckTxOccurring(stationManagement.activeIDsExit) = 0; +% resize stationManagement.hasTransmissionThisSlot +new_hasTransmissionThisSlot = zeros(numel(stationManagement.activeIDs), 1); +new_hasTransmissionThisSlot(indexOldVehicles) = stationManagement.hasTransmissionThisSlot(indexOldVehiclesToOld); +stationManagement.hasTransmissionThisSlot = new_hasTransmissionThisSlot; + +% Relinquish the BR for vehicles who exited +stationManagement.BRid(stationManagement.activeIDsExit) = -2; + %% CBR settings for the new vehicles if simParams.cbrActive && (outParams.printCBR || (simParams.technology==constants.TECH_COEX_STD_INTERF && simParams.coexMethod~=constants.COEX_METHOD_NON && simParams.coex_slotManagement==constants.COEX_SLOT_DYNAMIC)) timeManagement.cbr11p_timeStartMeasInterval(stationManagement.activeIDs(indexNewVehicles)) = timeManagement.timeNow; diff --git a/MainFiles/mainV2X.m b/MainFiles/mainV2X.m index be9a261..83e4e8f 100644 --- a/MainFiles/mainV2X.m +++ b/MainFiles/mainV2X.m @@ -30,6 +30,9 @@ % indexEvent is the index of the vector IDvehicle % idEvent is the ID of the vehicle of the current event [timeEvent, indexEvent] = min(timeManagement.timeNextEvent(stationManagement.activeIDs)); + if isempty(timeEvent) + timeEvent = timeManagement.timeNextPosUpdate; + end idEvent = stationManagement.activeIDs(indexEvent); % If the next C-V2X event is earlier than timeEvent, set the time to the @@ -56,7 +59,7 @@ % to the position update % With LTE, it must necessarily be done after the end of a subframe and % before the next one - if timeEvent >= (timeManagement.timeNextPosUpdate-1e-9) && ... + if any(timeEvent >= (timeManagement.timeNextPosUpdate-1e-9)) && ... (isempty(stationManagement.activeIDsCV2X) || (isfield(timeManagement, "ttiCV2Xstarts") && timeManagement.ttiCV2Xstarts==true)) timeEvent = timeManagement.timeNextPosUpdate; end @@ -195,7 +198,7 @@ %printDebugEvents(timeEvent,'LTE subframe starts',-1); %fprintf('Starts\n'); - if timeManagement.timeNow>0 + if timeManagement.timeNow > 0 && any(setdiff(stationManagement.activeIDsCV2X, stationManagement.activeIDsEnter)) [phyParams,simValues,outputValues,sinrManagement,stationManagement,timeManagement] = ... mainCV2XttiEnds(appParams,simParams,phyParams,outParams,simValues,outputValues,timeManagement,positionManagement,sinrManagement,stationManagement); end diff --git a/MainFilesCV2X/elaborateFateRxCV2X.m b/MainFilesCV2X/elaborateFateRxCV2X.m index a8f419e..bd3a42f 100644 --- a/MainFilesCV2X/elaborateFateRxCV2X.m +++ b/MainFilesCV2X/elaborateFateRxCV2X.m @@ -3,7 +3,10 @@ % transmissions % [ID TX, ID RX, BRid, distance] -distance = positionManagement.distanceReal(stationManagement.vehicleState(stationManagement.activeIDs)==100,stationManagement.vehicleState(stationManagement.activeIDs)==100); +LTEIndices = find(stationManagement.vehicleState == constants.V_STATE_LTE_TXRX); +ActiveIndices = stationManagement.activeIDs; +ActiveLTEIndices = intersect(LTEIndices, ActiveIndices); +distance = positionManagement.distanceReal(ActiveLTEIndices, ActiveLTEIndices); Ntx = length(IDvehicleTXLTE); % Number of tx vehicles %resultingList = zeros(Ntx*length(neighborsID(1,:)),5); % Initialize error matrix @@ -15,13 +18,6 @@ end for i = 1:Ntx - - %if IDvehicleTXLTE(i)==39 - % fp = fopen('Temp.txt','a'); - % fprintf(fp,'T=%f: new tx, attemmpt %d\n',timeManagement.timeNow,stationManagement.pckTxOccurring(IDvehicleTXLTE(i))); - % fclose(fp); - %end - % Find indexes of receiving vehicles in neighborsID indexNeighborsRX = find(neighborsID(indexVehicleTX(i),:)); @@ -53,7 +49,7 @@ resultingList(indexRaw,1) = IDvehicleTXLTE(i); resultingList(indexRaw,2) = IDvehicleRX; resultingList(indexRaw,3) = stationManagement.BRid(IDvehicleTXLTE(i),stationManagement.pckTxOccurring(IDvehicleTXLTE(i))); - resultingList(indexRaw,4) = distance(indexVehicleTX(i),stationManagement.activeIDsCV2X==IDvehicleRX); + resultingList(indexRaw,4) = distance(indexVehicleTX(i), IDvehicleRX); resultingList(indexRaw,5) = 1; % COLUMN 5=1 IS "CORRECT" % Mark that this packet has been received stationManagement.pckReceived(IDvehicleRX,IDvehicleTXLTE(i))=1; @@ -67,7 +63,7 @@ resultingList(indexRaw,1) = IDvehicleTXLTE(i); resultingList(indexRaw,2) = IDvehicleRX; resultingList(indexRaw,3) = stationManagement.BRid(IDvehicleTXLTE(i),stationManagement.pckTxOccurring(IDvehicleTXLTE(i))); - resultingList(indexRaw,4) = distance(indexVehicleTX(i),stationManagement.activeIDsCV2X==IDvehicleRX); + resultingList(indexRaw,4) = distance(indexVehicleTX(i), IDvehicleRX); resultingList(indexRaw,5) = 0; % COLUMN 5=0 IS "ERROR" elseif ~isinf(phyParams.Ksi) || isempty(find(IDvehicleTXLTE == IDvehicleRX, 1)) % ERROR IN ATTEMPT (NOT THE LAST ONE) AND THE RECEIVER IS NOT diff --git a/MainFilesCV2X/initLastPowerCV2X.m b/MainFilesCV2X/initLastPowerCV2X.m index 0a3f855..9d74f90 100644 --- a/MainFilesCV2X/initLastPowerCV2X.m +++ b/MainFilesCV2X/initLastPowerCV2X.m @@ -51,7 +51,7 @@ % ID rx vehicle IDrx = stationManagement.neighborsIDLTE(stationManagement.indexInActiveIDsOnlyLTE_OfTxLTE(i_tx),j_neigh); - RxPowerIDrx = RXpower_MHz_ofLTE(stationManagement.activeIDsCV2X==IDrx,stationManagement.indexInActiveIDsOnlyLTE_OfTxLTE); + RxPowerIDrx = RXpower_MHz_ofLTE(IDrx,stationManagement.indexInActiveIDsOnlyLTE_OfTxLTE); % Find BRT in use by rx vehicle j %BRTrx = BRidT(IDrx); @@ -120,4 +120,4 @@ % sinrManagement.neighPowerInterfLastLTE(i_tx,j_neigh) = (selfI + Itot) * phyParams.BwMHz_cv2xBR + Ifrom11p; end end -end \ No newline at end of file +end diff --git a/MainFilesCV2X/mainCV2XttiStarts.m b/MainFilesCV2X/mainCV2XttiStarts.m index 14c039c..aa486a7 100644 --- a/MainFilesCV2X/mainCV2XttiStarts.m +++ b/MainFilesCV2X/mainCV2XttiStarts.m @@ -42,7 +42,7 @@ end end % hasTransmissionThisSlot introduced from version 6.2 -stationManagement.hasTransmissionThisSlot(stationManagement.transmittingIDsCV2X)=1; +stationManagement.hasTransmissionThisSlot(find(ismember(stationManagement.activeIDsCV2X, stationManagement.transmittingIDsCV2X))) = 1; %% timeManagement.timeGeneratedPacketInTxLTE(stationManagement.transmittingIDsCV2X) = timeManagement.timeLastPacket(stationManagement.transmittingIDsCV2X); diff --git a/MatFilesInit/initiateMainSimulationParameters.m b/MatFilesInit/initiateMainSimulationParameters.m index d0ccd06..048cb27 100644 --- a/MatFilesInit/initiateMainSimulationParameters.m +++ b/MatFilesInit/initiateMainSimulationParameters.m @@ -178,30 +178,18 @@ % [XminTrace] % Minimum X coordinate to keep in the traffic trace (m) [simParams,varargin] = addNewParam(simParams,'XminTrace',-1,'Minimum X coordinate to keep in the traffic trace (m)','double',fileCfg,varargin{1}); - if simParams.XminTrace~=-1 && simParams.XminTrace<0 - error('Error: the value set for "simParams.XminTrace" is not valid'); - end % [XmaxTrace] % Maximum X coordinate to keep in the traffic trace (m) [simParams,varargin] = addNewParam(simParams,'XmaxTrace',-1,'Maximum X coordinate to keep in the traffic trace (m)','double',fileCfg,varargin{1}); - if simParams.XmaxTrace~=-1 && simParams.XmaxTrace<0 && simParams.XmaxTrace= NameValueArguments.XMin) & (VehiclePositions.X < NameValueArguments.XMax); + indices_in_y_bounds = (VehiclePositions.Y >= NameValueArguments.YMin) & (VehiclePositions.Y < NameValueArguments.YMax); + activeIds = VehiclePositions.Vehicle(indices_in_x_bounds & indices_in_y_bounds); + enteredIds = setdiff(activeIds, PreviouslyActiveIds); + exitedIds = setdiff(PreviouslyActiveIds, activeIds); +end + diff --git a/MatFilesPosition/initVehiclePositions.m b/MatFilesPosition/initVehiclePositions.m index 3468d6f..14ff26b 100644 --- a/MatFilesPosition/initVehiclePositions.m +++ b/MatFilesPosition/initVehiclePositions.m @@ -188,23 +188,18 @@ % Call function to load the traffic trace up to the selected simulation % time and, if selected, take only a portion of the scenario - [dataLoaded,simParams] = loadTrafficTrace(simParams); - - % Call function to interpolate the traffic trace (if needed) - [simValues,simParams] = interpolateTrace(dataLoaded,simParams,appParams.allocationPeriod); - - % Round time column (representation format) - simValues.dataTrace(:,1) = round(simValues.dataTrace(:,1), 2); - - % Find trace details (Xmin,Xmax,Ymin,Ymax,maxID) - positionManagement.Xmin = min(simValues.dataTrace(:,3)); % Min X coordinate Trace - positionManagement.Xmax = max(simValues.dataTrace(:,3)); % Max X coordinate Trace - positionManagement.Ymin = min(simValues.dataTrace(:,4)); % Min Y coordinate Trace - positionManagement.Ymax = max(simValues.dataTrace(:,4)); % Max Y coordinate Trace - simValues.maxID = max(simValues.dataTrace(:,2)); % Maximum vehicle's ID + [trafficTraceTimetable] = loadTrafficTrace(simParams.filenameTrace, "Duration", simParams.simulationTime); + simValues.maxID = max(trafficTraceTimetable.Vehicle); % Maximum vehicle's ID + simValues.IDvehicle = (1:simValues.maxID)'; + simValues.trafficTraceTimetable = trafficTraceTimetable; + % Call function to read vehicle positions from file at time zero - [positionManagement.XvehicleReal, positionManagement.YvehicleReal, simValues.IDvehicle, ~,~,~,~,positionManagement.v,positionManagement.direction] = updatePositionFile(0,simValues.dataTrace,[],-1,-1,-1,simValues,[]); + [positions] = updatePositionFile(trafficTraceTimetable, 0, simValues.IDvehicle); + positionManagement.XvehicleReal = positions.X; + positionManagement.YvehicleReal = positions.Y; + positionManagement.v = positions.V; + positionManagement.direction = NaN(height(positions)); end diff --git a/MatFilesPosition/interpolateTrace.m b/MatFilesPosition/interpolateTrace.m deleted file mode 100644 index 339309a..0000000 --- a/MatFilesPosition/interpolateTrace.m +++ /dev/null @@ -1,123 +0,0 @@ -function [simValues,simParams] = interpolateTrace(dataOrig,simParams,Tbeacon) -% This function interpolates the input traffic trace with the desired output -% time interval -% Inputs: the original file 'dataOrig' and the desired interval 'simValues.timeResolution' -% Outputs: the interpolated file -% The input file should be in the form of rows with four columns indicating -% 1) the time instant, 2) the vehicle ID, 3) its x-position, 4) its -% y-position -% The position of each vehicle is expected to be updated every time -% interval; such time interval must be constant and is derived by the function -% internally -% The output file has the same format -% If a vehicle is present only in one instant in the input file, that -% vehicle is neglected in the output -% The time interval set for the output should be an integer fraction of -% the input interal, and is adjusted otherwise; if it is not smaller than the -% interval of the input time, then the input file is returned directly - -if simParams.positionTimeResolution deltaTorig - simValues.timeResolution = simParams.positionTimeResolution; - simValues.dataTrace = dataOrig; - return; -end - -% The time interval set for the output should be an integer fraction of -% the input interval, and is adjusted otherwise using the ceil function -interpFactor = round(deltaTorig/simParams.positionTimeResolution); -if simParams.positionTimeResolution*interpFactor < deltaTorig-1e-9 || simParams.positionTimeResolution*interpFactor > deltaTorig+1e-9 - error('Error in interpolateTrace. Attempt to interpolate not with an integer number: deltaTorig=%.2f, positionTimeResolution=%.2f',deltaTorig,simParams.positionTimeResolution); -end -simValues.timeResolution = deltaTorig/interpFactor; -simParams.positionTimeResolution = simValues.timeResolution; - -% If the output time interval is not smaller than the interval of the input -% time, then the input file is returned directly -if interpFactor==1 - simValues.dataTrace = dataOrig; - return; -end - -fprintf('Interpolating Trace File\n'); - -tic - -% Vectors are set to speed up processing -t = dataOrig(:,1); -id = dataOrig(:,2); -xV = dataOrig(:,3); -yV = dataOrig(:,4); - -% For speed reasons, the output matrix is initialized larger than needed -% It will be later reduced to what strictly required -n = length(id); -dataAll = zeros(interpFactor * n,4); - -% Cycle among the vehicles in the trace -startIndex = 1; -for idToCheck = min(dataOrig(:,2)):max(dataOrig(:,2)) - - % IDs of vehicles that are not present or only compare in one instant - % are skipped - if nnz(dataOrig(:,2)==idToCheck)>1 - % Vectors that focus on a specific vehicle - tCheck = t(id==idToCheck); - xCheck = xV(id==idToCheck); - yCheck = yV(id==idToCheck); - - % Vectors related to those instants when the vehicle does not move - movingV = (xCheck(2:end)-xCheck(1:end-1))~=0 | (yCheck(2:end)-yCheck(1:end-1))~=0; - indexes = find(movingV==0); - - % This if considers the case when a vehicle never moves - if nnz(movingV)>0 - % Interpolation, excluding those instants when the vehicle does not move - tparz=tCheck(1):tCheck(nnz(movingV)+1); - xparz=[xCheck(movingV~=0); xCheck(end)]; - yparz=[yCheck(movingV~=0); yCheck(end)]; - tq = tparz(1):simValues.timeResolution:tparz(end); - xq = interp1(tparz,xparz,tq,'spline'); - yq = interp1(tparz,yparz,tq,'spline'); - else - % Initializations of xq and yq if the vehicle never moves - xq = xCheck(end); - yq = yCheck(end); - end - - % Re-addition of the instants when the vehicle does not move , with - % the output time interval - for i=1:length(indexes) - xq = [xq(1:(indexes(i)-1)*interpFactor) xq((indexes(i)-1)*interpFactor+1)*ones(1,interpFactor) xq((indexes(i)-1)*interpFactor+1:end)]; - yq = [yq(1:(indexes(i)-1)*interpFactor) yq((indexes(i)-1)*interpFactor+1)*ones(1,interpFactor) yq((indexes(i)-1)*interpFactor+1:end)]; - end - tq = tCheck(1):simValues.timeResolution:tCheck(end); - - % Concatenation to the previous vehicles - endIndex = startIndex + length(tq) - 1; - dataAll(startIndex:endIndex,1) = tq; - dataAll(startIndex:endIndex,2) = idToCheck; - dataAll(startIndex:endIndex,3) = xq; - dataAll(startIndex:endIndex,4) = yq; - startIndex = endIndex+1; - end -end -% Removal of null lines in dataAll (dataAll was initialized to larger than -% needed for speed purposes) -delIndex = (dataAll(:,2)==0); -dataAll(delIndex,:) = []; -% Sort of the output file along the time (it was sorted along the vehicle ID) -simValues.dataTrace = sortrows(dataAll,1); - -toc - -end \ No newline at end of file diff --git a/MatFilesPosition/loadTrafficTrace.m b/MatFilesPosition/loadTrafficTrace.m index 29fe41a..3eb6b78 100644 --- a/MatFilesPosition/loadTrafficTrace.m +++ b/MatFilesPosition/loadTrafficTrace.m @@ -1,128 +1,28 @@ -function [dataOut,simParams] = loadTrafficTrace(simParams) -% This function loads the traffic trace and if needed reduces it in time -% and space (both X and Y axis -% Input: 1) name of the file, 2) duration of the simulation, 3) minimum X -% to be simulated, 4) maximum X to be simulated, 5) minimum Y -% to be simulated, 6) maximum Y to be simulated -% Output: a matrix with the traffic trace -% If any of the input limitations (in time or space) is set to -1, then no -% limitation is assumed; for example, if the minimum X is set to -1, then -% the traffic trace is not reduced in the minimum X -% Note: if in the new trace a vehicle exits the scenario and later returns -% in it, then it is treated as two different vehicles; for this reason, the -% IDs of the original vehicles may not correspond to the IDs of the output -% trace - -% Store input value of the simulation time in duration -duration = simParams.simulationTime; - -fprintf('Loading Trace File\n'); - -tic - -% The full traffic trace is loaded -dataIn = load(simParams.filenameTrace); - -% The input time interval is derived from the input file -deltaTorig = max(dataIn(2:end,1)-dataIn(1:end-1,1)); - -% Check if time in input is shorter than time resolution in the trace file -if simParams.simulationTimemaxTime - fprintf('Simulation time exceeds maximum time in the trace file: '); - duration = maxTime; - fprintf('set to %.1fs\n', maxTime); -end - -% If the simulation time is not -1, then the trace is reduced in time -if simParams.simulationTime~=-1 - dataIn = dataIn(dataIn(:,1)<=duration,:); -end - -% The input time interval is derived from the input file -deltaT = max(dataIn(2:end,1)-dataIn(1:end-1,1)); - -% If the min X field is not -1, then the trace is reduced -if simParams.XminTrace~=-1 - dataIn = dataIn(dataIn(:,3)>=simParams.XminTrace,:); -end - -% If the max X field is not -1, then the trace is reduced -if simParams.XmaxTrace~=-1 - dataIn = dataIn(dataIn(:,3)<=simParams.XmaxTrace,:); -end - -% If the min Y field is not -1, then the trace is reduced -if simParams.YminTrace~=-1 - dataIn = dataIn(dataIn(:,4)>=simParams.YminTrace,:); -end - -% If the max Y field is not -1, then the trace is reduced -if simParams.YmaxTrace~=-1 - dataIn = dataIn(dataIn(:,4)<=simParams.YmaxTrace,:); -end - -% The data matrix is saved in vectors to speed up processing -t = dataIn(:,1); -id = dataIn(:,2); -xV = dataIn(:,3); -yV = dataIn(:,4); -if length(dataIn(1,:))>4 - vV = dataIn(:,5); -end - -% The output matrix is initialized with the correct size -dataAll = zeros(length(dataIn(:,1)),length(dataIn(1,:))); +function [trafficTraceTimetable] = loadTrafficTrace(TraceFileName, NameValueArgs) + arguments (Input) + TraceFileName (1, 1) string + NameValueArgs.Duration (1, 1) double {mustBePositive} = inf + end -% Cycle among the vehicles in the trace -% The IDs of output vehicles are sequential and start from 1 -startIndex = 1; -outputID = 1; -for idToCheck = min(dataIn(:,2)):max(dataIn(:,2)) - % IDs of vehicles that are not present are skipped - if nnz(dataIn(:,2)==idToCheck)>0 - % Vectors that focus on a specific vehicle - tCheck = t(id==idToCheck); - xCheck = xV(id==idToCheck); - yCheck = yV(id==idToCheck); - if length(dataIn(1,:))>4 - vCheck = vV(id==idToCheck); - end - - % Vectors related to possible events where a vehicle exits the - % scenario and later returns in the scenario - outAndIn = (tCheck(2:end)-tCheck(1:end-1))>deltaT; - indexesStart = [1; find(outAndIn==1)+1]; - indexesEnd = [find(outAndIn==1); length(tCheck)]; - for i=1:length(indexesStart) - % Concatenation to the previous vehicles - endIndex = startIndex + indexesEnd(i) - indexesStart(i); - dataAll(startIndex:endIndex,1) = tCheck(indexesStart(i):indexesEnd(i)); - dataAll(startIndex:endIndex,2) = outputID; - dataAll(startIndex:endIndex,3) = xCheck(indexesStart(i):indexesEnd(i)); - dataAll(startIndex:endIndex,4) = yCheck(indexesStart(i):indexesEnd(i)); - if length(dataIn(1,:))>4 - dataAll(startIndex:endIndex,5) = vCheck(indexesStart(i):indexesEnd(i)); - end - startIndex = endIndex+1; - % The ID of the next vehicle is updated - outputID = outputID+1; - end + arguments (Output) + trafficTraceTimetable (:, 4) timetable end -end -% The output file is sorted along the time column (it was sorted along the vehicle ID) -dataOut = sortrows(dataAll,1); -% Update value of the simulation time -simParams.simulationTime = duration; + t = readtable(TraceFileName); + if width(t) == 4 + t.Properties.VariableNames = ["Time", "Vehicle", "X", "Y"]; + t.V = NaN(height(t), 1); + elseif width(t) == 5 + t.Properties.VariableNames = ["Time", "Vehicle", "X", "Y", "V"]; + else + error("Trace file has %d columns, unknown format", width(t)); + end -toc + % Drop rows longer than duration + t(t.Time > NameValueArgs.Duration, :) = []; + + % Convert the first column to duration vector + t.Time = seconds(t.Time); -end \ No newline at end of file + trafficTraceTimetable = table2timetable(t, "RowTimes", "Time"); +end diff --git a/MatFilesPosition/updateDistanceChangeForShadowing.m b/MatFilesPosition/updateDistanceChangeForShadowing.m index 94e6589..db5631b 100644 --- a/MatFilesPosition/updateDistanceChangeForShadowing.m +++ b/MatFilesPosition/updateDistanceChangeForShadowing.m @@ -1,21 +1,38 @@ -function [dUpdate,S,distanceRealOld] = updateDistanceChangeForShadowing(distanceReal,distanceRealOld,indexOldVehicles,indexOldVehiclesToOld,Shadowing_dB,stdDevShadowLOS_dB) +function [dUpdate,S,distanceRealOld] = updateDistanceChangeForShadowing(distanceReal,distanceRealOld,stdDevShadowLOS_dB, activeVehicles, enteredVehicles, exitedVehicles) % This function calculates the difference of the distance between two % vehicles w.r.t. the previous instant and it updates the % shadowing matrix removing vehicles out of the scenario and ordering % indices +arguments (Input) + distanceReal (:, :) double {mustBeReal, mustBeNonempty} % current distance matrix, always size of max vehicles + distanceRealOld (:, :) double {mustBeReal, mustBeNonempty} % previous distance matrix, always size of max vehicles + stdDevShadowLOS_dB (1, 1) double {mustBeReal} % physical parameter + activeVehicles (:, 1) double {mustBeReal, mustBePositive} % currently active vehicles + enteredVehicles (:, 1) double {mustBeReal, mustBePositive} % vehicles that just entered in this epoch + exitedVehicles (:, 1) double {mustBeReal, mustBePositive} % vehicles that just exited in this epoch +end +arguments (Output) + dUpdate (:, :) double {mustBeReal} % change in position, max_vehicles size, diagonal must be 0 + S (:, :) double {mustBeReal} % change in shadowing, max_vehicles size + distanceRealOld (:, :) double {mustBeReal, mustBeNonempty} % return the current distance matrix +end -Nvehicles = length(distanceReal(:,1)); -dUpdate = zeros(Nvehicles,Nvehicles); -S = randn(Nvehicles,Nvehicles)*stdDevShadowLOS_dB; - +% sanity check - the global state matrices must have the correct size +if size(distanceReal) ~= size(distanceRealOld) + error("Matrices do not have the correct size") +end +max_vehicles = width(distanceReal); +S = randn(max_vehicles, max_vehicles)*stdDevShadowLOS_dB; % Update distance matrix -dUpdate(indexOldVehicles,indexOldVehicles) = abs(distanceReal(indexOldVehicles,indexOldVehicles)-distanceRealOld(indexOldVehiclesToOld,indexOldVehiclesToOld)); - -% Update shadowing matrix -S(indexOldVehicles,indexOldVehicles) = Shadowing_dB(indexOldVehiclesToOld,indexOldVehiclesToOld); +dUpdate = abs(distanceReal - distanceRealOld); % Update distanceRealOld for next snapshot distanceRealOld = distanceReal; +% sanity check - diagonals must be 0 +if any(diag(dUpdate)) + error("dUpdate's diagonal is not all 0") +end + end diff --git a/MatFilesPosition/updatePositionFile.m b/MatFilesPosition/updatePositionFile.m index 464993c..4881a90 100644 --- a/MatFilesPosition/updatePositionFile.m +++ b/MatFilesPosition/updatePositionFile.m @@ -1,64 +1,28 @@ -function [XvehicleReal,YvehicleReal,IDvehicle,indexNewVehicles,indexOldVehicles,indexOldVehiclesToOld,IDvehicleExit,speedNow, direction] = updatePositionFile(time,dataTrace,oldIDvehicle,XvehiclePrevious,YvehiclePrevious,timePrevious,simValues,outParams) -% Update position of vehicles from file - -%XvehiclePrevious = XvehicleReal; -%YvehiclePrevious = YvehicleReal; -tPrevious = find(dataTrace(:,1)4 - speedNow = dataTrace(fileIndex,5); -end - -% Sort IDvehicle, XvehicleReal and YvehicleReal by IDvehicle -[IDvehicle,indexOrder] = sort(IDvehicle); -XvehicleReal = XvehicleReal(indexOrder); -YvehicleReal = YvehicleReal(indexOrder); -if length(dataTrace(1,:))>4 - speedNow = speedNow(indexOrder); -else - speedNow = (((YvehicleReal - YvehiclePrevious).^2 + (XvehicleReal - XvehiclePrevious).^2).^0.5) / (time-tPrevious); -end - -direction = complex((XvehicleReal - XvehiclePrevious),(YvehicleReal - YvehiclePrevious))'; - -[~,indexNewVehicles] = setdiff(IDvehicle,oldIDvehicle,'stable'); - -% Find IDs of vehicles that are exiting the scenario -IDvehicleExit = setdiff(oldIDvehicle,IDvehicle); - -% Find indices of vehicles in IDvehicle that are both in IDvehicle and OldIDvehicle -indexOldVehicles = find(ismember(IDvehicle,oldIDvehicle)); - -% Find indices of vehicles in OldIDvehicle that are both in IDvehicle and OldIDvehicle -indexOldVehiclesToOld = find(ismember(oldIDvehicle,IDvehicle)); +function [positions] = updatePositionFile(TrafficTraceTimetable, AtTime, VehicleIds) + arguments (Input) + TrafficTraceTimetable (:, 4) timetable + AtTime (1, 1) double {mustBeReal, mustBeNonnegative} + VehicleIds (:, 1) double {mustBeReal, mustBePositive} + end -%figure(1) -%plot(XvehicleReal,YvehicleReal,'p'); + arguments (Output) + positions (:, 4) table + end -if length(dataTrace(1,:))==4 - speedNow = zeros(length(IDvehicle),1); - for i=1:length(IDvehicle) - iOld = find(oldIDvehicle==IDvehicle(i)); - if ~isempty(iOld) - speedNow(i) = sqrt((XvehicleReal(i)-XvehiclePrevious(iOld)).*(XvehicleReal(i)-XvehiclePrevious(iOld)) + ... - (YvehicleReal(i)-YvehiclePrevious(iOld)).*(YvehicleReal(i)-YvehiclePrevious(iOld)))/(time-timePrevious); - %else - % speedNow(i) = 0; + n_vehicles = numel(VehicleIds); + X = zeros(n_vehicles, 1); + Y = zeros(n_vehicles, 1); + V = NaN(n_vehicles, 1); + for i = 1:n_vehicles + vehicle = VehicleIds(i); + subtable = TrafficTraceTimetable(TrafficTraceTimetable.Vehicle == vehicle, :); + if isempty(subtable) + continue end - - % if IDvehicle(i)==1 - % figure(2) - % plot(time,speedNow(i),'pr'); - % hold on - % end + X(i) = interp1(subtable.Properties.RowTimes, subtable.X, seconds(AtTime), 'linear', 0); + Y(i) = interp1(subtable.Properties.RowTimes, subtable.Y, seconds(AtTime), 'linear', 0); end -end -% Print speed (if enabled) -if ~isempty(outParams) && outParams.printSpeed - printSpeedToFile(time,IDvehicle,speedNow,simValues.maxID,outParams); + positions = table(VehicleIds, X, Y, V, ... + 'VariableNames', ["Vehicle", "X", "Y", "V"]); end diff --git a/MatFilesResourceAllocationCV2X/BRreassignmentRandom.m b/MatFilesResourceAllocationCV2X/BRreassignmentRandom.m index 2a97e2b..3c6f91a 100644 --- a/MatFilesResourceAllocationCV2X/BRreassignmentRandom.m +++ b/MatFilesResourceAllocationCV2X/BRreassignmentRandom.m @@ -10,10 +10,10 @@ end % Was simParams.T1autonomousModeTTIs, simParams.T2autonomousModeTTIs -Nvehicles = length(IDvehicle(:,1)); % Number of vehicles +Nvehicles = numel(IDvehicle); % Number of vehicles % This part considers various limitations -BRid = zeros(length(IDvehicle(:,1)),1); +BRid = zeros(Nvehicles,1); % A cycle over the vehicles is needed for idV=1:Nvehicles if stationManagement.vehicleState(IDvehicle(idV))~=constants.V_STATE_LTE_TXRX @@ -62,4 +62,4 @@ Nreassign = Nvehicles; -end \ No newline at end of file +end diff --git a/MatFilesResourceAllocationCV2X/CV2XsensingProcedure.m b/MatFilesResourceAllocationCV2X/CV2XsensingProcedure.m index d4e3a2b..d2710b5 100644 --- a/MatFilesResourceAllocationCV2X/CV2XsensingProcedure.m +++ b/MatFilesResourceAllocationCV2X/CV2XsensingProcedure.m @@ -50,12 +50,16 @@ % Possible addition of 11p interfrence if simParams.technology~=constants.TECH_COEX_STD_INTERF || simParams.coexMethod~=constants.COEX_METHOD_C || ~simParams.coexC_11pDetection interfFrom11p = (sinrManagement.coex_averageTTIinterfFrom11pToLTE(stationManagement.activeIDsCV2X)); - sensedPowerCurrentTTI_MHz = sensedPowerCurrentTTI_MHz + repmat(interfFrom11p',appParams.NbeaconsF,1); + % note: repmat refuses to produce a nFx0 matrix in the special case + % where there are no active vehicles, so the resize is there to force it to be + % of a compatible size with the nFx0 sensed power matrix. it should + % have no effect at all other times when there is at least one vehicle. + sensedPowerCurrentTTI_MHz = sensedPowerCurrentTTI_MHz + resize(repmat(interfFrom11p',appParams.NbeaconsF, any(stationManagement.activeIDsCV2X)), size(sensedPowerCurrentTTI_MHz)); else % In case of method C, 11p interference is not added if an 11p % transmission has been detected interfFrom11p = (sinrManagement.coex_averageTTIinterfFrom11pToLTE(stationManagement.activeIDsCV2X)) .* ~sinrManagement.coex_lteDetecting11pTx(stationManagement.activeIDsCV2X); - sensedPowerCurrentTTI_MHz = sensedPowerCurrentTTI_MHz + repmat(interfFrom11p',appParams.NbeaconsF,1); + sensedPowerCurrentTTI_MHz = sensedPowerCurrentTTI_MHz + resize(repmat(interfFrom11p',appParams.NbeaconsF, any(stationManagement.activeIDsCV2X)), size(sensedPowerCurrentTTI_MHz)); sinrManagement.coex_lteDetecting11pTx(:,:) = false; end diff --git a/MatFilesSINR/computeChannelGain.m b/MatFilesSINR/computeChannelGain.m index 64c0c08..544905c 100644 --- a/MatFilesSINR/computeChannelGain.m +++ b/MatFilesSINR/computeChannelGain.m @@ -1,9 +1,32 @@ function [sinrManagement,X,Y,LOS] = computeChannelGain(sinrManagement,stationManagement,positionManagement,phyParams,simParams,dUpdate) % Compute received power and create RXpower matrix +arguments (Input) + sinrManagement + % uses: Shadowing_dB size is max_size + stationManagement + positionManagement + % uses: phyParams.P_ERP_MHz_CV2X size is global + phyParams + simParams + dUpdate (:, :) double {mustBeReal} % size is max_size +end +arguments (Output) + sinrManagement + % updates: Shadowing_dB P_RX_MHz + X + Y + LOS % size is n_active +end %% Initialization -distance = positionManagement.distanceReal; -Nvehicles = length(distance(:,1)); % Number of vehicles +activeIds = stationManagement.activeIDs; +distance = positionManagement.distanceReal(activeIds, activeIds); +direction = positionManagement.direction(activeIds); +Xreal = positionManagement.XvehicleReal(activeIds); +Yreal = positionManagement.YvehicleReal(activeIds); +Nvehicles = numel(activeIds); % Number of vehicles +oldShadowing_dB = sinrManagement.Shadowing_dB(activeIds, activeIds); +dUpdate = dUpdate(activeIds, activeIds); LOS = ones(Nvehicles,Nvehicles); if phyParams.channelModel>0 %~phyParams.winnerModel A = ones(Nvehicles,Nvehicles); @@ -12,7 +35,7 @@ %% Calculation of NLOSv PNLOSv=10.^(0.69); %6.9 dB are assumed for each vehicle, following ETSI TR 103 257 if phyParams.channelModel==constants.CH_5G_NLOSV % 5G - NLOSv = calculateNLOSv(positionManagement.XvehicleReal, positionManagement.YvehicleReal); + NLOSv = calculateNLOSv(positionManagement.XvehicleReal(activeIds), positionManagement.YvehicleReal(activeIds)); else NLOSv = zeros(Nvehicles,Nvehicles); end @@ -27,25 +50,23 @@ if simParams.typeOfScenario==constants.SCENARIO_URBAN % ETSI-Urban D1 = zeros(Nvehicles,Nvehicles); C = zeros(Nvehicles,Nvehicles); - horizontal=abs(real(positionManagement.direction)); - vertical=abs(imag(positionManagement.direction)); + horizontal=abs(real(direction)); + vertical=abs(imag(direction)); D_corr = 10; % Decorrelation distance for the shadowing calculation for i = 1:Nvehicles - if positionManagement.XvehicleReal(i)~=Inf + if Xreal(i)~=Inf for j = i+1:Nvehicles - if positionManagement.XvehicleReal(j)~=Inf - - LOS(i,j)=horizontal(i)*horizontal(j)*(abs(positionManagement.YvehicleReal(i)-positionManagement.YvehicleReal(j))<20)+... - vertical(i)*vertical(j)*(abs(positionManagement.XvehicleReal(i)-positionManagement.XvehicleReal(j))<20)+... - horizontal(i)*vertical(j)*((abs(positionManagement.XvehicleReal(i)-positionManagement.XvehicleReal(j)))<10)*... - ((abs(positionManagement.YvehicleReal(j)-positionManagement.YvehicleReal(i)))<10)+... - vertical(i)*horizontal(j)*((abs(positionManagement.XvehicleReal(i)-positionManagement.XvehicleReal(j)))<10)*... - ((abs(positionManagement.YvehicleReal(j)-positionManagement.YvehicleReal(i)))<10); + if Xreal(j)~=Inf + LOS(i,j)=horizontal(i)*horizontal(j)*(abs(Yreal(i)-Yreal(j))<20)+... + vertical(i)*vertical(j)*(abs(Xreal(i)-Xreal(j))<20)+... + horizontal(i)*vertical(j)*((abs(Xreal(i)-Xreal(j)))<10)*... + ((abs(Yreal(j)-Yreal(i)))<10)+... + vertical(i)*horizontal(j)*((abs(Xreal(i)-Xreal(j)))<10)*... + ((abs(Yreal(j)-Yreal(i)))<10); LOS(j,i)=LOS(i,j); - D1(i,j)=horizontal(i)*(abs(positionManagement.XvehicleReal(i)-positionManagement.XvehicleReal(j)))+... - vertical(i)*(abs(positionManagement.YvehicleReal(i)-positionManagement.YvehicleReal(j))); + D1(i,j)=horizontal(i)*(abs(Xreal(i)-Xreal(j)))+... + vertical(i)*(abs(Yreal(i)-Yreal(j))); C(i,j)=vertical(i)*horizontal(j)+vertical(j)*horizontal(i); %crossing between i and j - end end end @@ -61,9 +82,9 @@ % Compute attenuation due to walls and buildings for i = 1:Nvehicles - if positionManagement.XvehicleReal(i)~=Inf + if Xreal(i)~=Inf for j = i+1:Nvehicles - if positionManagement.XvehicleReal(j)~=Inf + if Xreal(j)~=Inf [Nwalls,Nsteps,granularity] = computeGrid(X(i),Y(i),X(j),Y(j),positionManagement.StepMap,positionManagement.GridMap,phyParams.channelModel); if phyParams.channelModel==0 %phyParams.winnerModel LOS(i,j) = 1-(Nwalls>0); @@ -132,7 +153,7 @@ newShadowing_dB = randn(Nvehicles,Nvehicles).*(LOS*phyParams.stdDevShadowLOS_dB + (~LOS)*(phyParams.stdDevShadowNLOS_dB)); % Calculation of correlated shadowing matrix - newShadowingMatrix = exp(-dUpdate/D_corr).*sinrManagement.Shadowing_dB + sqrt( 1-exp(-2*dUpdate/D_corr) ).*newShadowing_dB; + newShadowingMatrix = exp(-dUpdate/D_corr).*oldShadowing_dB + sqrt( 1-exp(-2*dUpdate/D_corr) ).*newShadowing_dB; Shadowing_dB = triu(newShadowingMatrix,1)+triu(newShadowingMatrix)'; Shadowing = 10.^(Shadowing_dB/10); @@ -152,8 +173,8 @@ % Compute RXpower % NOTE: sinrManagement.P_RX_MHz( RECEIVER, TRANSMITTER) -sinrManagement.P_RX_MHz = ( (phyParams.P_ERP_MHz_CV2X(stationManagement.activeIDs).*(stationManagement.vehicleState(stationManagement.activeIDs)==100))' + ... - (phyParams.P_ERP_MHz_11p(stationManagement.activeIDs).*(stationManagement.vehicleState(stationManagement.activeIDs)~=100) )' )... +sinrManagement.P_RX_MHz = ( (phyParams.P_ERP_MHz_CV2X(stationManagement.activeIDs).*(stationManagement.vehicleState(stationManagement.activeIDs)==constants.V_STATE_LTE_TXRX))' + ... + (phyParams.P_ERP_MHz_11p(stationManagement.activeIDs).*(stationManagement.vehicleState(stationManagement.activeIDs)~=constants.V_STATE_LTE_TXRX) )' )... * phyParams.Gr .* (min(1,CHgain) .* sinrManagement.mcoCoefficient(stationManagement.activeIDs,stationManagement.activeIDs)); -end \ No newline at end of file +end diff --git a/MatFilesUtility/computeNeighbors.m b/MatFilesUtility/computeNeighbors.m index 3d01e96..b6559a8 100644 --- a/MatFilesUtility/computeNeighbors.m +++ b/MatFilesUtility/computeNeighbors.m @@ -11,59 +11,52 @@ %% % LTE %distanceReal_LTE = positionManagement.distanceReal(:,(stationManagement.vehicleState(stationManagement.activeIDs)==100)); -if sum(stationManagement.vehicleState(stationManagement.activeIDs)==constants.V_STATE_LTE_TXRX)>0 -%if simParams.technology~=2 % Not only 11p - distanceReal_LTE = positionManagement.distanceReal; - distanceEstimated_LTE = positionManagement.distanceEstimated; - % Vehicles from which the received power is below a minimum are set to an infinite distance - %distanceReal_LTE(stationManagement.activeIDs,stationManagement.activeIDs) = distanceReal_LTE(stationManagement.activeIDs,stationManagement.activeIDs)./nonNegligibleReceivedPower; - % Vehciles that are not LTE are set to an infinite distance - distanceReal_LTE(:,(stationManagement.vehicleState(stationManagement.activeIDs)~=100))=Inf; - distanceEstimated_LTE(:,(stationManagement.vehicleState(stationManagement.activeIDs)~=100))=Inf; - % The diagonal must be set to 0 - distanceReal_LTE(1:1+length(distanceReal_LTE(1,:)):end) = 0; - distanceEstimated_LTE(1:1+length(distanceEstimated_LTE(1,:)):end) = 0; - % sort - [neighborsDistanceLTE, neighborsIndexLTE] = sort(distanceReal_LTE,2); - [~, neighborsIndexLTE_Estimated] = sort(distanceEstimated_LTE,2); - % remove the first element per each raw, which is self - neighborsDistanceLTE(:,1) = []; - neighborsIndexLTE(:,1) = []; - neighborsIndexLTE_Estimated(:,1) = []; - neighborsDistanceLTE_ofLTE = neighborsDistanceLTE(stationManagement.vehicleState(stationManagement.activeIDs)==100,:); - neighborsIndexLTE_ofLTE = neighborsIndexLTE(stationManagement.vehicleState(stationManagement.activeIDs)==100,:); +if any(stationManagement.vehicleState == constants.V_STATE_LTE_TXRX) + % Find vehicle indices that are using LTE and in active state + LTEIndices = find(stationManagement.vehicleState == constants.V_STATE_LTE_TXRX); + ActiveIndices = stationManagement.activeIDs; + ActiveLTEIndices = intersect(LTEIndices, ActiveIndices); + n_activeLTE = numel(ActiveLTEIndices); + + if n_activeLTE ~= 0 + % distance of LTE vehicles to every other vehicle + distanceReal_LTE = positionManagement.distanceReal(ActiveLTEIndices, ActiveIndices); + distanceEstimated_LTE = positionManagement.distanceEstimated(ActiveLTEIndices, ActiveIndices); - % Vehicles in order of distance - %allNeighborsID = IDvehicle(neighborsIndexLTE); - stationManagement.allNeighborsID = stationManagement.activeIDs(neighborsIndexLTE); - stationManagement.allNeighborsIDEstimated = stationManagement.activeIDs(neighborsIndexLTE_Estimated); + % sort + [neighborsDistanceLTE, neighborsIndexLTE] = sort(distanceReal_LTE,2); + [~, neighborsIndexLTE_Estimated] = sort(distanceEstimated_LTE,2); + % remove the first element per each raw, which is self + neighborsDistanceLTE(:,1) = []; + neighborsIndexLTE(:,1) = []; + neighborsIndexLTE_Estimated(:,1) = []; + + % Vehicle Indices in order of distance - LTE to everything + stationManagement.allNeighborsID = neighborsIndexLTE; + stationManagement.allNeighborsIDEstimated = neighborsIndexLTE_Estimated; - % Vehicles in the maximum awareness range - stationManagement.neighborsIDLTE = (neighborsDistanceLTE_ofLTE < phyParams.RawMaxCV2X) .*stationManagement.activeIDs(neighborsIndexLTE_ofLTE); + % Vehicle Indices in order of distance - LTE to LTE + neighborsDistanceLTE_ofLTE = neighborsDistanceLTE; + neighborsIndexLTE_ofLTE = neighborsIndexLTE; + neighborsIndexLTE_ofLTE_mask = ismember(neighborsIndexLTE_ofLTE, ~LTEIndices); + neighborsIndexLTE_ofLTE(neighborsIndexLTE_ofLTE_mask) = []; + neighborsDistanceLTE_ofLTE(neighborsIndexLTE_ofLTE_mask) = []; + % neighborsIndexLTE_ofLTE = reshape(neighborsIndexLTE_ofLTE, n_activeLTE, n_activeLTE); + % neighborsDistanceLTE_ofLTE = reshape(neighborsDistanceLTE_ofLTE, n_activeLTE, n_activeLTE); - % Vehicles in awareness range - if ~isempty(stationManagement.neighborsIDLTE) - stationManagement.awarenessIDLTE = zeros(length(neighborsDistanceLTE_ofLTE(:,1)),length(neighborsDistanceLTE_ofLTE(1,:)),length(phyParams.Raw)); + % Vehicles in the maximum awareness range - LTE to LTE + stationManagement.neighborsIDLTE = (neighborsDistanceLTE_ofLTE < phyParams.RawMaxCV2X) .* neighborsIndexLTE_ofLTE; + % Vehicles in varying awareness range - LTE to LTE + stationManagement.awarenessIDLTE = zeros(n_activeLTE, n_activeLTE - 1, numel(phyParams.Raw)); for iPhyRaw=1:length(phyParams.Raw) stationManagement.awarenessIDLTE(:,:,iPhyRaw) = (neighborsDistanceLTE_ofLTE < phyParams.Raw(iPhyRaw)) .* stationManagement.neighborsIDLTE; end - end - - % Removal of nodes that are not active - stationManagement.neighborsIDLTE = stationManagement.neighborsIDLTE(:,1:length(stationManagement.activeIDsCV2X)-1); - if ~isempty(stationManagement.neighborsIDLTE) - stationManagement.awarenessIDLTE = stationManagement.awarenessIDLTE(:,1:length(stationManagement.activeIDsCV2X)-1,:); else - stationManagement.awarenessIDLTE = []; + stationManagement.allNeighborsID = zeros(0, 0); + stationManagement.allNeighborsIDEstimated = zeros(0, 0); + stationManagement.neighborsIDLTE = zeros(0, 0); + stationManagement.awarenessIDLTE = zeros(0, 0, numel(phyParams.Raw)); end - %stationManagement.neighborsDistanceLTE = stationManagement.neighborsDistanceLTE(:,1:length(stationManagement.activeIDsCV2X)-1); - - % LTE vehicles interfering 11p - %if simParams.technology > 2 - % neighborsDistanceLTE_of11p = neighborsDistanceLTE(stationManagement.vehicleState(stationManagement.activeIDs)~=100,:); - % neighborsIndexLTE_of11p = neighborsIndexLTE(stationManagement.vehicleState(stationManagement.activeIDs)~=100,:); - % %stationManagement.LTEinterfereingTo11p_ID = (neighborsDistanceLTE_of11p < phyParams.RawMaxCV2X) .*stationManagement.activeIDs(neighborsIndexLTE_of11p); - %end end %% diff --git a/Simulations_test_trace.m b/Simulations_test_trace.m index aef53a1..277b65d 100644 --- a/Simulations_test_trace.m +++ b/Simulations_test_trace.m @@ -9,41 +9,9 @@ clear % Reset variables clc % Clear the command window -packetSize=1000; % 1000B packet size -nTransm=1; % Number of transmission for each packet -sizeSubchannel=10; % Number of Resource Blocks for each subchannel -Raw = 50; % Range of Awarness for evaluation of metrics -speed=70; % Average speed -speedStDev=7; % Standard deviation speed -SCS=15; % Subcarrier spacing [kHz] -pKeep=0.4; % keep probability -periodicity=0.1; % periodic generation every 100ms -sensingThreshold=-126; % threshold to detect resources as busy - % Configuration file -configFile = 'test_trace.cfg'; - - -%% NR-V2X PERIODIC GENERATION -BandMHz = 10; -MCS = 11; -rho = 100; % number of vehicles/km -simTime=10; % simTime=300 - -% related path, change your related path below -path_task = fileparts(mfilename("fullpath")); -dirTraceFile = fullfile(fileparts(path_task), "TrafficTraces", "Bologna", "BolognaAPositions.txt"); -outputFolder = fullfile(path_task, 'Output', 'test_trace'); +configFile = 'Bologna.cfg'; % Launches simulation WiLabV2Xsim(configFile,... - 'outputFolder',outputFolder, "filenameTrace", dirTraceFile,... - 'Technology','5G-V2X', 'MCS_NR',MCS, 'SCS_NR',SCS, 'beaconSizeBytes',packetSize,... - 'simulationTime',simTime, 'probResKeep',pKeep, 'BwMHz',BandMHz,... - 'cv2xNumberOfReplicasMax',nTransm,... - 'allocationPeriod',periodicity, 'sizeSubchannel',sizeSubchannel,... - 'powerThresholdAutonomous',sensingThreshold, 'Raw',Raw,'FixedPdensity',false,... - 'dcc_active',false,'cbrActive',true) - - - + 'cbrActive',false);