本文目标
把分散的 ADC、PWM、编码器、FOC 和校准知识,串成一次真实控制周期。核心判断:电机控制首先是时序系统,其次才是公式系统。
一、源码阅读边界
重点文件:
- low_level.cpp:ADC、PWM、母线电压、制动电阻等底层硬件。
- motor.cpp:电流偏置、相电阻/相电感测量、PWM更新和保护。
- encoder.cpp:编码器采样、PLL、方向、CPR/极对数检查和相位偏移校准。
- foc.cpp:按采样与输出时间戳补偿角度,检查控制数据是否错位。
已有基础可对照:相电流检测与重构、转子位置与速度信息获取 。
二、一次控制周期发生了什么
这里最重要的是两个时间:
input_timestamp:电流被采样的时刻;
output_timestamp:新PWM真正准备输出的时刻。
FOC分别用这两个时间预测电角度。高速时如果仍使用“当前读到的同一个角度”,采样、计算和输出延迟会转换成明显相位误差。
三、电流采样与零偏校准
3.1 为什么必须先做DC偏置
电流放大器在零电流时并不一定精确落在ADC中点。
dc_calib_cb() 对三相采样做低通积累,并要求:- 校准持续时间足够;
- 三相偏置没有超过允许范围;
- 校准无效时禁止把数据交给闭环。
运行时:
其余两相相同。若无法得到可信电流,而电机已经 armed,ODrive选择立即停机,而不是“先凑合跑”。
3.2 ADC量程也是保护边界
phase_current_from_adcval() 检查ADC值是否过于接近模拟前端上下限。靠近饱和区时,电流值已经不可信,系统报告 CURRENT_SENSE_SATURATION。注意:软件电流限幅保护不了已经饱和的传感器。看不见真实电流时,算法所谓的闭环只是自我安慰。
四、电机参数校准
4.1 相电阻测量
ODrive施加闭环测试电流,用积分调节测试电压,稳定后按:
得到相电阻。同时检查正交轴电流是否异常,借此发现相不平衡或接线问题。若达到最大允许电压仍不能建立测试电流,则认为电阻测量超出范围。
4.2 相电感测量
系统快速切换正负测试电压,累计电流纹波,根据:
估算相电感,并检查结果是否落在允许范围。
4.3 参数如何进入控制器
电流PI增益不是拍脑袋:
所以校准链是:
错误参数会同时破坏模型前馈和电流环增益。
五、编码器与电角度校准
5.1 编码器方向
ODrive开环旋转磁场并观察计数变化:
- 计数明显增加:方向为正;
- 计数明显减少:方向为负;
- 几乎没有变化:编码器无响应。
5.2 CPR与极对数一致性
编码器扫描期间,根据电角度扫描距离推算理论编码器增量,再与实际增量比较。偏差超过容差时报告
CPR_POLEPAIRS_MISMATCH。这能抓住一个常见配置错误:电机确实转了,编码器也确实有数据,但二者的比例关系不对。
5.3 相位偏移
偏移校准先正向扫描,再反向扫描,累计编码器计数并求平均,得到机械编码器零点与电气零点之间的偏移。双向扫描能减小摩擦、齿槽和单向间隙造成的偏差。
5.4 位置与速度估计
Encoder::update() 不直接把相邻计数差除以固定周期作为最终速度,而是使用 PLL 估计器。原因很直接:编码器输出是离散计数,低速时经常连续几个周期计数不变,随后突然跳一个计数。直接差分会把恒定低速误判成“多次零速度 + 一次速度尖峰”。PLL每个周期做了什么
PLL同时维护连续位置估计 和速度估计 。忽略单位换算和计数回绕处理后,一个控制周期可以写成:
对应源码含义是:
- 预测位置:假设上一周期的速度继续保持,用 把位置外推到当前时刻;
- 计算相位误差:比较实际编码器计数与预测位置,并处理 CPR 回绕;
- 比例修正位置:误差立即拉回位置估计,决定“当前位置纠正多快”;
- 积分修正速度:若相位误差持续同向存在,说明速度估计偏低或偏高,于是逐步修正 ;
- 低速吸零:当估计速度小于计数量化所能可靠分辨的阈值时,将速度置零,避免静止状态在正负小速度之间抖动。

一个低速量化示例
假设编码器为
8192 CPR,采样频率为 8 kHz,即 。若电机平均每四个采样周期只增加一个计数,真实平均转速约为:直接差分得到的瞬时转速却会循环出现:
平均值虽然接近真实速度,但送入速度环的是强烈脉冲。PLL根据历史速度连续预测,再用每次计数跳变产生的误差慢慢校正,因此输出会稳定在约
14.65 rpm 附近,而不是在 0 和 58.6 rpm 之间跳变。PLL带宽如何影响速度环
PLL带宽 | 直接效果 | 对速度环的影响 |
过高 | 位置和速度估计追踪快,但编码器量化、边沿抖动和机械振动更容易进入 | 速度反馈变脏,速度 PI 会把噪声转换成转矩抖动和电流纹波 |
过低 | 速度估计更平滑,但真实加减速需要更久才能反映出来 | 额外相位滞后降低速度环稳定裕度,表现为跟随迟钝、超调或振荡 |
合理 | 在目标速度环频段内及时跟踪,同时不过度放大量化噪声 | 速度环看到近似连续、延迟可控的反馈 |
整定顺序
先固定编码器分辨率和采样频率,再让 PLL 带宽高于目标速度环带宽,使估计器不会成为速度环的主要延迟来源;可从速度环带宽的约 3~5 倍开始试验,但不能把这个比例当定律。随后同时观察静止速度噪声、匀速纹波、速度阶跃滞后和电流抖动:噪声过大就降 PLL 带宽,估计明显落后且速度环相位裕度不足就提高带宽。
关键判断
PLL不是“消灭噪声”的魔法滤波器,而是利用运动模型把离散计数变成连续状态估计。带宽调得越高,越相信当前测量;调得越低,越相信上一周期的运动预测。
六、PWM安全更新
Motor::arm() 只设置软件armed状态,不立即粗暴打开PWM。真正流程是:- 复位控制器和积分状态;
- 下一个定时器更新中断执行控制律;
- 计算新的三相PWM;
- 写入CCR影子寄存器;
- 再下一个更新事件统一锁存并使能输出。
这样避免三个桥臂在不同时间更新。任何时候调用
disarm() 都会关闭自动输出使能和主输出,使三相浮空。七、面试问题与参考答案
问题1:为什么FOC必须记录采样时间戳和PWM输出时间戳?
参考答案:电流采样、控制计算和PWM生效并非同一时刻。高速时,延迟对应的电角度不可忽略。ODrive用相位速度把转子角度分别外推到电流采样时刻和PWM输出时刻;若控制数据与电流数据相差过大,则报告时序错误,而不是继续使用错位数据。
问题2:电机空载电流异常,应先调PI还是先查采样?
参考答案:先验证零偏、相电流极性、采样窗口和电角度。PI只能调节它看到的误差;输入错误时,调PI最多暂时掩盖问题。应检查三相零电流偏置、、转子静止时的d/q电流,以及示波器上ADC触发是否避开开关尖峰。
问题3:为什么测得相电阻和相电感后还要做范围检查?
参考答案:辨识结果直接决定电流环增益和前馈。如果接线错误、测试电压不足、采样饱和或电机未连接,计算仍可能吐出一个数字。范围和相平衡检查用于阻止“数学上有结果、物理上是垃圾”的参数进入闭环。
问题4:编码器方向正确,为什么还可能飞转?
参考答案:方向正确只说明计数增减符号正确。CPR、极对数、相序和电气相位偏移仍可能错误。FOC需要的是正确电角度,不是仅仅有一个单调变化的机械位置。
问题5:如何验证控制时序?
参考答案:用GPIO翻转或定时器捕获标记ADC触发、控制ISR开始/结束和CCR更新时刻;同时记录PWM周期、最坏执行时间和抖动。示波器确认采样点位于有效电流窗口,且最坏执行时间仍早于下一次PWM锁存截止点。
八、建议实验
在PWM关闭时采集三相原始ADC,统计均值、峰峰值和温漂。
对比校准前后 与 零点。
人为配置错误极对数,记录偏移校准失败信息。
降低PLL带宽,观察速度估计噪声与相位滞后的变化。
用GPIO测量
current_meas_cb() 到 pwm_update_cb() 的延迟和抖动。改变母线电压,验证相同电流目标下调制度变化是否合理。
九、结论
这一部分的掌握标准是:能从ADC触发一路解释到CCR生效,能说明每项校准测了什么、为何可信、失败时如何停机,并用时间测量和波形而不是猜测证明控制周期正确。
- Author:felixfixit
- URL:http://www.felixmicrospace.top/article/odrive-sampling-calibration-timing
- Copyright:All articles in this blog, except for special statements, adopt BY-NC-SA agreement. Please indicate the source!





