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
+
+
+
+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 @@
+
+
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 @@
+
+
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>