基础解释:

P:基础运动量(移动速度)

I:增幅器(修正误差)

D:抑制器(阻止超出目标)

各个参数过大过小情况

P参数

过小:不能达到目标

过大:超出目标,表现为抖动或脱离控制

I参数

过小:不能到目标,小偏差不能回正,还可能出现颤抖现象

过大:很容易超出目标,表现为系统迟钝,晃动

D参数

过小:脱离控制

过大:高频抖动,对误差很敏感

参数调整顺序:

根据上述,调整顺序如下:

  1. 调整P
  2. 调整D
  3. 调整I

C++代码实现

PidController.h

#pragma once

class PidController final
{ 
public:
    PidController(const float kp, const float ki, const float kd);
    ~PidController();
    float CalcExecValue(const float value);
    void Reset();

private:
    // kp:比例系数
    float m_kp;
    // ki:积分系数
    float m_ki;
    // kd:微分系数
    float m_kd;

    // 偏差
    float m_err;
    // 上一次偏差
    float m_lastErr;
    // 积分
    float m_integral;
    // 微分
    float m_differential;
};

PidController.cpp

#include "PidController.h"

PidController::PidController(const float kp, const float ki, const float kd)
{
    m_kp = kp;
    m_ki = ki;
    m_kd = kd;
    m_err = 0.0f;
    m_lastErr = 0.0f;
    m_integral = 0.0f;
    m_differential = 0.0f;
}

PidController::~PidController() = default;

float PidController::CalcExecValue(const float value)
{
    // 计算偏差
    m_err = value - m_err;
    // 计算积分
    m_integral += m_err;
    // 计算微分
    m_differential = m_err - m_lastErr;
    // 计算执行量
    const float output = m_kp * m_err + m_ki * m_integral /* * time */ + m_kd * m_differential; // / time;
    // 更新上一次偏差
    m_lastErr = m_err;
    return output;
}

void PidController::Reset()
{
    m_err = 0.0f;
    m_lastErr = 0.0f;
    m_integral = 0.0f;
    m_differential = 0.0f;
}