二轮平衡小车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
相关文章:
二轮平衡小车3:PID速度环
使用芯片:STM32 F103 C8T6 今日继续我的二路平衡小车开发之路,今日编写的是二轮平衡小车的PID速度环,我准备了纸飞机串口助手软件来辅助测试调节PID。 本文主要贴代码,之前的文章都有原理,代码中相应初始化驱动部分也…...
C语言之练习题
欢迎来到我的世界 希望这篇文章对你有所帮助,有不足的地方还请指正,大家一起学习交流 ! 目录 前言编程题第一题:珠玑妙算第二题:寻找奇数第三题:寻找峰值第四题:数对 总结 前言 这是暑假题目的收尾文章&am…...
没钱,没人,没经验?传统制造型企业如何用无代码实现转型
2023年,国家市场监督管理总局发布了三项重要标准,包括《工业互联网平台选型要求》、《工业互联网平台微服务参考框架》和《工业互联网平台开放应用编程接口功能要求》。这些标准的发布对于完善工业互联网平台标准体系,提升多样化工业互联网平…...
CentOS ARM 部署 kubernetes v1.24.6
1.背景 之前安装的kubernetes版本为v1.19.0 树莓派使用(CentOS7.9 armv71 Kubernetes1.19.0), 由于版本过低,一些HPA相关的功能支持不是特别好,因此需要将版本升级,本次会将版本升级为v1.24.6. 2. 如何upgrade 2.1. 优雅升级 kubeadm自带…...
LeetCode 725. Split Linked List in Parts【链表】中等
本文属于「征服LeetCode」系列文章之一,这一系列正式开始于2021/08/12。由于LeetCode上部分题目有锁,本系列将至少持续到刷完所有无锁题之日为止;由于LeetCode还在不断地创建新题,本系列的终止日期可能是永远。在这一系列刷题文章…...
云计算中的负载均衡技术,确保资源的平衡分配
文章目录 1. 硬件负载均衡器2. 软件负载均衡器3. DNS负载均衡4. 内容分发网络(CDN) 🎈个人主页:程序员 小侯 🎐CSDN新晋作者 🎉欢迎 👍点赞✍评论⭐收藏 ✨收录专栏:云计算 ✨文章内…...
探索 SOCKS5 代理在跨境电商中的网络安全应用
随着全球化的发展,跨境电商成为了商业界的一颗新星,为企业提供了无限的发展机遇。然而,随之而来的是网络安全的挑战,特别是在处理国际网络流量时。在这篇文章中,我们将探讨如何利用 SOCKS5 代理和代理 IP 技术来加强跨…...
全网独家:编译CentOS6.10系统的openssl-1.1.1多版本并存的rpm安装包
CentOS6.10系统原生的openssl版本太老,1.0.1e,不能满足一些新版本应用软件的要求,但是它又被wget、mysql-libs、python-2.6.6、yum等一众系统包所依赖,不能再做升级。故需考虑在不影响系统原生openssl的情况下,安装较新…...
【go】异步任务解决方案Asynq实战
文章目录 一.Asynq介绍二.所需工具三.代码示例四.Reference 一.Asynq介绍 Asynq 是一个 Go 库,一个高效的分布式任务队列。 Asynq 工作原理: 客户端(生产者)将任务放入队列服务器(消费者)从队列中拉出任…...
掌握 Android 自动化测试框架 UiAutomator UiAutomator2
掌握 Android 自动化测试框架 UiAutomator & UiAutomator2 一、UiAutomator 简介二、UiAutomator2 的诞生三、UiAutomator2 的应用实践总结你是否曾经在进行 Android 应用开发时,对于如何进行全面、有效的自动化测试感到困惑?你是否想要更高效地进行 UI 测试,而不是一遍…...
c#抽象类(abstract)
概述: C#中的抽象类是一种特殊类型的类,它不能被实例化,只能被继承。抽象类用于提供一个共享的基类,其中定义了一些方法和属性的签名,但没有具体的实现。这些方法和属性可以在派生类中进行实现。 使用抽象类的主要目…...
语义分割实践思考记录(个人备忘录)
一、任务管理器、NVDIA的GPU利用率显示[1][2] 若需要在任务管理器中查看基于Pytorch框架的GPU利用率,那么,我们需要将监控面板监测内容调整为cuda。图一(左)即为英伟达命令行工具面板。 图一 英伟达GPU使用率监控 二、基于混淆矩阵…...
Zebec Protocol 成非洲利比亚展会合作伙伴,并将向第三世界国家布局
在 9 月 6 日,The Digital Asset Summit ’23(利比亚大会)在尼日利亚首度阿布贾的 NAF 会议中心举办,该会议对 Web3 领域在非洲地区的发展进行了探索,旨在推动非洲地区区块链产业的进一步发展,据悉该会议室…...
随机流-RandomAccessFile
RandomAccessFile RandomAccessFile 基本操作案例 RandomAccessFile 基本操作 案例 import java.io.*;public class TestMain09 {public static void main(String[] args) throws Exception {insert("D:\\home\\product\\aa.txt",2,"ni");}public static…...
单例和静态类
C#中的单例(Singleton)和静态类(Static Class)是两种不同的设计模式,它们各自有不同的用途和特点。 单例模式是一种设计模式,它确保一个类只有一个实例,并提供全局访问点。通常,单例…...
PMP-项目风险管理的重要性
一、什么是项目风险管理 项目风险管理旨在识别和管理未被其他项目管理过程所管理的风险。如果不妥善管理,这些风险有可能导致项目偏离计划,无法达成既定的项目目标。因此,项目风险管理的有效性直接关乎项目成功与否。 每个项目都在两个层面…...
学习的心得
文章目录 第一节课心得**学会了敲写数学公式** 第一节课心得 老师讲得非常好,我们下载了xmind,如何制作思维导图 学会了敲写数学公式 ∫ 10 20 ( x 2 − 3 x 2 ) d x \displaystyle\int_{10}^{20}(x^2-3x2)dx ∫1020(x2−3x2)dx...
Python网络爬虫中这七个li标签下面的属性值,不是固定的,怎样才能拿到他们的值呢?...
点击上方“Python爬虫与数据挖掘”,进行关注 回复“书籍”即可获赠Python从入门到进阶共10本电子书 今 日 鸡 汤 愚以为宫中之事,事无大小,悉以咨之,然后施行,必能裨补阙漏,有所广益。 大家好,我…...
白鲸开源 DataOps 平台加速数据分析和大模型构建
作者 | 李晨 编辑 | Debra Chen 数据准备对于推动有效的自助式分析和数据科学实践至关重要。如今,企业大都知道基于数据的决策是成功数字化转型的关键,但要做出有效的决策,只有可信的数据才能提供帮助,随着数据量和数据源的多样…...
(其他) 剑指 Offer 65. 不用加减乘除做加法 ——【Leetcode每日一题】
❓ 剑指 Offer 65. 不用加减乘除做加法 难度:简单 写一个函数,求两个整数之和,要求在函数体内不得使用 “”、“-”、“*”、“/” 四则运算符号。 示例: 输入: a 1, b 1 输出: 2 提示: a, b 均可能是负数或 0结果不会溢出 …...
【2025年】解决Burpsuite抓不到https包的问题
环境:windows11 burpsuite:2025.5 在抓取https网站时,burpsuite抓取不到https数据包,只显示: 解决该问题只需如下三个步骤: 1、浏览器中访问 http://burp 2、下载 CA certificate 证书 3、在设置--隐私与安全--…...
Mac软件卸载指南,简单易懂!
刚和Adobe分手,它却总在Library里给你写"回忆录"?卸载的Final Cut Pro像电子幽灵般阴魂不散?总是会有残留文件,别慌!这份Mac软件卸载指南,将用最硬核的方式教你"数字分手术"࿰…...
论文解读:交大港大上海AI Lab开源论文 | 宇树机器人多姿态起立控制强化学习框架(一)
宇树机器人多姿态起立控制强化学习框架论文解析 论文解读:交大&港大&上海AI Lab开源论文 | 宇树机器人多姿态起立控制强化学习框架(一) 论文解读:交大&港大&上海AI Lab开源论文 | 宇树机器人多姿态起立控制强化…...
3403. 从盒子中找出字典序最大的字符串 I
3403. 从盒子中找出字典序最大的字符串 I 题目链接:3403. 从盒子中找出字典序最大的字符串 I 代码如下: class Solution { public:string answerString(string word, int numFriends) {if (numFriends 1) {return word;}string res;for (int i 0;i &…...
保姆级教程:在无网络无显卡的Windows电脑的vscode本地部署deepseek
文章目录 1 前言2 部署流程2.1 准备工作2.2 Ollama2.2.1 使用有网络的电脑下载Ollama2.2.2 安装Ollama(有网络的电脑)2.2.3 安装Ollama(无网络的电脑)2.2.4 安装验证2.2.5 修改大模型安装位置2.2.6 下载Deepseek模型 2.3 将deepse…...
【分享】推荐一些办公小工具
1、PDF 在线转换 https://smallpdf.com/cn/pdf-tools 推荐理由:大部分的转换软件需要收费,要么功能不齐全,而开会员又用不了几次浪费钱,借用别人的又不安全。 这个网站它不需要登录或下载安装。而且提供的免费功能就能满足日常…...
安全突围:重塑内生安全体系:齐向东在2025年BCS大会的演讲
文章目录 前言第一部分:体系力量是突围之钥第一重困境是体系思想落地不畅。第二重困境是大小体系融合瓶颈。第三重困境是“小体系”运营梗阻。 第二部分:体系矛盾是突围之障一是数据孤岛的障碍。二是投入不足的障碍。三是新旧兼容难的障碍。 第三部分&am…...
MFC 抛体运动模拟:常见问题解决与界面美化
在 MFC 中开发抛体运动模拟程序时,我们常遇到 轨迹残留、无效刷新、视觉单调、物理逻辑瑕疵 等问题。本文将针对这些痛点,详细解析原因并提供解决方案,同时兼顾界面美化,让模拟效果更专业、更高效。 问题一:历史轨迹与小球残影残留 现象 小球运动后,历史位置的 “残影”…...
【JVM】Java虚拟机(二)——垃圾回收
目录 一、如何判断对象可以回收 (一)引用计数法 (二)可达性分析算法 二、垃圾回收算法 (一)标记清除 (二)标记整理 (三)复制 (四ÿ…...
从 GreenPlum 到镜舟数据库:杭银消费金融湖仓一体转型实践
作者:吴岐诗,杭银消费金融大数据应用开发工程师 本文整理自杭银消费金融大数据应用开发工程师在StarRocks Summit Asia 2024的分享 引言:融合数据湖与数仓的创新之路 在数字金融时代,数据已成为金融机构的核心竞争力。杭银消费金…...
