Перейти к содержимому

CMSIS-DSP PID

Для подключения этой библиотеки нужно поставить галочку напротив DSP в менеджере библиотек в keil.

В самом файле проекта перед подключением необходимо указать на каком ядре построен МК.

 #define ARM_MATH_CM3

Затем подключить

#include "arm_math.h"

После этого мы можем использовать функции CMSIS-DSP. Нас интересует фун-ции PID Motor Control.

Эти функции подразделяются на группы функций работающие с типом данных q15, q31, f32. Тип данных q15, q31 fixed point,
f32 float point.

Алгоритм работы можно посмотреть там где описание библиотеки DSP. http://arm-software.github.io/CMSIS_5/DSP/html/group__PID.html

Вот сама функция на СИ

CMSIS_INLINE __STATIC_INLINE float32_t arm_pid_f32(
  arm_pid_instance_f32 * S,
  float32_t in)
  {
    float32_t out;

    /* y[n] = y[n-1] + A0 * x[n] + A1 * x[n-1] + A2 * x[n-2]  */
    out = (S->A0 * in) +
      (S->A1 * S->state[0]) + (S->A2 * S->state[1]) + (S->state[2]);

    /* Update state */
    S->state[1] = S->state[0];
    S->state[0] = in;
    S->state[2] = out;

    /* return to application */
    return (out);

  }

вот структура типов данных которая заполняется перед использованием функции

typedef struct
  {
    float32_t A0;          /**< The derived gain, A0 = Kp + Ki + Kd . */
    float32_t A1;          /**< The derived gain, A1 = -Kp - 2Kd. */
    float32_t A2;          /**< The derived gain, A2 = Kd . */
    float32_t state[3];    /**< The state array of length 3. */
    float32_t Kp;          /**< The proportional gain. */
    float32_t Ki;          /**< The integral gain. */
    float32_t Kd;          /**< The derivative gain. */
  } arm_pid_instance_f32;

Тут Kp-пропорциональный коэффициент, Ki-интегральный коэффициент, Kd-дифференциальный коэффициент; float32_t state[3]; это /* Update state */ S->state[1] = S->state[0]; S->state[0] = in; S->state[2] = out;

Перед заполнением структуры данных функции её нужно для начала объявить

/* ARM PID Instance, float_32 format */
arm_pid_instance_f32 PID; 

Затем можно заполнить структуру данных требуемыми параметрами

/* Set PID parameters */
    /* Set this for your needs */
    PID.Kp = PID_PARAM_KP;        /* Proporcional */
    PID.Ki = PID_PARAM_KI;        /* Integral */
    PID.Kd = PID_PARAM_KD;        /* Derivative */

Проинициализировать функцию

/* Initialize PID system, float32_t format */    
    arm_pid_init_f32(&PID, 1);

И теперь можно использовать функцию вычисления ПИД регулятора

duty = arm_pid_f32(&PID, pid_error);

Где PID — указатель на структуру данных;

pid_error — сигнал ошибки, рассогласования (тип переменной float), объявлен в начале программы;

duty — это значение с выхода фун-ции;

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

без anti windup

с anti windup
if (duty > max_PID) {
                duty = max_PID;
                PID.state[2] = max_PID;
    
            } else if (duty < min_PID) {
                duty = min_PID;
                PID.state[2] = min_PID;
            } 

max_PID — максимальное выходное значение с ПИД;

min_PID — минимальное значение c ПИД регулятора.

материал в интернете с использованием этой фун-ции.

Добавить комментарий