基础解释:

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

I:增幅器(修正误差)

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

各个参数过大过小情况

P参数

过小:不能达到目标

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

I参数

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

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

D参数

过小:脱离控制

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

参数调整顺序:

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

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

C++代码实现

PidController.h

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
#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

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
#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;
}