PID算法

合集下载

离散控制系统中的PID控制算法

离散控制系统中的PID控制算法

离散控制系统中的PID控制算法离散控制系统中的PID(Proportional-Integral-Derivative)控制算法是一种常用的控制算法,用于调整系统输出与设定值之间的误差,从而实现系统的稳定和精确性。

PID控制算法通过比较当前输出值和设定值,并根据比例、积分和微分三项参数的调节来计算控制器的输出,以达到最优控制效果。

一、PID控制算法的基本原理PID控制算法通过以下三个环节实现对离散控制系统的控制:1. 比例(P)环节:比例环节根据误差的大小,按比例调整控制器的输出。

它的作用是在误差较大时,加大控制器的输出,加速系统的响应速度。

比例系数越大,系统的响应越敏感,但也容易引起过冲和振荡;反之,比例系数越小,系统的响应越迟缓。

2. 积分(I)环节:积分环节根据误差的累积量,对控制器的输出进行修正。

它的作用是消除系统存在的稳态误差,使得输出逐渐接近设定值。

积分系数越大,系统对稳态误差的修正越快,但也容易引起过冲和振荡;反之,积分系数越小,系统对稳态误差的修正越慢。

3. 微分(D)环节:微分环节根据误差的变化率,对控制器的输出进行调整。

它的作用是减小系统对突变干扰的响应,提高系统的稳定性。

微分系数越大,系统对突变干扰的响应越快,但也容易引起过冲和振荡;反之,微分系数越小,系统对突变干扰的响应越慢。

二、PID控制算法的实际应用PID控制算法广泛应用于各种离散控制系统中,例如自动调节系统、温度控制系统、机器人控制系统等。

以下是PID控制算法在温度控制系统中的应用实例:1. 设置目标温度首先,需要设置目标温度作为设定值。

2. 读取当前温度值通过传感器等装置,实时读取当前温度值。

3. 计算误差将目标温度与当前温度值进行比较,得到误差值。

4. 计算PID输出根据比例、积分和微分的系数,计算出PID控制器的输出值。

5. 控制温度将PID控制器的输出值作为控制信号,通过执行机构(如加热元件)调节系统,使得温度逐渐接近目标温度。

PID算法

PID算法

0
数字PID控制算法
数值逼近的方法:用求和代替积分、用差分代替微分,使模拟PID离散化为差分方程
1 u KP e TI
de u0 0 edt TD dt
t

T uk K P [ek TI
位置式控制算法
t
o
e(t )dt T e j
j 0
k
计算机控制算法
控制概述
目的 方式 工程法 计算机仿真 闭环 比例 积分 微分 双环(串级) PID参数整定 采样周期选择 指标 对象
手段 结论
连续化设计方法
(模拟化设计方法)
数字PID算法 数字PID算法改进
离散化设计方法
(直接设计法)
最少拍有波纹控制器设计 最少拍无波纹控制器设计
大林(Dahlin)算法
PID整定的理论方法 通过调整PID的三个参数KP、TI、TD ,将系统的闭环特征根分 布在 s 域的左半平面的某一特定域内,以保证系统具有足够的稳定 裕度并满足给定的性能指标 只有被控对象的数学模型足够精确时,才能把特征根精确地配 置在期望的位置上,而大多数实际系统一般无法得到系统的精确模 型,因此理论设计的极点配置往往与实际系统不能精确匹配
有更大阻尼的算法:
ei 2ei 1 ei 2 用 ( yi 2 yi 1 yi 2 ) 代替,即:
T TD ui K P yi yi 1 ei ( yi 2 yi 1 yi 2 ) TI T
带死区的PID控制
消除由于频繁动作所引起的振荡
采样周期的选择
从香农(Shannon)采样定理看,系统采样频率的下限为 fs = 2fmax 从控制系统的随动和抗干扰的性能来看,要求采样周期短些 从微机的工作量和每个调节回路的计算来看,一般要求采样周期大些 从计算机的精度看,过短的采样周期是不合适的 实际选择采样周期时,必须综合考虑 — 采用周期要比对象的时间常数小得多,否则采样信号无法反映瞬变过程 — 采用周期应远小于对象的扰动信号的周期 — 考虑执行器的响应速度 — 当系统纯滞后占主导地位时,应按纯滞后大小选取,并尽可能使纯滞后时 间接近或等于采样周期的整数倍 — 考虑对象所要求的控制质量,精度越高,采样周期越短

pid算法公式详解

pid算法公式详解

pid算法公式详解
PID算法,即比例(proportional)、积分(integral)、微分(derivative)控制算法,是一种应用广泛的控制算法。

它结合了比例、积分和微分三种环节于一体,适用于连续系统的控制。

在工业应用中,它是最广泛算法之一,如四轴飞行器、平衡小车、汽车定速巡航、温度控制器等场景均有应用。

PID算法的公式如下:
\[U(t)=K_p e(t)+K_i\int_{0}^{t}e(\tau)d\tau+K_d frac{de(t)}{dt}\]
其中,
-\(U(t)\)是控制器输出的控制信号;
-\(e(t))是控制器输入的误差信号;
-\(K_p\)、\(K_i\)和\(K_d\)是比例、积分和微分系数;
-(\int_{0}^{t}e(\tau)d\tau)是误差信号的累积值,即积分项;
-(\frac{de(t)}{dt}\)是误差信号的变化率,即微分项。

这个公式描述了PID控制器如何根据当前的误差以及过去的误差来计算出控制信号。

比例项反映了当前误差的大小,积分项反映了过去误差的累积,微分项反映了误差变化的趋势。

通过调整这三个参数,可以实现对系统的精确和快速控制。

电机控制pid算法

电机控制pid算法

电机控制pid算法电机控制PID算法引言:PID(Proportional-Integral-Derivative)算法是一种常用的控制算法,广泛应用于电机控制领域。

本文将详细介绍PID算法的原理和应用,并探讨其在电机控制中的作用和优势。

一、PID算法原理1. 比例控制(P):比例控制是一种基本的反馈控制方法,其输出与误差成正比。

在电机控制中,比例控制可用于调整电机的速度或位置。

通过设置适当的比例增益,可以实现快速响应和准确控制。

2. 积分控制(I):积分控制用于消除静态误差,通过对误差进行积分来修正系统偏差。

在电机控制中,积分控制可用于消除电机运行过程中的误差,提高控制精度和稳定性。

3. 微分控制(D):微分控制用于抑制系统的超调和振荡,通过对误差的变化率进行微分来提前预测系统的响应。

在电机控制中,微分控制可用于提高系统的动态响应,减小系统的超调和振荡。

二、PID算法应用1. 电机速度控制:PID算法可用于电机的速度控制,通过测量电机的转速与设定值之间的误差,并根据比例、积分和微分系数对误差进行调整,控制电机的输出电压或电流,从而实现精确的速度控制。

2. 电机位置控制:PID算法也可用于电机的位置控制,通过测量电机的位置与设定值之间的误差,并根据比例、积分和微分系数对误差进行调整,控制电机的输出电压或电流,从而实现精确的位置控制。

3. 电机力矩控制:PID算法还可用于电机的力矩控制,通过测量电机的输出力矩与设定值之间的误差,并根据比例、积分和微分系数对误差进行调整,控制电机的输出电压或电流,从而实现精确的力矩控制。

三、PID算法的优势1. 简单易实现:PID算法是一种简单易实现的控制算法,只需调节比例、积分和微分系数即可实现对电机的控制。

算法结构简单,计算量小,适用于实时控制系统。

2. 鲁棒性强:PID算法具有较好的鲁棒性,能够适应不同的工作环境和负载变化。

通过合理调节PID参数,可以使电机控制系统具有较好的稳定性和鲁棒性。

PID控制算法及参数设定

PID控制算法及参数设定

PID控制算法及参数设定PID控制算法的基本原理是将控制信号分为三部分:比例项(P项)、积分项(I项)和微分项(D项)。

比例项用于根据当前的偏差大小调整控制量的大小,积分项用于累积偏差,消除偏差的累积效应,微分项用于预测偏差的变化趋势,避免系统产生超调现象。

比例项(P项)是最简单的控制项,它根据当前偏差的大小,乘以一个比例系数Kp来调整控制量的大小。

当偏差增大时,P项的作用使系统更快地达到目标值,但过大的比例系数可能导致系统产生过冲或震荡。

积分项(I项)用于消除偏差的累积效应,即调整控制量来消除系统的稳态误差。

积分项根据偏差累积值与一个积分系数Ki的乘积来调整控制量的变化,当系统的偏差较大时,I项的作用比P项更加明显,但过大的积分系数可能导致系统产生过调。

微分项(D项)用于预测偏差的变化趋势,通过对偏差的变化速率进行监测,来调整控制量的变化速度。

微分项根据偏差变化率与一个微分系数Kd的乘积来调整控制量的变化速度,当偏差的变化速率较大时,D项的作用比P项和I项更加明显,但过大的微分系数可能导致系统对噪声敏感。

参数设定是PID控制的关键,它直接影响系统的稳定性和性能。

常用的参数设定方法有经验法、试验法和自整定法。

经验法是根据经验和实际应用中的经验规则来设定参数,试验法是通过试验调整参数,观察系统的响应特性,并根据实际需求进行调整。

自整定法是通过对系统的数学模型进行分析,选取合适的准则和算法来自动调整参数。

常用的自整定方法有Ziegler-Nichols法和Chien-Hrones-Reswick 法。

Ziegler-Nichols法是基于试验法的参数设定方法,根据试验的系统响应特性来选取参数。

它通过改变比例增益和积分时间来观察系统的响应,并根据系统的临界稳定度来选择参数。

Chien-Hrones-Reswick法是基于数学模型的参数设定方法,根据系统的数学模型和性能指标来优化参数的选择,以达到最佳控制效果。

pid算法的原理和算法

pid算法的原理和算法

pid算法的原理和算法一、pid算法简介PID(Proportional-Integral-Derivative,比例-积分-微分)算法是一种广泛应用于工业控制领域的调节算法。

它通过计算系统误差与期望值的比值(比例控制)、误差积分和误差变化率(微分控制)来调节控制器的输出,从而使被控对象达到期望状态。

二、pid算法原理1.比例(P)控制:比例控制是根据系统误差与期望值的比值来调节控制器输出。

当误差较大时,比例控制输出较大,有利于快速消除误差;当误差较小时,比例控制输出较小,有利于提高系统的稳定性。

2.积分(I)控制:积分控制是根据系统误差的积分来调节控制器输出。

当误差持续存在时,积分控制输出逐渐增大,有助于消除误差。

但过大的积分控制会导致系统响应过慢,甚至产生振荡。

3.微分(D)控制:微分控制是根据系统误差的变化速度来调节控制器输出。

它能预测系统的变化趋势,从而减小超调量和调整时间,提高系统稳定性。

三、pid算法应用1.控制器设计:PID算法可以用于设计各类控制器,如PID控制器、模糊PID控制器、自适应PID控制器等。

2.参数调节:PID算法的三个参数(Kp、Ki、Kd)需要根据被控对象的特性进行调节。

合理的参数设置可以使系统在稳定性和响应速度之间达到平衡。

四、pid算法优化与改进1.抗积分饱和:当系统误差持续存在时,积分控制输出可能超过控制器最大输出,导致积分饱和。

通过引入抗积分饱和算法,可以限制积分控制的输出,提高系统稳定性。

2.抗积分粘滞:为避免积分控制输出在零附近震荡,可以采用抗积分粘滞算法,使积分控制输出在零附近呈现出非线性特性。

3.抗积分震荡:在积分控制中引入微分项,可以减小积分震荡,提高系统稳定性。

五、pid算法在实际工程中的应用案例PID算法在我国工业控制领域得到了广泛应用,如电力系统、温度控制系统、流量控制系统等。

通过合理设计PID控制器及其参数,可以实现对被控对象的稳定控制。

PID控制算法介绍与实现

PID控制算法介绍与实现PID控制算法是一种用于实现控制系统的经典算法。

PID代表了三个主要的控制参数,即比例(Proportional)、积分(Integral)和微分(Derivative)。

PID控制算法基于反馈控制原理,通过对系统当前状态和目标状态之间的误差进行分析和调整,实现对系统输出的精确控制。

PID控制算法的原理是,通过对比目标值和实际值之间的差异,计算出控制量,并根据调整参数的权重对控制量进行调节,以减小误差并将系统稳定在目标状态中。

比例项根据误差的大小和比例参数的比例关系,使控制量与误差呈线性关系;积分项则通过累计误差并乘以积分参数来补偿系统的漂移和持续误差;微分项则根据误差的变化率乘以微分参数,以增加控制的灵敏度和反应速度。

PID控制算法的实现一般分为两个主要步骤:参数设置和控制计算。

在参数设置阶段,需要根据具体的应用要求和系统特性,通过试验或者调试确定合适的比例、积分和微分参数。

在控制计算阶段,根据当前的误差和控制参数,计算出相应的控制量,并更新控制器,以实现系统的控制。

具体的PID控制算法实现可以通过如下步骤进行:1.初始化控制器:设置比例、积分和微分参数,并将误差累计器和上一次误差设为0。

2.读取目标值和实际值:从传感器或外部输入中读取目标值和实际值。

3.计算误差:根据目标值和实际值计算误差,即偏差。

4.计算控制量:根据比例、积分和微分参数,计算出相应的比例项、积分项和微分项,将它们加权求和得到控制量。

5.更新控制器:将当前的误差作为下一次的上一次误差,将当前的控制量作为下一次的上一次控制量。

6.输出控制量:将计算出的控制量输出到执行器或系统中,实现对系统的控制。

7.循环调用:以上步骤循环调用,实时更新控制参数和控制量,以实现系统的稳定控制。

除了基本的PID控制算法外,还存在一些改进和扩展的PID算法,如自适应PID控制算法、模糊PID控制算法、增量PID控制算法等。

这些算法在不同的应用场景和系统要求下,进一步优化和改进了传统的PID控制算法,提高了控制精度、调节性能和适应性。

PID控制算法与策略

PID控制算法与策略PID(Proportional-Integral-Derivative,比例-积分-微分)控制算法是一种常用的控制算法,广泛应用于工业控制、机器人控制、自动化控制等领域。

PID控制算法包括三个部分,分别是比例控制、积分控制和微分控制,通过调整这三个控制部分的权重和参数,可以实现精确的控制目标。

比例控制是PID控制算法的基础,它根据控制目标与实际输出之间的差别,按照一定的比例进行控制。

比例控制的输出与偏差成正比,比例系数KP越大,控制输出越大,系统响应也就越快,但可能会出现超调现象。

相反,比例系数KP越小,系统响应越慢,但也能减小超调。

积分控制是为了消除系统的稳态误差而引入的。

积分控制是根据系统的偏差历史累积值,按照一定的积分系数KI进行控制。

通过积分控制,能够消除系统存在的常态误差,提高系统的稳定性。

积分控制可以加快系统的响应速度,但过大的积分系数KI可能会引起系统的不稳定。

微分控制是为了抑制系统的震荡现象而引入的。

微分控制根据系统的偏差变化率,按照一定的微分系数KD进行控制。

微分控制可以提前预测系统的运动趋势,对系统的运动进行抑制,从而提高系统的稳定性。

微分控制可以减小系统的超调,但过大的微分系数KD可能会引起系统的振荡。

PID控制器的输出是比例控制、积分控制和微分控制三个部分的加权和。

其中,比例部分P与偏差成比例,积分部分I与偏差历史累积值成比例,微分部分D与偏差变化率成比例。

PID控制通过合理调整比例系数KP、积分系数KI和微分系数KD的参数,可以实现系统的快速响应、减小超调、提高稳定性等多种控制目标。

在实际应用中,PID控制算法还可以根据系统的动态特性和需求,采用不同的策略进行控制。

常见的PID控制策略包括:1.增量PID控制:根据前后两次采样值的差别进行控制,可以有效抑制噪声的影响,提高控制的精度和稳定性。

2.自适应PID控制:根据系统的动态变化,自适应地调整比例、积分和微分系数的参数,能够适应不同工况下的控制需求。

PID算法

NEVER STOP
IMPROVING
第三章 P,I,D各参数作用
伺服系统 | 变频器 | PLC | 机器视觉 | 工业互联网 | 新能源
积分环节:
积分为过去所有时间内误差的累计值,积分作用的根本目的是将累计值清零。 积分作用: S1+S2+S3+S4≈0 在大惯性系统中,其S1时间会很长, 所以积分的累计值会非常高,所以 积分超调是大惯性系统的一个大问 题。
过渡页
TRANSITION PAGE
第三章
开环模型+PID模式
第三章 P,I,D各参数作用
伺服系统 | 变频器 | PLC | 机器视觉 | 工业互联网 | 新能源
一、比例环节 即时成比例的反映控制系统的偏差信号,偏差一旦产生,控制器立即产生控制作 用,以减少偏差。通常随着值的加大,闭环系统的超调量加大,系统响应速度加快,但是当增 加到一定程度,系统会变得不稳定。 二、积分环节 主要用于消除静差,提高系统的无差度。积分作用的强弱取决于积分常数,越大, 积分作用越弱,反之越强。通常在不变的情况下,越大,即积分作用越弱,闭环系统的超调量 越小,系统的响应速度变慢。 3、微分控制可以减小超调量,克服振荡,使系统的稳定性提高,同时加快系统的动态响应速度, 减小调整时间,从而改善系统的动态性能。
此处修改PID积分作用强度。
NEVER STOP
IMPROVING
第二章 PID被控系统类型
伺服系统 | 变频器 | PLC | 机器视觉 | 工业互联网 | 新能源
小惯性系统(张力控制)
小惯性系统的过阻尼过程。(PID强度较 弱)
小惯性系统的过阻尼过程。(PID强度较 强)
NEVER STOP
IMPROVING

PID控制算法的原理及应用

PID控制算法的原理及应用1. 简介•PID(比例-积分-微分)控制算法是自动控制领域中最常用的一种控制算法。

•PID控制算法通过不断调整控制器的输出,使得被控对象的输出达到预期的目标值。

2. PID控制算法原理PID控制算法由三个部分组成:比例环节、积分环节和微分环节。

2.1 比例环节比例环节根据系统输出的偏离程度,以一定的比例输出控制信号。

比例系数越大,控制信号的变化越敏感。

2.2 积分环节积分环节根据系统输出的偏离累积值,以一定的比例输出控制信号。

积分环节用于消除长期偏差,提高系统的稳定性。

2.3 微分环节微分环节根据系统输出的变化速率,以一定的比例输出控制信号。

微分环节用于预测系统未来的变化趋势,提前进行调整。

2.4 PID算法公式PID控制算法的输出可以表示为:\[u(t) = K_p \cdot e(t) + K_i \cdot \int_0^te(\tau) \, d\tau + K_d \cdot \frac{de(t)}{dt}\]其中, \(u(t)\) 为控制信号, \(e(t)\) 为系统的偏差, \(K_p\) 、 \(K_i\) 和 \(K_d\) 分别为比例系数、积分系数和微分系数。

3. PID控制算法应用场景PID控制算法广泛应用于各种自动控制系统中。

以下为几个常见的应用场景:3.1 温度控制PID控制算法在温度控制中常常被应用。

通过测量温度并与目标温度进行比较,PID控制器可以调整加热或冷却设备的控制信号来保持温度稳定。

3.2 机器人控制PID控制算法在机器人控制中被广泛使用。

机器人的运动轨迹可以通过PID控制器来控制,以实现准确的位置控制和运动稳定性。

3.3 液位控制在液位控制系统中,PID控制器可以根据液位的偏差调整液位控制装置的输出信号,以维持液位稳定。

3.4 电机控制PID控制算法在电机控制中被广泛应用。

通过不断调整电机的输入信号,PID控制器可以精确控制电机的转速和位置。

  1. 1、下载文档前请自行甄别文档内容的完整性,平台不提供额外的编辑、内容补充、找答案等附加服务。
  2. 2、"仅部分预览"的文档,不可在线预览部分如存在完整性等问题,可反馈申请退款(可完整预览的文档不适用该条件!)。
  3. 3、如文档侵犯您的权益,请联系客服反馈,我们会尽快为您处理(人工客服工作时间:9:00-18:30)。

1.Arduino 智能小车寻迹原理寻迹采用的主要原理就是红外探测法,即利用红外线在不同颜色的物体表面具有不同的反射性质的特点Arduino 单片机就是以是否收到反射回来的红外光为依据来确定黑线的位置和小车的行走路线。

红外探测器探测距离有限,一般最大不应超过15cm。

对于发射和接收红外线的红外探头,可以自己制作或直接采用集成式红外探头2.Arduino 寻迹模块简介3.Arduino pwm 调速4.PID算法5.PID 算法与寻迹6.代码:.#include "pid.h"....#ifdef ARDUINO_DEBUG..int debugLeftSpeed;..int debugRightSpeed;..uint8_t debugIrs = 0;..#endif....const float motorSpeed = 140; //小车输出速度..const int IR_PIN[] = {A0, A1, A2, A3, A4}; //寻迹板引脚定义..const int IN_A1 = 7; //..const int IN_A2 = 6; //..const int IN_B1 = 5; //..const int IN_B2 = 4; //..const int _pwmLeftPin = 10;//左边 pwm 引脚..const int _pwmRightPin = 11;//右边 pwm 引脚..pid_t pid;..float pidValue = 0; //pid 值..bool turnFlag = false;....void setup(void)..{..int i;....//设置引脚功能..pinMode(IN_A1, OUTPUT); ..pinMode(IN_A2, OUTPUT); ..pinMode(IN_B1, OUTPUT); ..pinMode(IN_B2, OUTPUT); ....//设置寻迹板引脚为 INPUT..for (i = 0; i < 5; i++) { .pinMode(IR_PIN[i], INPUT);..}......pid.sampleTime = SAMPLE_TIME;//初始化采样时间..pid.Kp = KP_VALUE;..pid.Ki = KI_VALUE;..pid.Kd = KD_VALUE;..pid.error = 0;..pid.previous_error = 0;....Serial.begin(115200);//设置波特率..delay(5000);//延时 5s....analogWrite(_pwmLeftPin, motorSpeed );.analogWrite(_pwmRightPin, motorSpeed ); ....goForward();//小车向前行驶....return;..}........../**..获取寻迹板红外数据..*/..uint8_t getIrData(void)..{..int i, j;..uint8_t level;..uint8_t temp;..uint8_t irs[9] = {0};....//获取10组数据..for (j = 0; j < 9; j ++) {....for (i = 0; i < 5; i++) {..level = digitalRead(IR_PIN[i]); ..if (level) {..bitSet(irs[j], i);//设置对应位为1 ..} else {..bitClear(irs[j], i);//设置对应为0 .}..}..}....//对所有的数据进行排序..for (i = 0; i < 9 - 1; i ++) {..for (j = 0; j < 9 - i - 1; j ++) { ..if (irs[j] > irs[j + 1]) {..temp = irs[j];..irs[j] = irs[j + 1];..irs[j + 1] = temp;..}..}..}...#ifdef ARDUINO_DEBUG..debugIrs = irs[4];..#endif....//返回中间值..return irs[4];..}..../**..计算误差值..@param irs :获取的寻迹传感器的值..*/..int calcErrorByIrsValue(uint8_t irs) ..{..int curError = pid.error;....switch (irs) {..case B11110: curError = -8; break; ....case B10000:..case B11000: curError = -7; break; ....case B11100: curError = -6; break; ..case B11101: curError = -4; break; ..case B11001: curError = -2; break; ....case B00000:..case B11011: curError = 0; break; ...case B10011: curError = 2; break;..case B10111: curError = 4; break;..case B00111: curError = 6; break;....case B00011:..case B00001: curError = 7; break;....case B01111: curError = 8; break;..case B11111: curError = pid.error > 0 ? 9 : - 9; break; ..}....return curError;..}...../**..排序函数..*/..void _sortData(int *p, int n)..{..int temp;..int i, j;....for (i = 0; i < n - 1; i ++) {..for (j = 0; j < n - i - 1; j ++) { ..if (p[j] > p[j + 1]) {..temp = p[j];..p[j] = p[j + 1];..p[j + 1] = temp;..}..}..}....return;..}....../**..计算误差值..*/..void calcCurrentError(void) ..{..int i;..uint8_t irs;.float sum = 0;..int errorData[10];....//获取 10组数据..for (i = 0; i < 10; i ++) {..irs = getIrData();..errorData[i] = calcErrorByIrsValue(irs); ..}...._sortData(errorData, 10);....for (i = 1; i < 10 - 1; i ++) {..sum += errorData[i];..}...pid.error = sum / 8;....return;..}....void turnRight(void)..{..digitalWrite(IN_A1, LOW); ..digitalWrite(IN_A2, HIGH); ..digitalWrite(IN_B1, HIGH); ..digitalWrite(IN_B2, LOW); ..}....void turnLeft(void)..{..digitalWrite(IN_A1, HIGH); ..digitalWrite(IN_A2, LOW); ..digitalWrite(IN_B1, LOW); ..digitalWrite(IN_B2, HIGH); ..}....void goForward(void)..{..digitalWrite(IN_A1, HIGH); ..digitalWrite(IN_A2, LOW); ..digitalWrite(IN_B1, HIGH); ..digitalWrite(IN_B2, LOW); ..}.../**..小车控制函数..@param pidValue : 计算出来的 pid 值..@param turnFlag : 方向标志..*/..void motorControl(float pidValue, bool turnFlag)..{....int leftMotorSpeed = 0;..int rightMotorSpeed = 0;....//根据 pid 的值调整小车左右电机的速度..leftMotorSpeed = constrain((motorSpeed + pidValue), -255, 255); ..rightMotorSpeed = constrain((motorSpeed - pidValue), -255, 255); ...//当转弯标志被设置时,则需要使用左边与右边的轮子正转与反转来调整,提高调整速度..if (turnFlag) {..//按照较大的 pwm 值进行调整,速度最快,左边速度与右边速度一致..if (abs(leftMotorSpeed) > abs(rightMotorSpeed)) {..leftMotorSpeed = abs(leftMotorSpeed);..rightMotorSpeed = leftMotorSpeed;..} else {..rightMotorSpeed = abs(rightMotorSpeed);..leftMotorSpeed = rightMotorSpeed;..}..} else {..//当速度为正时,则取原值,当速度为负时,则取相反数,保持 pwm 的值为正值..leftMotorSpeed = leftMotorSpeed > 0 ? leftMotorSpeed : -leftMotorSpeed; ..rightMotorSpeed = rightMotorSpeed > 0 ? rightMotorSpeed : -rightMotorSpeed; ..}....analogWrite(_pwmLeftPin, leftMotorSpeed ); ..analogWrite(_pwmRightPin, rightMotorSpeed); ....#ifdef ARDUINO_DEBUG..debugLeftSpeed = leftMotorSpeed ;..debugRightSpeed = rightMotorSpeed;..#endif....return;..}..../***..计算 pid 的值.*/..bool calculatePid(float *pValue)..{..float P = 0;..static float I = 0 ;..float D = 0 ;..static unsigned long lastTime = 0; ..unsigned long now = millis();..int timeChange = now - lastTime; ....//没有到达采样时间..if (timeChange < pid.sampleTime) { ..return false;..}...P = pid.error;//错误值..I = I + pid.error;//积累误差..D = pid.error - pid.previous_error;//计算错误的变化率....*pValue = (pid.Kp * P) + (pid.Ki * I) + (pid.Kd * D) + 1; ..*pValue = constrain(*pValue, -motorSpeed,motorSpeed);....pid.previous_error = pid.error;..lastTime = now;....return true;..}....#if ARDUINO_DEBUG..void print_debug()..{..int i;..String irs2bin = String(debugIrs, 2); ..int len = irs2bin.length();..if (len < 5) {..for (i = 0; i < 5 - len; i++) {..irs2bin = "0" + irs2bin;..}..}....Serial.print("IRS : ");..Serial.print(irs2bin);..Serial.print(" ML:");..Serial.print(debugLeftSpeed);..Serial.print(" MR:");..Serial.print(debugRightSpeed);..Serial.print(" ERROR:");..Serial.print(pid.error, OCT);..Serial.println();..}..#endif..../**..计算运动方向..*/..void calcDirection(void)..{....if (pid.error >= 7 && pid.error <= 9) {..turnLeft();..turnFlag = true;..} else if (pid.error >= -9 && pid.error <= -7) { ..turnRight();..turnFlag = true;..} else {..goForward();..turnFlag = false;..}....return;..}....void loop(void)..{..bool ok;..float pidValue;....//计算错误值..calcCurrentError();..//计算 pid 的值..ok = calculatePid(&pidValue);..if (ok) {..calcDirection();//计算小车运动方向..motorControl(pidValue, turnFlag);//控制电机..}....//delay(500);....#if ARDUINO_DEBUG ..print_debug(); ..delay(1000); ..#endif....return;..}.。

相关文档
最新文档