4

简短的问题
是否有一种通用方法可以在其他统一的控制区域内处理非常大的异常(数量级)?

背景
我正在研究一种控制算法,该算法可以驱动电机穿过一个大致一致的控制区域。在没有/最小负载的情况下,PID 控制效果很好(快速响应,几乎没有超调)。我遇到的问题是通常至少会有一个高负载位置。该位置由用户在安装过程中确定,因此我无法合理地知道何时/何处可以期待它。

当我调整 PID 以处理高负载位置时,它会导致非负载区域出现较大的过冲(这是我完全预料到的)。虽然超出中间行程是可以的,但外壳上没有机械硬停止。缺少硬停止意味着任何显着​​的过冲都可能/确实导致控制臂与电机断开连接(产生死机)。

我正在制作原型的东西

  • 嵌套 PID(远离目标时非常激进,靠近时保守)
  • 远时固定增益,近时PID
  • 保守 PID(无负载工作)+ 一个外部控制,用于寻找 PID 停止并施加额外的能量,直到:达到目标或检测到快速变化率(即离开高负载区域)

硬件限制

  • 全行程定义
  • 无法添加硬停止(此时)

更新
我的回答并不表明这是最佳解决方案。这只是我认为我会分享的当前解决方案。

4

1 回答 1

0

初步解决方案

stalled_pwm_output = PWM / | ΔE |

PWM = 最大 PWM 值
ΔE = last_error - new_error

基于电机没有变化,初始关系成功地提高了 PWM 输出。有关示例输出,请参见下图。

这种方法适用于非侵略性 PID 停滞的情况。然而,它有一个不幸(且明显)的问题,即当非主动 PID 能够达到设定值并尝试减慢速度时,stalled_pwm_output 会上升。当行驶到空载位置时,这种上升会导致较大的超调。

1/ΔE 与 ΔE

当前解决方案

理论

stalled_pwm_output = (kE * PID_PWM) / | ΔE |

kE = 比例常数
PID_PWM = 来自非主动 PID 的当前 PWM 请求
ΔE = last_error - new_error

我目前的关系仍然使用 1/ΔE 概念,但使用非侵略性 PID PWM 输出来确定stall_pwm_output。这允许 PID 在开始接近目标设定点时限制stall_pwm_output,但在停止时允许 100% PWM 输出。需要缩放常数 kE 以确保 PWM 进入饱和点(下图中的 10,000 以上)。

伪代码

请注意,来自 cal_stall_pwm 的结果被添加到我当前控制逻辑中的 PID PWM 输出中。

int calc_stall_pwm(int pid_pwm, int new_error)
{
    int ret = 0;
    int dE = 0;
    static int last_error = 0;
    const int kE = 1;

    // Allow the stall_control until the setpoint is achived
    if( FALSE == motor_has_reached_target())
    {
        // Determine the error delta
        dE = abs(last_error - new_error);
        last_error = new_error;

        // Protect from divide by zeros
        dE = (dE == 0) ? 1 : dE;

        // Determine the stall_pwm_output
        ret = (kE * pid_pwm) / dE;
    }

    return ret;
}

输出数据

停滞的 PWM 输出 停滞的 PWM 输出

请注意,在停止的 PWM 输出图中,大约 3400 处的突然 PWM 下降是激活的内置安全功能,因为电机无法在给定时间内到达位置。

空载 PWM 输出 空载 PWM 输出

于 2013-02-08T08:41:30.817 回答