Leveling & ARB
DUT RX 校准流程中的 Leveling & ARB 特性化
概述
本文档描述 RequestExternalStimuli RPC 中 步骤 2.5 Leveling 和 步骤 2.6 ARB 特性化 的实现方案。
功率计底层驱动实现(NRPPowerMeter 类),本模块直接调用 pm.measure_power(freq_hz) 获取 dBm 值,专注于 Leveling 闭环算法和 ARB 特性化业务逻辑。
在 RequestExternalStimuli 中的位置
RequestExternalStimuli()
│
├── 步骤 2.1: 判断信号类型 (CW / 调制 / 多音)
├── 步骤 2.2: 分配硬件资源
├── 步骤 2.3: 加载波形 (仅调制/多音) ← 已实现
├── 步骤 2.4: 配置信号发生器 (频率、功率、RF ON) ← 已实现
│
├── 步骤 2.5: Leveling (电平校准) ★
│ └── perform_leveling(sg, pm, ...)
│
├── 步骤 2.6: ARB 特性化 (仅多音) ★
│ └── arb_characterization(sg, pm, arb_uploader, ...)
│
└── 步骤 2.7: 计算端口偏移响应
提供的功率计驱动
代码位置: tx_output_power_cal_service/nrp_power_meter.py
类名: NRPPowerMeter
连接方式: VISA (USB/LAN)
支持型号: R&S NRP8S / NRP40S 系列
Leveling 和 ARB 特性化中实际调用的函数:
| 函数 | 功能 | 返回 |
|---|---|---|
pm.measure_power(frequency_hz, average_count=4) |
设置频率+平均,测量功率 | float (dBm) 或 None |
pm.set_frequency(frequency_hz) |
设置功率计校正频率 | — |
pm.read_power() |
单次测量 (不改频率) | float (dBm) 或 None |
pm.connect() / pm.disconnect() |
连接/断开 VISA | — |
pm.reset() |
复位到已知状态 | — |
pm.zero_calibration() |
校零 (需断开 RF) | — |
使用方式:
from nrp_power_meter import NRPPowerMeter
pm = NRPPowerMeter(visa_resource="USB0::0x0AAD::0x00E2::108020::INSTR")
pm.connect()
pm.reset()
步骤 2.5: Leveling
触发条件
| 情况 | 行为 |
|---|---|
| 开关网络不支持 Leveling | 跳过,返回 0 |
| 信号输出未开启 | 跳过,返回 0 |
| 14天内缓存命中 | 用缓存值,不实测 |
| 以上都不满足 | 执行闭环校准 |
算法 (对应 C# PerformLevelingAsync)
wantedLevel = stimuliLevel + pathCompensation
迭代 (最多 10 次):
1. sg.set_level(rfLevel)
2. measured = pm.measure_power(freq_hz, average_count=4)
3. deviation = measured - wantedLevel
4. |deviation| < 0.1 dB → 收敛,完成
5. 每 3 次迭代: adjustmentFactor *= 0.75
6. adjustment = (wantedLevel - measured) * adjustmentFactor
7. |累计调整| > 2.0 dB → 异常终止
8. rfLevel += adjustment
调用方式
from service_client.leveling import perform_leveling
result = perform_leveling(
sg=signal_generator,
pm=power_meter, # NRPPowerMeter 实例
stimuli_level_dbm=-30.0,
frequency_hz=3.5e9,
path_compensation_db=3.7, # 路径衰减 (查表或默认 0)
serial_number="1419.4501k02/110489",
waveform="cw",
leveling_cache=leveling_cache, # 可选,14天缓存
)
# result.rf_level_dbm → 信号源最终电平
# result.signal_deviation_db → 残余偏差
# result.converged → 是否收敛
# result.from_cache → 是否来自缓存
步骤 2.6: ARB 特性化
触发条件
| 情况 | 行为 |
|---|---|
| 不是多音信号 | 跳过 |
| 输出未开启 / 调制未开启 | 跳过 |
| 开关网络不支持 ARB 特性化 | 用波形元数据默认值 |
| 14天内缓存命中 | 用缓存 |
| 以上都不满足 | 执行逐音测量 |
流程 (对应 C# RFGeneratorCharacterization)
Step 1: ALC 功率搜索
生成 +50kHz 单音 IQ → 上传 ARB → pm.measure_power() → 基准
Step 2: 逐音测量 (跳过中心音)
FOR each tone:
生成该音单音 IQ (sinusoidal_signal)
上传 ARB → 播放
pm.measure_power(tone_freq) → 记录
Step 3: 恢复原始多音波形
Step 4: rfLevel[tone] = measured - 10*log10(N+1)
Step 5: 中心音 = (相邻低音 + 相邻高音) / 2
Step 6: phase = hilbert_transform(rfLevel)
Step 7: 验证: 相邻差 < 0.5dB, 总差 < 1.5dB
Step 8: 保存缓存
调用方式
from service_client.leveling import arb_characterization
result = arb_characterization(
sg=signal_generator,
pm=power_meter, # NRPPowerMeter 实例
arb_uploader=arb_uploader,
tone_frequencies_hz=[3.497e9, 3.498e9, 3.499e9, 3.5e9, 3.501e9, 3.502e9, 3.503e9],
carrier_freq_hz=3.5e9,
sample_rate=122880000.0,
no_tones=7,
original_waveform="multitone.wf",
serial_number="1419.4501k02/110489",
wanted_level_dbm=-30.0,
arb_cache=arb_cache, # 可选,14天缓存
)
# result.rf_levels → 每个音的补偿电平 (dBm)
# result.phases → 每个音的相位 (rad)
# result.from_cache → 是否来自缓存
在 RFStimuliServicer 中的集成
from nrp_power_meter import NRPPowerMeter
from service_client.leveling import perform_leveling, arb_characterization
from service_client.leveling_cache import LevelingContainer, ArbCalibrationContainer
class RFStimuliServicer:
def __init__(self, signal_generator, power_meter_resource, ...):
self._sg = signal_generator
self._pm = NRPPowerMeter(visa_resource=power_meter_resource)
self._leveling_cache = LevelingContainer("leveling_cache.json")
self._arb_cache = ArbCalibrationContainer("arb_calibration_cache.json")
...
def RequestExternalStimuli(self, request, context):
# ... 步骤 2.1 ~ 2.4 ...
# 连接功率计
self._pm.connect()
self._pm.reset()
for sig_config in request.configurations:
for signal in sig_config.signals:
self._configure_signal(signal) # 步骤 2.4
# 步骤 2.5: Leveling
if self._leveling_support and self._sg.output_enabled:
lev_result = perform_leveling(
sg=self._sg,
pm=self._pm,
stimuli_level_dbm=stimuli_level,
frequency_hz=carrier_freq_hz,
path_compensation_db=path_compensation,
serial_number=sg_serial,
waveform=waveform_name,
leveling_cache=self._leveling_cache,
)
signal_deviation = lev_result.signal_deviation_db
else:
signal_deviation = 0.0
# 步骤 2.6: ARB 特性化 (仅多音)
if is_multitone and self._arb_char_support:
arb_result = arb_characterization(
sg=self._sg,
pm=self._pm,
arb_uploader=self._arb_uploader,
tone_frequencies_hz=tone_freqs,
carrier_freq_hz=center_freq,
sample_rate=sample_rate,
no_tones=no_tones,
original_waveform=waveform_name,
serial_number=sg_serial,
wanted_level_dbm=stimuli_level,
arb_cache=self._arb_cache,
)
rf_gen_levels = arb_result.rf_levels
rf_gen_phases = arb_result.phases
# 步骤 2.7: 计算端口偏移
...
self._pm.disconnect()
return ConfigurationResponse(...)
已实现的模块
| 文件 | 内容 | 对应 C# |
|---|---|---|
service_client/leveling.py |
perform_leveling() + arb_characterization() |
ExternalSignalStimuli.PerformLevelingAsync() + RFGeneratorCharacterization |
service_client/rf_stimuli_calculate.py |
sinusoidal_signal() + hilbert_transform() + validate_tone_consistency() |
RFStimuliCalculate.cs |
service_client/leveling_cache.py |
LevelingContainer + ArbCalibrationContainer |
LevelingContainer.cs + ArbCalibrationContainer.cs |
service_client/power_meter.py |
接口说明 | — |
文件结构
test-interface-client/
├── service_client/
│ ├── leveling.py # ★ Leveling + ARB 特性化核心逻辑
│ ├── leveling_cache.py # ★ 14天缓存 (JSON 文件读写)
│ ├── rf_stimuli_calculate.py # ★ 计算辅助函数
│ ├── power_meter.py # 接口说明 (实际用 NRPPowerMeter)
│ ├── rf_stimuli.py # SignalGeneratorController + RFStimuliServicer
│ └── waveform_loader.py # ARB 波形加载
├── test_case/
│ └── test_leveling_arb_characterization.py # 端到端验证脚本
└── docs/
├── EXTERNAL_SIGNAL_STIMULI_WORKFLOW.md
└── leveling_arb_characterization_workflow.md ← 本文档
tx_output_power_cal_service/ # 功率计代码
├── nrp_power_meter.py # NRPPowerMeter 驱动类
└── tx_output_power_cal/
├── servicer.py # TxOutputPowerCalService gRPC 服务
└── calibration_manager.py # 脉冲 Leveling 业务逻辑

浙公网安备 33010602011771号