本文为深蓝学院-自动驾驶控制与规划-第二章作业
目录
1 project introduction
本项目希望大家根据PID控制方法实现一个巡航控制系统。我们已经为大家开发了ROS1.0的系统框架,仅需要大家实现.cpp文件中的todo部分,即 control 实现以及 reset PID参数。
框架如下
  
   - 
    
     
    
    
     
      #include "pid_controller.h"
     
    
- 
    
     
    
    
      
     
    
- 
    
     
    
    
     
      namespace shenlan {
     
    
- 
    
     
    
    
     
      namespace control {
     
    
- 
    
     
    
    
      
     
    
- 
    
     
    
    
     
      PIDController::
      PIDController(
      const 
      double kp, 
      const 
      double ki,
     
    
- 
    
     
    
    
                                  
      const 
      double kd) {
     
    
- 
    
     
    
    
     
        kp_ = kp;
     
    
- 
    
     
    
    
     
        ki_ = ki;
     
    
- 
    
     
    
    
     
        kd_ = kd;
     
    
- 
    
     
    
    
     
        previous_error_ = 
      0.0;
     
    
- 
    
     
    
    
     
        previous_output_ = 
      0.0;
     
    
- 
    
     
    
    
     
        integral_ = 
      0.0;
     
    
- 
    
     
    
    
     
        first_hit_ = 
      true;
     
    
- 
    
     
    
    
     
      }
     
    
- 
    
     
    
    
      
     
    
- 
    
     
    
    
     
      // /**to-do**/ 实现PID控制
     
    
- 
    
     
    
    
     
      double PIDController::Control(const double error, const double dt) {
     
    
- 
    
     
    
    
       
     
    
- 
    
     
    
    
     
      }
     
    
- 
    
     
    
    
      
     
    
- 
    
     
    
    
     
      // /**to-do**/ 重置PID参数
     
    
- 
    
     
    
    
     
      void PIDController::Reset() {
     
    
- 
    
     
    
    
         
     
    
- 
    
     
    
    
     
      }
     
    
- 
    
     
    
    
      
     
    
- 
    
     
    
    
     
      }  
      // namespace control
     
    
- 
    
     
    
    
     
      }  
      // namespace shenlan
     
    
 2 思路提示
为实现PID控制,我们可以利用离散的PID控制来实现,当采样时间足够短时,也能保持较好的性能,公式如下

需要注意的点就是积分初始值为0、微分初始值为0
  
   - 
    
     
    
    
     
      double PIDController::Control(const double 
      error, const double dt) {
     
    
- 
    
     
    
    
     
      if (dt<=
      0)
     
    
- 
    
     
    
    
     
      {
      return previous_output_;
     
    
- 
    
     
    
    
     
      }
     
    
- 
    
     
    
    
      
     
    
- 
    
     
    
    
     
      double diff=
      0;
     
    
- 
    
     
    
    
     
      double 
      output=
      0;
     
    
- 
    
     
    
    
     
      if (first_hit_){
     
    
- 
    
     
    
    
     
      first_hit_=
      false;
     
    
- 
    
     
    
    
     
      }
     
    
- 
    
     
    
    
     
      else{
     
    
- 
    
     
    
    
     
      diff=(
      error-previous_error_)*kd_/dt;
     
    
- 
    
     
    
    
     
      }
     
    
- 
    
     
    
    
     
      integral_ += 
      error*dt*ki_;//积分的计算可以由下面两种方法替代
     
    
- 
    
     
    
    
     
      output=
      error*kp_+integral_+diff;
     
    
- 
    
     
    
    
     
      previous_error_=
      error;
     
    
- 
    
     
    
    
     
      previous_output_=
      output;
     
    
- 
    
     
    
    
     
      return 
      output;
     
    
- 
    
     
    
    
     
      }
     
    
 同时项目中还要求写一个 reset 的函数,我们需要更新下面这四个参数来保证从头开始
  
   - 
    
     
    
    
     
      void 
      PIDController::
      Reset() {
     
    
- 
    
     
    
    
     
        previous_error_ = 
      0.0;
     
    
- 
    
     
    
    
     
        previous_output_ = 
      0.0;
     
    
- 
    
     
    
    
     
        integral_ = 
      0.0;
     
    
- 
    
     
    
    
     
        first_hit_ = 
      true;
     
    
- 
    
     
    
    
     
      }
     
    
3 解决积分饱和的方法
3.1 IC 积分遇限削弱法
  
   - 
    
     
    
    
     
      // 积分遇限消弱法
     
    
- 
    
     
    
    
     
      double output_saturation_high=
      10.0;
     
    
- 
    
     
    
    
     
      double output_saturation_low=
      -10.0;
     
    
- 
    
     
    
    
     
      double u =
      error*kp_+integral_+
      error*dt*ki_+diff*kd_ ; 
      // 算当前时刻理应输出大小
     
    
- 
    
     
    
    
     
      if (((
      error *u)> 
      0) &&
     
    
- 
    
     
    
    
     
      ((u > output_saturation_high )||(u < output_saturation_low))) {
     
    
- 
    
     
    
    
     
      }
     
    
- 
    
     
    
    
     
      else {
     
    
- 
    
     
    
    
     
      integral_ += 
      error*dt*ki_;
     
    
- 
    
     
    
    
     
      }
     
    
3.2 BC 反馈抑制抗饱和
  
   - 
    
     
    
    
     
      // 反馈抑制抗饱和
     
    
- 
    
     
    
    
     
      double output_saturation_high=
      10.0;
     
    
- 
    
     
    
    
     
      double output_saturation_low=
      -10.0;
     
    
- 
    
     
    
    
     
      double kaw=ki_/kp_;
     
    
- 
    
     
    
    
     
      double u = error*kp_+integral_+error*dt*ki_+diff*kd_;
     
    
- 
    
     
    
    
     
      double aw_term =
      0.0;
     
    
- 
    
     
    
    
     
      if (u > output_saturation_high){
     
    
- 
    
     
    
    
     
      aw_term=(output_saturation_high-u)*kaw;
     
    
- 
    
     
    
    
     
      }
     
    
- 
    
     
    
    
     
      else 
      if (u < output_saturation_low)
     
    
- 
    
     
    
    
     
      aw_term=(output_saturation_low)*kaw;
     
    
- 
    
     
    
    
     
      else{
     
    
- 
    
     
    
    
     
      }
     
    
- 
    
     
    
    
     
      integral_+=aw_term+error*dt*ki_;
     
    
- 
    
     
    
    
     
      }
     
    
 4 ROS+LGSVL联合仿真

这里是联合仿真的链接
自动驾驶PID控制(ROS+LGSVL联合仿真)_哔哩哔哩_bilibili
转载:https://blog.csdn.net/weixin_65089713/article/details/128720062
查看评论
					 
					