diff --git a/lab_5/lab_5.m b/lab_5/lab_5.m index 299030a..3820884 100644 --- a/lab_5/lab_5.m +++ b/lab_5/lab_5.m @@ -13,12 +13,17 @@ satConfig.orbitPropagator = "two-body-keplerian"; groundStation.Lat = 52.515744683039436; groundStation.Lon = 13.325825073341306; groundStation.Name = "HFT building at Einsteinufer 25"; + +% below altitude was taken from: % https://www.randymajors.org/elevation-on-google-maps?x=13.3258251&y=52.5157447&cx=13.3258251&cy=52.5157447&zoom=15&labels=show groundStation.Altitude = 37; -calc_task1 = true; -calc_task2 = true; -calc_task3 = true; +% configure which task should be calculated +calc_task1 = false; +calc_task2 = false; +calc_task3 = false; +calc_task4 = false; +calc_task4_4 = true; if calc_task1 task1; @@ -40,4 +45,10 @@ if calc_task3 end task3; end - \ No newline at end of file + +if calc_task4 || calc_task4_4 + only_define_baseline_vars = true; + task2; + only_define_baseline_vars = false; + task4; +end \ No newline at end of file diff --git a/lab_5/leo_satellite_pass.md b/lab_5/leo_satellite_pass.md index 4a8bd17..4cb9c16 100644 --- a/lab_5/leo_satellite_pass.md +++ b/lab_5/leo_satellite_pass.md @@ -1,3 +1,11 @@ + +

Lab 5 - Wireless Networking Technologies

@@ -187,6 +195,8 @@ requiredAntennaGain = max(requiredTxPower - amplifiedTxPower, 0); With the 30dB amplifier, the remaining required antenna gain is between 30.99dB and 57.54dB. + + ### Task3 #### 3.1 @@ -209,6 +219,22 @@ The blue line shows the Doppler shift returned by MATLAB's `dopplershift` functi In this scenario, Doppler shift can support localization because it constrains the relative radial motion between satellite and ground station. However, Doppler alone is not sufficient for unique localization: the satellite orbit, time, and additional measurements such as range or elevation are still required. +### Task4 + +#### 4.1 - 4.3 + +![PER over SNR sweep with pre-compensation](per_over_snr_doppler_pre_compensation.svg) + +The plot compares the PER over SNR without Doppler pre-compensation, with ideal pre-compensation, and with imperfect pre-compensation errors of 10 Hz, 100 Hz, 1000 Hz, and 5000 Hz. + +Only small differences between the curves are visible. The maximum PER difference between no pre-compensation and ideal pre-compensation is 0.018, which corresponds to about 18 packets out of 1000. Therefore, Doppler pre-compensation has only a small visible effect in this simulation setup. + +A likely reason is that the 802.11 receiver still performs coarse and fine CFO correction using the WiFi preamble. Pilot tracking is disabled as required by the task, but the preamble-based CFO correction is still active. Because of this, even the case without transmitter-side pre-compensation can still decode many packets successfully. The additional benefit of ideal pre-compensation is therefore limited at the simulated 2.4 GHz carrier frequency. + +#### 4.4 + +For this compare only the test with ideal pre-compensation and without pre-compensation is run. + #### Special Thanks This lab was solved with contribution of GPT 5.5. diff --git a/lab_5/per_over_snr_doppler_pre_compensation.svg b/lab_5/per_over_snr_doppler_pre_compensation.svg new file mode 100644 index 0000000..47b2495 --- /dev/null +++ b/lab_5/per_over_snr_doppler_pre_compensation.svg @@ -0,0 +1,838 @@ + + +Qt SVG Document +MATLAB, The MathWorks, Inc. Version 26.1.0.3251617 R2026a Update 2 + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +SNR [dB] + + + + + + + + + + + + + + + + +0 + + + +5 + + + +10 + + + +15 + + + +20 + + + +25 + + + +30 + + + +35 + + + +40 + + + +PER + + + + + + + + + + + + + + + + + +0.1 + + + +0.2 + + + +0.3 + + + +0.4 + + + +0.5 + + + +0.6 + + + +0.7 + + + +0.8 + + + +0.9 + + + +1 + + + +PER over SNR with Doppler pre-compensation + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +none + + + +ideal + + + +10Hz + + + +100Hz + + + +1000Hz + + + +5000Hz + + + + + + + diff --git a/lab_5/per_over_snr_freq.svg b/lab_5/per_over_snr_freq.svg new file mode 100644 index 0000000..bc0145b --- /dev/null +++ b/lab_5/per_over_snr_freq.svg @@ -0,0 +1,1659 @@ + + +Qt SVG Document +MATLAB, The MathWorks, Inc. Version 26.1.0.3251617 R2026a Update 2 + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +SNR [dB] + + + + + + + + + + + + + + + + +0 + + + +5 + + + +10 + + + +15 + + + +20 + + + +25 + + + +30 + + + +35 + + + +40 + + + +PER + + + + + + + + + + + + + + + + + +0.1 + + + +0.2 + + + +0.3 + + + +0.4 + + + +0.5 + + + +0.6 + + + +0.7 + + + +0.8 + + + +0.9 + + + +1 + + + +Pre-compensation: none + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +2.4 GHz + + + +5 GHz + + + +6 GHz + + + +10 GHz + + + +20 GHz + + + +60 GHz + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +SNR [dB] + + + + + + + + + + + + + + + + +0 + + + +5 + + + +10 + + + +15 + + + +20 + + + +25 + + + +30 + + + +35 + + + +40 + + + +PER + + + + + + + + + + + + + + + + + +0.1 + + + +0.2 + + + +0.3 + + + +0.4 + + + +0.5 + + + +0.6 + + + +0.7 + + + +0.8 + + + +0.9 + + + +1 + + + +Pre-compensation: ideal + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +2.4 GHz + + + +5 GHz + + + +6 GHz + + + +10 GHz + + + +20 GHz + + + +60 GHz + + + + + + + diff --git a/lab_5/perform_access_analysis.m b/lab_5/perform_access_analysis.m index 1937328..3e4443a 100644 --- a/lab_5/perform_access_analysis.m +++ b/lab_5/perform_access_analysis.m @@ -1,4 +1,4 @@ -function res = perform_access_analysis(satSim, queryTime) +function res = perform_access_analysis(satSim, queryTime, carrierFrequency) sat = satSim.sat; ue = satSim.ue; @@ -17,7 +17,10 @@ function res = perform_access_analysis(satSim, queryTime) res.distanceToSatellite = r; res.elevationAngleToSatellite = el; - carrierFrequency = 2.4e9; + if nargin < 3 + carrierFrequency = 2.4e9; + end + [fshift,~,dopplerInfo] = dopplershift( ... sat,ue,queryTime,Frequency=carrierFrequency); res.rangeRate = -1*dopplerInfo.RelativeVelocity; diff --git a/lab_5/simulateTransmission.m b/lab_5/simulateTransmission.m index 39734a4..496ad6c 100644 --- a/lab_5/simulateTransmission.m +++ b/lab_5/simulateTransmission.m @@ -1,9 +1,9 @@ -function [numPacketErrors, numPacketsSimulated, cfrMagnitudes, rxPower, pathLoss]= simulateTransmission(accessAnalysisResults, cfgEHT, channel, maxChDelay, snr, maxNumErrors, simParameters) +function [numPacketErrors, numPacketsSimulated, cfrMagnitudes, rxPower, pathLoss]= simulateTransmission(accessAnalysisParameters, cfgEHT, channel, maxChDelay, snr, maxNumErrors, simParameters) numPacketErrors = 0; numPacketsSimulated = 0; cfrMagnitudes = []; - rxPower = zeros(size(accessAnalysisResults.elevationAngles)); - pathLoss = zeros(size(accessAnalysisResults.elevationAngles)); + rxPower = zeros(size(accessAnalysisParameters.elevationAngles)); + pathLoss = zeros(size(accessAnalysisParameters.elevationAngles)); ofdmInfo = wlanEHTOFDMInfo('EHT-Data', cfgEHT); ind = wlanFieldIndices(cfgEHT); @@ -26,11 +26,11 @@ function [numPacketErrors, numPacketsSimulated, cfrMagnitudes, rxPower, pathLoss lambda = physconst("lightspeed") / simParameters.CarrierFrequency; includePathLoss = isfield(simParameters, 'IncludeFreeSpacePathLoss') && simParameters.IncludeFreeSpacePathLoss; - while (powerOnlySimulation || numPacketErrors < maxNumErrors) && numPacketsSimulated < numel(accessAnalysisResults.elevationAngles) + while (powerOnlySimulation || numPacketErrors < maxNumErrors) && numPacketsSimulated < numel(accessAnalysisParameters.elevationAngles) numPacketsSimulated = numPacketsSimulated + 1; if includePathLoss - packetDistance = accessAnalysisResults.distances(numPacketsSimulated); + packetDistance = accessAnalysisParameters.distances(numPacketsSimulated); pathLoss(numPacketsSimulated) = 20 * log10(4 * pi * packetDistance / lambda); else pathLoss(numPacketsSimulated) = 0; @@ -45,15 +45,38 @@ function [numPacketErrors, numPacketsSimulated, cfrMagnitudes, rxPower, pathLoss tx = tx * sqrt(10^((txPower - 30) / 10)) / sqrt(stfPower); + packetElevationAngle = accessAnalysisParameters.elevationAngles(numPacketsSimulated); + if isfield(accessAnalysisParameters, "dopplerShifts") && isfinite(accessAnalysisParameters.dopplerShifts(numPacketsSimulated)) + packetDopplerShift = accessAnalysisParameters.dopplerShifts(numPacketsSimulated); + else + packetDopplerShift = dopplerShiftCircularOrbit(packetElevationAngle, simParameters.SatelliteAltitude, simParameters.MobileAltitude, simParameters.CarrierFrequency); + end + + if ~isfinite(packetDopplerShift) + packetDopplerShift = 0; + end + + channel.SatelliteDopplerShift = packetDopplerShift; + txPad = [tx; zeros(maxChDelay, cfgEHT.NumTransmitAntennas)]; + if isfield(accessAnalysisParameters, "preCompensation") + predictedDopplerShift = []; + if isnumeric(accessAnalysisParameters.preCompensation) + predictedDopplerShift = packetDopplerShift + accessAnalysisParameters.preCompensation; + elseif string(accessAnalysisParameters.preCompensation) == "ideal" + predictedDopplerShift = packetDopplerShift; + end + + if ~isempty(predictedDopplerShift) && isfinite(predictedDopplerShift) + txPad = frequencyOffset(txPad, simParameters.SampleRate, -predictedDopplerShift); + end + end + if powerOnlySimulation continue; end - packetElevationAngle = accessAnalysisResults.elevationAngles(numPacketsSimulated); - channel.SatelliteDopplerShift = dopplerShiftCircularOrbit(packetElevationAngle, simParameters.SatelliteAltitude, simParameters.MobileAltitude, simParameters.CarrierFrequency); - reset(channel); rx = awgn(channel(txPad) * db2mag(-pathLoss(numPacketsSimulated)), snrVal); @@ -90,7 +113,9 @@ function [numPacketErrors, numPacketsSimulated, cfrMagnitudes, rxPower, pathLoss rxData = rx(packetOffset + (ind.EHTData(1) : ind.EHTData(2)), :); demodSym = wlanEHTDemodulate(rxData, "EHT-Data", cfgEHT); - demodSym = wlanEHTTrackPilotError(demodSym, chanEstimate, cfgEHT, "EHT-Data"); + if ~isfield(accessAnalysisParameters, "enablePilotTracking") || accessAnalysisParameters.enablePilotTracking + demodSym = wlanEHTTrackPilotError(demodSym, chanEstimate, cfgEHT, "EHT-Data"); + end nVarEst = wlanEHTDataNoiseEstimate(demodSym(ofdmInfo.PilotIndices, :, :),pilotEstimate, cfgEHT); diff --git a/lab_5/task1.m b/lab_5/task1.m index 381c15e..b1dcdb4 100644 --- a/lab_5/task1.m +++ b/lab_5/task1.m @@ -16,7 +16,7 @@ progressQueue = parallel.pool.DataQueue; parfor_waitbar(f, progressTotal, progressStartText, true); progressListener = afterEach(progressQueue, @(info) parfor_waitbar(f, progressTotal, info, false)); -parfor idx = 1:numel(sampleTimes) +parfor idx = 1 : numel(sampleTimes) res = perform_access_analysis(satSim, sampleTimes(idx)); distancesToSat(idx) = res.distanceToSatellite; elevationAnglesToSat(idx) = res.elevationAngleToSatellite; diff --git a/lab_5/task2.m b/lab_5/task2.m index 1459471..5c0d585 100644 --- a/lab_5/task2.m +++ b/lab_5/task2.m @@ -20,6 +20,10 @@ amplifierGain = 30; cfgEHT.User{1}.MCS = 3; simParameters.TransmitPower = txPower; +if exist("only_define_baseline_vars", "var") && only_define_baseline_vars + return; +end + [~, numPacketsSimulated, ~, rxPower, pathLoss] = simulateTransmission(accessAnalysisResults, cfgEHT, channel, maxChDelay, [], inf, simParameters); packetIdx = 1:numPacketsSimulated; diff --git a/lab_5/task4.m b/lab_5/task4.m new file mode 100644 index 0000000..72454a7 --- /dev/null +++ b/lab_5/task4.m @@ -0,0 +1,268 @@ +minutesToSimulate = 10; +satConfig.stopTime = satConfig.startTime + minutes(minutesToSimulate); + +snrs = 0:1:40; + +if exist("satSim", "var") + clear satSim; +end + +satSim = create_satellite_sim(satConfig, groundStation); +packetsToTransmit = 1000; + +sampleTimes = satConfig.startTime:seconds(satConfig.sampleTime):satConfig.stopTime; +packetsPerTimeSlot = packetsToTransmit / numel(sampleTimes); + +packetTimes = satConfig.startTime + seconds(linspace(0, minutesToSimulate * 60, packetsToTransmit)); + +% viewer = satelliteScenarioViewer(satSim.sc); + +preCompensations = {"none", "ideal", 10, 100, 1000, 5000}; +preCompensationLabels = [ + "none" + "ideal" + "10Hz" + "100Hz" + "1000Hz" + "5000Hz" +]; + +markers = 'ox*sd^v>