- 发布日期
WRSP6TK 雷达 TR 测试软件源码精讲(4):暗室接收波瓣图(模式 4)
作者
M先生
WRSP6TK 雷达 TR 测试软件源码精讲(4):暗室接收波瓣图(模式 4)
本篇是系列中最复杂的一章。模式 4 的目标:在暗室里测量相控阵天线的接收方向图(波瓣图)——转台在仰角方向扫描,雷达用 DBF 同时形成多个接收波束,软件把每个波束在不同仰角上的响应记录下来,画成方向图。
一、整体流程图
┌─ DarkRoomRecvInit ──────────────────────────────────────┐
│ 1. 检查参数文件(LobeRecv...) │
│ 2. 关 TR、设直通系数 │
│ 3. 打开 UART(转台位置同步) │
│ 4. m_BeamBitNum = Cmd[dbfF0Beam] >> 1 (波位数) │
│ 5. 生成 DBF 波束系数(按 m_TrTestAngel + 窗函数) │
│ —— 每个波位一组系数,USER_SetBeamPara 下发 │
│ 6. 生成波位表 m_ScanBeamBit[](见下) │
│ 7. 开 DIFR 接收通道 │
│ 8. 初始化:m_LastDataEL=0, m_BeamCount=0, │
│ m_FirstDataELFlag=TRUE │
└──────────────────────────────────────────────────────────┘
│ 转台扫描,每帧(每个仰角)到达
▼
┌─ DarkRoomRecvDataProcess(每帧)────────────────────────┐
│ if 不扫描模式: │
│ 直接按波位 i 从 globalBuf 取 H/V I/Q → 暂存 │
│ else 扫描模式: │
│ 1. m_BeamCount++; 读仰角状态字 m_DataEL │
│ 2. 计算 StartBeamBit,在波位表中匹配 → Addr │
│ 3. 从 Addr 开始连续取 m_BeamBitNum 个波位的 H/V I/Q │
│ 4. 回到起始仰角且帧数够 → 一圈完成 → SetEvent │
└──────────────────────────────────────────────────────────┘
│
▼
┌─ DarkRoomRecvDataProc(处理线程)───────────────────────┐
│ 全部单元×份数扫完? │
│ ├─ 否 → m_CurScanedAllGapCount++,继续 │
│ └─ 是 → 关设备 → 蛇形数据重排 → 逐波位写文件 → 完成弹窗 │
└──────────────────────────────────────────────────────────┘
二、波位表(BeamBit)生成算法
2.1 什么是波位(Beam Bit)?
波位 = DBF 一个输出波束的指向编码。暗室测试时,转台在仰角方向扫,而 DBF 一次形成 个波束(波位),每个波位指向一个仰角。转台每到一个位置,软件要知道"这一帧数据对应波位表的哪一段"——这就是波位表的作用。
2.2 不扫描模式
if((Cmd[dbfSchema] & 0x01) == 0x01) // 不扫描
{
m_BeamBitChangeTime = 1;
for (i=0; i<m_BeamBitNum; i++)
m_ScanBeamBit[i] = (USHORT)(m_TrTestAngel[i]*10 + 450);
}
编码规则:角度(°) × 10 + 450。0.1° 分辨率,450 表示 0°(对应 -45°~+45° 范围的无符号编码)。
2.3 扫描模式
m_BeamBitChangeTime = (Cmd[dbfF0EOEL] - Cmd[dbfF0SOEL]) / Cmd[dbfF0Step] + 1;
// 波位组数 = (结束仰角 - 起始仰角)/步进 + 1
if (m_BeamBitNum % 2) m_BeamBitOffset = 0; // 奇数波位:天然对称
else m_BeamBitOffset = Cmd[dbfF0Interval] >> 1; // 偶数:偏半个间隔
k=0;
for (i=0; i<m_BeamBitChangeTime; i++) // 外循环:扫描组
for (j=0; j<m_BeamBitNum; j++) // 内循环:组内波位
m_ScanBeamBit[k++] = Cmd[dbfF0SOEL] + i*Cmd[dbfF0Step]
+ (j - (m_BeamBitNum >> 1))*Cmd[dbfF0Interval]
- m_BeamBitOffset;
公式解读:
| 项 | 含义 |
|---|---|
| 第 组扫描位置的起始仰角 | |
| 组内第 个波位相对组中心的间隔 | |
| 偶数波位时平移半个间隔,让波束组关于中心对称 |
为什么偶数波位要偏半个间隔? 时 得到 ,名义中心落在第 2、3 波位之间(不对称)。减去 后变成 ,组中心正好落在两组波位正中间,且与下一组()衔接时不重叠。
例子:SOEL=200(-20°),EOEL=600(+20°),Step=100(1°),Interval=100(1°),N=4:
- 组数 = (600-200)/100+1 = 5
- 第 0 组波位:-5°, +5°, +15°, +25°(编码 400,500,600,700 → 等等,验证:SOEL=200 + 0 + (0-2)*100 - 50 = 50 → 5°?)
实际计算:(编码 -50 → -5°),(5°),(15°),(25°)。第 1 组: 组中心每次 +100(1°),波束组交错 0.5°,形成交错的扫描栅格。
三、DBF 波束系数计算(接收波束形成)
3.1 窗函数初始化
switch(g_DBFBeamWindowType)
{
case 0: get_Rectangle(m_WindowPara, N); break; // 矩形窗
case 1: get_Hanning(m_WindowPara, N); break; // 汉宁窗
case 2: get_Hamming(m_WindowPara, N); break; // 汉明窗
case 3: get_Blackman(m_WindowPara, N); break; // 布莱克曼窗
case 4: get_Triang(m_WindowPara, N); break; // 三角窗
case 5: get_taylorwin(m_WindowPara, N, p0, p1); break; // 泰勒窗
}
术语注释(窗函数):给阵列各单元的幅度加一个锥削权重,抑制副瓣。
- 矩形窗:均匀激励,副瓣最高(-13.2dB),波束最窄
- 汉宁/汉明窗:余弦类锥削,副瓣 -31.5/-43dB,主瓣展宽约 1.6 倍
- 泰勒窗:可指定副瓣电平(如 -30dB),主瓣宽度可控,是雷达阵列最常用的低副瓣窗
3.2 波束系数公式
phase_inc = -2*pi*g_BeamArrayInterval * sin(θ_j) * m_RfFreqFloat / 30.0f;
for (i=0; i<N; i++)
{
amp = 0x7400 * m_WindowPara[i]; // 幅度 = 基准 × 窗
phase = phase_inc * i; // 相位线性递增
m_DBFBeamCoeff_DataI[j][i] = amp * cos(phase);
m_DBFBeamCoeff_DataQ[j][i] = amp * sin(phase);
}
推导:第 个波束指向 ,第 个单元的相位:
其中 , 为单元间距。代码里 m_RfFreqFloat/30.0f 是因为:频率以 GHz 计、间距以 cm 计、光速 30 cm/GHz·(ns 换算),即 :
所以 phase_inc = -2π × d × sinθ × f/30 正是"相邻单元相位差"(负号表示波束指向方向)。
0x7400 是什么? Q15 格式的 0.90625(29/32 ≈ -0.855dB)——默认系数基准,留约 0.86dB 余量防 DBF 求和溢出(详见《DBF 波束系数 0x7400 解析》)。
3.3 为什么 DBF 系数要在这里"现算"?
暗室测试要测不同指向的波束,每个波束需要不同的相位梯度。测试软件按 m_TrTestAngel[j](测试角度表)现场生成每组系数,通过 USER_SetBeamPara 下发到 DSP——这是"软件定义波束"(软件波束形成)的典型实现:同一硬件,不同时刻用不同系数,形成不同指向的波束。
四、数据获取:仰角匹配与多波位提取
4.1 仰角状态字与波位匹配
m_DataEL = (USHORT)(dspBuf[gZVWStart.STATUS_START + dspELSt]); // 当前仰角
StartBeamBit = m_DataEL/64 - (m_BeamBitNum >> 1)*Cmd[dbfF0Interval] + m_BeamBitOffset;
for (i=0; i<m_BeamBitChangeTime*m_BeamBitNum; i++)
if (StartBeamBit == m_ScanBeamBit[i]) { Addr = i; break; }
这是本模式最关键的环节:把转台的实际仰角(状态字)换算成波位表索引。 把状态字仰角编码换算到波位表编码(若状态字用 1/64° 编码,则 /64 得到度,再与 ×10+450 编码的波位表匹配——注意这里可能存在单位不匹配的隐患,详见系列第 1 篇的分析)。
匹配失败时 Addr 保持 0:这意味着该帧数据会被当作"第 0 组波位"的数据,造成波位错位——这也是前面分析过的静默错误风险点。
4.2 一圈完成判定
if ((m_FirstDataEL == m_DataEL) && (m_BeamCount >= m_BeamBitChangeTime))
{
// 转台扫完一圈回到起始仰角,且帧数足够 → 一圈完成
m_LastDataEL = 0; m_BeamCount = 0; m_FirstDataELFlag = TRUE;
SetEvent(m_TRTestDataEvent); // 通知处理线程
}
物理意义:转台从起始仰角扫到结束再回来 = 一圈。软件用"仰角状态字回到初值 + 帧数达标"双重条件判断一圈完成——状态字保证位置对,帧数保证数据全。
五、蛇形扫描与数据重排
5.1 为什么需要重排
暗室测试时,阵列按"行-列"方式扫描(转台+阵面移动),数据到达顺序是蛇形的:
物理扫描路径:行0 →(从左到右)→ 行1 ←(从右到左)← 行2 → ...
数据到达顺序:0,1,2,...,N-1(行0);N-1,...,1,0(行1)...
而 m_DarkRoomSouIQ[i][j] 约定:i=单元份数,j=线数(行)
5.2 重排代码
if(m_ArrayScanDir) // 反向蛇形
{
k = 0;
for (i=0; i<m_ArrayGapNum; i+=2) // 偶数行
{
for (j=m_NeedScanArrayNum-1; j>=0; j--) // 反向
m_DarkRoomSouIQ[i][j] = tmp[k++];
for (j=0; j<m_NeedScanArrayNum; j++) // 正向
m_DarkRoomSouIQ[i+1][j] = tmp[k++];
}
}
else // 正向
{ ... 与之对称 ... }
核心思想:把"蛇形到达"的数据,按"偶数行正向、奇数行反向"的规律重新铺回规则网格,保证后续处理(方向图计算)看到的是物理位置正确的二维阵列数据。
六、数据文件输出
// 逐波位写文件
for (nn=0; nn<m_BeamBitChangeTime*m_BeamBitNum; nn++)
{
ArrayFileName.Format("ArrayNear_暗室H_%.3fGHz_%.1f°_%04d....txt",
m_RfFreqFloat, (m_ScanBeamBit[nn]-450)*0.1f, ...);
WriteDarkRoomData(ArrayFileName, isTwo);
}
文件名里的角度 = (波位编码-450)×0.1°——一个波位一个文件,文件内容是该波位在阵列所有单元/线数上的幅度相位矩阵:
[测试方式说明]
[阵列信息] 频率、水平单元数、垂直线数、X/Y间距
[阵列数据] Amplitude Phase(每单元一行,按行×列)
后续用这些文件离线计算方向图(
OnBnClickedButtonTrdatacalculate,见第 7 篇)。
七、完成判定与状态显示
if (m_CurScanedAllGapCount >= (int)(m_NeedScanArrayNum * m_ArrayGapNum - 1))
→ 全部数据采集完成,进入收尾(重排、写文件、弹窗)
else
→ m_CurScanedAllGapCount++; // 继续下一圈
每完成一圈 m_CurScanedAllGapCount++,直到达到"单元数×份数"的总量——圈数与数据总量解耦,任何一圈缺帧都不会让程序误判完成(但会导致该圈数据空洞,需靠帧计数校验)。
八、一句话总结
暗室接收波瓣图 = 转台仰角扫描 + DBF 多波位同时接收 + 波位表匹配定位 + 蛇形重排记录。 关键技术点:波位表生成算法(偶数波位半间隔偏移)、DBF 系数在线生成(窗函数+相位梯度)、仰角状态字与波位匹配、一圈完成的双条件判定。它是"软件定义波束"在测试领域最典型的应用。
WRSP6TK 雷达 TR 测试软件源码精讲(4):暗室接收波瓣图(模式 4)
评论加载中…
