使用中断(
PinChangeInt
库)代替pulseIn
降低飞行员输入的频率
第二个简单得多的解决方案是在$(n + 1)$ PID更新中简单读取一次引导输入。因此,对于$ n $次,我们的更新时间为$ 8 \; ms $,对于$(n + 1)^ {th} $时间,我们的更新时间为T ms。 $ n $大约是$ 10 $。
这将创建一个平均运行$(n * 8 + T)/(n + 1)\的系统。 ms $。
现在,双/可变频率如何影响PID系统?系统是否表现为在有效频率下工作?我已经搜索了一段时间,但是找不到任何讨论这种情况的信息。
#1 楼
我认为您正在解决错误的问题。变频PID是一个非常糟糕的主意,因为您无法控制力的比例分量。换句话说,即使在两次更新之间您已经接近设定点,您对设定点的作用力仍保持恒定,并且PID将需要进行较大的调整-可能会剧烈波动。只能每〜35ms更新一次输入的约束意味着您期望的设定值将仅每〜35ms改变一次,但是PID只在乎平稳地达到该设定值。为此,理想情况下,PID应该以测量传感器和/或电机控制器的频率运行。
对于一个极端的示例,请考虑在期望设定点为恒定为零。仅在设定值永不改变的情况下以0Hz运行PID是很愚蠢的。
TL; DR,不要等待PID回路内的先导输入。让PID回路以恒定的频率运行,并在有可用值时将其提供给新的设定值。
评论
$ \ begingroup $
您的建议是我今天正在从事的工作。我从最初的方法转移到基于中断的输入,所以现在的更新时间为2-4毫秒。这篇文章更多是一个概念性问题,是在我最初考虑解决原始问题的方法时提出的。
$ \ endgroup $
–asheeshr
2014年6月3日14:44
#2 楼
只要您的PID算法了解到不是以恒定的速率调用它,就可以了。当前,您的函数未采用增量时间参数。让我们添加一个:int16_t pid_roll(int16_t roll, int16_t dT_ms)
{
static int16_t roll_old = 0;
int16_t result =
(KP_ROLL * roll) +
(KI_ROLL * (roll_old + roll)*dT_ms) +
(KD_ROLL * (roll - roll_old)/dT_ms);
roll_old += roll;
return -result;
}
但是,我想说的是,理想情况下,您将使用微控制器或Arduino,它们具有足够的处理能力来可靠地可靠地执行PID控制器率。
#3 楼
理想情况下,您将根据采样时间调整PID增益。很难说“正确”的调整,因为您需要离散每个时间步长的非线性四旋翼动力学,并找到使它们等效的两个闭环系统的增益。这不是一件微不足道的任务。如果您可以使用Matlab(或者免费的Octave),则可以用不同的比率在仿真中进行测试。如果没有的话,我只会做实验。也许尝试将较长的更新周期增益设置为快速增益的2 / 3、1 / 2、1 / 4、1 / 8等,然后看看在什么时候(如果有的话)您会注意到差异。
请注意,随着最大采样时间的减少,您需要越来越少地担心这一点。不过,就您而言,最大时间有点长,因此我至少会尝试进行不同的调整。
评论
在您的PID算法中,“滚动”参数是什么?是角度,还是角度或角度变化?@Rocketmagnet这是横摆角(所需角度-实际角度)中的误差。