PID driving algorithm control and code implementation in Jetbotmini

The PID algorithm is widely used in the industrial field. It is used in automobiles, aircrafts, missiles, temperature control on equipment, etc. The three letters of PID are the initials of Proportional ratio , Integral integral , and Derivative differential , and PID control The algorithm is a control algorithm that combines the three links of proportional, integral and differential. The essence of PID control is to operate according to the proportional, integral and differential functional relationship according to the input deviation value, and the calculation result is used to control the output. The combination of these three algorithms can effectively correct the deviation of the controlled object, so that it can reach a stable state.

For more details, you can check Baidu Encyclopedia's explanation: PID algorithm

To give a simple and popular example, such as automatic driving, maintain a speed of 30 yards, if according to common thinking, step on the accelerator to accelerate when the speed is lower than 30 yards, and step on the brake to slow down when the speed is higher than 30 yards, then the car will be very unstable Yes, sometimes it is fast and sometimes slow, besides sitting uncomfortable, safety is also a problem, so at this time, PID control is used. Just lightly apply the brakes at 30 yards, so that the car looks very stable. Of course, this example seems to only illustrate the proportional adjustment of P. Obviously, it will not have a good effect. Differentiation and integration are also needed, which means to make them fine-tune, so that a good stable output can be achieved.

1. PID formula and description

Let's get familiar with the formula of PID first, as follows:

Kp: Proportional gain, Kp has an inverse relationship with proportionality

Tt: Integral time constant

TD: Derivative time constant

u(t): output signal of PID controller

e(t): The difference between the given value r(t) and the measured value, or the difference between the two errors

The PID controller is shown in the figure:

It can be seen in the figure that after the addition of three algorithms, a stable output is obtained, and then applied to the controlled object.

The description of the three PID algorithms (which can also be regarded as adjusting three parameters) is as follows:

Proportional: In the analog PID controller, the function of the proportional link is to respond to the deviation instantaneously. Once the deviation occurs, the controller will immediately produce a control effect to make the control quantity change in the direction of reducing the deviation. The strength of the control action depends on the proportional coefficient. The larger the proportional coefficient, the stronger the control action, the faster the transition process, and the smaller the static deviation of the control process; but the larger it is, the easier it is to generate oscillation and destroy the stability of the system. sex. Therefore, the selection of the proportional coefficient must be appropriate in order to achieve less transition time, small static difference and stable effect.

Integral: From the mathematical expression of the integral part, it can be known that as long as there is a deviation, its control effect will continue to increase; only when there is a deviation, its integral can be a constant, and the control effect will not increase. constant. It can be seen that the integral part can eliminate the deviation of the system. e(t) = 0 Although the adjustment function of the integral link will eliminate the static error, it will also reduce the response speed of the system and increase the overshoot of the system. The larger the integral constant, the weaker the cumulative effect of the integral, and the system will not oscillate during the transition; but increasing the integral constant will slow down the process of eliminating static errors, and the time required to eliminate deviations is also longer, but it can be reduced Overshoot, improve the stability of the system. When Ti is small, the effect of integral is stronger, and oscillation may occur in the transition time of the system at this time, but the time required to eliminate the deviation is shorter. Therefore, Ti must be determined according to the specific requirements of actual control.

Derivative: In addition to eliminating static errors, the actual control system also requires speeding up the adjustment process. At the moment when the deviation occurs, or at the moment when the deviation changes, it is not only necessary to make an immediate response to the deviation (the role of the proportional link), but also to give appropriate corrections in advance according to the change trend of the deviation. In order to achieve this function, a differential link can be added on the basis of the PI controller to form a PID controller. The role of the differential link is to prevent the deviation from changing. It is controlled according to the variation trend (change speed) of the deviation. The faster the deviation changes, the larger the output of the differential controller and can correct the deviation before it becomes large. The introduction of differential action will help reduce overshoot, overcome oscillation, and make the system tend to be stable, especially for high-order systems, which speeds up the tracking speed of the system. However, the differential function is very sensitive to the noise of the input signal. For those systems with large noise, the differential is generally not used, or the input signal is filtered before the differential works. The role of the differential part is determined by the differential time constant Td. The larger the Td, the stronger the effect of inhibiting the deviation change; the smaller the Td, the weaker the effect of resisting the deviation change. The differential part obviously has a great effect on the stability of the system. Appropriate selection of the differential constant Td can optimize the differential action.

Digital PID control algorithms can be divided into positional PID and incremental PID control algorithms. Then we should first understand their respective principles before deciding which PID algorithm to use:

2. Positional PID algorithm

e(k): User-set value (target value) - the current state value of the control object

Proportion Kp: e(k)

Integral : ∑e(i), accumulation of errors

Differentiation : e(k) - e(k-1), this error - last error

The meaning of positional PID is the actual position of the current system, and the deviation from the expected position you want to achieve, and PID control is performed.

Because the error integral ∑e(i) has been accumulated, that is, the current output u(k) is related to all past states, and the accumulated value of the error is used; the output u(k) corresponds to the actuator Actual position, once the control output is wrong (the current state value of the control object has a problem), a large change in u(k) will cause a large change in the system, and when the position-type PID reaches saturation in the integral term, the error will still continue under the action of the integral Accumulation, once the error starts to change in reverse, the system needs a certain time to exit from the saturation area, so when u(k) reaches the maximum and minimum, the integral action must be stopped, and there must be integral limiting and output limiting, so in the use position In the case of PID, we generally use PD control directly, while the position PID is suitable for objects without integral components in the actuator, such as steering gear, the upright balance car and the control of the temperature control system

3. Incremental PID algorithm

Proportion KP: e(k)-e(k-1), this error-last error

Integral KI: e(i), error

Differential KD: e(k) - 2e(k-1)+e(k-2), this error -2* last error + last error

According to the formula of incremental PID, it can be well seen that as long as the deviation of the three measured values ​​before and after is used, the control increment ▲u(k) obtained by the formula can be calculated corresponding to the position error of the last few times. Incremental, instead of corresponding to the deviation from the actual position, there is no error accumulation , that is, no accumulation is required in incremental PID. The determination of the control increment Δu(k) is only related to the latest 3 sampling values, and it is easy to obtain a better control effect through weighting processing, and when a problem occurs in the system, the incremental method will not seriously affect the work of the system

4. The difference and advantages and disadvantages between positional PID and incremental PID

4.1, the difference between the two

1. Incremental algorithm does not need to do accumulation, the determination of control increment is only related to the last few deviation sampling values, and the calculation error has little influence on the calculation of control quantity. However, the positional algorithm needs to use the accumulated value of past deviations, which is prone to produce large accumulated errors.

2. The incremental algorithm obtains the increment of the control amount. For example, in the valve control, only the change part of the valve opening is output, and the influence of the error action is small. If necessary, the output can be limited or prohibited through logical judgment. , will not seriously affect the work of the system. The positional output directly corresponds to the output of the object, so it has a greater impact on the system.

3. The incremental PID control output is the increment of the control amount, and has no integral function, so this method is suitable for objects with integral components in the actuator, such as stepping motors. The position-type PID is suitable for objects without integral components in the actuator, such as electro-hydraulic servo valves.

4. When performing PID control, positional PID needs to have integral limiter and output limiter, while incremental PID only needs to have output limiter

4.2 Advantages and disadvantages of positional PID

advantage:

①Positional PID is a non-recursive algorithm that can directly control the actuator (such as a balance trolley). The value of u(k) corresponds to the actual position of the actuator (such as the current angle of the trolley). Therefore, in It can be used very well in objects with actuators without integral parts.

shortcoming:

①Each output is related to the past state, and e(k) needs to be accumulated during calculation, and the calculation workload is heavy.

4.3 Advantages and disadvantages of incremental PID

advantage:

① The influence of misoperation is small, and the method of logical judgment can be used to remove the wrong data if necessary.

②The impact is small when switching between manual and automatic, which is convenient for switching without disturbance. When the computer fails, the original value can still be maintained.

③ There is no need to accumulate in the formula. The determination of the control increment Δu(k) is only related to the latest 3 sampling values.

shortcoming:

① The integral truncation effect is large, and there is a steady-state error.

②The impact of overflow is great, and some controlled objects use incremental method, which is not so good.

Next, we pass the code and visualize it, and you may be more aware of the beauty of this algorithm. The code is generated by ChatGPT4, and then the visualized code is added to let everyone feel it intuitively.

5. Positional PID code

import numpy as np
import matplotlib.pyplot as plt

class PID:
  def __init__(self, Kp, Ki, Kd):
    self.Kp = Kp # 比例系数
    self.Ki = Ki # 积分系数
    self.Kd = Kd #微分系数
    self.last_error = 0 # 上一次的误差
    self.integral = 0 # 误差积分值
    
  def update(self, setpoint, position, dt):
    '''setpoint:目标值、position:当前位置、dt:时间步长'''
    self.setpoint = setpoint
    self.position = position
    self.dt = dt
    error = self.setpoint - self.position # 当前误差
    self.integral += error * dt # 积分项
    derivative = (error - self.last_error) / dt #微分项
    output = self.Kp * error + self.Ki * self.integral + self.Kd * derivative
    self.last_error = error
    self.position = output
    return self.position

  def fit_and_plot(self, count = 100):
    counts = np.arange(count)
    outputs = []
    for i in counts:
      outputs.append(self.update(self.setpoint,self.position,self.dt))
      print('Count %3d: output: %f' % (i, outputs[-1]))
    print('Done')
        
    plt.figure()
    plt.axhline(self.setpoint, c='red',ls='--')
    plt.plot(counts, np.array(outputs), 'g.')
    plt.ylim(min(outputs) - 0.1 * min(outputs), max(outputs) + 0.1 * max(outputs))
    plt.plot(outputs)
    plt.show()


pid = PID(0.2, 0.1, 0.01)
setpoint = 10.0
position = -5.0
dt = 0.5
pid.update(setpoint, position, dt)
pid.fit_and_plot(200)

6. Incremental PID code

import numpy as np
import matplotlib.pyplot as plt

class PID(object):
    def __init__(self, setpoint, position, dt, Kp, Ki, Kd) -> None:
        self.dt = dt  # 时间步长
        self.Kp = Kp  # 比例系数
        self.Ki = Ki  # 积分系数
        self.Kd = Kd  # 微分系数

        self.setpoint = setpoint
        self.position = position
        self._pre_error = 0  # t-1 时刻误差值
        self._pre_pre_error = 0  # t-2 时刻误差值

    def update(self):
        error = self.setpoint - self.position
        p_change = self.Kp * (error - self._pre_error)
        i_change = self.Ki * error
        d_change = self.Kd * (error - 2 * self._pre_error + self._pre_pre_error)
        delta_output = p_change + i_change + d_change  # 本次增量
        self.position += delta_output  # 计算当前位置

        self._pre_pre_error = self._pre_error
        self._pre_error = error

        return self.position

    def fit_and_plot(self, count=100):
        counts = np.arange(count)
        outputs=[]
        for i in counts:
            outputs.append(self.update())
            print('Count %3d: output: %f' % (i, outputs[-1]))
        print('Done')

        plt.figure()
        plt.axhline(self.setpoint, c='red',ls='-.',lw=2)  # 水平线,其中垂直线就是axvline
        plt.plot(counts, np.array(outputs), 'g.')
        plt.ylim(min(outputs) - 0.1 * min(outputs),max(outputs) + 0.1 * max(outputs))
        plt.plot(outputs)
        plt.show()

pid = PID(100, -80, 0.5, 0.2, 0.1, 0.001)
pid.fit_and_plot(150)

7. Use PID drive in unmanned vehicles

Let's take a look at how the driver file in the unmanned vehicle is written. The source code of PID.py is as follows:

'''
@Copyright (C): 2010-2019, Shenzhen Yahboom Tech
@Author: Malloy.Yuan
@Date: 2019-07-30 20:34:09
@LastEditors: Malloy.Yuan
@LastEditTime: 2019-08-08 16:10:46
'''
#  PID控制一阶惯性系统测试程序
#  PPID control first-order inertial system test program
#*****************************************************************#
#                      增量式PID系统                              #
#                 Incremental PID system                          #
#*****************************************************************#
class IncrementalPID:
    def __init__(self, P, I, D):
        self.Kp = P
        self.Ki = I
        self.Kd = D
 
        self.PIDOutput = 0.0             #PID控制器输出
                                         #PID controller output
        self.SystemOutput = 0.0          #系统输出值
                                         #System output value
        self.LastSystemOutput = 0.0      #上次系统输出值
                                         #Last system output value
        self.Error = 0.0                 #输出值与输入值的偏差
                                         #Deviation between output value and input value
        self.LastError = 0.0
        self.LastLastError = 0.0
 
    #设置PID控制器参数
    #Set PID controller parameters
    def SetStepSignal(self,StepSignal):
        self.Error = StepSignal - self.SystemOutput
        IncrementValue = self.Kp * (self.Error - self.LastError) +\
        self.Ki * self.Error +\
        self.Kd * (self.Error - 2 * self.LastError + self.LastLastError)

        self.PIDOutput += IncrementValue
        self.LastLastError = self.LastError
        self.LastError = self.Error

    #设置一阶惯性环节系统  其中InertiaTime为惯性时间常数
    #Set the first-order inertial link system, where inertiatime is the inertial time constant
    def SetInertiaTime(self,InertiaTime,SampleTime):
        self.SystemOutput = (InertiaTime * self.LastSystemOutput + \
            SampleTime * self.PIDOutput) / (SampleTime + InertiaTime)

        self.LastSystemOutput = self.SystemOutput
 
 
# *****************************************************************#
#                      位置式PID系统                               #
#                   Position PID system                            #
# *****************************************************************#
class PositionalPID:
    def __init__(self, P, I, D):
        self.Kp = P
        self.Ki = I
        self.Kd = D
 
        self.SystemOutput = 0.0
        self.ResultValueBack = 0.0
        self.PidOutput = 0.0
        self.PIDErrADD = 0.0
        self.ErrBack = 0.0
    
    #设置PID控制器参数
    #Set PID controller parameters
    def SetStepSignal(self,StepSignal):
        Err = StepSignal - self.SystemOutput
        KpWork = self.Kp * Err
        KiWork = self.Ki * self.PIDErrADD
        KdWork = self.Kd * (Err - self.ErrBack)
        self.PidOutput = KpWork + KiWork + KdWork
        self.PIDErrADD += Err
        self.ErrBack = Err

    #设置一阶惯性环节系统  其中InertiaTime为惯性时间常数
    #Set the first-order inertial link system, where inertiatime is the inertial time constant
    def SetInertiaTime(self, InertiaTime,SampleTime):
       self.SystemOutput = (InertiaTime * self.ResultValueBack + \
           SampleTime * self.PidOutput) / (SampleTime + InertiaTime)
       self.ResultValueBack = self.SystemOutput
#导入模块PID.py
import PID
#创建控制实例
follow_speed_pid = PID.PositionalPID(1.5, 0, 0.05)
turn_gain_pid = PID.PositionalPID(0.15, 0, 0.05)

Then configure the exit (original value + xservo_pid.SystemOutput) and entry value (Now_value) for the PID controller, set the inertia constant (InertiaTime), sampling time constant (SampleTime), and initial value (original_value).

Inertia Time Constant (InertiaTime): Simply put, it is the time it takes to overcome inertia.

Sampling time constant (SampleTime): Indicates the interval between the last input data of the PID controller and the adjacent input data, which is roughly equal to the time it takes to enter the main function of the PID controller once.

follow_speed_pid.SystemOutput = Now_value
follow_speed_pid.SetStepSignal(Target_value)
follow_speed_pid.SetInertiaTime(InertiaTime, SampleTime)
target_valuex = int(original_value + follow_speed_pid.SystemOutput)

通过上面的步骤,基本的PID控制器就完成了

8、PID控制器调参

这个跟前面深度学习中的超参数等类似,要想得到一组合适的参数也需要进行调试,在PID中调参非常烦杂,下面是一些经验调参步骤:

1、确定比例系数Kp

确定比例系数Kp时,首先去掉PID的积分项和微分项,可以令Ti=0、Td=0,使之成为纯比例调节。输入设定为系统允许输出最大值的60%~70%,比例系数Kp由0开始逐渐增大,直至系统出现振荡;再反过来,从此时的比例系数Kp逐渐减小,直至系统振荡消失。记录此时的比例系数Kp,设定PID的比例系数Kp为当前值的60%~70%。

2、确定积分时间常数Ti

比例系数Kp确定之后,设定一个较大的积分时间常数Ti,然后逐渐减小Ti,直至系统出现振荡,然后再反过来,逐渐增大Ti,直至系统振荡消失。记录此时的Ti,设定PID的积分时间常数Ti为当前值的150%~180%。

3、确定微分时间常数Td

微分时间常数Td一般不用设定,为0即可,此时PID调节转换为PI调节。如果需要设定,则与确定Kp的方法相同,取不振荡时其值的30%。

4、系统空载、带载联调

对PID参数进行微调,直到满足性能要求。

网上流传着调试PID的口诀,如下:

参数整定找最佳, 从小到大顺序查。
先是比例后积分, 最后再把微分加。
曲线振荡很频繁, 比例度盘要放大。
曲线漂浮绕大弯, 比例度盘往小扳。
曲线偏离回复慢, 积分时间往下降。
曲线波动周期长, 积分时间再加长。
曲线振荡频率快, 先把微分降下来。
动差大来波动慢, 微分时间应加长。
理想曲线两个波, 前高后低四比一。
一看二调多分析, 调节质量不会低。

PID是比例(P)、积分(I)、微分(D)控制算法,并不是必须同时具备这三种算法,也可以是PD,PI,甚至只有P算法控制。

Guess you like

Origin blog.csdn.net/weixin_41896770/article/details/129744078