从OpenMV到执行器:当PID算法开始“调教”舵机

如果到现在还不会驱动舵机——朋友,电赛的元器件清单每年都在对你“明示”,二维云台都快成祖传考题了!补课?现在!立刻!(当然,如果你脸皮够厚,也可以私信骚扰作者,但建议先自罚三杯咖啡熬夜恶补)。

好了,收起你的悔恨泪水,接下来才是硬核环节:STM32如何优雅地“吃掉”OpenMV的串口数据,用PID“驯服”舵机,最后让色块追得像初恋一样死心塌地。从协议解析到算法调参,全程无废话(这句是假的,但代码是真的)。

目标:让你从“能跑就行”进化到“跑得嚣张”。现在,系好安全带,你的代码即将起飞——(如果崩溃了,记得Ctrl+S)。

文章封面

欢迎关注QQ频道:电赛工坊

文章目录

  • 1. 串口数据解析:如何让STM32“听懂”OpenMV的“加密通话”
  • 2. 舵机控制:如何让云台“指哪打哪”(或者疯狂摇头)
  • 3. PID算法:从“帕金森”到“德芙级丝滑”的终极奥义

1. 串口数据解析:如何让STM32“听懂”OpenMV的“加密通话”

OpenMV发来的数据不是随便甩几个字节就能糊弄过去的——帧头、帧尾、校验和,少一个都算“通信事故”。(别问为什么这么严格,问就是被电赛现场的血泪史毒打过。)

为了让大家少走弯路,笔者含泪把帧解析模块解耦成独立.c/.h文件(复用性拉满,夸我!)。如果你的协议类似,直接CV大法好,省下的时间够你多调三次PID(然后发现还是调不好,笑)。

核心代码解析(附赠“人话”注释版)

/*** @brief  解析一帧数据* @param  frame: 帧数据指针* @param  len: 帧长度* @param  blob: 解析结果存储结构体* @retval 解析是否成功(0:失败, 1:成功)*/
u8 Protocol_ParseFrame (u8 *frame, u16 len, BlobData *blob)
{/* 检查最小长度 */if(len < FRAME_MIN_LEN){return 0;}/* 检查帧头 */if(frame[0] != FRAME_HEADER){return 0;}/* 检查帧尾 */if(frame[len-2] != '\r' || frame[len-1] != '\n'){return 0;}/* 提取数据部分(4字节) */u8 *data = &frame[1];if(data[0] == 0xFF && data[1] == 0xFF && data[2] == 0xFF && data[3] == 0xFF)   // 无目标情况{blob->has_target = 0;return 1;}/* 校验和检查 */u8 checksum = Protocol_CalChecksum(data, 4);if(checksum != frame[5]){return 0;}/* 解析dx和dy */blob->dx = (short)((data[0] << 8) | data[1]);blob->dy = (short)((data[2] << 8) | data[3]);blob->has_target = 1;return 1;
}

2. 舵机控制:如何让云台“指哪打哪”(或者疯狂摇头)

舵机控制,说白了就是PWM占空比的数字游戏——但如果你连定时器配置都搞不定……(电赛评委的凝视.jpg)。

笔者用的二维云台(某趣科技出品),水平270° + 垂直180°,两个舵机组成“摇头晃脑”二人组。

角度 ↔ 占空比 の 神秘公式

// 180°舵机:角度 → 占空比(0.5ms~2.5ms对应0°~180°)
duty = (angle * 1000) / 180 + 250;  // 250=0.5ms(基准值), 1000=2ms范围// 270°舵机:同理,但分母变成270(数学老师欣慰地笑了)
duty = (angle * 1000) / 270 + 250;  // 注意别让角度超限,否则舵机会“嘎嘣”一声

注:duty的单位是TIM的计数值,具体取决于你的时钟配置(不会算的速翻STM32参考手册第987页,假的)。

PWM操作:一句代码让舵机“扭起来”

初始化定时器(TIMx)和PWM通道后,只需调用库函数修改比较值:

TIM_SetCompare1(TIM2, duty_horizontal); // 水平舵机(TIM2通道1)
TIM_SetCompare2(TIM2, duty_vertical);   // 垂直舵机(TIM2通道2)

警告:

  • 直接TIM_SetCompare可能会让舵机“抽风”,建议渐变角度(比如每次变化≤10°)。
  • 270°舵机别给到angle=271°,否则它会用“齿轮打齿声”抗议你的数学能力。

下一幕:PID算法即将登场——
“当你以为调参是科学,其实全是玄学。”(手动狗头)

3. PID算法:从“帕金森”到“德芙级丝滑”的终极奥义

欢迎来到PID调参现场——这里没有科学,只有玄学、耐心和亿点点运气。你的云台要么优雅追踪,要么抽风摇头,全看这一趴!(友情提示:备好咖啡,调参前深呼吸三次。)

(一)PIDの灵魂拷问:方向别搞反!

在写代码前,先解决哲学问题

水平舵机(dx)

  • dx > 0(色块偏右)→ 舵机该往右转(占空比↑还是↓?)
  • dx < 0(色块偏左)→ 舵机该往左转(占空比?)

垂直舵机(dy):同理,但方向可能相反(取决于云台机械结构)。

验证方法

手动给dx=100,观察舵机转向是否符合预期。如果反向——要么改代码符号,要么改云台安装方向(物理调参法,简单粗暴)。

(二)“稳态误差”的暴击:为什么你的舵机中途摆烂?

笔者血泪史:当误差dx=50时,舵机竟然不动了!原因:

  • P值太小误差×Kp < 舵机死区阈值,输出力不足,舵机:“懒得动了。”
  • 解决方案加大Kp(可能引发震荡),引入Ki(积分项专治“摆烂”,用累积误差逼舵机动起来)

(三)PID代码实现(附“人话”注释)

/*** @brief  PID计算:让误差“社会性死亡”* @param  pid:   PID参数结构体(含Kp/Ki/Kd)* @param  actual: 当前误差(来自OpenMV的dx/dy)* @retval 控制量(直接喂给舵机)*/
short Pid_Calculate(PID_TypeDef *pid, short actual) 
{// 1. 计算当前误差(目标值通常是0,即对准中心)short error = pid->target - actual;  // 2. 【P项】当前误差的即时惩罚(Kp是下手狠度)float p_out = pid->kp * error;// 3. 【I项】历史误差的“秋后算账”(专治稳态误差)pid->integral += error;pid->integral = MAX(MIN(pid->integral, 1000), -1000); // 积分限幅防饱和float i_out = pid->ki * pid->integral;// 4. 【D项】预见未来:抑制过冲(Kd是刹车力度)float d_out = 0;if (pid->kd != 0) {d_out = pid->kd * (error - pid->last_error);pid->last_error = error; // 记录本次误差,下次算微分}// 5. 三路输出合体!(注意限制输出范围)return (short)(p_out + i_out + d_out);
}

关键操作解析

  • 积分限幅(±1000):防止长时间误差累积导致“积分饱和”(比如目标丢失时积分项爆炸)。
  • 微分项条件判断:如果Kd=0则跳过计算,变身PI控制器

调参口诀(默念三遍)

  1. 先Kp,后Ki,最后Kd(别一上来就三个一起调,会疯)。
  2. Kp从0.1开始,逐步加大,直到舵机开始高频抖动(然后回调20%)。
  3. Ki取Kp的1/10~1/100,慢慢加,直到稳态误差消失(但别让系统变“迟钝”)。
  4. Kd谨慎加,一般不超过Kp的1/10,否则系统会“过度紧张”。

经典翻车现场

  • “舵机蹦迪”(震荡严重)→ 降低Kp或增加Kd。
  • “反应迟钝”(跟踪慢)→ 增加Kp或Ki。
  • “抽风式微调”(高频抖动)→ 降低Kd或检查机械结构。

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

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

相关文章

xml映射文件的方式操作mybatis

映射文件 在Java spring中使用mybatis有两种方式&#xff0c;一种是注释的方式&#xff0c;一种是xml映射文件的方式。在简单的功能需求可以使用注释&#xff0c;方便简洁。而在大的功能逻辑上&#xff0c;更推荐使用xml映射文件&#xff0c;方便管理且结构清晰。 首先xml文件结…

Carla自动驾驶仿真_快速安装与运行Carla

大家好&#xff0c;我是橙子&#xff0c;今天给大家介绍Carla的基础安装和使用 目录 1.Carla介绍 2.Carla的安装与使用 3.Carla0.9.15安装包下载&#xff1a; ​编辑 4.运行Demo 5.运行一个简单场景&#xff1a; 6.相关资源 1.Carla介绍 Carla 是一个开源的自动驾驶仿…

远程登录docker执行shell报错input is not a terminal问题

背景 最近要远程去k8s docker里面获取信息&#xff0c;于是&#xff0c;写了一个如下的命令&#xff0c;执行完之后&#xff0c;报错了。 ssh 192.168.100.2 sudo crictl exec -it xxx.docker /usr/bin/lscpu --online --extended错误信息如下&#xff1a; time“2025-07-11T21…

使用FastAdmin框架开发二

继上一篇使用FastAdmin框架开发-CSDN博客教程 部署完项目后我们就可以边开发边调试了 在开发前我们可以先做一些基本设置 安装成功后会生成一个项目后台的地址http://域名/VrHGtzlfMB.php/index/login&#xff0c;后台入口文件是随机生成的&#xff0c;当然我们也可以根据我…

【DB2】load报错SQL3501W、SQL3109N、SQL2036N

最近老遇到迁移测试LOAD时报错&#xff0c;如图所示但是换成import又可以看描述是说load的内容将不会进入备份暂挂状态balbala… 下面的错误是说ixf文件无效 这里一直以为是SQL3501W的问题&#xff0c;去各种研究load参数和db2set里面的load参数&#xff0c;各种调整都不行 又以…

YOLO家族内战!v5/v8/v10谁才是你的真命天子?(附保姆级选择指南)

在目标检测领域&#xff0c;YOLO系列始终是工业部署与学术研究的焦点。从风靡全网的YOLOv5&#xff0c;到全面升级的YOLOv8&#xff0c;再到突破性能瓶颈的YOLOv10——每一次迭代都带来全新可能。作为开发者&#xff0c;究竟该选哪一代&#xff1f;本文用千字长文对比表格为你彻…

Claude Code是什么?国内如何使用到Claude Code?附国内最新使用教程

2025年已过大半&#xff0c;相信你也听说过 Claude——它是近年最受关注的 AI 模型之一&#xff0c;而 Claude Code 则是它面向编程场景的特别版本&#xff0c;专为代码理解、生成与重构而生&#xff0c;尤其擅长处理大项目、长上下文&#xff0c;和开发者对话更自然。 但对于一…

双轮驱动:政策激励与外部制约下的国产服务器市场演进

2025年6月&#xff0c;科智咨询正式发布《中国国产服务器市场研究报告&#xff08;2025&#xff09;》&#xff0c;报告从国产服务器产业概述、政策环境分析、市场现状与竞争格局、面临挑战与市场机遇等维度&#xff0c;深入剖析国产服务器市场现状及未来发展趋势。2022年10月&…

【工具变量】全国省市区县土地出让结果公告数据(2000-2024年)

土地出让结果公告数据是指政府主管部门在完成国有土地使用权出让后&#xff0c;依法依规对外公开的结果信息&#xff0c;涵盖土地出让时间、出让方式、竞得人、成交价、用地性质、面积等关键信息。土地出让数据是研究中国土地市场供需变化、城市发展轨迹以及地方财政收入结构的…

前端面试专栏-算法篇:22.树结构(二叉树、B树、红黑树)

&#x1f525; 欢迎来到前端面试通关指南专栏&#xff01;从js精讲到框架到实战&#xff0c;渐进系统化学习&#xff0c;坚持解锁新技能&#xff0c;祝你轻松拿下心仪offer。 前端面试通关指南专栏主页 前端面试专栏规划详情 树结构&#xff08;二叉树、B树、红黑树&#xff09…

爬虫-数据解析

1.解析概述特性re (正则表达式)bs4 (BeautifulSoup)xpath (lxml)pyquery本质文本模式匹配HTML/XML 解析器 (DOM树操作)XML路径语言 (节点导航)jQuery 式 CSS 选择器 (封装lxml)学习曲线陡峭中等中等简单 (熟悉jQuery/CSS)灵活性极高 (处理任意文本)高 (容错好&#xff0c;DOM操…

MySQL8.0基于GTID的组复制分布式集群的环境部署

前言&#xff1a; 需要清楚知道&#xff1a;MySQL 复制组能够以一种自动优先选择的单主模式运行&#xff0c;在某个时间只有一个服务器接受更新 。但是对于更高优先级的用户&#xff0c;组能够以多主模式部署&#xff0c;所有的服务器都能够接受更新&#xff0c;即使它们是同时…

中国国际会议会展中心模块化解决方案的技术经济分析报告

——以模块化、可持续材料与ESG为核心的运营效益提升路径研究-----中国会展经济研究会原副会长&#xff0c;学术委员会副主任 姚望一、报告概述1.1报告目的本报告深入探讨了一种经济视角下的综合评估&#xff0c;针对某国际会议会展中心采用的一种模块化、多功能、可持续升级的…

模拟开关、可编程增益仪表放大器电路

一、模拟开关1.CD4052CD4052是一种模拟多路开关&#xff0c;也可以称作是一个模拟多路复用器&#xff0c;输入引脚可以提供可变电压&#xff0c;可以通过输出引脚获得相同电压&#xff0c;常见的封装有DIP16、SOP16、TSSOP16。 CD4052的引脚功能如下图&#xff0c;可以用于控制…

时序数据库 TDengine × SSRS:专为工业、能源场景打造的报表解决方案

每当听到“做报表”三个字&#xff0c;是不是内心都会先叹口气&#xff1f;尤其在工业、能源、制造等场景&#xff0c;面对那些结构固定、字段繁多、格式要求严苛的报表任务&#xff0c;用 Excel 手动拼&#xff0c;真的是既费时又容易出错。 现在解决方案来了——时序数据库 …

C++设计秘籍:为什么所有参数都需类型转换时,非成员函数才是王道?

当所有参数都需要类型转换时,为什么要选择非成员函数? 在C++的世界里,有一个看似简单却蕴含深意的设计原则:当所有参数(包括被this指针所指的那个隐式参数)皆须进行类型转换时,请为此采用非成员函数实现。这个原则背后隐藏着C++类型系统的精妙设计,也揭示了成员函数与…

Markmap:基于Markdown生成思维导图

Markmap 是一款用于将 Markdown 文本转换为思维导图的免费工具。 Markmap 的核心原理是通过输入&#xff1a;结构化的 Markdown 文本&#xff0c;根据标题层级构建一个树形数据结构&#xff0c;然后使用 d3.js 可视化 JavaScript 库将树形数据渲染成可交互的 SVG 思维导图。 主…

学习threejs,使用自定义GLSL 着色器,生成漂流的3D能量球

&#x1f468;‍⚕️ 主页&#xff1a; gis分享者 &#x1f468;‍⚕️ 感谢各位大佬 点赞&#x1f44d; 收藏⭐ 留言&#x1f4dd; 加关注✅! &#x1f468;‍⚕️ 收录于专栏&#xff1a;threejs gis工程师 文章目录一、&#x1f340;前言1.1 ☘️GLSL着色器1.1.1 ☘️着色器…

分布式推客系统全栈开发指南:SpringCloud+Neo4j+Redis实战解析

一、推客系统概述与市场背景推客系统&#xff08;或称"推荐客"系统&#xff09;是一种基于社交关系和内容分发的推荐营销平台&#xff0c;近年来在电商、内容平台和社交媒体领域迅速崛起。根据最新统计数据&#xff0c;2023年全球社交电商市场规模已达1.2万亿美元&am…

Redis数据类型之list

上篇文章&#xff1a; Redis数据类型之hashhttps://blog.csdn.net/sniper_fandc/article/details/149139615?fromshareblogdetail&sharetypeblogdetail&sharerId149139615&sharereferPC&sharesourcesniper_fandc&sharefromfrom_link 目录 1 lpush、lpu…