第13章-循迹功能 循迹小车讲解 原理分析 STM32智能小车循迹教程 红外对管使用 PID循迹算法分析

讲解一下我们小车里面的循迹部分,包括红外基础使用,无PID循迹和有PID循迹。

第13章-循迹功能

13.1-非PID循迹功能完成

先红外对管调试

我们这里学习一下,如何实现循迹功能

如何才能让小车沿着黑线运动、要让小车感知到黑线的位置,使用这种传感器就可以反馈黑线是否存在
在这里插入图片描述
根据传感器特性,我们检测红外对管DO引脚的电压就可以知道,下面有没有黑线

DO 高电平->有黑线 小灯灭

DO低电平->没有黑线 小灯亮

这是好多地方对这个产品的说明

在这里插入图片描述
然后我们组合上面的红外对管,安装到小车上,就可以知道小车是否偏离了黑线,
在这里插入图片描述
下面我们通过单片机读取红外对管DO口的电压,就知道黑线在小车下面的位置了
STM32初始化

先看原理图需要初始化那些引脚
在这里插入图片描述

OUT_1-PA5、OUT_2-PA7、OUT_3-PB0、OUT_4-PB1初始化为输入模式
在这里插入图片描述
重新生成

然后我们在gpio.h 添加读取GPIO的宏,使得程序更简洁
在这里插入图片描述

#define READ_HW_OUT_1   HAL_GPIO_ReadPin(HW_OUT_1_GPIO_Port,HW_OUT_1_Pin) //读取红外对管连接的GPIO电平
#define READ_HW_OUT_2   HAL_GPIO_ReadPin(HW_OUT_2_GPIO_Port,HW_OUT_2_Pin)
#define READ_HW_OUT_3   HAL_GPIO_ReadPin(HW_OUT_3_GPIO_Port,HW_OUT_3_Pin)
#define READ_HW_OUT_4   HAL_GPIO_ReadPin(HW_OUT_4_GPIO_Port,HW_OUT_4_Pin)

根据红外对管状态控制电机速度

注意:整个主函数不要加入延时,这样实时性更高,可以根据红外对管状态做出及时控制
在这里插入图片描述

	if(READ_HW_OUT_1 == 0&&READ_HW_OUT_2 == 0&&READ_HW_OUT_3 == 0&&READ_HW_OUT_4 == 0 ){printf("应该前进\r\n");motorPidSetSpeed(1,1);//前运动}if(READ_HW_OUT_1 == 0&&READ_HW_OUT_2 == 1&&READ_HW_OUT_3 == 0&&READ_HW_OUT_4 == 0 ){printf("应该右转\r\n");motorPidSetSpeed(0.5,2);//右边运动}if(READ_HW_OUT_1 == 1&&READ_HW_OUT_2 == 0&&READ_HW_OUT_3 == 0&&READ_HW_OUT_4 == 0 ){printf("快速右转\r\n");motorPidSetSpeed(0.5,2.5);//快速右转}if(READ_HW_OUT_1 == 0&&READ_HW_OUT_2 == 0&&READ_HW_OUT_3 == 1&&READ_HW_OUT_4 == 0 ){printf("应该左转\r\n");motorPidSetSpeed(2,0.5);//左边运动}if(READ_HW_OUT_1 == 0&&READ_HW_OUT_2 == 0&&READ_HW_OUT_3 == 0&&READ_HW_OUT_4 == 1 ){printf("快速左转\r\n");motorPidSetSpeed(2.5,0.5);//快速左转}

然后测试

  1. 测试红外对管灵敏度,放在有黑线的地上或者纸上,然后把小车黑线比如放到最右边 及第一个红外对管,观察红外对管小灯变化情况和串口输出情况,如果小灯没有灭,就调节红外对管灵敏度和室内灯光,直到每个红外对管都可以感应到小灯。
  2. 然后在黑线上让小车循迹
    在这里插入图片描述

然后循迹功能完成

然后放到地上
在这里插入图片描述

13.2-加入循迹PID

前面的代码我们对循迹是判断的几个状态,然后PID控制电机不同速度,但是我们可以使用红外对管状态作为PID控制的输入然后再控制电机。

PID的输入是红外对管状态,我们设计 PID输入是红外对管的状态、然后输出一个速度值,然后左右电机去加或者减这个值,就可以完成根据红外对管输入对电机的差速控制

主函数添加的
在这里插入图片描述

extern tPid pidHW_Tracking;//红外循迹的PID
uint8_t g_ucaHW_Read[4] = {0};//保存红外对管电平的数组
int8_t g_cThisState = 0;//这次状态
int8_t g_cLastState = 0; //上次状态
float g_fHW_PID_Out;//红外对管PID计算输出速度
float g_fHW_PID_Out1;//电机1的最后循迹PID控制速度
float g_fHW_PID_Out2;//电机2的最后循迹PID控制速度

然后实现PID循迹控制、注意为了更加快,要减少没有必要的程序和优化判断、将没有必要的输出都注释掉
在这里插入图片描述

	g_ucaHW_Read[0] = READ_HW_OUT_1;//读取红外对管状态、这样相比于写在if里面更高效g_ucaHW_Read[1] = READ_HW_OUT_2;g_ucaHW_Read[2] = READ_HW_OUT_3;g_ucaHW_Read[3] = READ_HW_OUT_4;if(g_ucaHW_Read[0] == 0&&g_ucaHW_Read[1] == 0&&g_ucaHW_Read[2] == 0&&g_ucaHW_Read[3] == 0 ){
//		printf("应该前进\r\n");//注释掉更加高效,减少无必要程序执行g_cThisState = 0;//前进}else if(g_ucaHW_Read[0] == 0&&g_ucaHW_Read[1] == 1&&g_ucaHW_Read[2] == 0&&g_ucaHW_Read[3] == 0 )//使用else if更加合理高效{
//		printf("应该右转\r\n");g_cThisState = -1;//应该右转}else if(g_ucaHW_Read[0] == 1&&g_ucaHW_Read[1] == 0&&g_ucaHW_Read[2] == 0&&g_ucaHW_Read[3] == 0 ){
//		printf("快速右转\r\n");g_cThisState = -2;//快速右转}else if(g_ucaHW_Read[0] == 1&&g_ucaHW_Read[1] == 1&&g_ucaHW_Read[2] == 0&&g_ucaHW_Read[3] == 0){
//		printf("快速右转\r\n");g_cThisState = -3;//快速右转}else if(g_ucaHW_Read[0] == 0&&g_ucaHW_Read[1] == 0&&g_ucaHW_Read[2] == 1&&g_ucaHW_Read[3] == 0 ){
//		printf("应该左转\r\n");g_cThisState = 1;//应该左转	}else if(g_ucaHW_Read[0] == 0&&g_ucaHW_Read[1] == 0&&g_ucaHW_Read[2] == 0&&g_ucaHW_Read[3] == 1 ){
//		printf("快速左转\r\n");g_cThisState = 2;//快速左转}else if(g_ucaHW_Read[0] == 0&&g_ucaHW_Read[1] == 0&&g_ucaHW_Read[2] == 1&&g_ucaHW_Read[3] == 1){
//	    printf("快速左转\r\n");g_cThisState = 3;//快速左转}g_fHW_PID_Out = PID_realize(&pidHW_Tracking,g_cThisState);//PID计算输出目标速度 这个速度,会和基础速度加减g_fHW_PID_Out1 = 3 + g_fHW_PID_Out;//电机1速度=基础速度+循迹PID输出速度g_fHW_PID_Out2 = 3 - g_fHW_PID_Out;//电机1速度=基础速度-循迹PID输出速度if(g_fHW_PID_Out1 >5) g_fHW_PID_Out1 =5;//进行限幅 限幅速度在0-5之间if(g_fHW_PID_Out1 <0) g_fHW_PID_Out1 =0;if(g_fHW_PID_Out2 >5) g_fHW_PID_Out2 =5;if(g_fHW_PID_Out2 <0) g_fHW_PID_Out2 =0;if(g_cThisState != g_cLastState)//如何这次状态不等于上次状态、就进行改变目标速度和控制电机、在定时器中依旧定时控制电机{motorPidSetSpeed(g_fHW_PID_Out1,g_fHW_PID_Out2);//通过计算的速度控制电机}g_cLastState = g_cThisState;//保存上次红外对管状态

在pid.中
在这里插入图片描述

tPid pidHW_Tracking;//红外循迹的PID

在这里插入图片描述

pidHW_Tracking.actual_val=0.0;pidHW_Tracking.target_val=0.00;//红外循迹PID 的目标值为0pidHW_Tracking.err=0.0;pidHW_Tracking.err_last=0.0;pidHW_Tracking.err_sum=0.0;pidHW_Tracking.Kp=-1.50;pidHW_Tracking.Ki=0;pidHW_Tracking.Kd=0.80;

然后就可以跑一下试试了。

可以改进的地方

  1. 红外对管影响差速转向,也影响基础直行的速度 ,会有更好控制效果,所以可以加入每种红外对管状态下对基础速度的影响。
  2. 红外对管的数量越多,效果会越好。

第15章我们会讲解手机遥控的功能

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/diannao/16170.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

C/C++ vector详解

要想了解STL&#xff0c;就必须会看&#xff1a; cplusplus.comhttps://legacy.cplusplus.com/ 官方内容全都是英文的&#xff0c;可以参考&#xff1a; C/C初始识https://blog.csdn.net/2301_77087344/article/details/138596294?spm1001.2014.3001.5501 vector&#xff…

sql聚合函数使用-笔记

sql聚合函数使用-笔记 SELECT SUM ( case when procurement_type 公益推送 then 1 else 0 end ) gywxTotal,SUM ( CASE WHEN (status 1 and procurement_type 公益推送) THEN 1 ELSE 0 END ) gywxYsc,SUM ( CASE WHEN (status ! 1 and procurement_type 公益推送) THEN 1 …

辐射度技术在AI去衣中的魅力与科学

引言&#xff1a; 在当今的数字化时代&#xff0c;人工智能正逐渐渗透到我们生活的方方面面。其中&#xff0c;AI去衣技术作为一项颇具争议但又不失其科技创新的应用&#xff0c;正引起越来越多的关注和讨论。而在实现高质量图像渲染的过程中&#xff0c;辐射度技术凭借其卓越的…

CAD二次开发(5)-用户交互仿系统命令

1. 工具类&#xff1a;PromptTool.cs using Autodesk.AutoCAD.EditorInput; using Autodesk.AutoCAD.Geometry; using System; using System.Collections.Generic; using System.Linq; using System.Text; using System.Threading.Tasks;namespace _04用户交互 {public static…

GEE26:批量导出逐日、逐月、逐季节和逐年的遥感影像(以NDVI为例)

影像导出 写在前面1.逐日数据导出2.逐月数据导出3.季节数据导出4.逐年数据导出 写在前面 最近很多小伙伴们私信我&#xff0c;问我如何高效导出遥感数据&#xff0c;从逐日到逐季度&#xff0c;我都有一套自己的方法&#xff0c;今天就来和大家分享一下&#xff01;   &#…

基于YOLOv8+PySide6的快递分类管理系统

1、背景 随着电子商务的飞速发展&#xff0c;快递行业所承受的数据处理需求愈发庞大。在这样的背景下&#xff0c;传统的手工分类方法已经显得力不从心&#xff0c;因其不仅耗时耗力&#xff0c;还存在着易出错的隐患。因此&#xff0c;迫切需要研发出一套高效而准确的自动化系…

多线程案例(线程池)

White graces&#xff1a;个人主页 &#x1f649;专栏推荐:Java入门知识&#x1f649; &#x1f649; 内容推荐:<计算坤是如何工作的>&#x1f649; &#x1f439;今日诗词:百年兴衰皆由人, 不由天&#x1f439; ⛳️点赞 ☀️收藏⭐️关注&#x1f4ac;卑微小博主&…

go 微服务框架kratos使用中间件的方法

一、中间件的概念 在go语言中&#xff0c;中间件是一种用于处理http请求的开发模式&#xff0c;允许开发人员在请求到达处理程序之前或之后执行特定的操作&#xff0c;如日志记录、身份验证、错误处理等。 中间件通常是一个函数&#xff0c;它接收一个 http.Handler 作为参数…

Ardupilot开源代码之Rover上路 - 后续4

Ardupilot开源代码之Rover上路 - 后续4 1. 源由2. 深度配置2.1 设置倒车按钮2.1.1 前进2.1.2 倒退 2.2 MP无法连接ESP82662.3 最小油门校准 3. 遗留&后续3.1 高精度编码器问题3.2 OV5647 720P30FPS 马赛克问题 4. 参考资料 1. 源由 开源项目最主要的问题就是所有配置是开放…

信息安全从运维到运营:CISAW安全运维方向

随着数据中心规模扩大&#xff0c;安全运维内生需要逐渐向安全运营进化&#xff0c;统一安全理念&#xff0c;提高服务意识&#xff0c;提升专业能力。安全运营是对安全运维的继承式发展&#xff0c;而不是颠覆&#xff0c;意味着以业务发展为基础&#xff0c;以事件核查为线索…

【gradle】MAC下用gradle构建部署springboot项目

MAC下用gradle构建部署springboot项目 前言下载安装配置gradle下载安装下载可能出现的问题 &#xff08;zsh: command not found: brew&#xff09; 配置环境变量配置国内下载源全局配置单个项目配置 通过idea构建项目构建后的项目结构 小结延伸 前言 好久以前就听说gradle了&…

RAG概述(一):RAG架构的演进

目录 概述 RAG核心步骤 Indexing索引 Retrieval检索 Generation生成​​​​​​​ Native RAG Advanced RAG Modular RAG 参考 概述 RAG&#xff1a;Retrieval-Augmented Generation 检索增强生成。 RAG通过结合LLMs的内在知识和外部数据库的非参数化数据&#xff…

与MySQL的初相遇

&#x1f30e;初识MySQL 注&#xff1a;本文SQL语句只为了验证猜想&#xff0c;不会也不要紧。 文章目录&#xff1a; MySql开端 认识数据库       什么是数据库       主流数据库       MySQL的本质 MySQL基础使用       连接mysql服务器     …

自动化您的任务——crewAI 初学者教程

今天&#xff0c;我写这篇文章是为了分享您开始使用一个非常流行的多智能体框架所需了解的所有信息&#xff1a;crewAI。 我将在这里或那里跳过一些内容&#xff0c;使本教程成为一个精炼的教程&#xff0c;概述帮助您入门的关键概念和要点 今天&#xff0c;我写这篇文章是为了…

easy-rule规则引擎使用

简介 轻量级的规则引擎&#xff0c;易于学习的api 简单来说&#xff0c;规则引擎就是一个函数&#xff1a;yf(x1,x2,…,xn) 将业务代码和业务规则分离&#xff0c;解耦业务决策和业务代码的绑定关系 入门示例 依赖引入 <dependency><groupId>org.jeasy</grou…

页面<html>上多了一个滚动条,定位发现是<body>里面多了一个id为trans-tooltip的div

现象分析&#xff1a; 页面根标签html多了一个滚动条&#xff0c;发现body里面多了一个id为trans-tooltip的div&#xff0c;虽然width为0&#xff0c;height为0&#xff0c;但是其子元素还是有高度&#xff0c;占据了空间&#xff0c;最终导致了滚动条&#xff1b; 根本原因&…

专业渗透测试 Phpsploit-Framework(PSF)框架软件小白入门教程(十三)

本系列课程&#xff0c;将重点讲解Phpsploit-Framework框架软件的基础使用&#xff01; 本文章仅提供学习&#xff0c;切勿将其用于不法手段&#xff01; 接上一篇文章内容&#xff0c;讲述如何进行Phpsploit-Framework软件的基础使用和二次开发。 我们&#xff0c;继续讲一…

Java面试题--JVM大厂篇(1-10)

引言&#xff1a; 在这个信息时代&#xff0c;对于准备进入大厂工作的朋友们来说&#xff0c;对于JVM&#xff08;Java虚拟机&#xff09;的掌握是面试中的一项重要内容。下面是一些精选的JVM面试题&#xff0c;希望对大家能有所帮助。 正文&#xff1a; 1. JVM有哪几种垃圾收…

[CISCN2024]-PWN:gostack解析(go语言程序,syscall)

查看保护 ida比较复杂&#xff0c;建议动调配合静态分析程序运行 这里函数返回不用leave和ret&#xff0c;而是利用add rsp和ret&#xff0c;所以要动调查看到底要覆盖哪里。 完整exp&#xff1a; from pwn import* pprocess(./gostack) syscall0x4616c9 pop_rax0x40f984 po…

GB报文中的Cseq值的注意点

一、 问题现象 【问题现象】NVR使用GB接三方平台发现倍速回放时&#xff0c; 【现场拓扑】现场拓扑如下 &#xff08;1&#xff09; NVR侧使用家用宽带的方式&#xff0c;通过国标跨公网接入三方平台。 图1.1&#xff1a;网络拓扑 二、 抓包分析 INVITE sip:420000004013200…