function showResourceMatrix(cfgHE,cfgUI,RU_index,varargin) % **输入:含有RU分配信息的HE结构体、来自UI的额外控制参数 % **输出:含有'时间*频率*用户'三维的资源分配示意图 % 获取RU分配信息 if cfgUI.numUsers == 1 cfgHE = wlanHEMUConfig(RU_index); end allocInfo = ruInfo(cfgHE); % 画布初始化 if nargin == 3 % fig = figure('Name',getString(message('wlan:hePlotAllocation:FigureTitle'))); fig = figure('visible','off'); ax = axes(fig); else ax = varargin{1}; end cla(ax,'reset') % 绘图参数 dpi = 96; cbw = wlan.internal.cbwStr2Num(cfgHE.ChannelBandwidth); Nfft = cbw/20*256; isHETBNDP = isa(cfgHE,'wlanHETBConfig') && cfgHE.FeedbackNDP; centerColor = [1 0 0; 0.5 0 0; 0.25 0 0]; % Colors for special split RUs % infoLims contains tuples of channel bandwidth and the minimum RU size for % which RU information is to be displayed on a patch: [cbw rusize]. % tuple中记录给定带宽下可分配的最小RU大小 infoLims = ... [20 26; ... 40 52; ... 80 106; ... 160 242 ]; % 构建sequencial allocation matrix time_sequence_len = length(cfgUI.user1.t); frequency_sequence_len = length(cfgUI.user1.f); allo_sequencial=zeros(time_sequence_len,frequency_sequence_len,cfgUI.numUsers); for t = 1 : time_sequence_len for f = 1 : frequency_sequence_len for n = 1 : cfgUI.numUsers if n == 1 if cfgUI.user1.t(t) == 1 && cfgUI.user1.f(f) == 1 allo_sequencial(t,f,n) = 1; end elseif n == 2 if cfgUI.user2.t(t) == 1 && cfgUI.user2.f(f) == 1 allo_sequencial(t,f,n) = 1; end end end end end % Plot the HE occupied subcarriers kRUPuncture = wlan.internal.hePuncturedRUSubcarrierIndices(cfgHE); bi = 1; icenter = 1; startEndIdx = zeros(0,2); hRU = gobjects(allocInfo.NumRUs,2); % At most 2 patches per RU % 共有5个时隙,每个时隙都将相同的RU资源块分配给固定的几个用户 for seq = 1:size(allo_sequencial,1) i_accu = 0; for i = 1:allocInfo.NumRUs % Get the active subcarrier indices for the RU % 可用子载波序号 if isHETBNDP kFull = wlan.internal.heTBNDPSubcarrierIndices(cbw,cfgHE.RUToneSetIndex,cfgHE.FeedbackStatus); else kFull = wlan.internal.heRUSubcarrierIndices(cbw,allocInfo.RUSizes(i),allocInfo.RUIndices(i)); end if ~isempty(kRUPuncture) k = setdiff(kFull,kRUPuncture); % Discard punctured subcarriers else k = kFull; end % 配置patch的颜色和说明文字 UserIndex = 'User #'; colorToUse = 0; firstUser = 0; for n = 1 : cfgUI.numUsers if allo_sequencial(seq,i + i_accu,n) == 1 if colorToUse == 0 firstUser = n; % 方便后边构建字符:User #a-b UserIndex = [UserIndex,num2str(n)]; end colorToUse = colorToUse + n^2;% 使用平方避免颜色重复 end end UserInRU = sum(allo_sequencial(seq,i + i_accu,:));% 当前RU中用户总数 % RU中用户数超过1时,需要额外构造不同形式的字符串 if UserInRU > 1 UserIndex = [UserIndex,'-',num2str(firstUser + UserInRU - 1)]; end % Get the end index of each continuous block of subcarriers within the RU % 因为利用patch函数画图,需要以子载波是否连续划分patch nonContigEnd = [find(diff(k)~=1); numel(k)]; startIdx = 1; % The start index of the continuous block of subcarriers for j = 1:numel(nonContigEnd) % Plot a patch of the continuous block of subcarriers blkIdx = startIdx:nonContigEnd(j); startEndIdx(bi,:) = [k(blkIdx(1)) k(blkIdx(end))]; % y = [k(blkIdx(1)) k(blkIdx(end)) k(blkIdx(end)) k(blkIdx(1))]; % x = [0 0 1.5 1.5 ]; y = [k(blkIdx(1)) k(blkIdx(end)) k(blkIdx(end)) k(blkIdx(1))]; x = [0.05+1.6*(seq-1) 0.05+1.6*(seq-1) 1.55+1.6*(seq-1) 1.55+1.6*(seq-1)]; hold(ax,'on'); startIdx = nonContigEnd(j)+1; bi = bi+1; if colorToUse == 0 hRU(i,j) = patch(ax,x,y,'w');% 无用户使用该RU时填充为白色 UserIndex = ''; else hRU(i,j) = patch(ax,x,y,colorToUse);% 有用户使用该RU时即使用colorToUse对应的颜色 end % 标记用户序号 xMiddle = hRU(i,j).Vertices(1,1)+(hRU(i,j).Vertices(end,1)-hRU(i,j).Vertices(1,1))/2; yMiddle = hRU(i,j).Vertices(1,2)+(hRU(i,j).Vertices(2,2)-hRU(i,j).Vertices(1,2))/2; htext = text(ax,xMiddle,yMiddle,UserIndex,'HorizontalAlignment','center','FontSize',9); htext.PickableParts = 'none'; end switch length(k) case 242 i_offset = 3; case 106 i_offset = 1; case 52 i_offset = 0; end i_accu = i_accu + i_offset; end end % ylabel(ax,getString(message('wlan:hePlotAllocation:SubcarrierIndex'))) ylabel('Subcarrier Index'); xticks(ax,[]) ylim(ax,[-Nfft/2 Nfft/2-1]); ax.Box = 'on'; h = plot(ax,NaN,NaN,'ow'); % Placeholder for empty legend print(fig, 'RU_Alloc.png', '-dpng', ['-r', num2str(dpi)]); % pause(0.5); % close; end