3、辨识实验设计:如何设计激励信号?PRBS信号的原理与生成
做系统辨识这么多年,我最大的体会是:实验设计比算法更重要。你想想看,数据质量不行,再牛的辨识算法也白搭。而激励信号的设计,就是实验设计的核心。
今天咱们聊聊PRBS信号。这东西看着简单,但用好了,辨识精度能上一个台阶。
3.1 为什么需要精心设计激励信号?
说白了,辨识的本质就是「用输入输出数据反推系统模型」。如果输入信号不够丰富,系统的一些动态特性就「藏」起来了,你根本辨识不出来。
我遇到过这样一个项目:一个温度控制系统的辨识,一开始随便给了个阶跃信号。结果辨识出来的模型,低频段还行,高频段完全对不上。后来换了PRBS信号,一次搞定。
好的激励信号,需要满足几个条件:
- 持续激励:信号要能激发系统的所有模态
- 幅值合适:太小信噪比低,太大可能非线性
- 频谱够宽:覆盖你关心的频段
- 工程可行:执行器能实现,不损坏设备
核心原则:激励信号的频谱宽度,决定了你能辨识到的系统带宽。
3.2 PRBS信号是什么?
PRBS,全称是Pseudo-Random Binary Sequence,伪随机二进制序列。名字挺唬人,其实就两个特点:
- 二进制:只有两个幅值,比如+1和-1
- 伪随机:看起来随机,但其实是确定性的,可以重复
为什么用二进制?因为执行器最容易实现。阀门全开全关、电机正反转,都是二进制操作。我在现场调试时,最怕那种需要连续变化信号的实验,执行器跟不上,数据全是畸变的。
PRBS的「伪随机」特性,保证了它的自相关函数接近白噪声。这意味着它的频谱在感兴趣的频段内是平坦的,能均匀地激励系统。
3.3 PRBS的数学原理
PRBS的核心是线性反馈移位寄存器(LFSR)。嗯,这里要注意,LFSR不是啥新东西,但用来生成PRBS特别顺手。
它的工作原理是这样的:
- 有一个n位的移位寄存器,初始状态不能全0
- 每个时钟周期,寄存器右移一位
- 新移入的位,由某些位的异或运算得到
- 输出就是移位寄存器的某一位
生成的序列长度是 N = 2^n - 1 个比特。比如n=7,序列长度就是127个点。
小技巧:我习惯用n=7或n=9的PRBS。n太小,序列太短,频谱不够密;n太大,实验时间太长,现场等不起。
PRBS的几个关键参数:
| 参数 | 含义 | 我的建议 |
|---|---|---|
| 阶数 n | 移位寄存器位数 | 7~11,看系统时间常数 |
| 时钟周期 T_clk | 每个比特的持续时间 | 系统最小时间常数的1/5~1/10 |
| 幅值 A | 信号幅值 | 额定范围的5%~15% |
| 序列长度 N | 2^n - 1 | 至少覆盖系统稳定时间的5倍 |
3.4 如何生成PRBS?
生成PRBS,我推荐两种方式:
方式一:查表法
对于常用阶数,直接查本原多项式。比如n=7,多项式是 x^7 + x^3 + 1。网上有现成的表,拿来就用。
方式二:代码生成
我个人习惯用Python或MATLAB生成。下面给个Python的例子:
import numpy as np
def generate_prbs(n, length=None):
"""
生成PRBS信号
n: 移位寄存器阶数
length: 输出序列长度,默认2^n-1
"""
# 初始化寄存器,不能全0
reg = [1] * n
# 本原多项式系数(常用值)
# n=7: [7, 3]; n=9: [9, 5]; n=11: [11, 9]
taps = {7: [7, 3], 9: [9, 5], 11: [11, 9]}
if n not in taps:
raise ValueError(f"不支持的阶数: {n}")
tap1, tap2 = taps[n]
seq_len = 2**n - 1 if length is None else length
output = []
for _ in range(seq_len):
# 输出最低位
output.append(reg[-1])
# 计算反馈位
fb = reg[tap1-1] ^ reg[tap2-1]
# 移位
reg = [fb] + reg[:-1]
# 映射到[-1, 1]
return np.array(output) * 2 - 1
# 生成n=7的PRBS
prbs = generate_prbs(7)
print(f"序列长度: {len(prbs)}")
print(f"前20个点: {prbs[:20]}")
注意:寄存器初始状态不能全0,否则永远出不来。我刚开始学的时候犯过这个错,debug了半天。
3.5 PRBS的频谱特性
PRBS的功率谱密度,在 0 到 1/(2*T_clk) 的频段内是平坦的。这个频段就是你的有效激励频段。
举个例子:如果T_clk=0.1秒,有效频段就是0~5Hz。系统的时间常数如果是0.5秒(对应约0.3Hz),那这个激励就够用了。
我曾经在一个电机辨识项目里,系统带宽约20Hz,我选了T_clk=0.01秒,有效频段到50Hz,覆盖得妥妥的。
3.6 工程中的避坑指南
做PRBS实验,有几个坑我踩过,分享给你:
- 幅值别太大:我曾经为了信噪比,把幅值调到20%,结果系统进入非线性区,辨识出来的模型全是错的
- 时钟周期别太短:执行器有响应时间,T_clk太短,执行器跟不上,信号就失真了
- 别忘了加直流偏置:PRBS是零均值的,但很多系统需要工作点。我习惯在PRBS上叠加一个直流分量
- 数据采集要同步:输入输出必须同步采样,否则相位信息全乱
我的经验:正式实验前,先跑一次短序列的PRBS,看看执行器能不能跟上。没问题了再跑完整的实验。这招帮我省了不少事。
3.7 知识体系总览
下面这张图,把PRBS相关的核心逻辑串起来了:
PRBS这东西,原理不复杂,但用好了真能提升辨识精度。我建议你从n=7开始试,T_clk取系统最小时间常数的1/10左右,幅值先保守点。跑一次实验,看看数据质量,再调整参数。
记住:好的激励信号,是成功辨识的一半。