How to Correct 64-QAM Constellation Rotation After Free Space Channel Using phased.FreeSpace?

8 次查看(过去 30 天)
When I transmit a 64-QAM signal through a free-space channel using phased.FreeSpace, the resulting constellation at the receiver appears rotated due to a carrier phase offset. I attempted to correct this using comm.CarrierSynchronizer, but the constellation still remains misaligned.
How can I accurately estimate and correct this phase rotation to recover the original symbol alignment?
clear; clc; close all;
%% Parameters
M = 64; k = log2(M); fs = 1e7; fc = 2e9;
numData = 6000;
%% Generate data symbols and original bitstream
dataBits = randi([0 1], numData * k, 1);
dataSymbols = bit2int(dataBits, k, true);
figure;
stairs(dataSymbols(1:100))
% Modulate
modulated = qammod(dataSymbols, M, 'UnitAveragePower', true);
t = (0:length(modulated)-1)' / fs;
%% Plot Original Constellation
figure; scatterplot(modulated);
title('Original 64-QAM Constellation');
%% Plot original I/Q waveform
figure;
subplot(2,1,1); plot(t*1e6, real(modulated)); title('Tx I (Real)');
xlabel('Time (microseconds)'); ylabel('Amplitude'); grid on;
subplot(2,1,2); plot(t*1e6, imag(modulated)); title('Tx Q (Imag)');
xlabel('Time (microseconds)'); ylabel('Amplitude'); grid on;
%% Transmit over Passband with Phase Offset
tx_passband = modulated .* exp(1j * 2 * pi * fc * t);
fsChannel = phased.FreeSpace(...
'SampleRate', fs, ...
'PropagationSpeed', physconst('LightSpeed'), ...
'OperatingFrequency', fc, ...
'TwoWayPropagation', false);
txloc = [0;0;0]; rxloc = [100;0;0];
rx_signal = fsChannel(tx_passband, txloc, rxloc, [0;0;0], [0;0;0]);
%% Downconvert
rx_mixed = rx_signal .* exp(-1j * 2 * pi * fc * t);
% Plot received waveform
figure;
subplot(2,1,1); plot(t*1e6, real(rx_mixed)); title('Rx I (Real) Before Correction');
xlabel('Time (microseconds)'); ylabel('Amplitude'); grid on;
subplot(2,1,2); plot(t*1e6, imag(rx_mixed)); title('Rx Q (Imag) Before Correction');
xlabel('Time (microseconds)'); ylabel('Amplitude'); grid on;
%% Constellation before correction
figure; scatterplot(rx_mixed); title('Rx Constellation Before Phase Correction');
%% Phase estimation and correction
csync = comm.CarrierSynchronizer( ...
'Modulation', 'QAM', ...
'SamplesPerSymbol', 1, ...
'DampingFactor', 1, ...
'NormalizedLoopBandwidth', 0.01);
[rx_corrected, phEst] = csync(rx_mixed);
figure; scatterplot(rx_corrected); title('After CarrierSynchronizer');
figure; plot(phEst); title('CarrierSynchronizer Phase Estimate');
xlabel('Sample'); ylabel('Phase (rad)');
%% Plot corrected waveform
figure;
subplot(2,1,1); plot(t*1e6, real(rx_corrected)); title('Rx I (Real) After Correction');
xlabel('Time (microseconds)'); ylabel('Amplitude'); grid on;
subplot(2,1,2); plot(t*1e6, imag(rx_corrected)); title('Rx Q (Imag) After Correction');
xlabel('Time (microseconds)'); ylabel('Amplitude'); grid on;
%% Plot constellation after correction
figure; scatterplot(rx_corrected); title('Rx Constellation After Phase Correction');
%% Demodulate
demodulated = qamdemod(rx_corrected, M, 'UnitAveragePower', true);
% Convert to bitstream
rxBits = int2bit(demodulated, k, true);
%% Plot bitstream comparison
figure;
subplot(2,1,1); stairs(dataBits(1:200)); title('Original Bitstream (First 200 bits)');
xlabel('Bit Index'); ylabel('Bit'); ylim([-0.5 1.5]); grid on;
subplot(2,1,2); stairs(rxBits(1:200)); title('Received Bitstream (First 200 bits)');
xlabel('Bit Index'); ylabel('Bit'); ylim([-0.5 1.5]); grid on;
%% BER Calculation
bitErrors = sum(rxBits ~= dataBits(1:length(rxBits)));
BER = bitErrors / length(rxBits);
fprintf('BER: %.5f (%d bit errors)\n', BER, bitErrors);

回答(1 个)

Jaskirat
Jaskirat 2025-6-11
Hi @Jakub,
I understand you want to estimate and correct the phase offset.
This can be done by using the “comm.CoarseFrequencyCompensator” object to correct frequency offset, followed by fine-tuning the correction using carrier synchronization.
You can refer to the following example for more details:
You can also refer to the following documentation to learn more about comm.CoarseFrequencyCompensator:
Hope this helps!

类别

Help CenterFile Exchange 中查找有关 Synchronization and Receiver Design 的更多信息

Community Treasure Hunt

Find the treasures in MATLAB Central and discover how the community can help you!

Start Hunting!

Translated by