我正在尝试使用 Arduino 控制电动推子(线性滑动电位器)。
PID 控制为“跳跃”到特定目标位置提供了良好的结果,但跟踪斜坡是一个问题,它根本不平滑。无论我尝试什么,运动都非常生涩。
这是同一测试的视频。
在商业系统上,它似乎更流畅,请参阅this。
详细信息:
电动推子是Alps RSA0N11M9A0K。为了驱动它,我使用的是ST L293D H 桥,由稳压 10 V 直流电源 ( XL6009 ) 供电。
在 Arduino UNO (ATmega328P) 上,我使用引脚 9 和 10,PWM 频率为 31.372 kHz 以使其听不见(预分频器为 1 的 Timer1,TCCR1B = (TCCR1B & 0b11111000) | 0b001
)。
电位器连接在地和 5V 之间,抽头像往常一样连接到 ADC0。
控制器:
我正在使用一个带有抗饱和的简单 PID 控制器,它以 1 kHz (Ts = 1e-3 s) 的速率更新:
float update(int16_t input) {
int16_t error = setpoint - input;
int16_t newIntegral = integral + error;
float output = k_p * error
+ k_i * newIntegral * Ts
+ k_d * (input - previousInput) / Ts;
if (output > maxOutput)
output = maxOutput;
else if (output < -maxOutput)
output = -maxOutput;
else
integral = newIntegral;
previousInput = input;
return output;
}
控制器的输出是一个从 -127 到 127 的值。PWM 输出产生如下:
const int8_t knee = 48;
uint8_t activation(int8_t val) {
if (val == 0)
return 0;
else {
return map(val, 0, 127, 2 * knee, 255);
}
}
void writeMotor(int8_t val) {
if (val >= 0) {
analogWrite(forward, activation(val));
digitalWrite(backward, 0);
} else {
analogWrite(backward, activation(-val));
digitalWrite(forward, 0);
}
}
我将 48 添加到 7 位 PWM 信号,因为这是电机开始以 31 kHz 移动的地方,然后我将其放大到 8 位数字(因为这是analogWrite
函数所期望的):
我尝试过的:
我尝试将 EMA 滤波器添加到输入、控制信号、PID 控制器的微分组件,但无济于事。我还尝试降低模拟输入的分辨率,使用滞后来阻止它在静止时在两个值之间翻转。这似乎不影响任何事情。将时间步长增加到 10 毫秒似乎也无济于事。
我还尝试在 MATLAB 中进行系统识别,并尝试在 Simulink 中对其进行调整(按照此视频系列)。我得到了一个拟合度为 91% 的模型,但我不知道如何处理 MATLAB 模型的输入和输出非线性,它们如何影响 PID 调整,以及如何在 Arduino 上实现它。
我尝试的最后一件事是制作两种不同的控制器:一种用于参考位置的大跳跃,另一种用于跟踪斜坡时的小误差。这似乎有点帮助,因为这样我可以在跟踪时增加积分系数,而不会增加跳跃时的超调。
然而,通过增加积分(和比例)增益,电机现在总是在做一些事情,即使它应该是静止的并且参考值不会改变。(它并没有真正移动,但你可以感觉到它在振动。)
我几乎没有微分增益,因为将它增加到高于 1e-4 似乎会使它更加抖动,而且我并没有真正注意到 0 和1e-4。
我的猜测是它需要更多的动力来克服静摩擦,然后动摩擦就更少,所以它会过冲,所以它会向后驱动电机,导致它再次停止,然后它必须再次克服静摩擦,它再次向前冲, 等等。
商业控制器如何克服这个问题?
我的背景:
我在电气工程专业的第三个学士年,我学习了控制理论、数字信号处理、LQR 控制等课程,所以我有一些理论背景,但我无法将所有这些理论应用于这个真实世界的系统。
编辑:
我已经按照laptop2d 的建议测试了开环传感器测量值,我对结果感到非常惊讶:在高PWM 频率下,读数中有令人讨厌的峰值。在 490 Hz 时,没有。
这是在一个恒定的占空比下,所以我无法想象当电机快速反转方向时我会得到什么样的噪音。
所以在我再次开始使用控制器之前,我必须找到一种方法来过滤掉这些噪音。
编辑 2:
使用指数移动平均滤波器不足以滤除噪声。
我尝试过使用 0.25、0.50 和 0.75 的极点。小极点影响不大,大极点增加了太多延迟,所以我不得不降低增益以保持稳定,导致整体性能更差。
我在电位器(雨刮器和地之间)添加了一个 0.1 µF 电容器,这似乎可以清理它。
目前,它运行良好。与此同时,我正在阅读Tim Wescott 发表的论文。
感谢大家的帮助。