На самом деле, это всего лишь ПИ-регулятор!

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

Давайте рассмотрим простой пример управления с обратной связью с обратной связью, и вы поймете, где должен появиться ПИД-регулятор.

Обычный термостат в вашем доме имеет простой контроллер, чтобы поддерживать в доме желаемую температуру. Это может быть, а может и не быть ПИД-регулятор, потому что в этом нет необходимости. Скажем так, это простой регулятор без алгоритма ПИД-регулирования. Термостат имеет датчик температуры для измерения температуры в вашем доме. Летом вы, конечно же, захотите сохранять прохладу, и термостат может сделать это за вас. После включения вы устанавливаете комфортную температуру. Сначала он примет измеренную в помещении температуру и сравнит ее с той, которую вы только что установили — назовем эту уставку (SP) и измеряемую переменную измеренной температуры (MV).

В первые 10 минут вам и в голову не придет закатывать истерику из-за того, что термостат еще не работает. Это займет время. Итак, вы ждете.

Под белой коробкой на вашей стене он вычисляет разницу между MV и SP, а затем снова исправляет себя. Скажем, ваша SP составляет 20 градусов по Цельсию, а MV — 25. Потребуются годы, чтобы она достигла 20, если термостат выдает температуру 20, потому что должны быть возмущения, которые влияют на температуру в помещении, чтобы оставаться выше 20. Разумно, это принимает курс действий, чтобы свернуть его до 18, в надежде достичь 20 за 5 минут. И если он перепрыгнет и упадет до 18, он снова поднимет его до 22 в надежде достичь 20.

В некоторых домах термостат работает только путем включения и выключения, и это называется системой управления ВКЛ/ВЫКЛ (или системой управления Bang-Bang).

Это простая система управления с обратной связью. Он принимает разницу, корректирует себя, чтобы закрыть разницу, и повторяет этот шаг до тех пор, пока разница не станет равной нулю!

Однако это может быть не идеальным решением. Видите ли, если она колеблется между 18 и 22, хотя вы можете испытывать идеальные 20 градусов по Цельсию, это может создать проблемы для многих промышленных приложений, требующих точности.

Здесь на помощь приходит ПИД-регулятор.

Пропорциональная часть контроллера работает следующим образом: этот член зависит только от разницы между SP и MV — называется членом ошибки. Допустим, он определяет, что пропорциональный коэффициент усиления должен быть равен 1, а член ошибки равен -5, он понизит температуру на 5 градусов Цельсия, чтобы достичь 20. Помните, что здесь не учитывается время, необходимое для достижения 20. Поскольку член ошибки становится меньше, пропорциональное усиление также становится меньше. Это означает, что система может быть не в состоянии достичь SP, и в конце дня все еще есть некоторое смещение.

Не идеально.

А вот и неотъемлемая часть. Этот компонент в системе управления суммирует погрешность во времени. Чем дольше ошибка остается в системе с той же величиной, тем больше становится интегральный выход. Если ошибка не равна нулю, контроллер все равно будет выводить интегральную составляющую. Пока существует ошибка, неотъемлемый компонент системы будет предпринимать соответствующие действия, чтобы свести ошибку к нулю.

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

Введите производный компонент. Этот компонент вызывает снижение выходной температуры, если MV быстро меняется. Этот компонент обычно «предсказывает» будущее значение, принимая предыдущее значение MV. Чем быстрее изменяется ошибка, тем больше величина регулятора производной. Другими словами, по мере того, как мы приближаемся к нашему SP, скорость изменения ошибки становится меньше, и наш производный член будет уменьшаться по пути, достигая нашего конечного SP.

Объединение всех трех компонентов дает функциональную систему управления, которая может помочь нам эффективно и результативно управлять нашей бытовой техникой.

Но… как мы реализуем это в программном обеспечении? Проще говоря, алгоритм ПИД-регулирования служит только в качестве подхода, то, как мы его реализуем, полностью зависит от нас, и, конечно же, это выполнимо в программном обеспечении.

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

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

Давайте попробуем это на языке C.

Разбивая это более простыми словами:

P — разница между MV и SP

I — интеграл ошибки по времени

D — Скорость изменения ошибки

Если мы правильно запомним нашу передаточную функцию ПИД-регулятора, мы получим следующие окончательные функции:

* Отказ от ответственности: ссылка на код из репозитория git https://github.com/pms67/PID/blob/master

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

#ifndef PID_CONTROLLER_H
#define PID_CONTROLLER_H

typedef struct {

     /* Controller gains */
     float Kp;
     float Ki;
    
     /* Output limits */
     float minLimit;
     float maxLimit;
     
     /* Integrator limits */
     float integralMinLimit;
     float integralMaxLimit;
    
     /* Sample time (in seconds) */
     float T;
    
     /* Controller "memory" */
     float proportional;
     float integral;
     float prevError; 
     float prevMeasurement;  
    
     /* Controller output */
     float out;

} PIDController;

В файле C мы определяем несколько функций. Во-первых, функция инициализации, в которой определены наши структурные переменные.

void PIDController_vInit (PIDController *pid) {

     /* Reset controller variables */
     pid->integral = 0.0f;
     pid->prevError  = 0.0f;
    
     pid->prevMeasurement = 0.0f;
    
     pid->out = 0.0f;
    
}

Затем давайте напишем нашу функцию процесса ПИД-регулятора:

float PIDController_vProcess (PIDController *pid, float setpoint, float measurement)
{
    // Error
    float error = setpoint - measurement;

    // Proportional
    pid->proportional = pid->Kp * error;

    // Integral
    pid->integral = pid->integral + 0.5f * pid->Ki * pid->T * (error + pid->prevError);
    // Limit the integral output
    if (pid->integral > pid->integralMaxLimit)
    {
        pid->integral = pid->integralMaxLimit;
    }
    else if (pid->integral < pid->integralMinLimit)
    {
        pid->integral = pid->integralMinLimit;
    }

    // Compute the output
    pid->out = pid->proportional + pid->integral;
    // Limit the final output
    if (pid->out > pid->maxLimit)
    {
        pid->out = pid->maxLimit;
    }
    else if (pid->out < pid->minLimit)
    {
        pid->out = pid->minLimit;
    }

    // Store error and measurement for the next cycle
    pid->prevError = error;
    pid->prevMeasurement = measurement;

    return pid->out;
}

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

Теперь, если мы хотим протестировать этот контроллер, давайте создадим еще один скрипт для подачи входных данных.

/* Controller parameters */
#define KP 2.0f
#define KI 0.5f

#define MIN_LIMIT -10.0f
#define MAX_LIMIT 10.0f

#define INTEGRAL_MIN_LIMIT -5.0f
#define INTEGRAL_MAX_LIMIT 5.0f

#define SAMPLE_TIME 0.01f

/* Maximum run-time of simulation */
#define SIMULATION_TIME_MAX 4.0f

float TestSystem_fUpdate(float inp) 
{
    static float output = 0.0f;
    static const float alpha = 0.02f;

    output = (SAMPLE_TIME * inp + output) / (1.0f + alpha * SAMPLE_TIME);

    return output;
}


int main()
{
    /* Initialise PID controller */
    PIDController pid = { KP, KI, 
                          MIN_LIMIT, MAX_LIMIT, 
                          INTEGRAL_MIN_LIMIT, INTEGRAL_MAX_LIMIT,
                          SAMPLE_TIME };

    PIDController_vInit(&pid);

    /* Simulate response using test system */
    float setpoint = 1.0f;

    printf("Time \tPlant Output\tPIDControllerOutput\n");
    for (float t = 0.0f; t <= SIMULATION_TIME_MAX; t += SAMPLE_TIME) {

        /* Get measurement from system */
        float measurement = TestSystem_fUpdate(pid.out);

        /* Compute new control signal */
        PIDController_vProcess(&pid, setpoint, measurement);

        printf("%f\t%f\t%f\r\n", t, measurement, pid.out);

    }

    return 0;
}

Не стесняйтесь изменять параметры или уставку, чтобы увидеть, как изменится выходной сигнал. Если вы попытаетесь ввести числа и запустить код, вы получите таблицу значений, как показано ниже:

Как видите, наше время симуляции составляет 4 секунды, и по его окончании выход нашей системы очень близок к заданному значению 1f! В последнем столбце мы также можем увидеть, как выход нашего контроллера ведет себя с ошибкой.

Отсюда мы можем настроить все, что мы хотим, наши пропорциональные или интегральные усиления по своему вкусу и поиграть с этим контроллером. Будьте уверены, что это не настоящая машина или завод, так что вперед и ломайте вещи!

Надеюсь, я ясно показал вам, что такое ПИД-регулятор, и, самое главное, реальный вариант его использования в автомобильном дисплее. Надеюсь, я также ясно продемонстрировал, как мы можем реализовать ПИ-регулятор в коде C. До следующей автомобильной статьи поэкспериментируйте с этим фрагментом кода!

Если вам интересны мои статьи, не стесняйтесь читать больше ниже.

Статьи, посвященные разработке игр:





Как «настоящие геймдизайнеры создают игры
Вы будете удивлены. По крайней мере, я был.raychunyin00.medium.com»





Или, если вы хотите узнать, как выглядит мой рабочий день в Continental Automotive Singapore, посмотрите его здесь: