ПД-регулятор

В этом уроке

  • Д-регулятор и за что он отвечает
  • Настройка регулятора
  • Управление машинкой с помощью ПД-регулятора

Видео версия урока

Общие сведения о ПД-регуляторе:

В прошлом уроке мы разобрались с работой П-регулятора.

Пропорциональный регулятор возвращает результат, который
пропорционален текущему значению ошибки.

Это достигается простым умножением текущей ошибки на коэффициент kP.
P = ОШИБКА * kP

П-регулятор указывает машине повернуть в сторону линии. Чем дальше линия от центра бампера, тем сильнее ошибка отличается от 0, и тем круче поворот машины.

Недостатком П-регулятора является то, что он не может работать на больших скоростях.

Для борьбы с указанным недостатком в одном регуляторе совмещают пропорциональную (П) и дифференциальную (Д) составляющую, — получается ПД-регулятор.

Дифференциальная составляющая (от лат. differentia – разность) — это разность между текущей и предыдущей ошибкой.

Дифференциальный регулятор возвращает результат, который
зависит от скорости изменения текущей ошибки.

Это достигается умножением разности ошибок на коэффициент kD.
D = (ОШИБКА – предыдущая ОШИБКА) * кD

Ошибки для Д-регулятора берутся через одинаковые интервалы времени, значит, разность между текущей и предыдущей ошибкой является скоростью изменения ошибки.

Чем выше скорость изменения ошибки, тем сильнее влияние Д-регулятора.

Д-регулятор выполняет сразу две задачи: он помогает П-регулятору справиться с резкими поворотами и превращает крутой въезд на линию в более пологий.

ПД-регулятор возвращает результат, который
является суммой пропорциональной и дифференциальной составляющих.
PD = P + D

Поведение составляющих ПД-регулятора:

Следующая картинка показывает, как ведут себя П-регулятор и Д-регулятор, если бампер движется по линии змейкой (МОТОРЫ НЕ ПОДКЛЮЧЕНЫ):

  • Оранжевым цветом отражена текущая ошибка, возвращаемая бампером;
  • Зелёным цветом отражено воздействие П-регулятора;
  • Синим цветом отражено воздействие Д-регулятора.

(Картинка кликабельна)

Видно, что пик активности одного регулятора совпадает с бездействием другого.

Изначально, когда бампер возвращает ошибку 4.0 (значит, линия находится под крайним правым датчиком), П-регулятор указывает максимально круто повернуть вправо (в сторону линии). В это время Д-регулятор не проявляет никакой активности. По мере приближения линии к центру бампера (ошибка приближается к 0.0), П-регулятор снижает свою активность, выравнивая скорости моторов, а Д-регулятор до пересечения центра бампера с линией указывает повернуть влево, чтобы не переехать линию, а въехать на неё под пологим углом.

Если подключить моторы, то ПД-регулятор отработает следующим образом:

Код ПД-регулятора:

i  = bum.getErrPID(); // Получаем текущую ошибку
P  = i * kP;          // Определяем пропорциональную составляющую регулятора
D  = (i-j) * kD;      // Определяем дифференциальную составляющую регулятора
PD = P + D;           // Получаем результат ПД-регулятора
j  = i;               // Сохраняем текущую ошибку «i», как предыдущую «j», для следующего прохода по коду

Настройка ПД-регулятора:

  • Настройка ПД-регулятора сводится к поиску коэффициентов для пропорциональной и дифференциальной составляющих;
  • Назначение коэффициента П-регулятора kP описано в статье П-регулятор;
  • Как уже было сказано ранее, задача Д-регулятора — получить разность ошибок и выдать число, на которое должны отличаться скорости колёс;
  • Если Д-регулятор просто вернёт значение разности ошибок, этого может быть либо недостаточно для манёвра, либо слишком много;
  • Поэтому Д-регулятор умножает разность ошибок на некий коэффициент kD.
    Код Д-регулятора умещается в три строки: i = bum.getErrPID(); D = (i-j)*kD; j=i;,
    где i — текущая ошибка, j — предыдущая ошибка, D — результат.
  • Подбор коэффициентов:
    • Если kP=0, то ПД-регулятор будет работать как Д-регулятор;
    • Если kD=0, то ПД-регулятор будет работать как П-регулятор;
    • Сначала подбирается коэффициент kP для П-регулятора при kD=0. Значение kP должно быть таким, чтобы бампер машины не покидал линию трассы на всех её поворотах. Или был как можно ближе к линии на поворотах. При этом машина может "вилять" на прямых участках трассы — это нормально;
    • Оставляем найденный kP и подбираем kD для дифференциальной составляющей;
    • Постепенно увеличиваем kD. При этом машина будет всё меньше "вилять" на прямых участках трассы и лучше проходить крутые повороты;
    • Слишком высокий коэффициент приведёт к тому, что машина начнёт "дрожать" на прямой линии. Это называется перерегулированием;
    • Слишком низкий коэффициент не избавит от "виляний" машины на прямых участках трассы и не улучшит прохождение крутых поворотов. Это называется недорегулированием;
    • Оптимальным является коэффициент, при котором бампер машины не покидает линию на всех поворотах трассы, при этом машина не "виляет" и не "дрожит" на прямых участках.
  • Коэффициенты kP и kD являются константами, только если машина движется с одной скоростью.

Коэффициент регулятора определяет силу воздействия регулятора.

Чем больше коэффициент, тем сильнее меняется выходная величина.

Скетч для одной скорости:

Скорость колёс в скетче задаётся функцией setSpeed() в процентах.
Выберем скорость машины, равную 60%. Именно эту скорость мы и указываем обоим колёсам.
Предположим, что при kD = 0 и kP = 8 машина не покидает повороты трассы.
Предположим, что при kD = 14.4 и kP = 8 машина перестала "вилять" на прямых участках.

#include <Wire.h>                         // Подключаем библиотеку для работы с аппаратной шиной I2C
#include <iarduino_I2C_Motor.h>           // Подключаем библиотеку для работы с мотором  I2C-flash
#include <iarduino_I2C_Bumper.h>          // Подключаем библиотеку для работы с бампером I2C-flash
                                          //
iarduino_I2C_Motor mot_R (0x0A);          // Объявляем объект mot_R для правого мотора, указав адрес модуля на шине I2C
iarduino_I2C_Motor mot_L (0x0B);          // Объявляем объект mot_L для правого мотора, указав адрес модуля на шине I2C
iarduino_I2C_Bumper bum(0x0C);            // Объявляем объект bum  для работы с бампером I2C-flash, указав адрес модуля на шине I2C
                                          //
float i, j;                               // Переменные для хранения ошибок
float speed = 60;                         // Скорость машины в %
float kP    = 8;                          // Коэффициент пропорциональной составляющей
float kD    = 14.4;                       // Коэффициент дифференциальной составляющей
                                          //
void setup(){                             //
     mot_R.begin();                       // Инициируем работу с левым  мотором I2C-flash
     mot_L.begin();                       // Инициируем работу с правым мотором I2C-flash
     bum.begin();                         // Инициируем работу с бампером I2C-flash
     mot_R.setDirection(true);            // Указываем правому мотору, что его вращение должно быть прямым (по часовой стрелке при положительных скоростях)
     mot_L.setDirection(false);           // Указываем левому мотору, что его вращение должно быть обратным (против часовой стрелки при положительных скоростях)
}                                         //
                                          //
void loop(){                              //
           i  = bum.getErrPID();          // Получаем текущую ошибку центрирования линии
     float P  =  i    * kP;               // Вычисляем пропорциональную составляющую
     float D  = (i-j) * kD;               // Вычисляем дифференциальную составляющую
     float PD = P+D;                      // Получаем значение от ПД-регулятора
     mot_R.setSpeed(speed - PD, MOT_PWM);  // Устанавливаем скорость правого мотора
     mot_L.setSpeed(speed + PD, MOT_PWM);  // Устанавливаем скорость левого мотора
}

Дополнительное задание.

Попробуйте изменить коэффициент Д-регулятора kD и посмотрите на результат.

Скетч для диапазона скоростей:

В предыдущем скетче коэффициенты для пропорциональной и дифференциальной составляющих ПД-регулятора были найдены для скорости 60%. Если уменьшить скорость движения машины speed с 60% до 30%, то найденные ранее коэффициенты будут слишком велики, и мы получим перерегулирование.

Выход из положения — найти kP и kD для минимальной и максимальной скоростей машины, после чего вывести формулы зависимости коэффициентов от скорости. Как это сделать для коэффициента пропорциональной составляющей, описано в статье П-регулятор. Но стоит учитывать, что kP имеет более линейную зависимость от скорости speed, чем kD. В нашем примере коэффициент дифференциальной составляющей kD имеет прямую зависимость от квадрата скорости speed, для других систем зависимость будет иной.

Теперь можно написать скетч, у которого скорость можно менять от 20 до 60%:

#include <Wire.h>                         // Подключаем библиотеку для работы с аппаратной шиной I2C
#include <iarduino_I2C_Motor.h>           // Подключаем библиотеку для работы с мотором I2C-flash
#include <iarduino_I2C_Bumper.h>          // Подключаем библиотеку для работы с бампером I2C-flash
                                          //
iarduino_I2C_Motor mot_R (0x0A);          // Объявляем объект mot_R для правого мотора, указав адрес модуля на шине I2C
iarduino_I2C_Motor mot_L (0x0B);          // Объявляем объект mot_L для правого мотора, указав адрес модуля на шине I2C
iarduino_I2C_Bumper bum(0x0C);            // Объявляем объект bum  для работы с бампером I2C-flash, указав адрес модуля на шине I2C
                                          //
float i, j;                               // Переменные для хранения ошибок
float speed = 60;                         // Скорость машины в %
float kP    = 3 + 0.125*(speed-20);       // Коэффициент пропорциональной составляющей
float kD    = speed*speed/250;            // Коэффициент дифференциальной составляющей
                                          //
void setup(){                             //
     mot_R.begin();                       // Инициируем работу с левым  мотором I2C-flash
     mot_L.begin();                       // Инициируем работу с правым мотором I2C-flash
     bum.begin();                         // Инициируем работу с бампером I2C-flash
     mot_R.setDirection(true);            // Указываем правому мотору, что его вращение должно быть прямым (по часовой стрелке при положительных скоростях)
     mot_L.setDirection(false);           // Указываем левому мотору, что его вращение должно быть обратным (против часовой стрелки при положительных скоростях)
}                                         //
                                          //
void loop(){                              //
           i  = bum.getErrPID();          // Получаем текущую ошибку центрирования линии
     float P  =  i    * kP;               // Вычисляем пропорциональную составляющую
     float D  = (i-j) * kD;               // Вычисляем дифференциальную составляющую
     float PD = P+D;                      // Получаем значение от ПД-регулятора
     mot_R.setSpeed(speed - PD, MOT_PWM);  // Устанавливаем скорость правого мотора
     mot_L.setSpeed(speed + PD, MOT_PWM);  // Устанавливаем скорость левого мотора
}

Этот скетч отличается от предыдущего только тем, что значения kP и kD определены не числами, а формулами.

При изменении значения скорости speed в пределах от 20% до 60%, будут автоматически пересчитываться коэффициенты kP и kD, и машина продолжит корректно двигаться по линии.

Теперь наша машинка может ездить, в том числе, и на высокой скорости.

Недостаток ПД-регулятора:

При движении по прямой линии ПД-регулятор не способен корректировать слабые ошибки. Это выражается в незначительных отклонениях центра бампера от центра прямой линии.

При движении по кругу, дугам и поворотам П-регулятор оставляет незначительную ошибку. Это выражается в смещении центра бампера к внешнему краю линии.

  • Влияние П-регулятора тем сильнее, чем больше текущая ошибка;
  • Влияние Д-регулятора тем сильнее, чем выше скорость изменения текущей ошибки;
  • При движении машины по прямой линии, центр линии находится вблизи центра бампера; текущая ошибка слишком мала и слабо меняется, следовательно, ПД-регулятор не может её скорректировать;
  • На поворотах П-регулятору нужна ошибка, иначе он не сможет повернуть, поэтому центр бампера проходит ближе к внешней границе линии;
  • Д-регулятор не будет работать, если ошибки считываются слишком быстро, или с разными интервалами;
  • Д-регулятор подвержен "шумам", он резко реагирует на некорректные данные;
Поздравляю с изучением данного урока!
Следующий урок:
№22. ПИД-регулятор.
приступить к изучению

Продукт в магазине

«ROBORACE» — Образовательный набор на базе Arduino

В магазин

Обсуждение

Гарантии и возврат. Используя сайт, Вы соглашаетесь с условиями.