Петли ПИД-контроля с большими и непредсказуемыми аномалиями


10

Короткий вопрос
Существует ли распространенный способ обработки очень больших аномалий (порядка величины) в пределах иначе однородной контрольной области?

Предпосылки
Я работаю над алгоритмом управления, который управляет двигателем через в целом однородную область управления. При отсутствии / минимальной загрузке ПИД-регулятор работает отлично (быстрый отклик, перерегулирование практически отсутствует). Проблема, с которой я сталкиваюсь, заключается в том, что обычно будет как минимум одно место с высокой нагрузкой. Положение определяется пользователем во время установки, поэтому у меня нет разумного способа узнать, когда и где его ожидать.

Когда я настраиваю PID для обработки места с высокой нагрузкой, это вызывает большие перегрузки на незагруженных участках (что я полностью ожидал). Хотя это нормально , чтобы перерегулирование середины путешествие, нет никаких механических жестких остановок на корпусе. Отсутствие стойких поверхностей означает, что любое значительное превышение может привести к тому, что рычаг управления будет отключен от двигателя (что приведет к остановке агрегата).

Вещи я прототип

  • Вложенные PID (очень агрессивные, когда далеко от цели, консервативные, когда рядом)
  • Фиксированное усиление, когда далеко, PID, когда близко
  • Консервативный PID (работает без нагрузки) + внешнее управление, которое ищет PID для остановки и подачи дополнительной энергии до тех пор, пока либо не будет достигнута цель, либо не будет обнаружена быстрая скорость изменения (т. Е. Выход из области высокой нагрузки)

Ограничения

  • Определено полное путешествие
  • Hardstops не может быть добавлен (на данный момент)
  • Ошибка, скорее всего, никогда не обнулится
  • Высокая нагрузка могла быть получена из-за менее чем 10% хода (что означает отсутствие «запуска»)

Ответы:


2

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

Если я правильно понял ваш код

// Determine the error delta
dE = abs(last_error - new_error);
last_error = new_error;

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

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

if(TD)                                                 // Calculate D term
{  
   Last_C += (Error - Last_C) / TD;                    // D term simulates
   Dterm = (Error - Last_C) * KD;                      // capacitor discharging
}
else    
   Dterm = 0;                                          // D term is OFF (TD is 0)

Здесь следует отметить две интересные вещи:

  • Значение TD является не производным коэффициентом усиления (который является KD), а производным временем, пользовательской константой, которая управляет временем накопления ошибки. Если он был установлен на ноль, D-часть PID отключается независимо от установленного значения усиления KD.

  • Обратите внимание, как текущая ошибка использовалась, чтобы «зарядить» значение Last_C, прежде чем перейти к вычислению части D. Переменная Last_C действует как конденсатор, она будет накапливаться, пока ошибка велика, так что ваша производная часть будет действовать также на основе недавней «истории» ошибки, а после этого (когда ошибка была меньше) этой «истории» разряжается как конденсатор.

Конечно, вы должны ограничить общий вывод так, как вы, вероятно, уже это делаете (сброс настроек windup, безударный автоматический переход на ручной перенос и другие обычные вещи).

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


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

Понятно, что у вас есть D-член в вашем «основном» PID плюс все, что обнаружение останова вносит в расчет.
Drazen Cika

1
Это правильно. Dterm PID используется, хотя и не очень агрессивно, во время настройки. Что делает эту проблему еще более сложной, так это то, что нагрузка может освободиться за очень короткий промежуток времени. IE связь отключается. Это резкое снятие силы вызывает большие выбросы, когда к силам сваливания применяется любая функция сглаживания (суммирование).
Адам Льюис

Злая проблема, было бы интересно узнать, насколько хорошо этот алгоритм нечеткой логики справится с этим. По крайней мере, вы можете встроить больше своего опыта, связанного с проблемами, в алгоритм, вместо того, чтобы оставаться в рамках стандартных решений. Во всяком случае, удачи с этим :-)
Drazen Cika

1

Начальное решение

stalled_pwm_output = PWM / | ΔE |

ШИМ = Макс. Значение ШИМ
ΔE = last_error - new_error

Исходное соотношение успешно увеличивает выходную мощность ШИМ на основании отсутствия изменений в двигателе. См. График ниже для примера вывода.

Этот подход делает для ситуации, когда неагрессивный PID остановился. Тем не менее, он имеет неприятную (и очевидную) проблему, заключающуюся в том, что когда неагрессивный PID способен достичь заданного значения и пытается замедлить, stalled_pwm_output увеличивается. Это нарастание вызывает большой выброс при движении в незагруженном положении.

1 / ΔE против ΔE

Текущее решение

теория

stalled_pwm_output = (kE * PID_PWM) / | ΔE |

kE = Константа масштабирования
PID_PWM = Текущий запрос ШИМ от неагрессивного ПИД
ΔE = last_error - new_error

Мои текущие отношения все еще используют концепцию 1 / ΔE, но используют неагрессивный выход PID PID для определения stall_pwm_output. Это позволяет ПИД регулировать уровень stall_pwm_output, когда он начинает приближаться к целевому заданному значению, и в то же время позволяет выводить 100% ШИМ при остановке. Константа масштабирования kE необходима для обеспечения того, чтобы ШИМ попал в точку насыщения (более 10000 на графиках ниже).

Псевдокод

Обратите внимание, что результат из cal_stall_pwm добавляется к выходу PID PWM в моей текущей логике управления.

int calc_stall_pwm(int pid_pwm, int new_error)
{
    int ret = 0;
    int dE = 0;
    static int last_error = 0;
    const int kE = 1;

    // Allow the stall_control until the setpoint is achived
    if( FALSE == motor_has_reached_target())
    {
        // Determine the error delta
        dE = abs(last_error - new_error);
        last_error = new_error;

        // Protect from divide by zeros
        dE = (dE == 0) ? 1 : dE;

        // Determine the stall_pwm_output
        ret = (kE * pid_pwm) / dE;
    }

    return ret;
}

Выходные данные

Задержка выхода ШИМ Задержка выхода ШИМ

Обратите внимание, что на графике вывода остановленного ШИМ внезапное падение ШИМ на уровне ~ 3400 является встроенной функцией безопасности, которая активируется, потому что двигатель не смог достичь положения в течение заданного времени.

Ненагруженный ШИМ-выход ШИМ-выход без нагрузки


1

Вы не говорите, что вы контролируете ... скорость двигателя? должность? Что бы это ни было, первым шагом будет определение допустимой ошибки. Например, если управление для скорости, может быть установлена ​​максимальная ошибка в пределах 1% от цели. Без определения допустимой ошибки вы не сможете определить, какое разрешение вам нужно для АЦП или счетчика ШИМ. Без этого компенсация ПИД могла бы быть идеальной, но все равно имела бы колебания предельного цикла.

Тогда вам нужно знать динамику разомкнутой системы. Без этого вы не сможете узнать, какие усиления нужны для пропорциональной (P), интегральной (I) и производной (D) частей цикла. Вы можете измерить динамику с помощью шага ввода (шаг изменения уровня привода или ШИМ) или изменения шага в нагрузке (кажется, это будет иметь отношение к вам).

Использование изменения ошибки от цикла к циклу в знаменателе вашего алгоритма управления для изменения значения ШИМ гарантирует, что цикл никогда не установится. Это обеспечивает ограничение цикла колебаний в управлении. Большинство клиентов не смирится с этим.

P-часть цикла заботится о немедленной ошибке (быстро реагирует на ошибку). Но он будет иметь конечное усиление, поэтому некоторая ошибка останется. I-часть цикла медленно реагирует с течением времени, применяя бесконечное усиление (бесконечное время для бесконечного усиления), чтобы исправить ту ошибку, которая была оставлена ​​P-частью.

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

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

Используя наш сайт, вы подтверждаете, что прочитали и поняли нашу Политику в отношении файлов cookie и Политику конфиденциальности.
Licensed under cc by-sa 3.0 with attribution required.