当前位置: 首页 > news >正文

二轮平衡小车3:PID速度环

使用芯片:STM32 F103 C8T6

今日继续我的二路平衡小车开发之路,今日编写的是二轮平衡小车的PID速度环,我准备了纸飞机串口助手软件来辅助测试调节PID。

本文主要贴代码,之前的文章都有原理,代码中相应初始化驱动部分也有注释~~

文章提供源码,解释以及工程下载,测试效果视频。

PID基础概念:

 这里简单介绍一下PID算法是反馈调节的算法,只需输入期望值与传感器反馈值即可实现自动调节电机PWM控制速度始终在期望值附近,即:反馈小了就加占空比,反馈大了就减占空比,但却不是简单的加减运算。

原理之前写过,这里直接贴出文章连接:

PID输出反馈回路调控算法原理_NULL指向我的博客-CSDN博客

编码器测速逻辑:

此处贴出函数,相关逻辑在之前的文章讲过:

MSP432自主开发笔记1:编码器测速_外部中断捕获法测速\测正反转_msp432编码器_NULL指向我的博客-CSDN博客

对于速度单位的理解与计算有各种各样,有喜欢算到  (cm/s) (m / s)  (rad / second )等等,需要通过不同电机转速,需求来选定。

这里我是用的电机减速比比较大,扭矩与载重大,但因此转速就慢,因此我采用每25ms采样的脉冲数作为速度来比较,使速度环闭合。

//定时器3中断服务程序	  (编码器捕获脉冲数)
void TIM3_IRQHandler(void)
{ if(TIM_GetITStatus(TIM3, TIM_IT_CC1)) //通道1发生捕获事件{	Wheel[2].CAPTURE++;TIM_ClearITPendingBit(TIM3, TIM_IT_CC1);}	  //每次进入中断都要清空中断标志,否则主函数将无法正常执行if(TIM_GetITStatus(TIM3, TIM_IT_CC2)) //通道2发生捕获事件{Wheel[2].CAPTURE++;TIM_ClearITPendingBit(TIM3, TIM_IT_CC2);}		//每次进入中断都要清空中断标志,否则主函数将无法正常执行	if(TIM_GetITStatus(TIM3, TIM_IT_CC3)) //通道3发生捕获事件{Wheel[1].CAPTURE++;TIM_ClearITPendingBit(TIM3, TIM_IT_CC3);}		//每次进入中断都要清空中断标志,否则主函数将无法正常执行	if(TIM_GetITStatus(TIM3, TIM_IT_CC4)) //通道4发生捕获事件{Wheel[1].CAPTURE++;TIM_ClearITPendingBit(TIM3, TIM_IT_CC4);}	  //每次进入中断都要清空中断标志,否则主函数将无法正常执行
}void calculate_speed(void)
{uint16_t tt;tt=50;if(SPEED_flag==1){SPEED_flag=0;Wheel[1].SPEED=Wheel[1].CAPTURE;Wheel[2].SPEED=Wheel[2].CAPTURE;//		printf("V1=%d,V2=%d\r\n",Wheel[1].SPEED,Wheel[2].SPEED);printf("P1=%d,P2=%d\r\n",Wheel[1].PWM_DIV,Wheel[2].PWM_DIV);PRINT(plotter, "%d, %d, %d",Wheel[1].SPEED,Wheel[2].SPEED,tt);				PID_guide_peed(tt,tt);set_wheels(Wheel[1].PWM_DIV,Wheel[2].PWM_DIV,1,1);Wheel[1].CAPTURE=0; Wheel[2].CAPTURE=0;}
}

PID算法贴出:

 参数需要自己调,玄学调参......

#include "PID.h"PID_TYPE suduhuan1;
PID_TYPE suduhuan2;//PID 1~4号轮设置期望速度
void PID_guide_peed(uint16_t w1,uint16_t w2)
{Pid_increment_Cal(&suduhuan1,w1,Wheel[1].SPEED);Pid_increment_Cal(&suduhuan2,w2,Wheel[2].SPEED);	Wheel[1].PWM_DIV=suduhuan1.OutPut;Wheel[2].PWM_DIV=suduhuan2.OutPut;
}PID_结构体  target_目标  measure_当前值
void Pid_increment_Cal(PID_TYPE *PID, int target, int measure)
{PID->Error = target - measure;                                            // 误差PID->Pout = PID->P * (PID->Error - PID->PreError);                        // 比例控制PID->Iout = PID->I * PID->Error;                                          // 积分控制PID->Dout = PID->D * (PID->Error - 2 * PID->PreError + PID->PrePreError); // 微分控制// 比例 + 积分 + 微分总控制if (PID->Iout > PID->Irang) // 积分限幅PID->Iout = PID->Irang;if (PID->Iout < -PID->Irang) // 积分限幅PID->Iout = -PID->Irang;PID->OutPut += PID->Pout + PID->Iout + PID->Dout;PID->PrePreError = PID->PreError;  // 记忆e(k-2)PID->PreError = PID->Error;       // 记忆e(k-1)}void PidParameter_init(void)
{suduhuan1.P =38;suduhuan1.I=18;suduhuan1.D=0;suduhuan1.PreError=0;suduhuan1.PrePreError=0;suduhuan1.Irang=12;suduhuan1.OutPut=0;suduhuan2.P =38;suduhuan2.I=18;suduhuan2.D=0;suduhuan2.PreError=0;suduhuan2.PrePreError=0;suduhuan2.Irang=12;suduhuan2.OutPut=0;
}
#ifndef _PID_H_
#define _PID_H_#include "headfire.h"typedef struct PID
{int P;         //参数int I;int D;float Error;     //比例项e(k)float Integral;  //积分项int Differ;    //微分项int PreError;   //e(k-1)int PrePreError;//e(k-2)float Ilimit;float Irang;int Pout;int Iout;int Dout;int OutPut;uint8_t Ilimit_flag;    //积分分离
}PID_TYPE;extern PID_TYPE suduhuan1;
extern PID_TYPE suduhuan2;PID_结构体  target_目标  measure_当前值
void Pid_increment_Cal(PID_TYPE *PID, int target, int measure);
void PidParameter_init(void); //PID参数初始化 //PID 设置期望速度
void PID_guide_peed(uint16_t w1,uint16_t w2);#endif

http://www.lryc.cn/news/158164.html

相关文章:

  • C语言之练习题
  • 没钱,没人,没经验?传统制造型企业如何用无代码实现转型
  • CentOS ARM 部署 kubernetes v1.24.6
  • LeetCode 725. Split Linked List in Parts【链表】中等
  • 云计算中的负载均衡技术,确保资源的平衡分配
  • 探索 SOCKS5 代理在跨境电商中的网络安全应用
  • 全网独家:编译CentOS6.10系统的openssl-1.1.1多版本并存的rpm安装包
  • 【go】异步任务解决方案Asynq实战
  • 掌握 Android 自动化测试框架 UiAutomator UiAutomator2
  • c#抽象类(abstract)
  • 语义分割实践思考记录(个人备忘录)
  • Zebec Protocol 成非洲利比亚展会合作伙伴,并将向第三世界国家布局
  • 随机流-RandomAccessFile
  • 单例和静态类
  • PMP-项目风险管理的重要性
  • 学习的心得
  • Python网络爬虫中这七个li标签下面的属性值,不是固定的,怎样才能拿到他们的值呢?...
  • 白鲸开源 DataOps 平台加速数据分析和大模型构建
  • (其他) 剑指 Offer 65. 不用加减乘除做加法 ——【Leetcode每日一题】
  • RestTemplate 的用法
  • postgresql-使用plpgsql批量插入用户测试数据
  • 通过Siri打造智能爬虫助手:捕获与解析结构化数据
  • 【电源专题】典型设备的接地设计
  • LeetCode-216-组合总和Ⅱ
  • [技术杂谈]几款常用的安装包制作工具
  • 旋转屏幕显示方向-rk3568
  • 07 Linux补充|秋招刷题|9月6日
  • 【JavaGuide学习笔记】Day.1
  • 大数据课程K18——Spark的ALS算法与显式矩阵分解
  • Android Jetpack架构组件库:Hilt