# Arduino小车PID调速——整定参数初试水

2023-11-13

Arduino小车PID调速——整定参数初试水

在实现了小车较为可靠的测速基础上,便可以正式开展PID调速实验了。本文是基于使用Arduino平台上由Brett Beauregard大神写的PID库进行参数整定的,侧重于在对PID算法有基本了解下,通过实验自己动手整定参数,观察不同的参数值对小车调速效果的影响,从而对PID算法产生感性的认知。

PID基本知识

所谓PID算法,是一种在工程应用领域被使用最为广泛的负反馈调节方法,通过PID算法中比例、积分、微分三个部分的作用,达到使系统稳定的效果。有关PID的介绍在网络上已经非常多且详细,本文不再展开论述。

公式

Output=Kpe(t)+KIe(t)dt+KDddte(t)

Where:e=SetpointInput

上面的公式是一种最为常见的PID算法形式,由比例、积分、微分三个部分组成,在实际工作中三者相互配合作用于控制系统

P就是比例作用,是把调节器的输入偏差乘以一个系数,作为调节器的输出,它能够使系统趋于稳定,但却不能有效地使系统达到设定值
I就是积分作用,它的作用使如果系统存在输入偏差,那么积分作用将使系统按照一定的速度向一个方向累加下去,它的作用在于可以消除系统静态偏差,让系统达到设定值
D就是微分作用,能够起到超前调节的作用,即如果被调量没有变化,则微分作用不产生变化,一旦发生变化,则微分作用可以很快的做出响应。

以上是PID的公式和各个参数的意义的简单陈述,目的在于产生一个基本的认识,而对于真正进行PID参数整定的实际工作来说,还是远远不够的,需要不断地深入理解各个参数对系统的影响以及多个参数之间的关系。

参数整定口诀

这里笔者比较推崇由白志刚编著的《自动调节系统解析与PID整定》一书中的趋势读定法整定口诀

自动调节并不难,复杂系统化简单

整定要练硬功夫,图形特征看熟练

趋势读定三要素,设定被调和输出

三个曲线放一起,然后曲线能判读

积分微分先去掉,死区暂时也不要

比例曲线最简单,被调输出一般般

顶点谷底同时刻,升降同时同拐点

波动周期都一样,静态偏差没办法

比例从弱渐调强,阶跃响应记时间

时间放大十来倍,调节周期约在内

然后比例再加强,没有周期才算对

静差消除靠积分,能消静差就算稳

不管被调升或降,输出直观偏差存

输入偏差等于零,输出才会不积分

积分不可加太强,干扰调节成扰因

被调拐点零点间,输出拐点仔细辨

积分拐点再靠前,既消静差又不乱

微分分辨最容易,输入偏差多注意

偏差不动微分死,偏差一动就积极

跳动之后自动回,微分时间管回归

系统若有大延迟,微分超前最合适

风压水位易波动,微分作用要丢弃

比例积分和微分,曲线判读特征真

如果不会看曲线,多看杖策行吟文

综合比较灵活用,盛极衰来扼杀因

参数整定

首先需要将PID库运用到自己已能实现测速功能的程序中,接下来只需调节Kp、Ki、Kd三个参数即可。

第一步:纯比例作用整定

由于是第一次进行PID参数整定,笔者先以把小车速度整定到250mm/s为目标,在程序中输入设定值。根据上面的口诀,先把系统设定为纯比例作用,即只有比例增益Kp不为0,积分增益Ki和微分增益Kd都暂时设定为0.因为是这个小车第一次整定参数,笔者也不知道什么比例增益比较好。根据口诀所说比例作用从弱到强调节,因此笔者就随便写了个自认为不大的值2,然后观察小车运行情况。实际的运行结果令我大吃一惊,小车电机以一定的周期在转和不转之间震荡。根据口诀中“然后比例再加强,没有周期才算对”得知,肯定是比例作用已经非常大了,因此赶紧将比例增益调整为0.2,小车的电机不再出现剧烈的“抽搐”,开始以一种比较缓慢的姿态转动,但通过观察输出波形,还是存在较小的波动,而根据网上查阅资料得,比例作用过分小也会导致系统震荡,但与之前较大比例作用下的震荡相比,显然“温柔”多了。于是笔者继续增加比例作用,直至Kp = 0.7时,输出波形已经相较其他参数下稳定很多了。
这里写图片描述

第二步:比例积分作用

由上图可看出,一个适合的比例作用可以使系统趋于稳定,但却无法消除静态偏差,因此需要引入积分作用,其最大的好处就是可以消除静态偏差。笔者继续采用由小逐渐加大积分增益的方式。当设定Ki = 0.3时,由图可见
这里写图片描述
静态偏差逐渐减小,输出的速度越来越接近设定的250mm/s的目标,不过调节速度太慢,还是不能满足需求。
于是继续加积分作用,当Ki = 5时,可以看出,系统反应速度已经很快,可以在0.1秒内
这里写图片描述
由波形可以看出,此时速度已基本能够快速准确地达到设定值,但仍然存在着些许波动。在比例积分作用下产生波动,可能是由于比例作用过大,也有可能是积分作用过强产生了积分干扰,因此可以适当降低比例或积分作用,来尝试减弱波动。由于比例作用和积分作用是相对的,因此为了使系统稳定,降低其中一种作用时,另外一种作用也要随之降低。故把参数设定为Kp = 0.65,Ki = 4.5,此时效果如图
这里写图片描述
可明显看出,速度得到进一步的稳定,且系统反应迅速,在不到0.1秒的时间内便使速度达到稳定。考虑到测速中存在的干扰以及电机机械转动的问题,剩余的些许波动可以被忽略。

第三步:测试在其他速度下的效果

以上的实验是建立在设定速度恒定为250mm/s的条件下进行的,能保证在250mm/s的速率下良好的调节效果,而这个参数是否适合在其他速率下工作,还需要进一步测试。

一、低速运行情况下

当笔者尝试将速度设定为200mm/s时,再观察波形,结果出现了非常频繁的波动,极端情况下,达到设定速度附近一段时间后,系统居然开始出现越来越大的波动,越来越发散
这里写图片描述
由此可得出,在参数不变的情况下,适合一个特定速度的调节方式不一定适合低速条件,在低速条件下会出现不稳定。
是什么导致这样波动的发生?比例作用可以使系统稳定,虽然积分可以消除静态偏差,但如果比例设定的不合理,静态偏差也难以被消除。而之前设定的参数是在250mm/s的情况下合适的,此时设定速度降低到200mm/s。比例作用是把调节器的输入偏差乘以一个系数,作为调节器的输出,因此可以设想此时比例作用相对于积分作用实际上偏向于减弱了。这就可能造成了积分作用过强,导致积分干扰。因此笔者尝试降低积分作用, 并相应略微降低比例作用。将参数设定为Kp = 0.5,Ki = 2
这里写图片描述
可以看出,波动已得到一定的抑制,同时在运行一段时间后,不再出现波动范围越来越大,波动周期越来越明显的“抽搐”发生,证明了高速条件下的参数运用到低速条件下会出现积分干扰的猜想。

二、高速运行情况下

笔者再次尝试将适合250mm/s的参数运用到300mm/s,看看会有什么情况发生。
这里写图片描述
对比250mm/s下的波形可以观察得,在300mm/s下工作,系统的快速性变弱,系统的稳定时间比250mm/s下要长了一点,同时波形出现了小幅度的有周期震荡。
系统稳定时间变长有两方面的原因,第一可能是比例作用偏弱,会导致难以消除静态偏差,第二是积分作用偏弱也会导致消除静态偏差的过程变慢。比例作用偏强和偏弱都会导致一定的震荡,偏强时的曲线是周期性很强,基本呈正弦波形式的,而偏弱时候波动也会有一定的周期,但在一个波动周期内,往往掺杂着几个小的波峰。由本图可看出,此时的波动属于比例作用偏小的情况。
当把参数调节到Kp = 0.75,Ki = 5.5时,得到的曲线如图
这里写图片描述
很明显,波动得到了抑制,稳定时间也缩短了。

总结

通过以上实验证明了pid调速过程中,一个特定的参数仅对一定的速度区间有比较好的调节效果。若比这个速度低,则会出现比例积分作用过强,从而出现震荡;若比这个速度高,则会出现比例作用不强,系统的稳定时间变长,且出现小幅度周期性波动的情况。

不足与改进

小车在实际工作中,不会一直只工作在一个恒定的速度下,因此在进行PID调速时不能在一个速度下调成功了就觉得万事大吉了。为了能达到PID调速对更大的速度区间内有效,一个简单的办法就是在电机低速转动的情况下进行调速,这样基本可以实现从慢速到高速都能速度稳定的效果,但这样的一个缺点在于高速情况下稳定时间变长,且会出现小幅度周期性波动。在这个基础上的一个改进办法是通过分别调节低速、中速、高速三种不同情况下适合的PID,可以设定速度区间,当速度设定值落在某个区间内,则启用适合那个速度下的PID参数进行调速。进一步深挖,可以尝试自动整定参数,达到最好的PID调速效果。
以上是本人的一点尝试和经验,难免有不足之处,还望各位多多指教!

参考

  1. 白志刚《自动调节系统解析与PID整定》化学工业出版社
本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

# Arduino小车PID调速——整定参数初试水 的相关文章

  • Arduino F()宏的实现

    我试图了解 Arduino 中的 F 宏实际上对 PGMEM 和 RAM 做了什么以及运行时的影响是什么 有人可以指出定义这个宏的文件吗 这可能是旧版本 但定义它的一个地方是Wstring h as in here http andybro
  • 将 Arduino RGB LED 从一种颜色渐变为另一种颜色?

    目前 我已成功让 LED 灯循环显示我选择的八种颜色 一切都工作正常 除了我想要一种更自然的感觉 并且想要从一种颜色褪色 过渡到下一种颜色 而不是让它们互相替换 到目前为止 这是我的代码 int redPin 11 int greenPin
  • Arduino:将数据存储在 EEPROM 中的轻量级压缩算法

    我想将大量数据存储到我的 Arduino 上ATmega168 http www atmel com devices atmega168 aspx ATmega328 http www atmel com devices atmega328
  • C++ 递减单字节(易失性)数组的元素不是原子的!为什么? (另外:如何在 Atmel AVR mcus/Arduino 中强制原子性)

    由于试图通过一些我不知道的简单内容来调试我的代码 我损失了几天的时间 实际上是大约 25 小时的工作 事实证明 在 AVR ATmega328 8 位微控制器 Arduino 上 用 C 递减单字节数组的元素不是原子操作 并且需要原子访问防
  • Arduino 中的字符串比较

    我正在开发基于网络的家庭自动化系统 因此我的Arduino向服务器发送请求并在串行监视器中获得以下响应以及 loneOn 这是由于Serial println r 陈述 HTTP 1 1 200 OK Date Mon 13 Oct 201
  • 如何查看linux中特定进程每5秒的内存消耗情况

    我只是想知道如何找到特定进程在特定时间 比如5秒 的内存消耗 我是linux新手 因此 详细的步骤将不胜感激 Use top p PID其中 PID 是进程 ID 应显示有关进程的信息 包括使用的系统内存百分比 类型d以及一个以秒为单位的整
  • 查看用户最近执行的Android任务

    我想查看我的 Android 手机最近的任务 我尝试了一些来自互联网的代码 但没有一个能正常工作 我只想获取用户最后执行的应用程序的PID和名称 例如 如果我执行计算器应用程序 然后执行我创建的最近任务应用程序 则该应用程序应该能够告诉我类
  • Fedora 中的 Arduino 上传错误“stk500_recv(): 程序员没有响应”

    我正在尝试上传库存Blink在 Fedora Core 15 Linux 中使用 Arduino IDE 绘制草图 我收到此错误 avrdude stk500 recv 程序员没有响应 要重现该问题 通过 USB 线插入 Arduino U
  • PID和TID的区别

    PID和TID有什么区别 标准答案是 PID 用于进程 而 TID 用于线程 然而 我发现有些命令可以互换使用它们 例如 htop有一个 PID 列 其中显示同一进程的线程的 PID 具有不同的值 那么PID什么时候代表线程或进程呢 这很复
  • 读取串行端口 - 忽略在一定时间内写入串行端口的部分数据

    我想定期读取串行端口上的数据和Arduino 所以本质上是这样的 读一读 Wait 读一读 Wait Take etc 我面临的问题是端口将缓冲其信息 因此一旦我调用等待函数 串行端口上的数据就会开始缓冲 等待函数完成后 我尝试再次读取数据
  • 如何使用arduino从sim900模块的RTC读取日期和时间数据?

    include SIM900 h include
  • 如何将 char 数组定义为常量?

    这里是 C C 菜鸟 我已经在头文件中定义了它 typedef unsigned char BitChar 9 8 data bytes chars and one width byte char extern BitChar BitFon
  • Android BLE 扫描与 UUID 过滤器列表混淆

    我正在 Android 移动设备 A 上执行 UUID 过滤扫描 并且有两个测试用例 一个人在另一台 Android 设备 移动设备 b 上使用名为 BLE Scanner 的应用程序来创建具有两个测试服务 每个服务都有自己唯一的 UUID
  • Python自动选择串口(适用于Arduino)

    目前 Python 程序必须知道设备 Arduino 位于哪个端口 然后 Python 才能与设备进行通信 Problem 每当设备拔出并重新插入时 其 COM 端口都会发生变化 因此必须再次向 Python 提供正确的串行端口 以便它找到
  • C#读取Arduino

    我正在尝试制作一个从 Arduino 读取传出信号的应用程序 但我无法使其在 C 中工作Windows 窗体 http en wikipedia org wiki Windows Forms 仅在控制台中 我的 C Windows 窗体代码
  • SIM900 GSM/GPRS 未获得正确的 AT+CREG?回答

    我使用的是带有 IComsat SIM900 GSM GPRS 扩展板的 Arduino UNO 使用以下教程 Arduino 实时 GPS 追踪器 http www samaria me uk 2011 12 arduino live g
  • 在声明对象之前在全局函数中使用类的成员函数

    我有一个事件处理函数 在该函数中调用了类的成员函数 事件处理函数在类 cpp 文件中声明 但不是类的一部分 它不是成员函数 当我编译代码时 编译器表示该函数在范围内 因为它正在调用全局事件处理函数中的成员函数 我的问题如下 有没有办法在全局
  • 通过iPhone音频插孔读取数据

    我正在寻找一种方法来读取通过 iPhone 的音频插孔从 Arduino 发送的原始数据 我搜索了很多并发现this https github com sanjibahmad Is Headphone Plugged In tree mas
  • 如何在 Arduino 中将 char 变量作为数字打印到串行端口?

    我正在使用 Arduino Uno 我正在从 EEPROM 读取一个字节值并将该值存储在类型变量中char 1 字节 我想将变量的值作为数字 而不是相应的 ASCII 代码 打印到串行监视器 例如考虑char val 5 我想查看串行监视器
  • 如何使用基于HM-10蓝牙模块的BLE Shield?

    我是 arduino 项目的新手 我想请你帮忙 我从 http imall iteadstudio com development platform arduino shields im130704001 html http imall i

随机推荐

  • 关于hexo的笔记 以及 常见问题

    在 Hexo 中有两份主要的配置文件 其名称都是 config yml 其中 一份位于站点根目录下 blog config yml 主要包含 Hexo 本身的配置 另一份位于主题目录下 blog themes next config yml
  • 程序员的算法课(15)-分治法获取文件中出现频次最高100词

    一 问题描述 这个问题在大数据面试中容易出现 问题如下 有一个1G大小的一个文件 里面每一行是一个词 词的大小不超过16字节 内存限制大小是1M 要求返回频数最高的100个词 二 思路 此处1G文件远远大于1M内存 分治法 先hash映射把
  • sp3585调试

    最近在调试sp3485目前已调试成功 后续把调试过程补全
  • 用Python获取链家二手房房源数据,做可视化图分析数据

    前言 数据采集的步骤是固定 发送请求 模拟浏览器对于url地址发送请求 获取数据 获取网页数据内容 gt 请求那个链接地址 返回服务器响应数据 解析数据 提取我们需要的数据内容 保存数据 保存本地文件 所需模块 win R 输入cmd 输入
  • 从计组和操作系统详解IO控制方式

    IO控制方式 实际上IO在操作系统和计组里面都有讲到 这两个内容各有侧重 又有很大的重合 这里就整理一下 操作系统里面就讲了一下基本的过程 计组还讲了各个接口电路 1 直接程序控制方式 直接程序控制方式由用户进程直接控制主存或 CPU 和外
  • ARP报文头部格式和请求流程

    文章目录 ARP头部格式 ARP请求流程 ARP头部格式 格式说明 硬件类型 16位字段 用来定义运行ARP的网络类型 每个局域网基于其类型被指派一个整数 例如 以太网的类型为1 ARP可用在任何物理网络上 协议类型 16位字段 用来定义使
  • 随记:Flutter获取widget的大小位置,状态栏高度

    也可参考 https www jianshu com p 8117fbc5b4d3 1 获取状态栏高度 MediaQueryData fromWindow WidgetsBinding instance window padding top
  • Spring Boot日志

    目录 1 日志的作用 2 自定义打印日志 3 日志级别 4 日志持久化 5 使用lombok输出日志 1 日志的作用 日志是程序的重要组成部分 其实我们几乎无时无刻都在接触日志 简单的说它其实就是程序运行过程中产生的信息 它的主要作用就是帮
  • k8s之Deployment篇

    Deployment控制器 概念 原理解读 Deployment官方文档 https kubernetes io docs concepts workloads controllers deployment Deployment概述 Dep
  • 大数据——Ubuntu配置docker的阿里云镜像加速

    Ubuntu配置docker的阿里云镜像加速 阿里云镜像加速 阿里云镜像加速 由于docker的官方的镜像源速度太慢 在国内可以通过使用阿里云或者网易云的镜像源提高下载速度 通常使用阿里云的镜像源 下面介绍怎么使用阿里云的镜像加速器 注册阿
  • python编程练习题:随机生成的各科成绩,60分以下为10-15%之间,60-90分的占70-75%之间,90分以上10%-15%之间

    d 题目 python编程练习题 随机生成的各科成绩 60分以下为10 15 之间 60 90分的占70 75 之间 90分以上10 15 之间 分析 各分数之间生成分数的概率并不是独立的 而是相互影响的 比如60分以下的占10 那么为了满
  • html纵向导航,【练习实例】HTML+CSS制作导航栏(横向与纵向)

    纵向导航栏 建立一个列表 主页 新闻 联系 关于 2 定义列表基本样式 ul 去掉列表的样式 list style type none width 200px background color DDDDDD li a 将内联元素转换为块级元
  • 安装并使用 iDRAC 服务模块

    DELL服务器 Integrated Dell Remote Access Controller 8 7 默认增加了iDRAC Service Module 但是根据官方文档 这个功能默认是没有打开 需要在服务器上安装 未安装前方法如下 1
  • linux下,用crontab定时执行scrapy任务

    之前尝试过很多方法用crontab执行scrapy的爬虫任务 但是都没出成功 总结下来有两点错误与相应的解决方法 1 手动执行时 在工程目录下输入scrapy crawl xxx就可以执行爬虫脚本了 但是用crontab时 如果直接在cro
  • 请收藏——QKL123!它能帮你挖掘项目价值(附2019年3月排行榜)

    QKL123区块链排行榜包括区块链项目 区块链交易平台 区块链媒体 区块链公众号 区块链矿机 区块链矿池 EOS Dapp ETH Dapp 区块链钱包九大榜单 相对第二期 2019年02月 榜单 该期首次新增ETH Dapp排行榜 并改进
  • 今天给大家分享一个绘图的 RGB COLOR TABLE

    如果大家觉得有用 就点个赞让更多的人看到吧
  • unity 触摸屏幕

    if Event current type EventType MouseDown 这里写鼠标按下 屏幕触摸按下 的代码 if Event current type EventType MouseDrag 这里写鼠标拖动 屏幕触摸滑动 的代
  • docker学习笔记--狂神

    Docker入门 Docker能做什么 虚拟机技术 虚拟机技术缺点 资源占用十分多 冗余步骤多 启动很慢 容器化技术 容器化技术不是模拟的一个完整的操作系统 比较Docker 和 虚拟机技术不用 传统虚拟机 虚拟出一条硬件 运行一个完整的操
  • springboot+mybatis实现多数据源

    1 前言 最近做项目碰到了一个需要连4个不同数据库的需求 其中db1 db2表结构都不相同 另外两个数据库same db private same db public表结构完全相同 一个对内一个对外 只是从物理上隔离了数据而已 所以打算通过
  • # Arduino小车PID调速——整定参数初试水

    Arduino小车PID调速 整定参数初试水 在实现了小车较为可靠的测速基础上 便可以正式开展PID调速实验了 本文是基于使用Arduino平台上由Brett Beauregard大神写的PID库进行参数整定的 侧重于在对PID算法有基本了