PID循迹机器人及整定

如何对线路循迹机器人进行编程

  1. 如何对线路循迹机器人进行编程 (robotresearchlab.com)
  2. PID调谐文章:http://robotresearchlab.com/2019/02/16/pid-line-follower-tuning/

介绍人们选择对循迹机器人进行线路编程的两种主要方式,并比较两者。将详细比较“简单循迹”和“PID 循迹”。在低速下,简单的循迹算法是完全可以接受的,因为速度的增加,简单的循迹算法不如PID控制算法。

简单的线路循迹

首先,我们有简单的线路循迹,这种类型的循迹背后的一般前提是,您有一个到几个传感器,并且您根据传感器看到线路对电机响应进行硬编码。这通常是人们在循迹行时学习的第一种方法,因为它易于理解且易于编程。让我们首先回顾一下典型的传感器选项。

一个传感器

以下一条传感器线背后的一般思路是,您将一个电机设置为以略微降低或增加电机速度运行,以便机器人偏向一个方向(朝向线的方向)。当传感器看到线路时,您将短暂加速最靠近线路的电机,以防止交叉。
single_sensor_line_follow_path

**优点

  • 电路简单
  • 易于编程
  • 在最低水平上完成工作
  • 对于直线来说,这不是一个糟糕的解决方案

缺点

  • 如果你超过这条线一次,那可能是灾难性的
  • 仅在平滑的线条中工作良好(没有突然转弯)
  • 旅行额外的距离(而不是直行)浪费时间
  • 根本走不快
示例代码

下面应该让你了解这段代码的样子,我还没有测试过这段代码,所以请谨慎行事。

#define L_MOTOR         9
#define R_MOTOR         10
#define MAX_SPEED       200
#define SET_SPEED       150
#define MIN_SPEED       135
#define MIDDLE_IR       A1
#define TAPE_THRESHOLD  350   // Anything less is a Black reflectance

void setup() {
  // Intialize pins
  pinMode(MIDDLE_IR, INPUT);
}

void loop() {
  
  if (analogRead(MIDDLE_IR) < TAPE_THRESHOLD) {
    // We are seeing the line under the middle sensor
    analogWrite(L_MOTOR, SET_SPEED);
    analogWrite(R_MOTOR, MAX_SPEED);
    
  } else {
    // Drive slightly right to hug the line
    analogWrite(L_MOTOR, SET_SPEED);
    analogWrite(R_MOTOR, MIN_SPEED);
  }
}

两个传感器

循迹两条传感器线的一般思路是,当一个传感器看到线时,您会减慢或停止看到线的传感器另一侧的电机。传感器协同工作,使机器人保持在轨道上。如果您使用这种方法,请尝试将传感器靠得很近,传感器越近,机器人在驾驶时晃动就越小,这将使您获得更直接的驾驶外观并浪费更少的时间,因为您在调整之前与目标的距离更短。
two_sensor_line_follow_path

优点

  • 简单的电路
  • 易于编程

缺点

  • 如果您丢失了线路,则可能很难恢复
  • 时间浪费在左右旅行上
  • 不适合高速
示例代码
#define L_MOTOR         9
#define R_MOTOR         10
#define MAX_SPEED       250
#define SET_SPEED       200
#define MIN_SPEED       50
#define LEFT_IR         A0
#define RIGHT_IR        A2
#define TAPE_THRESHOLD  350   // Anything less is a Black reflectance

void setup() {
  // Intialize pins
  pinMode(LEFT_IR, INPUT);
  pinMode(RIGHT_IR, INPUT);
}

void loop() {
  
  if (analogRead(LEFT_IR) < TAPE_THRESHOLD) {
    // We are seeing the line under the left sensor, turn left
    analogWrite(L_MOTOR, MIN_SPEED);
    analogWrite(R_MOTOR, SET_SPEED);

  } else if (analogRead(RIGHT_IR) < TAPE_THRESHOLD) {
    // We are seeing the line under the right sensor, turn right
    analogWrite(L_MOTOR, SET_SPEED);
    analogWrite(R_MOTOR, MIN_SPEED);
    
  }
}

三个或更多传感器

以下三个传感器系列背后的想法是,它比两个传感器更加灵敏。通常,您将第三个传感器放在中间,除了像使用两个传感器循迹器一样进行调整外,还可以添加第三个甚至第四个情况。第三种情况是,如果线路位于中间传感器下方,请将两个电机设置为相同的速度以保持直线路径。可选的第四种情况是,如果没有传感器看到线路,则关闭电机或旋转直到再次找到线路。

此外,如果添加更多传感器,则可以添加调整层。假设您有四个传感器,如果最左边的传感器看到线,那么您可以关闭右侧电机,而如果左边的第二个传感器看到线,您可以简单地减慢右电机的速度,这样它会对尖角做出更突然的反应,或者如果由于某种原因它远离生产线。

优点

  • 最稳健的简单循迹方法
  • 能够检测线路是否丢失
  • 渐进调整与严格的开/关或高/低速
  • 易于编程

缺点

  • 仍然不是对误差的真正模拟响应(机器人在循迹线路时经常抖动)
  • 不适合高速
示例代码
#define L_MOTOR         9
#define R_MOTOR         10
#define MAX_SPEED       200
#define SET_SPEED       200
#define MIN_SPEED       50
#define STOP_SPEED      0
#define LEFT_IR         A0
#define MIDDLE_IR       A1
#define RIGHT_IR        A2
#define TAPE_THRESHOLD  350   // Anything less is a Black reflectance

void setup() {
  // Intialize pins
  pinMode(LEFT_IR, INPUT);
  pinMode(MIDDLE_IR, INPUT);
  pinMode(RIGHT_IR, INPUT);
}

void loop() {
  
  if (analogRead(LEFT_IR) < TAPE_THRESHOLD) {
    // We are seeing the line under the left sensor, turn left
    analogWrite(L_MOTOR, MIN_SPEED);
    analogWrite(R_MOTOR, SET_SPEED);

  } else if (analogRead(MIDDLE_IR) < TAPE_THRESHOLD) {
    // We are seeing the line under the middle sensor, go straight
    analogWrite(L_MOTOR, SET_SPEED);
    analogWrite(R_MOTOR, SET_SPEED);
    
  } else if (analogRead(RIGHT_IR) < TAPE_THRESHOLD) {
    // We are seeing the line under the right sensor, turn right
    analogWrite(L_MOTOR, SET_SPEED);
    analogWrite(R_MOTOR, MIN_SPEED);
    
  } else {
    // We don't see the line at all, let's stop
    analogWrite(L_MOTOR, STOP_SPEED);
    analogWrite(R_MOTOR, STOP_SPEED);
  }
}

PID 循迹

现在让我们介绍一个稍微复杂但更准确的行跟踪算法,PID 行跟踪。我注意到许多初学者对 PID 线跟踪的复杂性望而却步,并倾向于依靠库来进行 PID 计算。我建议你从你自己的简单PID算法开始,这样你就会明白发生了什么。当然,你可以侥幸使用PID库,但你并没有真正了解它是如何工作的,所以很难微调你的值并确切地知道这将如何影响结果。

优点

  • 非常流畅和准确的线路循迹
  • 通常可以比“简单”方法更快地遵循该线
  • 如果您想沿着不同的位置循迹,则具有更大的灵活性(循迹中心,稍微向左,稍微向右)

缺点

  • 需要调整,这可能需要一些时间
  • 如果没有指导,可能会显得难以理解(希望本文能解决这个问题)
  • 更多的传感器将需要更多时间来捕获读数

什么是 PID?

首先,让我们讨论一下PID是什么。PID是比例、积分、导数的首字母缩写,但不要让它吓到你,它很容易,并且不需要微积分。PID背后的想法是你有一个实际值和一个目标值或一个设定值。您可以根据目标和实际值之间的差异对系统进行一些调整。

P

该调整的第一个方面是 P,它只是一个系数…也就是说,这是一个数字,您将误差乘以该数字,然后将其作为调整应用。假设您正在驾驶汽车,并且试图保持 55 英里/小时的恒定速度,如果您阅读车速表并看到它目前是 55,您知道低了5 英里/小时,所以您需要踩下油门才能将速度恢复。假设您每秒检查一次车速表并进行调整,很可能会慢慢松开油门。因此,对于 P 值,我们需要确定一个值来将我们的距离转换为我们需要调整油门的程度。

例如,假设一英寸的油门运动通常会在一秒钟内将速度提高一英里/小时。好吧,做一些简单的数学运算,我们可以为此想出一个非常简单的算法。如果我们将误差乘以 MPH(英里/小时),则 P 值为 1。

adjustment = P*error

adjustment = 1*error

瞧,如果速度低于 6 英里/小时,我们的调整将是 (16) 或 6英寸,如果是 12 英里/小时,(112) 或 12 英寸来移动油门。同样,如果它超过 8 英里/小时,我们将调整8英寸。关键是,现在我们有一个基于一些知识的调整,就我们的电机而言,如果机器人只是稍微小点,我们会进行较小的调整。

任何曾经驾驶过车辆的人都知道,您移动油门的距离与一秒钟内增加的速度之间没有线性关系。这就是PID的其他元素发挥作用的地方。

I

我有一个警告是,我通常不会在行追随者中使用这个术语。I 术语是初学者使用的最复杂的术语,因此除非您有经验,否则我会在这里使用库。但同样,我通常不使用 i,所以我会向您展示一个不使用这个术语但仍然为您提供出色循迹的示例。

P值很好,但你看它不是一个完美的系统吗?事实是,当车辆行驶较慢时,您的加速度将与行驶速度较快时不同。此外,如果你的脚在一个 6 英寸油门上,当你遇到山坡时会发生什么,同样的油门位置不会保持你的速度,这就是 I 术语将发挥作用的地方。关于 I 术语的事情是它跟踪您的误差并考虑外部因素。如果你的P值似乎没有以适当的速度进行适当的改变,那么I项将慢慢增长,迫使你的调整更大,因为它将每个误差相加并将其应用于你的调整。因此,PI 控制器算法如下所示:

adjustment = P*error + I*sumOfErrors

其中,总和误差是每次计算调整时误差的累加。所以,回到我提到的上坡问题,如果你能够在不移动油门的情况下巡航,那么你爬上了一座小山,你的实际速度与你的目标将会增长一个误差,每次你有一个误差,你的 I 术语会告诉你在油门上踩更多,直到最终你加快速度。一旦你到达山顶,你现在已经增加了更多的油门,但山已经消失了,你需要开始释放油门,一般来说,这时 I 项会尝试恢复平稳,你超过目标,所以你的误差将是负的,从而从你的 I 值的总和中减去。I 的问题是您需要知道何时重置它或可能让它自行解决。这是我不使用 I 的主要原因,初学者很难掌握,它会极大地影响您的结果,而不会在循迹机器人的情况下真正提供太多好处。

对于循迹线的机器人,I 项非常有用的部分是,如果您的电机出现故障,因此您的机器人不断向一侧行驶。你的 I 项是将所有误差相加,最终该总和将稳定到一个点,它将弥补那个弱电机并不断在该方向上应用额外的调整。

D

比例控制算法本身就很棒,除了不稳定,它永远不会很好地达到目标值。这是因为它只是一个应用于误差范围的简单系数,而事实上,我们希望该系数在我们达到目标时可能会降低自己的效率。这就是 D 值的用武之地,D 值计算上一个误差和当前误差之间的差值。因此,例如,如果第一个读数误差 5,而新读数是误差 1,则导数调整将是 D 系数乘以误差差 (1-5) 或 -4。如果我们将 D 项添加到 PI 控制器,它将如下所示:

adjustment = P*error + I*sumOfErrors + D*(error – lastError)

或者,如果我们只是有一个PD控制算法

adjustment = P*error + D*(lastError – error)

因此,如果我们尝试分析PD所示的计算,我们可以看到我们的P部分,正如我们已经知道的那样,根据误差量应用乘法因子。但是,D 值将乘法因子应用于误差的差,那么这意味着什么?当我们接近目标时,我们的 D 值将抑制 P 的效果,因此我们不会超过目标。如果您注意到,我们的示例具有负值,因此当我们接近误差 0 时,这将有效地减少调整。

line_with_errors

你也可以这样想,如果误差在增长,那么P做得不够好,在这种情况下,新误差会大于旧误差,因为我们正在远离目标。较大的数字减去较小的数字将导致一个正值,该值将添加到P部分以帮助回到正轨。另一方面,如果我们正确地接近目标,我们将有一个比前一个误差小的当前误差,这将从 P 部分减去以确保我们不会超过我们的目标。请参阅右侧的图像,以更好地了解与线条相关的误差。

PID循迹算法

现在我们已经对PID是什么以及它是如何工作的有了基本的了解,让我们回到讨论如何在循迹机器人中实现这一点。

流程图

让我们首先浏览一个流程图,该流程图涵盖了PID线跟踪的基本方面。希望流程图能帮助您理解与代码相关的算法,如果您通过阅读代码本身来更好地理解代码,那么我在流程图之后有一些示例代码。

img

示例代码

这里需要提前提几件事,这段代码是基于Pololu QTR-8RC传感器阵列的使用。您可以轻松地为 QTR-8A 阵列修改它,甚至可以与单个 QTR-1RC 或 QTR-1A 红外传感器一起使用,我在 PID 线路循迹器上使用过多达四个红外传感器,并取得了巨大的成功。 只需调整传递到 QTRSensorsRC 对象的NUM_SENSORS和引脚编号。此外,如果你有不同数量的传感器,如果你想循迹中心,你的目标会有所不同。要计算中心,请使用以下算法:(NUM_SENSORS – 1)*500。当然,您不必循迹中心,您可以循迹传感器范围内的任何地方。

您需要拥有 QTR 传感器库,该库可在此处找到,该链接是指向我个人版本的库的指针。我发现了一个误差,我建议他们修复,但他们还没有,它可能会导致一些古怪的值,所以我建议你使用我修改后的库和修复。

readLine(sensorValues) 函数返回一个介于 0 和(NUM_SENSORS – 1)*1000之间的值。如果您有 8 个传感器,读数将为 0-7000,6 个传感器将为 0-5000。在每种情况下,0 表示最左侧的传感器,之后的每个增量 1000 表示另一个传感器。0 == 第一个传感器,1000 == 第二个传感器,两者之间也有范围。500 表示线位于第一个和第二个传感器之间,1200 表示它在第二个和第三个传感器之间,但更接近第二个传感器…你的想法对吗?

最后,我的 KP 和 KD 值很可能不适用于您的机器人,因为每个机器人都是不同的。这些值取决于电机速度、机器人重量、车轮尺寸、传感器相对于车轮的位置等。

#include <QTRSensors.h>

#define SETPOINT    3500  // The goal for readLine (center)
#define KP          0.2   // The P value in PID
#define KD          1     // The D value in PID
#define L_MOTOR     9     // Left motor pin
#define R_MOTOR     10    // Right motor pin
#define MAX_SPEED   200   // The max speed to set motors to
#define SET_SPEED   200   // The goal speed to set motors to
#define MIN_SPEED   0     // The min speed to set motors to
#define NUM_SENSORS 8     // The number of QTR sensors
#define TIMEOUT     2500  // Timeout for the QTR sensors to go low
#define EMITTER_PIN 2     // Emitter pin for QTR sensor emitters

// PID **************************************
int lastError = 0;  // For storing PID error

// SENSORS **********************************
// sensors 0 through 7 are connected to digital pins 3 through 10, respectively
QTRSensorsRC qtrSensors((unsigned char[]) {3, 4, 5, 6, 7, 8, 9, 10}, NUM_SENSORS, TIMEOUT, EMITTER_PIN);
unsigned int sensorValues[NUM_SENSORS];   // For sensor values of readLine()

void setup() {
  // Initialize Pins
  pinMode(L_MOTOR, OUTPUT);
  pinMode(R_MOTOR, OUTPUT);
}

void loop() {
  // Take a reading
  unsigned int linePos = qtrSensors.readLine(sensorValues);

  // Compute the error
  int error = SETPOINT - linePos;

  // Compute the motor adjustment
  int adjust = error*KP + KD*(error - lastError);

  // Record the current error for the next iteration
  lastError = error;

  // Adjust motors, one negatively and one positively
  analogWrite(L_MOTOR, constrain(SET_SPEED - adjust, MIN_SPEED, MAX_SPEED));
  analogWrite(R_MOTOR, constrain(SET_SPEED + adjust, MIN_SPEED, MAX_SPEED));
}
PID 调谐

调整 PD 控制算法的 P 和 D 值不在本文的讨论范围之内。如前所述,这些KP和KD值可能不适用于您的机器人,因为每个机器人都是不同的。PID调谐是算法的一个重要方面,每个机器人都需要根据特定于该机器人的一系列参数进行调整。我将在未来几天内包括一篇文章,并在准备好时提供一个链接。作为该文章发布之前的提示,将 KD 设置为 0(这将只为您提供一个 P 控制器)并尝试获取遵循该行的 KP 值,在 KP 工作之前不要担心 KD。此外,尝试将电机设置为所需速度的至少一半进行调谐,除非您的全速已经很慢,否则很难全速调谐。

更新:PID调谐文章可以在这里找到:http://robotresearchlab.com/2019/02/16/pid-line-follower-tuning/

PID 线路跟随器整定

PID Line Follower Tuning (robotresearchlab.com)

本文是我之前关于如何对线路跟随机器人进行编程的文章的延续,将介绍 PID 循迹机器人调整。本文假设您了解什么是 PID 以及如何实现 PID 或 PD 控制环路。有一些参考(例如目标和设定值)特定于您使用 Pololu 的 QTRSensors 库获得的值,您不必使用它们的传感器,只需使用本文中所做的一些参考的库。让我们学习如何调整PID循迹机器人!

建立

仅使用 P

要调整 PID 或 PI 和 D 的任意组合,我总是从调整 P 本身开始。比例值对正确巡线的贡献最大,因此正确获取此值非常重要。如果你包含了I或D,你不知道你的P是导致了问题还是其他原因,所以消除其他两个,只考虑比例或KP值。

速度

我看到的最大错误之一是人们试图以他们的全部预期速度进行调整。全速调整 PID 非常困难。我总是建议将速度降低到至少预期的全速的 50%,除非您的全速已经很慢了。在提高速度时,您可能需要调整 PID 值,但使用已经不错的值全速调谐比使用已经不错的全速值调谐要容易得多。此外,更快的速度会带来其他问题,这可能会使调谐变得困难,其中一个问题是牵引力。如果您不能确定自己是否获得了全部牵引力,那么您就不能将 KP 值作为调整问题的全部影响因素。我全速调谐有几个原因,PID 值的效果以更快的速度显示得更多(这就是我建议放慢速度的原因)。另一个原因是因为我的机器人一开始不是很快。

我想在这里说明的另一个注意事项是,我的速度是 0 到 100,因为我使用的是我编写的库,该库适用于一些常见的电机驱动器,并使用 0 到 100 的“功率”范围。如果我不使用库,我可能会有一个 0 到 255 的范围,这是完整的 PWM 范围。

我的初始速度是 100% (100)

确定起点

了解传感器范围

array_readline_values

所以,我得到的最大问题是,如何选择 KP 的起始值?我的方法非常简单,只涉及一些基本的数学。QTRSensors 库中的 readLine() 函数返回一个介于 0 和 1000*(NUM_SENSORS – 1)之间的值因此,对于我的机器人,我有八个传感器,因此我的readLine()结果将在0到1000*(8-1)或7000之间。以图像为例,0 表示线位于最左侧的传感器下方,1000 表示线位于第二个传感器下方,依此类推,直到第八个传感器的值为 7000。readLine() 函数的美妙之处在于它提供了一个“模拟”范围,它可以有 1200 的值,这意味着它在第二个传感器下方,但略微靠近第三个传感器。它可能的值为 3538,这意味着它大致位于第四和第五个传感器的中间。

我的范围是 0 到 7000

确定目标

现在您了解了来自 readLine() 的值,如果我想关注中心,那么我的目标将是 MAX_VALUE/2 或 7000/2 或 3500。这应该是有道理的,因为我有八个传感器,我想在第四个和第五个传感器之间跟踪以跟随中心,第四个和第五个传感器之间的readLine()值将是 3500。这里只是注意,我不必跟随中心,如果线旁边有障碍物,我可以沿着中心的左侧或右侧通过这个障碍物,这是PID的另一个美妙之处,很容易改变你的目标。

我的目标是 3500

确定您的初始 KP

array_motor_speeds

最后,我们可以为我们的 KP 值找到一个很好的起点。我所做的是计算我能得到的最高误差,并找到将最大误差转换为等于我的速度的值的系数。为了澄清这一点,这里有一些更基本的数学。 假设我偏离了右边的线,我能得到的最远是 readLine() 返回 0 的点,因为这是最左边的传感器会看到这条线的时候。因此,我的目标 (3500) 减去此最大误差是 3500 – 0 或 3500。同样的事情是另一个方向,如果我向左漂移,我能得到的最远的地方是readLine()返回 7000 的点,因为这是最右边的传感器会看到这条线的时候。因此,我的目标减去此最大值是 3500 – 7000 或 -3500。在任何一种情况下,我的最大误差都是 3500 的值(忽略负数)。

现在,如果我的电机速度是 100(如 100%),我会想出一个值将 3500 转换为 100。为了让您理解原因,请在阅读下一句时查看图像。当最左边的传感器或最右边的传感器看到这条线时,我的调整(KP*error)将变为100,因此,如果机器人离得那么远,请关闭电机,因为我们将从一个电机中减去该调整并将其添加到另一个电机中。为了确定起始 KP 值,我的基本数学如下。

  1. MAX_SPEED = MAX_ERROR * KP
  2. 填写我们的已知值
  3. 100 = 3500 * KP
  4. 为了解决 KP,我们将 3500 移到另一侧并得到
  5. 100 / 3500 = KP

我的 KP 是 0.028

最后一点,我通常只去千分之一的地方,有时只去百分之一的地方,但在这种情况下,我想要粒度,所以我将使用完整的 0.028

让我们开始调整吧!

进入本节,您应该了解以下信息

  • 您的传感器系列
  • 您的目标位置(设定值)
  • 您的电机速度为 50% 或更低
  • 从上面计算出的 KP

将我的信息放入代码中(您可以在本文中找到示例)后,让我们看看我的第一次运行情况如何。请记住,我们至少需要两次试运行,然后才能开始就如何调整 KP 做出任何决定。

试用 1

试验一的初始 KP 值为 0.028

KP 0.028
KD 0.0
MAX_SPEED 100
MIN_SPEED 0
SET_SPEED 100
分析

p_just_right

我对我的机器人仅使用初始KP值跟踪线的准确性感到非常惊讶。很可能是因为我习惯于使用较重的机器人,因此它们不像这个轻便的小机器人那样响应迅速。在这一点上,我们没有什么可判断的,所以我喜欢越来越低,以确定 KP 值应该朝哪个最终方向发展。我们的目标 KP 将为我们提供一条循迹模式,看起来像您在此处看到的图像。路径应以紧密的模式保持在线路上的路线并保持一致。

进入试用2…

试用 2

首先,我喜欢贬值,看看会发生什么。通过将KP降低到0.018,电机不会关闭,直到我们达到~5500的误差,但由于我们的最大误差是3500,这意味着我们永远不会达到电机关闭的点。我们将进行的最大调整是 3500*0.018=63,因此我们的电机在此 KP 下永远不会低于 47 的值。

KP 0.018
KD 0.0
MAX_SPEED 100
MIN_SPEED 0
SET_SPEED 100
分析

p_too_low

正如你看到的,较低的KP增加了循迹中的摇摆量,这并不好,我们想要一些比我们的初始值更激进的东西。另一件需要注意的事情是,我不得不添加另一块“轨道”,因为较低的 KP 允许我的机器人离开线路太多,如果我不这样做,它就会跑出轨道。低 PD 值会给你一个像你在图像中看到的模式,它可能一致也可能不一致,但更重要的是,它不能很好地遵循这条线。一旦你到达一个转弯处,KP太低的机器人可能会完全错过转弯,永远无法回到线路上。

试用 3

现在,我将在另一个方向上与初始值保持相同的距离。通过查看试用 1 和试用 2,我应该期望这个 KP 会更紧地遵循,但它会不会太高 KP?

KP 0.038
KD 0.0
MAX_SPEED 100
MIN_SPEED 0
SET_SPEED 100
分析

虽然在视频中可能不那么明显,但这比我的初始值更具侵略性。这不会超过好的线,所以我认为这就是我要使用的值。如果我只是使用 KP,我可能会坚持使用我最初的 0.028 值,但由于我要添加一个 KD,我希望它更激进一点,因为 KD 值会稍微柔和一点。

试用 4

如果不包含值过高的示例,操作方法文章将是不完整的。

KP 0.8
KD 0.0
MAX_SPEED 100
MIN_SPEED 0
SET_SPEED 100
分析

p_too_high

如您所见,机器人正在左右超调(没有双关语)。我无法获得足够高的KP来向您展示这个机器人,但是对于较重的机器人,KP太高而无法在短时间内跟随并且最终变得如此不稳定以至于完全脱离线是很常见的。这是知道您的 KP 太高的一种方法,看看图像,它显示了您在 KP 太高时看到的可能模式。

试用 5

一般来说,KD 值的良好起点是 KP 值的 10-20 倍。所以,我从十倍于我的 KP 值的 KD 开始。

KP 0.038
KD 0.38
MAX_SPEED 100
MIN_SPEED 0
SET_SPEED 100
分析

这对 KD 来说是一个相当不错的价值,我什至可能倾向于停在这里,但我确实注意到当机器人撞到转弯时会有一点延迟响应,我知道增加我的 KD 将有助于解决这个问题。

试用 6

KP 0.038
KD 0.76
MAX_SPEED 100
MIN_SPEED 0
SET_SPEED 100
分析

我不认为我会比这更好,为了这个机器人的目的,我不需要。你可能想花更多的时间来微调你的机器人,其中很多将归结为你行进的速度和你的轨道是什么样子的。对于急转弯的赛道,您需要比平稳转弯的赛道调整更多。

试用 7

与高 KP 一样,如果没有过高的 KD 示例,操作方法文章将是不完整的。

KP 0.038
KD 2.76
MAX_SPEED 100
MIN_SPEED 0
SET_SPEED 100
分析

可能并不完全明显,但机器人已经开始再次振荡,就像它在高KP时所做的那样,以至于它增加了半秒的单圈时间。这似乎不多,但如果你正在与你的机器人比赛,这可能是第一和第二之间的区别。

这是一个要显示的例子,如果你同时调整两个数字,很难知道哪个是坏的。由于我已经单独调整了我的 KP,我知道罪魁祸首是我的 KD 值。

结语

最后我想介绍一些内容,因为了解影响PID算法的最常见方面非常重要。请留意以下内容。

  • 牵引力 – 如果您没有良好的牵引力,您的 KP 将永远不会允许您遵循这条线。
  • 速度 – 如果您走得太快,尤其是在赛道上转弯时,将很难调整初始值,这与处理器速度低于
  • 传感器位置 – 如果传感器离车轮较远,则可能需要更高的 KP,因为与变化点(支点)的距离更远,因此会产生更大的影响。
  • 处理器速度 – 是的,这可以产生巨大的差异。如果您的处理速度较慢且机器人速度快,则采样率将非常低。例如,如果您以 3 英尺/秒的速度行驶并且能够每秒进行调整 50 次,那么您每 3/4 英寸读取一次线路,这还不错。但是,如果你的处理器速度很慢,或者你的程序中有很多其他事情发生,并且你每秒只更新 10 次,你每 3.6 英寸读取一次行,这意味着你可能在意识到之前离线 3.6 英寸。调整 PID 时,尽量将代码限制为仅 PID 代码,也避免打印语句。

猜你喜欢

转载自blog.csdn.net/acktomas/article/details/130356508