【Arduino小车实践】PID应用之四驱小车

news2024/9/23 23:27:19

一、 PID公式

二、 PID应用的必要性

1. 四驱小车运动

左边两个驱动轮和右边两个驱动轮的速度相同直线
右边轮子的速度大于左边轮子的速度左偏
右边轮子的速度小于左边轮子的速度

右偏

2. 产生多种运动的原因

        小车的4个电机,减速箱以及车轮在物理层面上存在误差,虽然给4个轮子通了相同pwm(电流),但是却没办法保证运行时车子的4个轮子的转速相同。

        我们只知道通过改变电流让电机旋转起来,却不知道轮子的实际转速,所以没法保证小车跑直线。这就是开环控制

3. 解决方案分析

        小车跑偏就是因为小车现在的控制系统是开环的,只能用pwm控制电机让它旋转,并不知道轮子的实际速度是多少。

        只有知道了方向是否发生了偏转,才能进一步对小车的运动方向进行控制调整。例如,往左偏了,我们就把右边的轮子速度降低一点。如果往右边偏了,我们就把边的轮子速度升高一点。

4. 解决方案

        引入反馈信号:如果我们能得知车子的运动方向,就可以对车子的方向加以纠正,控制小车跑直线(闭环控制)。

(1)给小车安装电子陀螺仪

        用它来测量小车运行的方向信号,从而控制单片机pwm的输出值(input)去修正电机的工作电流,从而修改轮子的实际速度(output),从而纠正小车的跑偏的问题,从而使用PID技术实现方向对小车方向的闭环控制。

        闭环比开环多了反馈信号feedback。我们这里的feedback信号选用了电子陀螺仪的偏转角(yaw值)。根据闭环控制,设计一个小车的实际控制方案,例如,保持左边的轮子速度不变,当车子向右发生偏转时,我就加快右边轮子的转速。当车子向左偏的时候,我就降低右边轮子的转速。

(2)确定反馈信号量和控制量之间的比例关系

方向没有发生改变反馈为0输出变化为0 ,不需要改变输出值
车子往右偏改变右轮的速度输入变化是?输出应该改变?
车子往左偏改变左轮的速度输入变化是?输出应该改变?

        输入信号和输出信号存在一种比例关系,即传感器的值yaw驱动电机的pwm的值存在一种比例关系(比例P)。方向偏的越多,那么右轮的pwm应该越大,方向偏的越少,右轮的pwm应该越少。方向偏的多少(偏差error)就是[yaw的目标值]-[yaw的当前值]

        出现的问题原因:左轮输入的Input和右轮驱动输入的Input是一样的,但是由于左轮和右轮的执行器有差异,导致左轮的Output1和右轮的Output2的值不一样。于是我们保持左轮依然使用开环系统,而把右轮系统改成可以调整转速的闭环系统。这样使得输入右轮系统的数值就不仅仅是Input了,还增加了电子陀螺仪反馈回来的偏转角(jaw)的误差值error。把这两个数值通过控制器处理后,再输入到执行器,让右轮最终产生的Output2等于左轮的Output1

(3)在系统的Controller部分引用PID比例部分

pwm=error*Kp+input

error=yaw的目标值-yaw的当前值

根据error的值的大小设定一个比例系数Kp,Kp是一个系数常数,需要根据系统的性能手动设定。然后加上原来input,形成新的pwm值。

当小车发生右偏时当小车发生左偏时
偏转角测量出来的当前测量值就会跟初始方向产生一个误差error偏转值跟初始方向同样产生一个error
假设初始方向是1
第一次测量测出来是0.2第一次测量测出来是1.2
error = 1-0.2=0.8,pwm就不等于input了,而是input+0.8Kperror = 1 - 1.2 = - 0.2,pwm就不等于input了,而是input-0.2Kp
由于0.8Kp是一个正数,所以最总pwm也就是升高由于-0.2Kp是一个负数,所以最终pwm也就是降低
右轮的速度就会增加,小车开始往左,纠正小车右偏右轮的速度就会减小,小车开始往右偏,纠正小车左偏

        因为电子陀螺仪的采样率大概为100ms一次。所以需要在计算机里每100ms 采样一次得到yaw的值:error = [yaw的目标值]-[yaw的当前值]。新的pwm=error*Kp+input,用来驱动右轮的电机。

        Kp值的选取:只有在Kp选取到一个合适的值,小车才能保持直线。

Kp过大震荡,小车会摇摆行驶
Kp过小纠正的不够,产生稳态误差

        稳态误差产生的原因:纠正的过程中,当前的测量值会跟目标值越来越小,那么error就会变得很小,使得error*Kp 也会变得很小; error*Kp 由于过小就会失去纠正的作用,离目标值始终存在一个误差,称之为稳态误差

(4)在系统的Controller部分引用PID积分部分

        问题:合适的Kp是很难找的,我们可以引入E*Ki(误差的积分)。当 error*Kp 部分的量纠正不够的时候,可以靠 I 部分的量(对每100ms测量出来的误差进行累加)来补充上去。

        假设:a. 开始向右偏转,只要不向左偏转,I 值是一直增加的。b. P 的输出一开始是比较猛的,但是当越来越靠近目标。c. 当 P 因误差 error 过小失去调整作用时,可以用 I 积分部分来弥补比例部分的稳态误差。

pwm = error * Kp + E * Ki + input

E = 每次测量的error 的累加和,系统每100ms测量一次jaw的值,每次测量的jaw的值和jaw的目标值有一个差值,我称之为err,把每次测量的err累加在一起就是E。

E*Ki 过大会出现积分饱和,系统依然会振荡
E*Ki 过小纠正不够

(5)在系统的Controller部分引用PID微分部分

        我们可以通过限制 I 的最大值的方法,来进行限制。也可以再增加一个微分量 D*Kd,Kd为系数常数。每100ms测量一次jaw偏转角,而D指的就是这一次的误差和上一次测量的误差之间的差值,是一个反映误差纠正快慢的量,重点是负值。

        在图上看,就是图像变化陡峭的部分。当Input加上这个值以后,系统可以有效抑制运行过程中变化过快的部分,比如振荡期。而对变化缓慢的部分,比如稳定期,微分部分几乎就不起作用。有点像起一个柔和的缓冲作用。

pwm = error * Kp + E * Ki + D * Kd + input

D=当前一次测量的error - 上一次测量的error,每100ms测量一次jaw,并计算出err,D反应的是系统的err变化率。所以err变化剧烈的区域,D会对总的输出值进行抑制,防止剧烈的振荡,而稳定之后的区域,D对输出值的影响就很小了。

三、程序编写

1. 核心公式

pwm = error * Kp + E * Ki + D * Kd + input

2. 相关参数及说明

pwm控制左边轮子和右边轮子的速度在650-899的范围内,pwm的值越大,轮子的速度越快。低于650时 小车不运动了。
E每次测量的error加到一起电子陀螺仪PDU6050测量的偏转角值为jaw。按下小车启动按键时,测量到的 jaw 就为目标值。之后每100ms测量出来的 jaw 值为当前值,用目标值减去当前值为每次测量的误差error
D0/

        最后每100ms 计算一次公式 pwm = error * Kp + E*Ki + D * Kd + input ,把计算出来的pwm值作为右轮的电机驱动的参数,代入电机的驱动程序里,根据实际场景调整一下系统参数Kp,Ki。

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

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

相关文章

Spark(21):SparkStreaming之DStream入门

目录 0. 相关文章链接 1. WordCount 案例实操 1.1. 需求 1.2. 添加依赖 1.3. 编写代码 1.4. 启动程序并通过netcat发送数据 2. WordCount 解析 0. 相关文章链接 Spark文章汇总 1. WordCount 案例实操 1.1. 需求 使用 netcat 工具向 9999 端口不断的发送数据&#xf…

Flutter系列文章-Flutter环境搭建和Dart基础

Flutter是Google推出的一个开源的、高性能的移动应用开发框架,可以用一套代码库开发Android和iOS应用。Dart则是Flutter所使用的编程语言。让我们来看看如何搭建Flutter开发环境,并了解Dart语言的基础知识。 一、Flutter环境搭建 1. 安装Flutter SDK …

Blender 3.6 LTS更新的5个新功能,一定要试试

Blender基金会已正式发布Blender 3.6 LTS(长期支持)。它是备受期待的该公司开源 3D 软件的长期支持版本,也是 Blender 3.x 系列的最终 LTS 版本。Blender 3.6有一个用于设置基于粒子的模拟的模拟节点和一个升级的 UV 封装系统,其中…

IDEA自动添加注释作者版本时间等信息

File | Settings | Editor | Live Templates 点击加号,选择第二项 设置一个名称 再次点击加号,选择第一项 填写名称(设置完成后再代码中输入该名称即可插入该注释内容),描述,及内容 /*** author 名字…

深度图像Range Image

从点云创建深度图并显示 函数原型 RangeImage::createFromPointCloud (const PointCloudType& point_cloud, float angular_resolution, float max_angle_width, float max_angle_height, …

Leaflet Ant Path(水系流动效果)

一、源代码&#xff1a; 用leaflet库中的Leaflet.AntPath插件 将通量动画&#xff08;如蚂蚁行走&#xff09;放入折线中 <!DOCTYPE html> <html><head><meta http-equiv"Content-Type" content"text/html; charsetutf-8" /><…

【UE】运行游戏时就获取鼠标控制

问题描述 我们经常在点击运行游戏后运行再在视口界面点击一下才能让游戏获取鼠标控制。其实只需做一个设置就可以在游戏运行后自动获取鼠标控制。 解决步骤 点击编辑器偏好设置 如下图&#xff0c;点击“播放”&#xff0c;再勾选“游戏获取鼠标控制” 这样当你运行游戏后直…

12、k8s Namespaces 资源隔离

Kubernetes Namespaces _ Kubernetes(K8S)中文文档_Kubernetes中文社区 Kubernetes Namespaces 实现资源隔离和配额的隔离,比如下面的信息: 所有对象都在Namespace中? 大多数Kubernetes资源(例如pod、services、replication controllers或其他)都在某些Namespace中,…

【LeetCode热题100】打卡第36天:多数元素打家劫舍

文章目录 【LeetCode热题100】打卡第36天&#xff1a;多数元素&打家劫舍⛅前言 多数元素&#x1f512;题目&#x1f511;题解 打家劫舍&#x1f512;题目&#x1f511;题解 【LeetCode热题100】打卡第36天&#xff1a;多数元素&打家劫舍 ⛅前言 大家好&#xff0c;我是…

pytorch安装问题【超级简单版】

pytorch安装问题 当前遇到的问题&#xff1a; python3.9无法安装读取coco数据集的 pycocotools-windows,那么需要切换版本到3.6/7/8&#xff0c;但是切换到python 3.6之后&#xff0c;无法安装torchvision和pytorch【在python就叫torch】&#xff0c;显示没有这个版本 pip i…

MS1205N激光测距用高精度时间测量(TDC)电路

MS1205N 是一款高精度时间测量 (TDC) 电路&#xff0c;具有四通 道、多脉冲的采样能力、高速 SPI 通讯、多种测量模式&#xff0c;适合 于激光雷达和激光测距。 主要特点  单精度模式 60ps  双精度模式 30ps  非校准测量范围 3.5ns(0ns) 至 25μs  单…

案例分析:成功的APP开发背后的故事

如今&#xff0c;我们生活在一个信息化时代&#xff0c;在这个信息时代&#xff0c;不管是工作还是生活都离不开手机 APP。因为有了手机 APP&#xff0c;我们的生活变得更加便捷、智能。但随着移动 APP开发的火热&#xff0c;很多企业都想要制作一个自己的 APP。然而在众多的 A…

822. 走方格

链接&#xff1a; 链接 题目&#xff1a; 给定一个 nmnm 的方格阵&#xff0c;沿着方格的边线走&#xff0c;从左上角 (0,0)(0,0) 开始&#xff0c;每次只能往右或者往下走一个单位距离&#xff0c;问走到右下角 (n,m)(n,m) 一共有多少种不同的走法。 输入格式 共一行&#xff…

【Docker】简单的Linux安装Redis

目录 Docker 安装 Redis拉取镜像安装容器修改配置文件容器随docker启动自动运行redis客户端 史上最详细Docker安装Redis &#xff08;含每一步的图解&#xff09;实战 Docker 安装 Redis 拉取镜像 docker pull redis安装容器 创建redis配置文件目录&#xff1a;如果内部没有相…

数据结构初阶--顺序表

目录 一.顺序表的定义 二.顺序表的分类 2.1.静态顺序表 2.2.动态顺序表 三.顺序表的特点 四.顺序表的功能实现 4.1.顺序表的定义 4.2.顺序表的初始化 4.3.顺序表的销毁 4.4.顺序表的容量检查 4.5.顺序表的打印 4.6.顺序表的尾插 4.7.顺序表的头插 4.8.顺序表的尾…

用ChatGPT搞定12 种编程语言:看看它如何表现

众所周知ChatGPT可以写代码&#xff0c;但当有一堆语言一起抛向它时&#xff0c;它的表现如何呢&#xff1f;答案是&#xff1a;还不错&#xff08;但并不完美&#xff09;。 在过去的几个月里&#xff0c;我们已经领教了ChatGPT的编码能力。我对它进行了PHP和WordPress的测试…

前端学习——Web API (Day6)

正则表达式 语法 <!DOCTYPE html> <html lang"zh-CN"> <head><meta charset"UTF-8"><meta http-equiv"X-UA-Compatible" content"IEedge"><meta name"viewport" content"widthdevice…

SPEC CPU 2017 1.0.5 不同版本CentOS 7 8 安装笔记

CentOS 7.9.2009 x86_64 gcc版本 安装成功 runcpu编译报错 gcc版本太低&#xff0c;不识别-fno-tree-loop-vectorize 去掉config/gcc.cfg中 -fno-tree-loop-vectorize编译优化参数。 用例编译中 CentOS 8.3.2011 x86_64 gcc版本 安装失败&#xff0c;需要自行编译tools 手动…

#{} 和 ${} 的区别?

一、区别概述 1.1、主要区别&#xff1a; 1、#{} 是预编译处理&#xff0c;${} 是直接替换&#xff1b;2、${} 存在SQL注入的问题&#xff0c;而 #{} 不存在&#xff1b;Ps&#xff1a;这也是面试主要考察的部分~ 1.2、细节上&#xff1a; 1、${} 可以实现排序查询&#xff…

亚马逊云科技联合Nolibox定制工业设计AIGC解决方案

从机器学习算法到深度学习再到强化学习&#xff0c;AI创新浪潮奔流不息。而AIGC&#xff08;AI-generated Content&#xff0c;人工智能生成内容&#xff09;的到来&#xff0c;更是让AI成为众多企业的得力助手&#xff0c;开拓了文本、图像、音视频等领域的天花板。 在洞悉到…