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

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