You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
227 lines
11 KiB
227 lines
11 KiB
clear;
|
|
close all;
|
|
clc;
|
|
|
|
%% LabVIEW界面参数配置-发送模式-界面选择部分
|
|
%
|
|
cfgUI.ChannelBandwidth = 'CBW20'; % 下拉选择:'CBW20''CBW40''CBW80'
|
|
cfgUI.NTX2_enabled = 1; % 与第三方硬件连接
|
|
max_run_time = 60; %最大允许的等待时间
|
|
SEED = 1;
|
|
|
|
cfgUI.numUsers = 1; % 当前版本用户数量,1-2
|
|
cfgUI.DataType = 'test'; % 下拉选择:'test''text''photo'image.png
|
|
numPkt = 5; %时隙内包的数量,当前版本1~5
|
|
pktLength = 1001; % 包长度设定下拉选择(short,medium,long)对应几个数字1001,7007,12012,赋值给APEPLength
|
|
if strcmp(cfgUI.DataType,'photo')
|
|
txPSDUByte = imread('image.png');
|
|
I_gray = im2gray(txPSDUByte);
|
|
[len,width] = size(I_gray);
|
|
binary = dec2bin(I_gray(:),8);
|
|
bitstream = reshape(binary',1,[]);%将二进制数连接起来形成比特流
|
|
byte_array = reshape(bitstream',8,[])';%将比特流转换为字节流
|
|
txPSDUByte = bin2dec(byte_array);
|
|
% 包长度与包个数自适应判断 zjd3.26
|
|
if numPkt*pktLength >= length(txPSDUByte) % 如果当前包长度在5个包内能传输当前数据量
|
|
for pktNum = 1:numPkt % 判断当前包长度下最少用几个包传数据
|
|
if pktNum*pktLength >= length(txPSDUByte)
|
|
numPkt = pktNum;
|
|
break
|
|
end
|
|
end
|
|
else % 当前包长度不能在5个包内能传输当前数据量,自动调整
|
|
if numPkt*7007 >= length(txPSDUByte)
|
|
for pktNum = 1:numPkt % 判断当前包长度下最少用几个包传数据
|
|
if pktNum*7007 >= length(txPSDUByte)
|
|
numPkt = pktNum;
|
|
pktLength = 7007;
|
|
break
|
|
end
|
|
end
|
|
else
|
|
for pktNum = 1:numPkt % 判断当前包长度下最少用几个包传数据
|
|
if pktNum*12012 >= length(txPSDUByte)
|
|
numPkt = pktNum;
|
|
pktLength = 12012;
|
|
break
|
|
end
|
|
end
|
|
end
|
|
end
|
|
txPSDUByteUser = zeros(len*width+3,cfgUI.numUsers); % 将图片分给两个用户
|
|
for i = 1:cfgUI.numUsers
|
|
byteLen = length(txPSDUByte);
|
|
byteLenBit = int2bit(byteLen,16);
|
|
Len1 = bit2int(byteLenBit(1:8),8);
|
|
Len2 = bit2int(byteLenBit(9:16),8);
|
|
txPSDUByteUser(1:len*width+2,i) = [Len1;Len2;txPSDUByte];
|
|
txPSDUByteUser(end,i) = mod(sum(txPSDUByteUser(:,i)),256);
|
|
end
|
|
txPSDUByteUser = uint8(txPSDUByteUser);
|
|
save('TXPackets\txPSDUByteUser.mat','txPSDUByteUser');
|
|
elseif strcmp(cfgUI.DataType,'text')
|
|
else
|
|
txPSDUByteUser = 0;
|
|
end
|
|
|
|
cfgUI.UserMode = 'SU'; % 使用模式下拉选择:'MU','SU',SU情况下只有单用户、可扩展40MHz、STBC等,MU模式可以对单用户进行资源分配(lxr)
|
|
cfgUI.FeedbackMode = 'openloop'; % 下拉选择: 'openloop','feedback',对应菜单栏的‘手动’和‘智能’
|
|
SoundingMode = 0; % 环境感知模式,作为一个按钮
|
|
|
|
cfgUI.numTx = 1; % 发射天线数,当前版本1~2
|
|
cfgUI.numRx = 1; % 接收天线数,当前版本1~2
|
|
|
|
cfgUI.AI.PAPR = 'PAPR'; % 下拉选择:'default','PAPR-Net'
|
|
cfgUI.PhySecur = 'default'; % 下拉选择:'无','CP随机化','信道密钥'
|
|
|
|
%----------------以下是可以手动配置的部分---------------------
|
|
%---资源矩阵部分
|
|
cfgUI.user1.s = 1;
|
|
cfgUI.user1.f = [1,1,1,1]; % 显示为4个方格,可用则为黑色为1,不可用则为白色为0
|
|
cfgUI.user1.t = ones(1,numPkt); % 显示为numPkt个方格,可用则为黑色为1,不可用则为白色为0
|
|
cfgUI.user1.p = 0.5; %
|
|
cfgUI.user2.s = 1;
|
|
cfgUI.user2.f = [1,1,1,1];
|
|
cfgUI.user2.t = ones(1,numPkt);
|
|
cfgUI.user2.p = 0.5;
|
|
%---波形参数部分---user1
|
|
cfgUI.user1.ChannelCode = 'LDPC'; % 下拉选择编码方式:BCC or LDPC
|
|
cfgUI.user1.CodeRate = 3/4; % 编码码率下拉选择:1/2 or 2/3 or 3/4 or 5/6
|
|
cfgUI.user1.CodeLengt = 1600; % 编码码长:200*8=1600,800
|
|
cfgUI.user1.InterWeaveMode = 'random'; % 交织方式下拉选择:random,horizontal
|
|
cfgUI.user1.InterWeaveDepth = 1024; % 交织深度:2048,1024
|
|
cfgUI.user1.ScrambleLength = 6; % 扰码长度:32
|
|
cfgUI.user1.CPLength = '1/4'; % CP长度下拉选择:1/16 or 1/8 or 1/4
|
|
cfgUI.user1.FFTSize = 256; % FFT尺寸:128 or 256 or 512
|
|
cfgUI.user1.NumSubcarrier = 242; % 子载波数:128 or 256 or 512
|
|
cfgUI.user1.ModulationMode = '16QAM'; % 调制方式下拉选择:4QAM or 8QAM or 16QAM or 32QAM or 64QAM
|
|
cfgUI.user1.MultiAntennaMode = 'STBC'; % 多天线方式下拉选择:'ZF-BF','MMSE-BF', SU模式下才能使用STBC'STBC'
|
|
cfgUI.user1.SpatialMapping = 'Hadamard'; % 空间映射方式下拉选择:'Direct','Hadamard','Fourier','Custom'----------zjd 3.21修改
|
|
cfgUI.user1.APEPlength = pktLength; % 包长度设定下拉选择(short,medium,long)对应几个数字1001,7007,12012
|
|
cfgUI.user1.pilotInterval = 5;
|
|
%---波形参数部分---user2
|
|
cfgUI.user2.ChannelCode = 'LDPC'; % 编码方式:BCC or LDPC
|
|
cfgUI.user2.CodeRate = 3/4; % 编码码率:1/2 or 2/3 or 3/4 or 5/6
|
|
cfgUI.user2.CodeLengt = 1600; % 编码码长:200*8=1600,800
|
|
cfgUI.user2.InterWeaveMode = 'random'; % 交织方式:random,horizontal
|
|
cfgUI.user2.InterWeaveDepth = 1024; % 交织深度:2048,1024
|
|
cfgUI.user2.ScrambleLength = 6; % 扰码长度:32
|
|
cfgUI.user2.CPLength = '1/4'; % CP长度:1/16 or 1/8 or 1/4
|
|
cfgUI.user2.FFTSize = 256; % FFT尺寸:128 or 256 or 512
|
|
cfgUI.user2.NumSubcarrier = 242; % 子载波数:128 or 256 or 512
|
|
cfgUI.user2.ModulationMode = '16QAM'; % 调制方式:4QAM or 8QAM or 16QAM or 32QAM or 64QAM
|
|
cfgUI.user2.MultiAntennaMode = 'ZF-BF'; % 多天线方式:'ZF-BF','MMSE-BF','STBC'
|
|
cfgUI.user2.SpatialMapping = 'Direct'; % 空间映射方式:'Direct','Hadamard','Fourier'
|
|
cfgUI.user2.APEPlength = pktLength; % 包长度设定
|
|
cfgUI.user2.pilotInterval = 5;
|
|
%% TX运行
|
|
if SoundingMode %%% 判断TX工作状态
|
|
tic;
|
|
feedback_stat = false;
|
|
while feedback_stat==false && toc < max_run_time % 没接收到反馈或者超过最大等待时间
|
|
txNDP = channelSounding(cfgUI); % 开始发送探测和NDP序列
|
|
tx_data = txNDP;
|
|
save('TXPackets\transmit_data.mat','tx_data','cfgUI');% 发送NDP
|
|
pause(1); % 暂停5s等待反馈
|
|
numUsers = cfgUI.numUsers;
|
|
feedback_data = struct(); % 初始化结构体
|
|
stat = zeros(1,numUsers);
|
|
for uid = 1:numUsers
|
|
filename = ['TXPackets/NDPfeedback_for_User' num2str(uid) '.mat'];
|
|
stat(uid) = 1;
|
|
if exist(filename,'file') ~= 2 % 待读取的反馈文件不存在
|
|
filename = ['TXPackets/NDPfeedback_Default_for_User' num2str(uid) '.mat']; % 读取默认的反馈文件
|
|
stat(uid) = 0; % 此时反馈参数为0
|
|
end
|
|
feedback_data = setfield(feedback_data,['user' num2str(uid)],loadfeedback(filename)); % 加载每个用户对应的反馈文件---需补充snr等(lxr)
|
|
end
|
|
feedback_stat = all(stat == 1); % 判断反馈状态
|
|
end
|
|
% 超时停止
|
|
if feedback_stat==false
|
|
error("Time Out !!!");
|
|
else
|
|
disp("feedback received");
|
|
end
|
|
|
|
elseif strcmp(cfgUI.FeedbackMode,'openloop')
|
|
while(1)
|
|
% 进入数据传输步骤
|
|
numUsers = cfgUI.numUsers; % 读取用户数
|
|
feedback_data = struct(); % 初始化结构体
|
|
for uid = 1:numUsers
|
|
filename = ['TXPackets/NDPfeedback_for_User' num2str(uid) '.mat'];
|
|
if exist(filename,'file') ~= 2 % 待读取的反馈文件不存在
|
|
filename = ['TXPackets/NDPfeedback_Default_for_User' num2str(uid) '.mat']; % 读取默认的反馈文件
|
|
end
|
|
feedback_data = setfield(feedback_data,['user' num2str(uid)],loadfeedback(filename)); % 加载每个用户对应的反馈文件
|
|
if eval(['isnan(sum(feedback_data.user' num2str(uid) '.staFeedback,"all")) || isempty(feedback_data.user' num2str(uid) '.staFeedback)']) % 判断staFeedback是否为空或NaN
|
|
filename = ['TXPackets/NDPfeedback_Default_for_User' num2str(uid) '.mat']; % 改为读取默认的反馈文件
|
|
feedback_data = setfield(feedback_data,['user' num2str(uid)],loadfeedback(filename));
|
|
end
|
|
end
|
|
[paraCal,tx_data,cfgUI,errorMessage] = TX_transmit(numPkt,SEED,cfgUI,feedback_data,txPSDUByteUser);
|
|
save('TXPackets\transmit_data.mat','tx_data','cfgUI');
|
|
if cfgUI.AI.PAPR == 'PAPR'
|
|
% PAPR DPD
|
|
end
|
|
end
|
|
|
|
elseif strcmp(cfgUI.FeedbackMode,'feedback')
|
|
|
|
while(1)
|
|
tic;
|
|
feedback_stat = false;
|
|
while feedback_stat==false && toc < max_run_time
|
|
txNDP = channelSounding(cfgUI); % 开始发送探测和NDP序列
|
|
tx_data = txNDP;
|
|
save('TXPackets\transmit_data.mat','tx_data','cfgUI');% 发送NDP
|
|
pause(0); % 暂停5s等待反馈
|
|
numUsers = cfgUI.numUsers; % 读取用户数
|
|
stat = zeros(1,numUsers); % 初始化stat参数
|
|
feedback_data = struct(); % 初始化结构体
|
|
for uid = 1:numUsers
|
|
filename = ['TXPackets/NDPfeedback_for_User' num2str(uid) '.mat'];
|
|
stat(uid) = 1;
|
|
if exist(filename,'file') ~= 2 % 待读取的反馈文件不存在
|
|
filename = ['TXPackets/NDPfeedback_Default_for_User' num2str(uid) '.mat']; % 读取默认的反馈文件
|
|
stat(uid) = 0; % 此时反馈参数为0
|
|
end
|
|
feedback_data = setfield(feedback_data,['user' num2str(uid)],loadfeedback(filename));
|
|
if eval(['isnan(sum(feedback_data.user' num2str(uid) '.staFeedback,"all")) || isempty(feedback_data.user' num2str(uid) '.staFeedback)']) % 判断staFeedback是否为空或NaN
|
|
filename = ['TXPackets/NDPfeedback_Default_for_User' num2str(uid) '.mat']; % 改为读取默认的反馈文件
|
|
feedback_data = setfield(feedback_data,['user' num2str(uid)],loadfeedback(filename));
|
|
end
|
|
end
|
|
feedback_stat = all(stat == 1); % 判断反馈状态
|
|
end
|
|
% 超时停止
|
|
if feedback_stat==false
|
|
error("Time Out !!!");
|
|
else
|
|
disp("feedback received");
|
|
end
|
|
%
|
|
|
|
% 进入参数配置步骤,数据传输步骤
|
|
ack_feedback_stat=true;
|
|
stat = 1;
|
|
while ack_feedback_stat==true && stat==1
|
|
load('TXPackets\feedback.mat');
|
|
feedback_data = feedback;
|
|
[paraCal,tx_data,cfgUI,errorMessage] = TX_transmit(numPkt,SEED,cfgUI,feedback_data,txPSDUByteUser);
|
|
save('TXPackets\transmit_data.mat','tx_data','cfgUI');
|
|
if cfgUI.AI.PAPR == 'PAPR'
|
|
% PAPR+DPD
|
|
end
|
|
pause(1); % 暂停 等待反馈
|
|
ACK_feedback = cell(1,numUsers);
|
|
for uid = 1:numUsers
|
|
load(['TXPackets\ACKfeedback_for_User' num2str(uid) '.mat'])
|
|
ACK_feedback{uid} = ACK;
|
|
end
|
|
% 显示空口波形参数,PAPR,以及AI算法的reward
|
|
show2LabVIEW(); %!!!
|
|
end
|
|
end
|
|
end
|
|
|