(六)【平衡小车制作】位置式PID、直立环与速度环编程

这篇具有很好参考价值的文章主要介绍了(六)【平衡小车制作】位置式PID、直立环与速度环编程。希望对大家有所帮助。如果存在错误或未考虑完全的地方,请大家不吝赐教,您也可以点击"举报违法"按钮提交疑问。

本篇文章我将针对位置式PID算法直立环速度环等的编程进行详细的讲解,让每位小伙伴能够对这三个概念的编程逻辑有更加清晰的理解。

一、直立环(PD控制器)

1.中文公式
 直立环输出=Kp1×角度偏差+Kd×角度偏差的微分
 // 角度偏差=真实角度-期望角度

2.英文公式
 直立环PD控制器:Kp×Ek+Kd×Ek_D
 (Ek:角度偏差;Ek_D:角度偏差的微分)

Ek=真实角度-期望角度(Angle-Med,由陀螺仪MPU6050测得)
Ek_D=真实角速度(gyro_Y,由陀螺仪MPU6050测得)---角度的微分值代表角速度

3.软件编程
  根据理论公式进行软件编程,相信看完上面的讲解后这段代码应该比较清晰易懂。

/*****************  
直立环PD控制器:Kp*Ek+Kd*Ek_D
入口:Med:机械中值(期望角度),Angle:真实角度,gyro_Y:真实角速度
出口:直立环输出
******************/
int Vertical(float Med,float Angle,float gyro_Y) 
{
  int PWM_out;
  
  PWM_out = Vertical_Kp*(Angle-Med)+Vertical_Kd*(gyro_Y-0);
  
  return PWM_out;
} 

 

二、速度环(PI控制器)


1.中文公式

 速度环输出=Kp2×电机速度偏差+Ki2×电机速度偏差的积分
 // 电机速度偏差=真实速度-期望速度

2.英文公式

 速度环PI控制器:Kp×Ek+Ki×Ek_S
 (Ek:电机速度偏差;Ek_S:电机速度偏差的积分)

Ek=真实速度-期望速度(真实速度:左电机速度+右电机速度;期望速度:0)
Ek_S=速度偏差的累加
3.低通滤波

  期间需要低频滤波,我们是以直立环为主,速度环为辅,速度环相对于直立环来说是一个干扰,最终目的是直立。低频滤波作用是使得波形更加平滑,滤除高频干扰,防止速度过大影响直立环正常工作。

4.积分限幅

  通过比较限制积分在规定范围内变动,不得超出。

5.软件编程

  根据理论公式进行软件编程,相信看完上面的讲解后这段代码应该比较清晰易懂。

/*****************  
速度环PI控制器:Kp*Ek+Ki*Ek_S(Ek_S:偏差的积分)
******************/
int Velocity(int Target,int encoder_left,int encoder_right)
{
  // 定义成静态变量,保存在静态存储器,使得变量不丢掉
  static int PWM_out,Encoder_Err,Encoder_S,EnC_Err_Lowout,EnC_Err_Lowout_last;
  float a=0.7;
  
  // 1.计算速度偏差
  //舍去误差--我的理解:能够让速度为"0"的角度,就是机械中值。
  Encoder_Err = ((encoder_left+encoder_right)-Target);
  
  // 2.对速度偏差进行低通滤波
  // low_out = (1-a)*Ek+a*low_out_last
  EnC_Err_Lowout = (1-a)*Encoder_Err + a*EnC_Err_Lowout_last; // 使得波形更加平滑,滤除高频干扰,放置速度突变
  EnC_Err_Lowout_last = EnC_Err_Lowout;   // 防止速度过大影响直立环的正常工作
  
  // 3.对速度偏差积分出位移
  Encoder_S+=EnC_Err_Lowout;
  
  // 4.积分限幅
  Encoder_S=Encoder_S>10000?10000:(Encoder_S<(-10000)?(-10000):Encoder_S);
  
  // 5.速度环控制输出
  PWM_out = Velocity_Kp*EnC_Err_Lowout+Velocity_Ki*Encoder_S;
  
  return PWM_out;
}

三、转向环

1.中文公式

 转向环输出=系数×Z轴角速度
 (Z轴角速度由陀螺仪MPU6050测得)

2.软件编程

  转向环的编程比较简单,我们只需设置一个参数调节Z轴角速度即可。

/*****************  
转向环:系数*Z轴角速度
******************/
int Turn(int gyro_Z)
{
  int PWM_out;
  
  PWM_out = (-0.6)*gyro_Z;
  
  return PWM_out;
}

四、控制函数


1、采集编码器数据和MPU6050角度信息

 编码器数据:左电机速度,右电机速度
(两个电机是相对安装,刚好相差180度,为了编码器输出极性一致,就需要对其中一个取反)
 MPU6050数据:角度数据,角速度数据,角加速度数据
2、将数据压入闭环控制中,计算出控制输出量

 直立环输出
 速度环输出
 转向环输出
3、把控制输出量加载到电机上,完成最终的控制

 左电机输出(编码器放置相对)
 右电机输出
 限幅
 赋值
4、控制中断函数
 首先要判断是否接受到中断请求,即检测MPU6050的ANT引脚是否处在低电平(即为发生中断),然后清除中断标志位,进行接下来三步(即上面的三个步骤)。
 

void EXTI9_5_IRQHandler(void)
{
  int PWM_out;
  if(EXTI_GetITStatus(EXTI_Line5)!=0) // 一级判定
  {
    if(PBin(5)==0)    // 二级判断
    { 
      EXTI_ClearITPendingBit(EXTI_Line5); // 清除中断标志位
      // 1.采集编码器数据&MPU6050角度信息
      // 电机是相对安装,刚好相差180度,为了编码器输出极性一致,就需要对其中一个取反
      Encoder_Left  = -Read_Speed(2); 
      Encoder_Right = Read_Speed(4);
      
      mpu_dmp_get_data(&Pitch,&Roll,&Yaw);	    // 读取角度
      MPU_Get_Gyroscope(&gyrox,&gyroy,&gyroz);  // 读取角速度
      MPU_Get_Accelerometer(&aacx,&aacy,&aacz); // 读取加速度
      // 2.将数据压入闭环控制中,计算出控制输出量
			Velocity_out=Velocity(Target_Speed,Encoder_Left,Encoder_Right); // 速度环
      Vertical_out=Vertical(Velocity_out+Med_Angle,Roll,gyrox);			  // 直立环
			Turn_out=Turn(gyroz);	
      
      PWM_out=Vertical_out;//最终输出
      
      // 3.把控制输出量加载到电机上,完成最终控制
      MOTO1 = PWM_out-Turn_out; // 左电机
      MOTO2 = PWM_out+Turn_out; // 右电机
      Limit(&MOTO1,&MOTO2);     // PWM限幅
      Load(MOTO1,MOTO2);        // 加载到电机上
    }
  }
}

五、整个控制函数源代码

1、control.c

#include "control.h"

float Med_Angle=0;      // 机械中值,能使得小车真正平衡住的角度 
float Target_Speed=0;	  // 期望速度。---二次开发接口,用于控制小车前进后退及其速度。
float 
  Vertical_Kp=0,
  Vertical_Kd=0;     // 直立环Kp、Kd
float 
  Velocity_Kp=0,     // 速度环Kp、Ki(正反馈)
  Velocity_Ki=0;
float 
  Turn_Kp=0;

int Vertical_out,Velocity_out,Turn_out; // 直立环&速度环&转向环的输出变量

int Vertical(float Med,float Angle,float gyro_Y); // 函数声明
int Velocity(int Target,int encoder_left,int encoder_right);
int Turn(int gyro_Z);

void EXTI9_5_IRQHandler(void)
{
  int PWM_out;
  if(EXTI_GetITStatus(EXTI_Line5)!=0) // 一级判定
  {
    if(PBin(5)==0)    // 二级判断
    { 
      EXTI_ClearITPendingBit(EXTI_Line5); // 清除中断标志位
      // 1.采集编码器数据&MPU6050角度信息
      // 电机是相对安装,刚好相差180度,为了编码器输出极性一致,就需要对其中一个取反
      Encoder_Left  = -Read_Speed(2); 
      Encoder_Right = Read_Speed(4);
      
      mpu_dmp_get_data(&Pitch,&Roll,&Yaw);	    // 读取角度
      MPU_Get_Gyroscope(&gyrox,&gyroy,&gyroz);  // 读取角速度
      MPU_Get_Accelerometer(&aacx,&aacy,&aacz); // 读取加速度
      // 2.将数据压入闭环控制中,计算出控制输出量
			Velocity_out=Velocity(Target_Speed,Encoder_Left,Encoder_Right); // 速度环
      Vertical_out=Vertical(Velocity_out+Med_Angle,Roll,gyrox);			  // 直立环
			Turn_out=Turn(gyroz);	
      
      PWM_out=Vertical_out;//最终输出
      
      // 3.把控制输出量加载到电机上,完成最终控制
      MOTO1 = PWM_out-Turn_out; // 左电机
      MOTO2 = PWM_out+Turn_out; // 右电机
      Limit(&MOTO1,&MOTO2);     // PWM限幅
      Load(MOTO1,MOTO2);        // 加载到电机上
    }
  }
}

/*****************  
直立环PD控制器:Kp*Ek+Kd*Ek_D

入口:Med:机械中值(期望角度),Angle:真实角度,gyro_Y:真实角速度
出口:直立环输出
******************/
int Vertical(float Med,float Angle,float gyro_Y) 
{
  int PWM_out;
  
  PWM_out = Vertical_Kp*(Angle-Med)+Vertical_Kd*(gyro_Y-0);
  
  return PWM_out;
} 

/*****************  
速度环PI控制器:Kp*Ek+Ki*Ek_S(Ek_S:偏差的积分)
******************/
int Velocity(int Target,int encoder_left,int encoder_right)
{
  // 定义成静态变量,保存在静态存储器,使得变量不丢掉
  static int PWM_out,Encoder_Err,Encoder_S,EnC_Err_Lowout,EnC_Err_Lowout_last;
  float a=0.7;
  
  // 1.计算速度偏差
  //舍去误差--我的理解:能够让速度为"0"的角度,就是机械中值。
  Encoder_Err = ((encoder_left+encoder_right)-Target);
  // 2.对速度偏差进行低通滤波
  // low_out = (1-a)*Ek+a*low_out_last
  EnC_Err_Lowout = (1-a)*Encoder_Err + a*EnC_Err_Lowout_last; // 使得波形更加平滑,滤除高频干扰,放置速度突变
  EnC_Err_Lowout_last = EnC_Err_Lowout;   // 防止速度过大影响直立环的正常工作
  // 3.对速度偏差积分出位移
  Encoder_S+=EnC_Err_Lowout;
  // 4.积分限幅
  Encoder_S=Encoder_S>10000?10000:(Encoder_S<(-10000)?(-10000):Encoder_S);
  
  // 5.速度环控制输出
  PWM_out = Velocity_Kp*EnC_Err_Lowout+Velocity_Ki*Encoder_S;
  
  return PWM_out;
}

/*****************  
转向环:系数*Z轴角速度
******************/
int Turn(int gyro_Z)
{
  int PWM_out;
  
  PWM_out = Turn_Kp*gyro_Z;
  
  return PWM_out;
}

以上就是平衡小车系列文章第六讲——位置式PID、直立环与速度环软件编程讲解,平衡小车系列文章作者在持续更新中。若文章中出现错误或者小伙伴对以上内容有所疑问,欢迎大家在评论区留言,小政看到后会尽快回复大家!文章来源地址https://www.toymoban.com/news/detail-435442.html

到了这里,关于(六)【平衡小车制作】位置式PID、直立环与速度环编程的文章就介绍完了。如果您还想了解更多内容,请在右上角搜索TOY模板网以前的文章或继续浏览下面的相关文章,希望大家以后多多支持TOY模板网!

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处: 如若内容造成侵权/违法违规/事实不符,请点击违法举报进行投诉反馈,一经查实,立即删除!

领支付宝红包 赞助服务器费用

相关文章

  • 直流有刷电机位置环控制与位置速度双环控制(位置式PID)流程解析

    今天看野火的直流有刷电机pid控制的教程视频,整个代码实现过程看了好几遍后还是感觉云里雾里,尤其是速度环、位置环、位置速度双环这样看下来,虽然老师视频里该说的都说了,自己也能明确感受到位置环与位置速度双环是有区别的,但不好好捋一下还真没一下领略到

    2023年04月12日
    浏览(48)
  • 位置环速度环串级位置式PID实现全过程解析(详细)

    电机型号:MD36N行星减速电机_AB两相光电编码器霍尔编码器 电机参数: 单片机型号:STM32F429IG,keil 程序最终功能:串级位置式PID反复调节电机,使得电机可以在一定范围内精准任意停靠在某个位置,比如电机控制目标在圆形轨道转动,就可以实现在固定角度的位置停靠,四

    2023年04月08日
    浏览(42)
  • stm32平衡小车制作遇到的问题和解决方案分享

            1、电机带负载所引起的死区补偿问题         2、利用MPU6050传感器进行某一轴的角度测量问题         3、stm32串口通讯得到的数据用DMA转运问题         我选用的电机为直流减速电机,型号为GA25-370,是12V的电机。         电机运行分为带负载和不

    2024年01月18日
    浏览(49)
  • 不要将程序钉在直立位置

    Don’t Nail Your Program into the Upright Position I once wrote a spoof(恶作剧) C++ quiz(测验), in which I satirically(讽刺地) suggested the following strategy for exception handling: By dint of plentiful (大量的) try…catch constructs throughout our code base, we are sometimes able to prevent our applications from aborting. We think of

    2024年02月04日
    浏览(29)
  • 平衡小车——陀螺仪

    可以通过MPU6050获取加速度信息 可以通过DMP库获取角度信息 MPU6050 MPU6050是一种常用的集成电路(IC),结合了3轴陀螺仪和3轴加速度计。它用于各种需要运动跟踪和感应的电子项目和设备。MPU6050由英飞凌科技公司(InvenSense)制造,现在已被TDK收购。它的一些主要特点包括:

    2024年02月02日
    浏览(40)
  • 基于stm32的平衡小车

    目录 前言 一、电机驱动部分 1、TB6612FNG电机驱动模块接线方式: 2、代码使用定时器2的4路输出pwm 3、gpio引脚初始化,以及前进,后退引脚设置 二、MPU6050陀螺仪部分 三、编码器捕获部分 四、pid部分 1、直立环KD 2、速度环KI 3、转向环(PD) 五、蓝牙通信部分 总结 经过几天对

    2024年02月09日
    浏览(41)
  • 平衡小车学习教程1——硬件资源及其小车底层硬件介绍篇

    大家在学会了Stm32后,可以做一个项目来进行来进行练手, 平衡小车 就 是一个很好的练手项目,可以检验自己的学习成果 ,也可以对学习到的知识进行一个复习。再一个就是 通过做项目来锻炼自己的工程能力。 好啦,废话不多说, 本套教程预计分为两部分 , 硬件底层介

    2024年02月11日
    浏览(41)
  • 复刻stm32平衡小车(适合入门)

    目录 前言: 1.硬件部分 1.1 STM32最小系统 1.2 电源 1.3 TB6612电机驱动模块 1.4 串口通信 1.5 OLED模块 1.6 蓝牙模块 1.7 LED灯模块  1.8 MPU6050模块​编辑 1.9 硬件焊接与调试 1.10 组装 2.软件部分 2.1 代码 2.2 逻辑实现 2.2.1 control.c 2.2.2 usart.c 结尾 本文主要为复刻b站up主开源的平衡小车以及

    2024年02月13日
    浏览(56)
  • PID智能小车快速入门(一)

            1、什么是PID?                 PID控制器是一种线性控制器,通俗的来讲如人走直线一样,眼睛是观测器,下肢为执行器,当走偏了由眼睛观测得出当前位置和直线的偏差,由人脑根据偏差调整脚步回归直线的过程就是一个负反馈调节的过程,而PID控制器就是得到偏

    2024年01月20日
    浏览(31)
  • 智能车PID控制详细介绍(普通PID、串级PID、改进PID)——适用于四轮车、三轮车、平衡车

    声明:该文是本人原创,后续将参与智能车相关书籍的写作,为了防止侵权只能先发图片版还请谅解,如有问题,敬请指出,欢迎讨论~~~~ 1 舵机组成及其工作原理 2 舵机PID控制策略 1 直流电机调速系统组成及其工作原理 2 电机PID控制策略 一、四轮电机控制 二、两轮平衡车与

    2023年04月23日
    浏览(44)

觉得文章有用就打赏一下文章作者

支付宝扫一扫打赏

博客赞助

微信扫一扫打赏

请作者喝杯咖啡吧~博客赞助

支付宝扫一扫领取红包,优惠每天领

二维码1

领取红包

二维码2

领红包