认识LTE(七):LTE中的两种无反馈模式:发射分集(TM2)和开环空分复用(TM3)

文章目录

  • 认识LTE(七):LTE中的两种无反馈模式:发射分集(TM2)和开环空分复用(TM3)
  • 零.代码地址
  • 一.LTE中MIMO的一些基本概念
  • 二.TM2:发射分集
    • 1. 原理
    • 2.全流程
  • 三.TM3:开环空间复用
    • 1.原理
    • 2.全流程

零.代码地址

https://github.com/liu-zongxi/LTE_simulation

请大家看完觉得有用别忘了点赞收藏,github项目给star哦

一.LTE中MIMO的一些基本概念

在介绍这两种模式之前,我们要大致说一下MIMO的一些基本概念

  1. LTE的MIMO包括两个步骤,层映射和预编码,所谓层映射,是指把数据流映射到多个层,MIMO中就可以按层数发送,预编码则是MIMO的手段。分集使用SFBC,二MIMO则是用于减小计算量的SVD
  2. 层,什么是层呢?

  1. 层数怎么来确定呢?这涉及到两方面,一个是发射天线和接收天线数,层数和Rank相关,二是要确保要满秩,满秩就要环境足够复杂
  2. 流:这被称为CodeWord,非常迷惑人的一个称呼,他表示的实际上是有几个数据流
  3. Rank:这会被再CSI中用RI参数来反馈矩阵的秩的大小
  4. 层映射,把流映射到层、

二.TM2:发射分集

1. 原理

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-MXuaYMzQ-1660205620527)(http://images.lzxixi.ltd/image-20220811143519619.png)]

开局一张图

在之前的博客中,我详细的写过STBC的原理和实现,大家可以去翻看一下

那么SFBC有什么区别呢,答案是没什么区别,只是把其中一个进行了一个符号的变换

有趣的是,在TM2中,四天线和二天线本质上是一致的,哪怕是八天线,其实还是二天线

function out = TDEncode(in, numTx)
%   Both SFBC and SFBC with FSTD
persistent hTDEnc;
if isempty(hTDEnc)% Use same object for either schemehTDEnc = comm.OSTBCEncoder('NumTransmitAntennas', 2);
end
switch numTxcase 1out=in;case 2 % SFBC% 为了公用Alamouti的代码,把第二个符号取负共轭in((2:2:end).') = -conj(in((2:2:end).'));% STBC Alamoutiy= step(hTDEnc, in);       % Scaleout = y/sqrt(2);case 4inLen=size(in,1);y = complex(zeros(inLen, 4));% 同样的操作,STBC到SFBC的转换in((2:2:end).') = -conj(in((2:2:end).'));% 取出一二两根天线,然后又是使用matlab的特性把他们两交织在一起% 这个在之前插值中已经使用过此技巧了% idx12的序列是1 2 5 6 9 10...% 这最终会被映射到13天线idx12 = ([1:4:inLen; 2:4:inLen]); idx12 = idx12(:);% 34天线% 映射到24天线idx34 = ([3:4:inLen; 4:4:inLen]); idx34 = idx34(:);% 进行STBCy(idx12, [1 3]) = step(hTDEnc, in(idx12));y(idx34, [2 4]) = step(hTDEnc, in(idx34));out = y/sqrt(2);
end
function y = TDCombine(in, chEst, numTx, numRx)
% LTE transmit diversity combining
%   SFBC and SFBC with FSTD.
persistent hTDDec;
% 为什么只设置2*2的呢,因为即使是4天线也是两个2天线组成的
% 接收具体是如何实现的呢
% function s = Alamouti_Combiner1(u,H)
% %#codegen
% % STBC_DEC STBC Combiner
% % Outputs the recovered symbol vector
% LEN=size(u,1);
% Nr=size(u,2);
% BlkSize=2;
% % 2个为一组
% NoBlks=LEN/BlkSize;
% % Initialize outputs
% h=complex(zeros(1,2));
% s=complex(zeros(LEN,1));
% % Alamouti code for 2 Tx
% indexU=(1:BlkSize);
% for m=1:NoBlks
% t_hat=complex(zeros(BlkSize,1));
% h_norm=0.0;
% % 一个天线一个天线来接受
% for n=1:Nr
% % 一次使用两个时间的即h1和h2
% h(:)=H(2*m-1,:,n);
% % 代表着能量
% h_norm=h_norm+real(h*h');
% r=u(indexU,n);
% r(2)=conj(r(2));
% % 分子
% shat=[conj(h(1)), h(2); conj(h(2)), -h(1)]*r;
% t_hat=t_hat+shat;
% end
% s(indexU)=t_hat/h_norm; % Maximum-likelihood combining
% indexU=indexU+BlkSize;
% end
% end
if isempty(hTDDec)% OSTBC combiner - always numTx = 2hTDDec = comm.OSTBCCombiner('NumTransmitAntennas', 2, ...'NumReceiveAntennas', numRx);
end
inLen = size(in, 1);
Index=(2:2:inLen)';
switch numTxcase 1y=in;case 2   % For 2TX - SFBC% 恢复本来大小in = sqrt(2) * in; % Scaley = step(hTDDec, in,chEst);% ST to SF transformation.% Apply blockwise correction for 2nd symbol combining% 恢复成SFBCy(Index) = -conj(y(Index));case 4   % For 4Tx - SFBC with FSTDin = sqrt(2) * in; % ScaleH = complex(zeros(inLen, 2, numRx));idx12 = ([1:4:inLen; 2:4:inLen]); idx12 = idx12(:);idx34 = ([3:4:inLen; 4:4:inLen]); idx34 = idx34(:);% 找到对应的信道H(idx12, :, :) = chEst(idx12, [1 3], :);H(idx34, :, :) = chEst(idx34, [2 4], :);y = step(hTDDec, in, H);% ST to SF transformation.% Apply blockwise correction for 2nd symbol combining% 恢复成SFBCy(Index) = -conj(y(Index));
end

2.全流程

function [dataIn, dataOut, txSig, rxSig, dataRx, yRec, csr_ref]...= commlteMIMO_TD_step(nS, snrdB, prmLTEDLSCH, prmLTEPDSCH, prmMdl)
%% TX
%  Generate payload
% 生成数据
dataIn = genPayload(nS,  prmLTEDLSCH.TBLenVec);
% 添加CRC
% Transport block CRC generation
tbCrcOut1 =CRCgenerator(dataIn);
% Channel coding includes - CB segmentation, turbo coding, rate matching,
% bit selection, CB concatenation - per codeword
[data, Kplus1, C1] = lteTbChannelCoding(tbCrcOut1, nS, prmLTEDLSCH, prmLTEPDSCH);
%Scramble codeword
scramOut = lteScramble(data, nS, 0, prmLTEPDSCH.maxG);
% Modulate
modOut = Modulator(scramOut, prmLTEPDSCH.modType);
% TD with SFBC
numTx=prmLTEPDSCH.numTx;
alamouti = TDEncode(modOut(:,1),numTx);
% Generate Cell-Specific Reference (CSR) signals
% CSR的处理
csr = CSRgenerator(nS, numTx);
csr_ref=complex(zeros(2*prmLTEPDSCH.Nrb, 4, numTx));
for m=1:numTxcsr_pre=csr(1:2*prmLTEPDSCH.Nrb,:,:,m);csr_ref(:,:,m)=reshape(csr_pre,2*prmLTEPDSCH.Nrb,4);
end
% Resource grid filling
txGrid = REmapper_mTx(alamouti, csr_ref, nS, prmLTEPDSCH);
% OFDM transmitter
txSig = OFDMTx(txGrid, prmLTEPDSCH);
%% Channel
% MIMO Fading channel
[rxFade, chPathG] = MIMOFadingChan(txSig, prmLTEPDSCH, prmMdl);
% Add AWG noise
nVar = 10.^(0.1.*(-snrdB));
rxSig =  AWGNChannel(rxFade, nVar);
%% RX
% OFDM Rx
rxGrid = OFDMRx(rxSig, prmLTEPDSCH);
% updated for numLayers -> numTx
[dataRx, csrRx, idx_data] = REdemapper_mTx(rxGrid, nS, prmLTEPDSCH);
% MIMO channel estimation
if prmMdl.chEstOnchEst = ChanEstimate_mTx(prmLTEPDSCH, csrRx,  csr_ref, prmMdl.chEstOn);hD     = ExtChResponse(chEst, idx_data, prmLTEPDSCH);
elseidealChEst = IdChEst(prmLTEPDSCH, prmMdl, chPathG);hD =  ExtChResponse(idealChEst, idx_data, prmLTEPDSCH);
end
% Frequency-domain equalizer
if (numTx==1)% Based on Maximum-Combining Ratio (MCR)yRec = Equalizer_simo(dataRx, hD, nVar, prmLTEPDSCH.Eqmode);
else% Based on Transmit Diversity  with SFBC combineryRec = TDCombine(dataRx, hD, prmLTEPDSCH.numTx, prmLTEPDSCH.numRx);
end
% Demodulate
demodOut = DemodulatorSoft(yRec, prmLTEPDSCH.modType, nVar);
% Descramble received codeword
rxCW =  lteDescramble(demodOut, nS, 0, prmLTEPDSCH.maxG);
% Channel decoding includes - CB segmentation, turbo decoding, rate dematching
[decTbData1, ~,~] = lteTbChannelDecoding(nS, rxCW, Kplus1, C1,  prmLTEDLSCH, prmLTEPDSCH);
% Transport block CRC detection
[dataOut, ~] = CRCdetector(decTbData1);
end

我们可以看到,在TM2中,层映射和预编码是在一步完成的,SFBC自然而然的把输出序列变为了两列,是非常巧妙的!其他的和SISO没有太大的变化

三.TM3:开环空间复用

1.原理

既然是MIMO了,首先我们先来讲一下预编码,理想的预编码是SVD,这是最好的,但很遗憾,这要求反馈信道,这是做不到的

因此LTE使用了码本,开环选用固定的码本,而闭环的会变化,这就是区别

主要注意,在TM3中,不仅仅有码本W,还有CCD,循环延时分集的操作,这是书中没有提到的,具体可以看https://zhuanlan.zhihu.com/p/495045923,把两天线的情况说的比较清晰了

function out = LayerMapper(in1, in2, prmLTEPDSCH)
% LTE Layer mapper for spatial multiplexing.
%
%   Assumes two codeword input for spatial multiplexing.
%   As per TS 36.211 v10.0.0, Section 6.3.3.2.%   Copyright 2012 The MathWorks, Inc.%#codegen
% Assumes the incoming codewords are of the same length.
% 参数获取
q = prmLTEPDSCH.numCodeWords;           % Number of codewords
v = prmLTEPDSCH.numLayers;                   % Number of layers
% 两个数据流,TM3总是支持双流的,而现在考虑的是满秩情况
inLen1 = size(in1, 1);
inLen2 = size(in2, 1);
% 根据数据流分类
switch q% 如果是单流,那直接根据层数分列就可以了case 1  % Single codeword% for numLayers = 1,2,3,4out = reshape(in1, [], v);% 双流的情况case 2  % Two codewordsswitch v% 两层case 2% 双流双层,分别对应即可out = complex(zeros(inLen1, v));out(:,1) = in1(:,1);out(:,2) = in2(:,1);case 3 % => different length input codewordsassert(false, '3 layers for 2 codewords is not implemented yet.');case 4% 双流四层% 一个流则对应两个层out = complex(zeros(inLen1/2, v));out(:,1:2) = reshape(in1, 2, inLen1/2).';out(:,3:4) = reshape(in2, 2, inLen2/2).';case 5 % => different length input codewordsassert(false, '5 layers for 2 codewords is not implemented yet.');case 6% 双流六层% 一个流对应三个层out = complex(zeros(inLen1/3, v));out(:,1:3) = reshape(in1, 3, inLen1/3).';out(:,4:6) = reshape(in2, 3, inLen2/3).';case 7 % => different length input codewordsassert(false, '7 layers for 2 codewords is not implemented yet.');case 8% 双流八层out = complex(zeros(inLen1/4, v));out(:,1:4) = reshape(in1, 4, inLen1/4).';out(:,5:8) = reshape(in2, 4, inLen2/4).';end
end% [EOF]
function [out1, out2] = LayerDemapper(in, prmLTEPDSCH)
% LTE Layer demapper for spatial multiplexing.
%
%   Assumes two codeword input for spatial multiplexing.
%   Based on TS 36.211 v10.0.0, Section 6.3.3.2.%   Copyright 2012 The MathWorks, Inc.%#codegen
%   Assumes the incoming codewords are of the same length. Assumes the
%   input signal is oriented similarly as the output of the layer mapper.q = prmLTEPDSCH.numCodeWords;       % Number of codewords
v = size(in, 2);                    % Number of layers
% 注意,这不是单纯的反过来,还是把数据映射到数据流,但要根据层来
switch qcase 1  % Single codewordout1 = in(:);out2 = out1; % dummycase 2  % Two codewordsswitch vcase 2out1 = in(:,1);out2 = in(:,2);case 4temp = in(:,1:2).';out1 = temp(:);temp = in(:,3:4).';out2 = temp(:);case 6temp = in(:,1:3).';out1 = temp(:);temp = in(:,4:6).';out2 = temp(:);case 8temp = in(:,1:4).';out1 = temp(:);temp = in(:,5:8).';out2 = temp(:);otherwiseout1 = in;out2 = in;endotherwiseout1 = in;out2 = in;
end
function out = SpatialMuxPrecoderOpenLoop(in, prmLTEPDSCH)
% Precoder for PDSCH spatial multiplexing
%#codegen
% Assumes the incoming codewords are of the same length
v = prmLTEPDSCH.numLayers;              % Number of layers
% Initialize the output
out = complex(zeros(size(in)));
inLen = size(in, 1);
% Apply the relevant precoding matrix to the symbol over all layers
for n = 1:inLen% Compute the precoding matrix% 获得 W D U[W, D, U] = PrecoderMatrixOpenLoop(n, v);T=W *D*U;% 预编码temp = T* (in(n, :).');out(n, :) = temp.';
end
function [W, D, U] = PrecoderMatrixOpenLoop(n, v)
% 开环MIMO的预编码矩阵
% 实现有问题,参考https://zhuanlan.zhihu.com/p/495045923进行了修改
% LTE Precoder for PDSCH spatial multiplexing.
%#codegen
% i四个就循环了,所以直接mod4
idx=mod(n-1,4);
switch v% 层为1,会退化到TM2,不考虑这样的情况case 1% 涉及到TM3模式的CCD有WUD三个矩阵% 单流就是这样,相当于没有进行CCDW=complex(1,0);U=W;D=W;% 层为2case 2% 是否少了(1/sqrt(2))% W= [1 0; 0 1];W=(1/sqrt(2)) * [1 0; 0 1];U=(1/sqrt(2))*[1 1;1 exp(-1j*pi)];D=[1 0;0 exp(-1j*pi*idx)];case 4 k=1+mod(floor(n/4),4);switch kcase 1, un = [1 -1 -1 1].';case 2, un = [1 -1 1 -1].';case 3, un = [1 1 -1 -1].';case 4, un = [1 1 1 1].';endW = eye(4) - 2*(un*un')./(un'*un);switch k    % order columnscase 3W = W(:, [3 2 1 4]);case 2W = W(:, [1 3 2 4]);enda=[0*(0:1:3);2*(0:1:3);4*(0:1:3);6*(0:1:3)];U=(1/2)*exp(-1j*pi*a/4);b=0:1:3;D=diag(exp(-1j*2*pi*idx*b/4));
end

2.全流程

function [dataIn, dataOut, txSig, rxSig, dataRx, yRec, csr_ref]...= commlteMIMO_SM_Mode3_step(nS, snrdB, prmLTEDLSCH, prmLTEPDSCH, prmMdl)
%% TX
%  Generate payload
dataIn = genPayload(nS,  prmLTEDLSCH.TBLenVec);
% Transport block CRC generation
tbCrcOut1 =CRCgenerator(dataIn);
% Channel coding includes - CB segmentation, turbo coding, rate matching,
% bit selection, CB concatenation - per codeword
[data, Kplus1, C1] = lteTbChannelCoding(tbCrcOut1, nS, prmLTEDLSCH, prmLTEPDSCH);
%Scramble codeword
scramOut = lteScramble(data, nS, 0, prmLTEPDSCH.maxG);
% Modulate
modOut = Modulator(scramOut, prmLTEPDSCH.modType);
% Map modulated symbols  to layers
% 调制后进行层映射,这里是单流
numTx=prmLTEPDSCH.numTx;
LayerMapOut = LayerMapper(modOut, [], prmLTEPDSCH);
% Precoding
% 预编码
PrecodeOut = SpatialMuxPrecoderOpenLoop(LayerMapOut, prmLTEPDSCH);
% Generate Cell-Specific Reference (CSR) signals
csr = CSRgenerator(nS, numTx);
csr_ref=complex(zeros(2*prmLTEPDSCH.Nrb, 4, numTx));
for m=1:numTxcsr_pre=csr(1:2*prmLTEPDSCH.Nrb,:,:,m);csr_ref(:,:,m)=reshape(csr_pre,2*prmLTEPDSCH.Nrb,4);
end
% Resource grid filling
txGrid = REmapper_mTx(PrecodeOut, csr_ref, nS, prmLTEPDSCH);
% OFDM transmitter
txSig = OFDMTx(txGrid, prmLTEPDSCH);
%% Channel
% MIMO Fading channel
[rxFade, chPathG] = MIMOFadingChan(txSig, prmLTEPDSCH, prmMdl);
% Add AWG noise
sigPow = 10*log10(var(rxFade));
nVar = 10.^(0.1.*(sigPow-snrdB));
rxSig =  AWGNChannel(rxFade, nVar);
%% RX
% OFDM Rx
rxGrid = OFDMRx(rxSig, prmLTEPDSCH);
% updated for numLayers -> numTx
[dataRx, csrRx, idx_data] = REdemapper_mTx(rxGrid, nS, prmLTEPDSCH);
% MIMO channel estimation
if prmMdl.chEstOnchEst = ChanEstimate_mTx(prmLTEPDSCH, csrRx,  csr_ref, prmMdl.chEstOn);hD     = ExtChResponse(chEst, idx_data, prmLTEPDSCH);
elseidealChEst = IdChEst(prmLTEPDSCH, prmMdl, chPathG);hD =  ExtChResponse(idealChEst, idx_data, prmLTEPDSCH);
end
% Frequency-domain equalizer
if (numTx==1)% Based on Maximum-Combining Ratio (MCR)yRec = Equalizer_simo(dataRx, hD,mean(nVar), prmLTEPDSCH.Eqmode);
else% Based on Spatial MultiplexingyRec = MIMOReceiver_OpenLoop(dataRx, hD, prmLTEPDSCH, nVar);
end
% Demap received codeword(s)
[cwOut, ~] = LayerDemapper(yRec, prmLTEPDSCH);
if prmLTEPDSCH.Eqmode < 3% DemodulatedemodOut = DemodulatorSoft(cwOut, prmLTEPDSCH.modType, mean(nVar));
elsedemodOut = cwOut;
end
% Descramble received codeword
rxCW =  lteDescramble(demodOut, nS, 0, prmLTEPDSCH.maxG);
% Channel decoding includes - CB segmentation, turbo decoding, rate dematching
[decTbData1, ~,~] = lteTbChannelDecoding(nS, rxCW, Kplus1, C1,  prmLTEDLSCH, prmLTEPDSCH);
% Transport block CRC detection
[dataOut, ~] = CRCdetector(decTbData1);
end

可以看到,数据先进行层映射,再进行预编码,在层映射阶段,数据被映射为层数列,而预编码的意义就是再把层数映射到天线数列

这里要重点说一下的是接收机的均衡的解算

function y = MIMOReceiver_MMSE_OpenLoop(in, chEst, nVar, v)
%#codegen
% MIMO Receiver:
%   Based on received channel estimates, process the data elements
%   to equalize the MIMO channel. Uses the MMSE detector.
% noisFac = numLayers*diag(nVar);
noisFac = diag(nVar);
numData = size(in, 1);
y = complex(zeros(size(in)));
%% MMSE receiver
for n = 1:numData[W, D, U] = PrecoderMatrixOpenLoop(n, v);% iWn = (W *D*U)';             % Orthonormal matrix,W并不一定是酉矩阵吗这是不对的iWn = inv(W *D*U);h = chEst(n, :, :);               % numTx x numRx% 哪有这样的,层不一定等于天线数!h = reshape(h(:), v, v).';    % numRx x numTxQ = (h'*h + noisFac)\h';x = Q * in(n, :).';tmp = iWn * x;y(n, :) = tmp.';
end

这份代码有一个重大的问题,就是它默认了层=天线数,这是错误的!但由于是2天线的情况,暂时不追究

此外,W不是一个酉矩阵,不可以这样解算

认识LTE(七):LTE中的两种无反馈模式:发射分集(TM2)和开环空分复用(TM3)相关推荐

  1. Linux中的两种守护进程stand alone和xinetd

    Linux中的两种守护进程stand alone和xinetd --http://www.cnblogs.com/itech/archive/2010/12/27/1914846.html#top 一 ...

  2. 批量插入数据库语句java_java相关:MyBatis批量插入数据到Oracle数据库中的两种方式(实例代码)...

    java相关:MyBatis批量插入数据到Oracle数据库中的两种方式(实例代码) 发布于 2020-7-22| 复制链接 本文通过实例代码给大家分享了MyBatis批量插入数据到Oracle数据库 ...

  3. java类型转换答案,在java中支持两种类型的类型转换,自动类型转换和强制类型转换。父类转化为子类需要强制转换。...

    在java中支持两种类型的类型转换,自动类型转换和强制类型转换.父类转化为子类需要强制转换. 更多相关问题 计算机病毒通过()传染扩散得极快,危害最大. 当一个现象的数量由小变大,另一个现象的数量相反 ...

  4. link linux 跨设备,Linux中的两种link方式

    Linux系统中包括两种链接方式:硬链接(hard link)和符号链接(symbolic link),其中符合链接就是所谓的软链接(soft link),那么两者之间到底有什么区别呢? inode ...

  5. Java中的两种异常类型及其区别?

    Java中的两种异常类型及其区别? 参考文章: (1)Java中的两种异常类型及其区别? (2)https://www.cnblogs.com/zxfei/p/11182730.html (3)htt ...

  6. <随笔03>Java中的两种异常类型

    <随笔03>Java中的两种异常类型 参考文章: (1)<随笔03>Java中的两种异常类型 (2)https://www.cnblogs.com/newlyfly/p/744 ...

  7. Allegro中显示两种单位方法

    Allegro中显示两种单位方法

  8. Matlab中的两种除法

    Matlab中的两种除法 matlab中的向量运算,试比较: >>a=[1,1,1] a = 1     1     1 >> b=[2,2,2] b = 2     2    ...

  9. ASP.NET Core MVC中的两种404错误

    我们在使用某些系统的时候,如果访问了一个不存在的地址怎么办,比如http://52abp. com/airport/fly:或者访问的地址路由和操作方法虽然存在,但是地址参数id不存在,比如https ...

最新文章

  1. 《疯狂Java讲义》11
  2. 14 张Python数据科学速查表
  3. 中点击按钮新建widget_iOS 14-Widget开发
  4. 基于事件驱动架构构建微服务第9部分:处理更新
  5. php 废弃,PHP 7 废弃特性
  6. expdp导出表结构_(转)oracle使用expdp、impdp和exp、imp导入导出表及表结构
  7. H264视频压缩编码标准简介(二)
  8. 在你的网站中使用 AdSense广告
  9. 「代码随想录」123.买卖股票的最佳时机III【动态规划】力扣详解!
  10. SHELL 读取文件的每一行内容并输出
  11. JDK API文档中文版(1.6、1.8、1.9)(附百度网盘下载地址)
  12. 诺基亚:丑小鸭的重生
  13. johnson算法(johnson算法最优顺序怎么算)
  14. UI控件--时间选择(日期拾取器)
  15. 机器学习实战之信用卡诈骗(一)
  16. PyTorch搭建ANN实现时间序列预测(风速预测)
  17. 启动IDEA都会打开Licenses激活弹窗
  18. 元宇宙都市传说02:《头号玩家》的隐喻
  19. opc是什么? opc ua是什么?
  20. 部分mp4视频在ios手机端上无法播放问题

热门文章

  1. mysql安装过程中root口令_MySQL5.7安装过程并重置root密码的方法(shell 脚本)
  2. java毕业设计基于的电商平台的设计与实现Mybatis+系统+数据库+调试部署
  3. FairyGUI学习使用
  4. MATLAB处理图像时出错:错误使用 rgb2gray>parse_inputs (line 80)MAP 必须为 m x 3 的数组。
  5. 【读书笔记->数据分析】BDA教材《数据分析》书籍介绍
  6. 医院IPTV系统解决方案找点量IPTV
  7. IC_EDA虚拟机安装
  8. ppt怎么压缩,ppt压缩教程
  9. 计算机2010应用安装方法,ppt2010安装应用程序教程
  10. Ubuntu安装QT Creater和配置