1. 项目概述为什么要费劲测一台直流电机的频率响应做电机控制这些年我一直觉得一个有意思的事情是很多工程师调试伺服系统、PID参数时全靠“感觉”和“试错”。先给个积分增益跑一下看抖不抖再给个比例增益听一下有没有嗡嗡声。说实话这种方法并不是不行但它的天花板很低——尤其是当你面对一台新型号电机、一套不熟悉的机械负载或者一个要求很高的运动控制项目时这种“玄学调参”会浪费大量时间甚至把系统调到震荡边缘还不自知。测量直流电机的频率响应本质上就是在做一件事把这个“玄学”变成“科学”。它就像给电机做一次体检把电机从“电压输入”到“转速输出”这一整条路径的动态特性用一条清晰的曲线画出来。这条曲线我们通常叫它伯德图Bode Plot它告诉我们这台电机在什么频率下响应灵敏在什么频率下开始衰减在什么频率下会出现谐振峰值以及它的相位滞后有多大。为什么这些信息值钱因为闭环控制器的设计本质上就是在跟这些“频率特性”打交道。你知道了电机的带宽就知道你的速度环增益最多能推到多少而不引发振荡你知道了机械谐振点的位置就知道该在滤波器里加陷波器还是低通你看懂了相位裕度就知道系统的稳定余量到底够不够。这篇博文适合谁说实话它不是写给纯做理论的人看的。如果你正在做运动控制、机器人、自动化设备、无人机云台、电动工具或者任何用到直流电机闭环控制的项目而且你已经对PID、编码器、PWM这些概念有一定基础那么这篇内容对你最有用。当然如果你想深入了解电机特性或者纯粹好奇工程师怎么给电机“做体检”这篇文章也足够通俗你可以跟着步骤把实验复现出来。我在这里要提醒一句这个测量方法不只是针对“直流有刷电机”它同样适用于无刷直流电机BLDC、永磁同步电机PMSM的机械频率特性辨识只是驱动方式稍有不同。文章里的核心思路是通用的。2. 整体思路拆解扫频vs逐点正弦我的选型理由2.1 频率响应测量的两种主流方案测量系统频率响应业界最常用的方法大概分两类扫频正弦Swept Sine / Chirp和步进正弦Stepped Sine。这两种我都实测过都有自己的优缺点这里说下我的感受。扫频正弦的思路很简单从一个低频比如0.1Hz开始连续或分段地把正弦信号的频率逐渐升高到目标上限比如100Hz甚至更高同时记录系统的输入和输出最后通过FFT或相关分析法得到每个频率点的幅值增益和相位差。步进正弦则更“笨”一点不连续扫频而是设定一系列离散的频率点比如0.1、0.2、0.5、1、2、5、10、20、50、100Hz在每个频率点单独发一段固定频率的正弦波等系统稳定后记录稳态输出算完这个点的幅值相位再跳到下一个频率点。我做这个项目时两台电机一台用了扫频一台用了步进正弦对比下来发现维度扫频正弦步进正弦测量速度快几十秒完成全频段慢每个频点都要等待稳定可能要几分钟频谱泄露风险高需要加窗处理低稳态正弦信号本身就很干净非线性敏感度较高瞬态响应会混入结果较低可以只取稳态部分平均对摩擦/死区的鲁棒性较弱低速段容易失真较强每个点都可以做补偿硬件实现难度低一个对数扫频信号即可低但要控制频率切换时序数据后处理复杂需要FFT加窗简单逐点算RMS和相位如果你只求快、求方便而且电机负载不复杂扫频完全够用。但如果电机带载后存在明显非线性比如齿轮箱齿隙、皮带打滑、摩擦负载建议老老实实用步进正弦。这个项目里最终我主要采用步进正弦因为实测数据更干净拟合出的模型参数也更可信。2.2 为什么选择电流环内环机械外环的测量拓扑这里有一个关键设计决策值得展开讲讲。直流电机的“完整”传递函数既包括电气部分电枢回路也包括机械部分转动惯量、阻尼。理论上你确实可以直接从“电压输入”到“转速输出”建一个完整模型。但实际测量时我强烈建议你把电流环先闭环起来然后测量“电流给定→转速输出”的频响。为什么两个原因。第一电机的电气时间常数通常远小于机械时间常数。直接测电压到转速得到的伯德图会在某个转折频率处混合着电气和机械两个极点你很难把它们区分开。但如果先把电流环闭环带宽通常做到1kHz以上电流环的动态相对机械响应来说快得多于是整个测量主通道就简化成了“电流→力矩→转速”的机械路径物理意义更单纯。第二电流环闭环后会显著降低电枢电阻、反电动势等因素对测量结果的影响。这意味着你测出来的频率响应曲线更接近“纯机械特性”这对后续机械参数辨识、负载识别都更有利。实际接线也很简单你用一台带电流环的驱动器把速度环断开直接给电流环一个电流指令信号然后高速采集编码器转速作为系统的输出。整套系统的“输入”就是电流指令安培“输出”就是电机转速rad/s。2.3 激励信号幅值的选择逻辑选幅值这件事看起来好像没什么技术含量其实坑很多。如果激励幅值太大电机会跑飞、电流会超限甚至撞上机械限位如果幅值太小摩擦和死区会吃掉有效信号输出的转速波形会严重扭曲测出来的增益比实际偏小。我可以分享一个实际选择的经验公式先用一个很小的正弦电流比如额定电流的2%频率放在中频段比如10Hz观察电机的转速波动幅度。如果转速波动峰值小于额定转速的2%说明激励太弱需要放大如果超过额定转速的10%就要小心非线性带来的谐波污染。对于多数小型直流电机额定电流1~3A我从额定电流的5%开始试基本都能找到合适的区间。另外一个实用技巧是低速运行阶段把电流幅值适当加大一些因为摩擦在低速段占的比重很大你需要用更大的力矩来“冲破”静摩擦的束缚才能在输出里看到有效的运动。3. 核心细节解析与实操要点3.1 硬件链路的搭建编码器分辨率决定了你的测量上限测频响本质上是一个高保真“录音”过程输入一个已知信号记录输出响应。这套系统里最关键的两个硬件是信号生成端和转速测量端。信号生成端我用的是一块带16位DAC的实时控制板配合一个简单的C程序生成正弦扫频序列。很多人会问直接用函数信号发生器行不行完全可以但要注意信号发生器输出的是电压信号而你的驱动器电流环输入通常也是电压接口比如0-10V对应0-额定电流所以要做一下标定——知道几伏对应几安培。不做这一步后面拟合模型时电流到力矩的换算就会出现系统性偏差。转速测量端我强烈建议用增量式编码器 高速计数器/定时器捕获而不是用测速发电机的模拟电压。测速发电机的输出电压纹波大、响应慢而且模拟采样的噪声会直接污染你的频响曲线。编码器的分辨率直接决定了你的测量精度上限——比如每转1000线的编码器配合4倍频后是4000计数/转在转速100rpm约1.67rps下每秒能产生约6670个脉冲。如果你的采样频率是1kHz那么每个采样周期内大约能捕获6-7个脉冲够用了。但如果转速低到10rpm每周期只有不到1个脉冲测出来的转速数据会锯齿状严重频响的数据质量就完蛋了。我在这个项目里用的是一台2000线编码器4倍频后8000计数/转配合5kHz的采样频率在最低测试频率0.1Hz、转速波动幅度可控的前提下数据质量还是能保证的。3.2 采样率与抗混叠噪声控制的配合关于采样率我遇到过不少新手翻车的情况采样率设低了高频段频率响应完全错乱采样率设高了数据文件大得离谱后处理时电脑卡顿。我的经验是采样率至少设为最高激励频率的50~100倍。比如你最高测100Hz采样率至少要5kHz~10kHz。这样既不会出现混叠又能对高频段的转速信号做足够精细的重建。这里还有一个细节很多控制板上的ADC或编码器捕获自带一个简单的低通滤波这个滤波的截止频率如果低于你的最高激励频率就会在高频段引入额外相位滞后。实测中我发生过这种问题后来学乖了所有滤波一律关掉或者把截止频率设到采样率的五分之一以上宁可让数据里带一点高频噪声也不要把有效的频响信息给滤没了。3.3 数据采集时的时间戳同步问题开始的时候我没有太在意时间同步觉得只要同时采就行。但这个项目里因为输入信号是控制板DAC发的输出信号是编码器捕捉的两者分属不同的硬件模块如果不在同一个时间基准下记录那么每个频率点的相位都会偏一个随机量——这会导致最后画的伯德图相位曲线像被狗啃过一样完全没法看。解决办法有两个第一用同一个定时器中断去触发ADC采样和编码器寄存器读取然后在同一个中断服务程序里把这两个数据打上同一个全局时间戳。这是最干净的方法。我用的控制板正好支持这种操作实测相位曲线平滑得多了。第二如果没有这种硬实时能力那就只能用互相关的方法来离线对齐输入输出。方法是在信号的前面加一段已知的参考标记比如一个短脉冲在数据分析时先找出这个标记然后按照已知的采样率把输入输出对齐。这个方法稍微麻烦一点但确实有效。3.4 电机安全工作区确认这是整个实验里最不能跳过的一步。电机的频率响应测量意味着你要故意给电机一个波动的指令让它在一个宽频范围内来回转动。如果你不控制好安全工作区轻则数据作废重则烧驱动、毁电机。我的安全检查清单电流限制驱动器的电流限幅设为额定电流的120%留一点缓冲但不至于失控。尤其做低频段测试时电机可能要持续输出大力矩长时间运行容易过热。速度限制在控制器里加一个转速软限位万一出现意外比如机械谐振放大立即把电流指令置零。我见过一次谐振引起的啸叫声音听起来像金属被撕裂如果不是限位及时电机轴估计要废。机械行程如果你测试的对象是带减速器的机构不要让电机连着机构跑太远。最好把负载脱开只测电机本体的空载频响这样既安全又纯粹。4. 实操过程与核心环节实现4.1 测试平台的搭建与初始标定我这次实验用了一台额定电压24V、额定电流2.1A、额定转速3000rpm的直流有刷电机配一个2000线增量编码器驱动器工作在电流环模式。整个测试平台的接线如下控制板DAC输出 → 驱动器电流指令输入0~10V对应-2.1A~2.1A编码器A/B相 → 控制板正交解码接口驱动器故障输出 → 控制板数字输入急停用硬件连线完成后第一件事不是测频响而是做静态标定。给电流指令一个已知的直流值比如1A看电机是否以稳定的力矩趋势运行再用测速仪验证编码器读数是否正确。这个步骤看似浪费几分钟实际能帮你排除大量低级错误。标定的核心项目标定项目方法作用电流指令标定用万用表测量驱动器电流监视输出对照指令电压确认“几伏对应几安”编码器方向检测手动正向转动电机观察计数方向防止闭环后正反馈转速换算系数已知转速下核对编码器计数确认rpm到计数/s的换算因子4.2 步进正弦测试的执行流程标定完成后我写了一个简单的Python脚本通过串口控制板切换工作模式。核心流程是这样的第1步设定频率点序列。我用的频率点是[0.1, 0.2, 0.5, 1, 2, 3, 5, 8, 10, 15, 20, 30, 50, 80, 100] Hz。注意低频段取了更多点因为机械系统的幅频特性在低频过渡带变化剧烈需要更细的分辨率来捕捉转折点。第2步逐个频率点执行测试。对每个频率f先估算需要多少个周期才能让系统进入稳态。经验公式稳态时间 2 / (2πf × 阻尼比)对于典型的直流电机系统阻尼比大约在0.2~0.5之间所以低频时要等很长时间。0.1Hz时需要等约20~30秒才稳定高频段就快得多。为了平衡时间和精度我再取稳态后的5~10个周期做数据记录。第3步转速数据处理。对记录的转速波形计算每个周期内的峰值、零点和平均值然后把所有周期做平均消除随机噪声和谐波影响。这种做法本质上是“时域同步平均”效果非常好。4.3 从时域数据到频响曲线计算增益与相位这一步是整个项目中最核心的计算环节。对于每一个测试频率f我们拿到了输入电流信号I(t) A·sin(2πft) 和输出转速信号ω(t) B·sin(2πft φ)。通过以下方法提取B和φ增益 20·log10(B/A)单位是dB如果以转速/电流为单位则变为dB·(rpm/A)相位差φ单位是度实际操作中我是用Python的scipy.signal做的。具体来说用正弦拟合sine curve fitting比简单FFT更精确import numpy as np from scipy.optimize import curve_fit def sine_func(t, amplitude, phase, offset): return amplitude * np.sin(2 * np.pi * freq * t phase) offset # 对每个频率点做拟合 for freq in freq_list: # t 是时间向量omega 是转速数据 p0 [np.std(omega) * np.sqrt(2), 0.0, np.mean(omega)] popt, _ curve_fit(sine_func, t, omega, p0p0) amp_out popt[0] phase_out popt[1] # gain 20*log10(amp_out / amp_in)这里有一个重要的细节曲线拟合时一定要把直流偏移量offset也拟合出来。很多教程里默认信号均值为零但电机转速因为摩擦的存在往往带有一个非零的平均转速如果不拟合offset振幅和相位都会出现偏差。4.4 我实测的一组数据和模型拟合结果整个频段测完后我得到了一组典型的直流电机机械频响数据。以1Hz为参考增益设为0dB部分实测数据如下频率(Hz)实测增益(dB)实测相位(deg)模型增益(dB)模型相位(deg)0.1-0.2-3-0.1-20.5-1.1-15-1.2-141.00.0-250.0-262.0-1.5-48-1.6-475.0-8.0-75-8.3-7710.0-13.5-88-13.2-8720.0-18.0-92-17.5-9150.0-23.0-95-23.6-95这个数据形态非常典型低频段增益基本平坦0dB在转折频率附近开始以约-20dB/decade的斜率下降相位从0度逐步向-90度逼近。这说明系统可以用一个一阶惯性模型来近似转子模型G(s) K / (τs 1)其中K是直流增益单位rpm/Aτ是机械时间常数。从数据里看到转折频率大约在0.8Hz左右对应时间常数τ 1/(2π×0.8) ≈ 0.2s。直流增益K可以直接从低频段的输出转速除以输入电流得到比如在0.1Hz时输入0.15A电流转速稳定在约500rpm则K ≈ 3333 rpm/A。把这两个参数代回一阶模型得到图中的红色曲线和实测数据对得非常好。这说明这台电机本身没有明显的机械谐振——很多实际系统会在这里出现一个谐振峰如果有你就得把模型升级为二阶系统并额外引入一个谐振频率和阻尼比。4.5 如果测出谐振峰该怎么处理虽然我这次测试的电机没出现明显的谐振峰但干这一行总会遇到。电机装上负载后联轴器的弹性、皮带的柔性、负载本身的转动惯量都会引入谐振。我处理过一台带着同步带的直流电机在25Hz处出现了一个6dB的谐振峰相位从-90度直接跳到-170度当时的闭环PID只要增益稍微调高一点就啸叫。对于这种情况测出来的频响曲线会很像一个“二阶弹性能系统一阶惯性系统”的组合。拟合模型时要加入一个谐振项G(s) K / ((τs1) · (s²/ωn² 2ζs/ωn 1))通过最小二乘法拟合谐振频率ωn和谐振阻尼比ζ然后你就可以在控制器里加一个陷波滤波器Notch Filter专门在谐振频率处把增益压下去再稳定地提高环路的整体增益。这在伺服驱动器的参数自整定功能里是非常常规的操作。5. 实操过程中踩过的坑问题排查与解决实录5.1 转速波形严重削顶激励幅值过大的信号第一次做步进正弦测试时我在低频段0.1Hz~0.5Hz发现转速波形看起来像方波正弦的顶部和底部被“削平”了。这不是电机问题而是电流指令太猛转速超出了正常运行范围被驱动器限速或者电机反电动势限制输出被“限幅”了。解决方式很直接立即减小低频段的电流激励幅值。我用了一个可变的激励安排低频段幅值为额定电流的3%中频段5%高频段8%。这个安排的逻辑是低频段电机的响应增益高小信号就能产生足够的转速波动高频段电机响应衰减大需要更大的信号才不至于让输出幅度掉到噪声里。5.2 相位曲线在某一点突然跳变180度方向反了测试过程中我还碰到过一个诡异的现象当频率超过某个点后相位曲线突然从-170度跳到-350度看起来像是不连续的。后来分析才发现这根本不是什么物理现象——是因为在该频率点输出的转速信号幅度太小有效信号和噪声混在一起正弦拟合的相位结果不稳定跳到了错位。排查方法是看这个频率点附近的相干性Coherence指标。相干性低于0.9的数据点基本上不可信。我处理的方式是在数据处理流程中加一道过滤凡是拟合残差过大R²0.95的频率点自动标记为无效并提高激励幅值重新补测一次。5.3 摩擦非线性导致低频段增益偏差大低频测量还有个老大难问题摩擦。0.1Hz时电机的速度很慢接近零速时摩擦从动摩擦过渡到静摩擦表现为一个“粘滞”区。这会使得输出转速不再是平滑的正弦波而是带有明显的“平顶”和“死区”。这种情况下强行用正弦拟合会得到偏小的增益和偏大的相位滞后。解决办法有几个使用更大的电流幅值让电磁力矩远大于摩擦力矩压缩非线性的相对影响。在测试前先做摩擦辨识补偿把已知的库仑摩擦力矩前馈补进去相当于在输入端把摩擦抵消掉。只记录稳态部分的数据并且把所有数据段做周期平均尽量减少随机干扰。我在这个项目里采用了第一种第三种组合效果足够好了。5.4 高频段数据被噪声淹没时的解决方案当频率升到50Hz以上时电机的机械响应已经衰减得很厉害了转速波动幅度可能只有1~2rpm而编码器量化噪声和机械震动噪声在这个量级上是不可忽略的。这时候数据信噪比急剧下降幅频曲线开始乱跳。我的应对方案是增大正弦波的数据记录长度而不是一味地增大激励幅值。每一个高频频率点记录100个周期再做同步平均这相当于把周期性的信号在时域里叠加100次而随机噪声按根号10010倍减弱。信噪比提高了20dB数据一下就清晰了。这个方法非常实用在强噪声环境下做辨识时几乎是必选项。5.5 常见问题速查表现象可能原因处理方法低频段转速波形削顶激励幅值过大转速超限降低低频段电流幅值高频段幅频曲线乱跳信噪比不足增加记录周期数并做同步平均相位曲线不连续信号过弱导致拟合相位翻转提高该频点幅值重测或标记无效相位曲线整体偏大输入输出时间戳不同步使用同一中断里采集或离线对齐截止频率处增益异常凸起存在机械谐振用二阶谐振模型拟合考虑加陷波器1Hz以下增益明显低于预测摩擦/死区非线性提高激励幅值或加摩擦前馈补偿6. 进一步扩展如何利用频响结果优化闭环控制6.1 根据频响数据设计速度环增益测频响并不是为了画一张好看的图而是为了给控制设计提供依据。以我实测的那台电机为例它的频响在0.8Hz处有一个转折相位在10Hz附近已接近-90度。如果给速度环加一个PI控制器理论推导和经验都表明穿越频率每接近其相位滞后-135度的频率点系统就越接近不稳定边界。按照这个数据我很快算出了速度环带宽的安全上限大约在10~15HzPI增益可以据此设定。再去跑实际闭环测试时一上来就落在了一个比较稳的起点上后续只需要微调几个参数就够了。6.2 与离线仿真模型的交互验证拿到实测频响之后我还在MATLAB/Simulink里搭了一个仿真模型把真实测到的K和τ填进去对比了开环阶跃响应。实测和仿真基本吻合说明这个模型已经足够用于后续的控制器设计仿真。之后再改控制算法时就可以先在电脑上验证少烧一堆硬件。6.3 从频响辨识到参数自整定很多商用伺服驱动器里的“自动整定”功能底层逻辑就是这套东西给系统一个激励信号测出频率响应自动辨识出模型参数再根据模型计算出最优PID增益。你自己动手实现了这套测量流程之后就相当于掌握了一个简易的“参数自整定仪”。以后遇到新电机或者新机构只要跑一遍这个流程就能快速掌握它的“性格”再也不用凭感觉盲调了。最后再分享一个小的实操体会测频响这件事第一次做可能会因为各种细节问题折腾一两天但一旦把流程跑通后续再做任何电机项目的速度都很快。这套方法值得你花时间在实验室里沉淀成自己的标准工具。