ВходНаше всё Теги codebook 无线电组件 Поиск Опросы Закон Суббота
1 февраля
1494494 Топик полностью
LordNфилософ (30.01.2025 10:09, просмотров: 138) ответил Eddy_Em на Жесть-то какая! Зачем на ублюдской змеюке-то?
ну вот на сях 

Реализация ПИД-регулятора на языке C с учетом всех указанных требований может выглядеть следующим образом:


#include <stdio.h>

// Параметры ПИД-регулятора

typedef struct {

float Kp; // Пропорциональный коэффициент

float Ki; // Интегральный коэффициент

float Kd; // Дифференциальный коэффициент

float Ts; // Время дискретизации

float deadzone; // Мертвая зона

float error_limit; // Ограничение ошибки

float integral; // Интегральная составляющая

float prev_error; // Предыдущее значение ошибки

} PIDController;

// Инициализация ПИД-регулятора

void PID_Init(PIDController *pid, float Kp, float Ki, float Kd, float Ts, float deadzone, float error_limit) {

pid->Kp = Kp;

pid->Ki = Ki;

pid->Kd = Kd;

pid->Ts = Ts;

pid->deadzone = deadzone;

pid->error_limit = error_limit;

pid->integral = 0.0f;

pid->prev_error = 0.0f;

}

// Вычисление выходного сигнала ПИД-регулятора

float PID_Compute(PIDController *pid, float setpoint, float measured_value) {

float error = setpoint - measured_value;

// Ограничение ошибки

if (error > pid->error_limit) {

error = pid->error_limit;

} else if (error < -pid->error_limit) {

error = -pid->error_limit;

}

// Мертвая зона

if (error > -pid->deadzone && error < pid->deadzone) {

error = 0.0f;

}

// Пропорциональная составляющая

float P = pid->Kp * error;

// Интегральная составляющая

pid->integral += error * pid->Ts;

// Ограничение интегральной составляющей

if (pid->integral > 1.0f) {

pid->integral = 1.0f;

} else if (pid->integral < 0.0f) {

pid->integral = 0.0f;

}

float I = pid->Ki * pid->integral;

// Дифференциальная составляющая

float D = pid->Kd * (error - pid->prev_error) / pid->Ts;

pid->prev_error = error;

// Суммарный выходной сигнал

float output = P + I + D;

// Ограничение выходного сигнала

if (output > 1.0f) {

output = 1.0f;

// Отключение накопления интегральной составляющей при ограничении

pid->integral -= error * pid->Ts;

} else if (output < 0.0f) {

output = 0.0f;

// Отключение накопления интегральной составляющей при ограничении

pid->integral -= error * pid->Ts;

}

return output;

}

int main() {

// Пример использования ПИД-регулятора

PIDController pid;

PID_Init(&pid, 1.0f, 0.1f, 0.01f, 0.01f, 0.05f, 1.0f);

float setpoint = 1.0f;

float measured_value = 0.0f;

for (int i = 0; i < 100; i++) {

float output = PID_Compute(&pid, setpoint, measured_value);

measured_value += output * 0.01f; // Пример изменения измеренного значения

printf("Output: %f, Measured: %f\n", output, measured_value);

}

return 0;

}


### Описание кода:

1. **Нормировка коэффициентов**:

- Коэффициенты `Kp`, `Ki`, `Kd` уже нормированы к входной ошибке и времени дискретизации `Ts`.

2. **Нормировка выхода регулятора**:

- Выходной сигнал ограничен диапазоном `0...1`.

3. **Ограничение интегральной части**:

- Интегральная составляющая ограничена диапазоном `0...1`.

4. **Отключение накопления интегральной части**:

- Если выходной сигнал достигает границ диапазона `0...1`, накопление интегральной составляющей прекращается.

5. **Мертвая зона**:

- Если ошибка находится в пределах мертвой зоны, она считается равной нулю.

6. **Ограничение ошибки**:

- Ошибка ограничена на заданном уровне `error_limit`.

### Пример использования:

В цикле `for` моделируется работа ПИД-регулятора, где измеренное значение `measured_value` постепенно приближается к заданному значению `setpoint`. Выходной сигнал регулятора выводится на каждом шаге.

Этот код можно адаптировать под конкретные требования и условия работы системы.

ЛН