SimpleFOC源码学习02(v2.3.2) - 低通滤波器lowpass_filter.cpp与lowpass_filter.h

张开发
2026/5/17 19:51:00 15 分钟阅读
SimpleFOC源码学习02(v2.3.2) - 低通滤波器lowpass_filter.cpp与lowpass_filter.h
前言github源码https://github.com/simplefoc/Arduino-FOC/tree/master/src/common低通滤波器Low-Pass Filter是一种信号处理工具它的作用是让变化缓慢的信号通过过滤掉变化剧烈噪声的信号。在电机控制中传感器读到的速度、电流值经常带有噪声抖动低通滤波器就是用来平滑这些数值的。一、lowpass_filter.hclassLowPassFilter{public:LowPassFilter(floatTf);// 构造函数传入时间常数floatoperator()(floatx);// 重载()运算符让对象像函数一样调用floatTf;// 时间常数越大越平滑响应越慢protected:unsignedlongtimestamp_prev;// 上次调用的时间戳微秒floaty_prev;// 上次的滤波输出值};关键概念 —Tf时间常数Tf单位是秒Tf越大 → 滤波越强信号越平滑但响应越迟钝Tf越小 → 几乎不滤波跟随输入但噪声多典型值0.01f10ms用于电流0.1f100ms用于速度二、lowpass_filter.cpp2.1、构造函数LowPassFilter::LowPassFilter(floattime_constant):Tf(time_constant)// 记录时间常数,y_prev(0.0f)// 初始输出为0{timestamp_prev_micros();// 记录当前时间微秒}2.2、核心滤波函数operator()floatLowPassFilter::operator()(floatx){unsignedlongtimestamp_micros();// 距离上次调用过了多少秒。floatdt(timestamp-timestamp_prev)*1e-6f;// 换算成秒if(dt0.0f)dt1e-3f;// 时间溢出保护 → 用1ms代替elseif(dt0.3f){// 超过0.3秒没调用y_prevx;// 直接输出当前值认为系统停了timestamp_prevtimestamp;returnx;}floatalphaTf/(Tfdt);// 核心公式floatyalpha*y_prev(1.0f-alpha)*x;// 加权混合y_prevy;timestamp_prevtimestamp;returny;}三、理解核心公式这是整个代码最重要的两行floatalphaTf/(Tfdt);// 核心公式floatyalpha*y_prev(1.0f-alpha)*x;// 加权混合直觉理解alpha接近 1如 0.99 → 90%相信旧值10%相信新输入 → 非常平滑很迟钝alpha接近 0如 0.1 → 10%旧值90%新输入 → 几乎不滤波跟随快但噪声多四、如何使用这个类// 创建一个时间常数为0.01秒的滤波器LowPassFilterlpf(0.01f);// 在循环中调用像函数一样用floatraw_speedsensor.read();// 读到带噪声的速度floatsmooth_speedlpf(raw_speed);// 滤波后的平滑速度operator()的重载让对象可以直接当函数调用写法非常简洁。五、总结六、Tf的数值怎样选取? 比如电流环20KHz,速度环1KHz。6.1、先算出dt6.2、理解alpha和Tf的关系alpha Tf / (Tf dt)alpha 决定了每次保留多少旧值。实际工程中alpha 的合理范围是0.8 ~ 0.98低于 0.8 → 几乎不滤波噪声太多高于 0.98 → 延迟太大控制器反应迟钝由此可以反推 TfTf alpha × dt / (1 - alpha)实际项目参数设置6.3、关键约束电流环Tf 必须远小于速度环周期电流环的 Tf 引入延迟这个延迟会传递到速度环。速度环周期是 1ms所以电流环滤波器的延迟必须远小于 1ms电流环 Tf 0.0005f0.5ms 速度环 dt1ms✅ 合理 电流环 Tf 0.005f 5ms 速度环 dt1ms❌ 危险会破坏速度环稳定性

更多文章