一直想画一个捕获过程的3D图像来直观感受自相关峰值,今天终于鼓捣出来了,本文就用于存档。
我想画的图是这样的:
首先,因为这个SDR程序每个函数都单独封装好了,所以还是要运行postProcess这个函数。
一开始我想在plotAcquisition里面加入画图部分,也就是把acqResults.carrFreq, acqResults.codePhase,acqResults.peakMetric分别作为xyz,但是发现画不出来。于是去检查它们的类型,发现这三个都是1×32向量,这时才反应过来搞错了,acqResults结构体存放的应该是32颗卫星的载波相位、码相位和最大峰值,而我要找的是对某颗具体卫星在码和载波全平面上的自相关情况,所以不应该对这个结构体进行操作。
那么因为plotAcquisition函数输入的参数就只有acqResults,显然我们不能够在这个函数里面做手脚了,于是只能来到捕获的函数acquisition.
回忆捕获的具体操作,发现在对32颗卫星进行循环处理的过程中,用来暂时存放数据的是results,并且它只是个矩阵,不是结构体,也就是说行和列分别表示码和载波,而对应元素
a
i
j
a_{ij}
aij表示自相关数值。
现在问题就很简单了,也就是研究怎么把results这个矩阵变成三维图像。进行了一些搜索之后也是成功画了出来。从结果来看,15号卫星是成功捕获的,所以选择画它的三维图像:
...
[peakSize frequencyBinIndex] = max(max(results, [], 2));
[peakSize codePhase] = max(max(results));%最大值所对应的列索引即码相位
% =============================
if(PRN == 15)
[m, n] = size(results);
[X, Y] = meshgrid(1:n, 1:m);
% 绘制三维图像
figure;
surf(X, Y, results);
shading flat
xlabel('carrFreq');
ylabel('codePhase');
zlabel('value');
title('3D Surface Plot');
end
% ==============================
%--- Find 1 chip wide C/A code phase exclude range around the peak ----
samplesPerCodeChip = round(settings.samplingFreq / settings.codeFreqBasis);%每个码片的采样值个数
excludeRangeIndex1 = codePhase - samplesPerCodeChip;
excludeRangeIndex2 = codePhase + samplesPerCodeChip;
...
我是把画图的代码插入到了这部分,因为前面已经开始找最大值来确定载波和码相位了,所以这里的results一定是所有操作都结束之后最终的矩阵。
思想也比较简单,首先进入判断语句,因为results每轮循环都会变化,如果不判断的话会出32张图。选定15号星之后,用size函数确定results矩阵的横纵尺寸,注意这里尺寸是个数值,所以后面需要用 : 取范围。
两个关键函数,一个是meshgrid,用来生成xy二维网格(也就是图像的底面);
另一个是surf函数,它就是画三维图像用的,注意这里第三个输入的参数需要是个矩阵,并且尺寸也要吻合。
最后调整一下配色,标上三个轴的名称和图片标题,捕获的程序就修改好了。然后只需要运行postProcess就大功告成。
总结:
画图的两个函数并不难,网上很容易搜到相关信息,用的时候查就行,主要是选择使用什么数据生成图像,所以一开始就把有用的数据存好是很重要的(比如说这里就是用的矩阵形式,非常适配捕获的这个场景,也方便后续画图和找max)对于我们使用者来说,要明白别人写好的源程序里每个变量到底存放的是什么数据,按照什么原则存放,这样才能正确处理和使用。
今天也算是知道了怎样依据矩阵和结构体画图,具体语句应该如何编写(其实大差不差,结构体就是变成A.a形式而已,它们都是要把有用数据拉出来赋值给XYZ这样子)
tbc…