目前整个软件框架已经搭建完成 各种初始化 校正 驱动和维护代码占用了大半的代码空间 还剩下10k左右 可以用于指令识别和运动控制这些真正的核心功能 也是我犹豫好久 直到现在还在犯选择困难症的地方
但是不好再拖了 我自己也没有能力弄出一种崭新的控制理论 只能根据要求 选择最合适的框架进行修改 这篇回复也是梳理的过程 可能有误 其实我经常把这里当开发笔记用 项目完成后保存网页就直接当开发记录了
既然要闭环控制 核心算法还是以PID控制为主
首先确定一点 关于齿槽扭矩 我原先的想法原本是进行简单的补偿 使得输出函数更加线性化 减少执行噪声 目前看来是不可能的了
实际上 在小电流情况下 齿槽扭矩会有强大的非线性误差 其导数绝对值超过1 这意味着用线性方法弥补 反而会越补越差 (这其实从数学上解释了 为什么普通力度的手拧步进电机 其实不可能达到一个精确的位置 如果深究也挺好玩) 实在无法在有限的代码代价和时间代价下完成补偿
虽然不打算校正输出(或许以后再说) 不过通过以上观察 可以确定一点 如果保持一个最小电流的存在 可以减少执行函数的非线性
常规的FOC角度是90度 而电流大小根据PID输出变化 何妨改变一下 当电流需要小到一定程度的时候 以减少磁链夹角来达到同样的效果 从前面的测量看 我决定应该保证最小1/8满电流 其实这时候执行函数其实已经不能保证递增递减性了 理想的是至少1/4满电流
采用更小的磁链夹角的另一个好处是抑制过冲 电流也无须经常在正负90度间大方向切换 实际上这是一个数字控制系统 按20kHz频率 每次决策 至少执行50us 然后附加了一个实时控制系统 目标值为磁链夹角 通常运行中 这个夹角可能会偏离预期目标非常小 对高频干扰具有很好的抵抗性 这等于结合了部分开环和闭环的好处 当需要大扭矩高速运转时候 仍然可以输出90度的扭矩 但是也可以在误差增益较小时候 也达到较大的刚度
从控制系统的角度来看 FOC常规控制函数 类似 $\frac {I} {s ^ 2 +k*s}$ k是速度正比的阻力 如果采用电流恒定 完全通过磁链角度控制输出 在夹角小的时候近似$\frac {I} {s ^ 2 +k*s +1}$ 后者不难看出更具稳定性 所以可以两者混合一下
此外PID控制部分 我想采用双自由度PID 以兼顾排除干扰和稳定跟踪两者 而其中前置滤波型的变形 具有最简洁的数学形式 各参数独立性强 与旧PID参数具备继承性 其框架如下
传递函数为 $Y(s)=\frac {H(s) G(s) X(s)} {\frac {1} {P(s)}+G(s)} +\frac {N(s)} {\frac {1} {P(s)}+G(s)}$
这样 就等于在传统PID上增加了一个H(s)滤波器 G(s)就可以用传统PID算法和技巧 包括死区 微分先行 积分分离 抗积分饱和 消弱积分法 有效偏差法 不完全微分 增量式等等 因此三个传统参数 Kp Td Ti在此设定 既 G(s)应该具备 $ Kp ( 1 + Td *s + \frac {1} {Ti * s})$ 的形式
为了后面的定性分析 对于P(s) 作为一个电机 完全有理由认为它具备 $ \frac {k_0} {s^2+k_1*s+k_2}$ 的形式 有两个极点 $\frac{ -k_1 \pm \sqrt{k_1^2-4k_2 } } {2}$
干扰项变为 $ \frac {k_0 * N(s)*s} {s^3+(k_1+k_0 K_p T_d)s^2 +(k_0 K_p+k_2)s+\frac{k_0 K_p}{T_i}} $ 上面的s表明干扰项没有稳态响应
响应项与常规PID算法相比 完全等于原输入乘于个H(s) 变为 $ \frac {k_0 K_p(T_d*s^2+s+\frac{1}{T_i}) H(s)X(s)} {s^3+(k_1+k_0 K_p T_d)s^2 +(k_0K_p+k_2)s+\frac{k_0K_p}{T_i}} $ 显然其稳态响应与H(s)的稳态响应一致 因此H(s)稳态响应应该设计为1
对于以上电机模型 数学上居然有办法 让响应项变为一阶低通形式 $\frac {\omega_0} {s+\omega_0} $ 比如说 对于20kHz的采样控制过程 电机应该能有1kHz的响应速度 50极电机对应每秒20转 经过烦死人的推导 我得到一个精确解
$ K_p=\frac {\omega_0k_1} {k_0} $
$ T_i=\frac {k_1} {k_2} =>K_i=\frac {\omega_0k_2} {k_0} $
$ T_d=\frac 1 {k_1} => K_d=\frac {\omega_0} {k_0} $
但是现实中 模型是不可能精确的 而且也缺少了许多方面的考虑 实现也是不可能完美的 参数也是得不到的 上面这个推导结论其实也是有趣才给出 有些参考价值 但是实际上并无大用
而且此时干扰项也变为$ N(s)(1-\frac {\omega_0} {s+\omega_0}) \frac {k_0} {(s^2+k_1*s+k2)} $ 其意义是叠加一个反向的低通信号进行抗干扰 这个低通也与响应的低通是一样的 如果希望增强抗干扰性 那么$\omega_0$ 就需要加大 即加大Kp 而Ti Td主要看机械阻尼情况来决定 这就是PID三参数的整定思路 这个整定 大概只能逐渐摸索了 仿真是一个很好的手段 实操是最终的手段 网上虽然有出于各种思路 根据各种代价提供的手法 比如Ziegler-Nichols之类的经验手法 都只能作为参考
对于铣雕系统而言 如果对空载马达整定调试好了 就差不多了 因为较高的力量放大比 后端带来的影响不大 很直观的实验就是你如果试图推动机械来带动步进电机 是困难或者不可能的 阻尼也比较大 但是对于3D打印系统或者机械臂 可能要考虑在系统整定以获得最佳表现 不过大致来说 使用保守一些的参数 接受保守一点的效果 也可以免去过多的调试 毕竟比起许多需要建模的算法 PID本身就以鲁棒性和适应性见强
现实中 根据经验 可以想象当Kp加大 过冲超调就会越明显 除了Ti Td的参数调整 此时 对于响应项而言 这个过冲可以通过H(s)修饰来弥补 这就是二自由度PID的意义 实就是G(s)构成的PID系统 可以按抗干扰的目的设计 允许对干扰有较大的超调 而通过前置滤波H(s)来抵消响应上的超调
观察响应传递函数 $\frac {H(s) } {\frac {1} {P(s)G(s)}+1} $ , 显然最好的H(s)是 $\frac {1} {P(s)G(s)}+1 $ , 这有点麻烦, G(s)是已知的 P(s)不是 如果搭P(s)模型 弄观察器什么的 就变成另一种控制方法了 要简化 忽略 接近 代入PID模型 变为
$\frac {H(s) } {\frac {s} {P(s) K_p T_d(s^2+\frac s {T_d}+\frac 1 {T_iT_d})}+1} $ ==(ZN整定)==> $\frac {H(s) } {\frac {s} {P(s) K_p T_d(s+\frac 1 {2T_d})^2}+1} $
忽略电机P(s)频谱 认为一直处于变换不大的范围 没有共振之类 纯粹只为了抵消PID 于是观察式子左下部分 有一个零点在稳态响应处 有两个PID控制带来的极点 $ \frac {-1 \pm \sqrt {1-4\frac {T_d} {T_i}}} {2T_d}$ 有意思的是 当采用Ziegler-Nichols的最佳整定策略时 $\frac{ T_i } {T_d} =4 $ 此时合并为一个极点 $-\frac 1 {2T_d}$ 然后估测其频谱 有个转折角频率是$\frac 1 {2T_d}$ 既便不采用ZN整定 除非PID参数搞得一塌糊涂 否则也大致可以用两个极点中间的$\frac 1 {2T_d}$来简化分析的
那么可以看出 式子下左下的频谱大致是这样的 从角频率0响应0开始 以6dB每倍频上升 到达 $\frac 1 {2T_d}$时 值达到$\frac 1 {P(s)K_p}$ 之后以6dB每倍频下降 无穷大角频率处变回0 如果再加上稳态响应1 这应该是H(s)函数应该模拟的频谱形状
一个附加分析是 如果H(s)是直通的 那么整个系统剔除电机影响后的响应 从角频率0响应1开始 逐渐下降 到达 $\frac 1 {2T_d}$时 达到低谷 之后又慢慢在无穷大角频率时候回到1
另一个附加的分析 干扰响应$\frac {1} {\frac {1} {P(s)}+G(s)}$ 代入PID模型 变成
$\frac {s } {\frac {s} {P(s)} + K_p T_d(s^2+\frac s {T_d}+\frac 1 {T_i T_d})} $ ==(ZN整定)==> $\frac {s } {\frac {s} {P(s)} + K_p T_d(s+\frac 1 {2T_d})^2} $
大致也是个先升后的样子 大的KpTd可以减少干扰的峰值
回到H(s)的构建 考虑为了减少不必要的输入噪声 比方说传输上的抖动 计算的误差 中断带来的延迟等等 实际上 有必要再给H(s)做一个低通 让它的响应在无穷大角频率时候不是1 而是0 于是H(s)最终表现为一个0频率处为1 无穷处为0 在$\frac 1 {2T_d}$有个峰值的滤波器 引入参数 Kf 一个简单的形式大概是
$\frac {K_f*s+1} {(2T_d*s+1)^2} $ 或者 $\frac {K_f*s+1} {(2T_d*s+1)(\frac 1 {\omega_1}s+1)} $ 其中${\omega_1}$是设计好的系统截止频率
其稳定响应为1 从角频率1/Kf开始以6dB每倍频上升直到角频率1/(2Td)后以6dB每倍频下降 无穷大角频率处为0
之所以不直接采用G(s) 一来是减少运算量 是因为无法避开P(s)的未知 即便采用了G(s)作为H(s)的部分 依然需要一个滤波器来涵盖P(s) 最终结果并不会造成更大阶数的效果 只会起起伏伏的波动 以上滤波器就能同时大致地涵盖P(s)和G(s)的影响
下面是一个仿真
当没有前置滤波时 PID抗干扰效果不错 但是超调明显
加入滤波后 超调小了很多 但是抗干扰效果依然
不过显然 滤波会带来一定的延时 以上都未对相位进行任何分析 一个最简单的办法 就是提高系统速度 降低对系统的期待 比如说 一个设计在1kHz响应上的系统 如果只用在500Hz 显然延时问题真少很多 一个最复杂的方法 就是对机械系统进行建模 用现代控制理论去控制它 但是又想适用性强 又想反应迅速 目前我没有找到什么更好的办法
------------------------2023.11.10------------------------
在应用微分先行算法时候发现 这时候 等效于X(s)中缺乏了微分项 于是有了类似
这其实已经实现了之前计划的 H(s) 的分母项 稳态响应为1 高频处趋于0 只是分子项在s的一阶系数上有区别 在思路上也很明确 将输入项的微分重新加个系数再注入 实现响应和输入微分方面的二自由度 这样得到了一个更简单更好实现的系统框图(此时Kf定义已经和上面不同 但是作用是一样的 作为第4个PID参数 当Kf等于1时 就和传统的PID一致)
仿真表明 调整Kf 系统可用在过冲和缓和之间过渡 如果细心调整 可用得到理想的状态
介于用的单片机只是一个M0 (我看到AT有2块钱的M4 好像也是20脚) 算法应该足够简单 所以也不打算弄得太复杂 应该就按这个框图设计了 基本上整定的思路是
1 根据刚性要求确定Kp Kp的基准值应该是当单极上相差90度时 提供最大电流数 实际上为了比传统马达要好 应该在此基础上提高2-3倍
2 根据电机响应速度要求确定Td, 因为 $ 2 \pi f = \frac 1 {2*T_d} => \frac {T_d} {T_s} = \frac {f_s} {4 \pi f}$ 实际上一般最大的f应该是fs(采样处理频率)的1/20左右 所以实际在数字计算中用的系数 $\frac{T_d}{T_s}$ 应该以 1.6为基准 然后推荐Ti是4倍Td 所以计算中用的系数 $\frac{T_i}{T_s}$ 应该以6.4为基准 设计响应频率变小 则调大两者 (但是两者不适合太小 会造成响应频率虚大 这时候会可能造成复杂的过冲 震荡的情况 这在仿真中也得到相同的结论)
3. 然后根据电机运转情况 是反应偏慢 还是过冲太大 调整Kf比例 Kf应该以1为基准 表明是这时候和普通PID一样
按照上面方法整定 应该具备较大的适应性 可用作为缺省值提供
时段 | 个数 |
---|---|
{{f.startingTime}}点 - {{f.endTime}}点 | {{f.fileCount}} |