Перейти к содержанию

PID-регулятор

PID (Пропорционально-Интегрально-Дифференциальный) регулятор — классический алгоритм управления с обратной связью, широко применяемый в аэрокосмической отрасли, робототехнике и промышленной автоматизации. Наша реализация следует соглашениям MATLAB/Simulink и включает автоматический подбор коэффициентов в стиле MATLAB.

Блок-схема PID

Теория

PID-регулятор вычисляет управляющий сигнал \(u(t)\) на основе ошибки \(e(t) = r(t) - y(t)\) между уставкой \(r(t)\) и измеренным выходом \(y(t)\):

\[ u(t) = K_p e(t) + K_i \int_0^t e(\tau)\,d\tau + K_d \frac{de(t)}{dt} \]

Компоненты

Составляющая Роль Эффект
Пропорциональная (P) Реагирует на текущую ошибку Быстрый отклик, может давать статическую ошибку
Интегральная (I) Накапливает прошлую ошибку Устраняет статическую ошибку, может вызывать перерегулирование
Дифференциальная (D) Предсказывает будущую ошибку Демпфирует колебания, чувствительна к шуму

Дискретная реализация

В дискретном времени с шагом \(\Delta t\):

\[ u_k = K_p e_k + K_i \sum_{j=0}^{k} e_j \Delta t + K_d \frac{y_{k-1} - y_k}{\Delta t} \]

Производная по измерению

Наша реализация использует производную по измерению (а не по ошибке), как это принято по умолчанию в Simulink. Это позволяет избежать "derivative kick" при резком изменении уставки.

Anti-Windup

Когда управляющий выход насыщается (достигает пределов исполнительного механизма), интегральная составляющая может "накручиваться", вызывая большое перерегулирование. Наша реализация включает условное интегрирование (anti-windup): интегратор замораживается при насыщении выхода.

Быстрый старт

import numpy as np
import gymnasium as gym

from tensoraerospace.agent.pid import PID
from tensoraerospace.signals.standard import unit_step
from tensoraerospace.utils import generate_time_period

# Опорный сигнал — ступенька 5° по тангажу
dt = 0.01
tp = generate_time_period(tn=20, dt=dt)
number_time_steps = len(tp)
reference_signal = np.reshape(
    unit_step(degree=5, tp=tp, time_step=2.0, output_rad=True),
    [1, -1],
)

# Создаём окружение
env = gym.make(
    'LinearLongitudinalB747-v0',
    number_time_steps=number_time_steps,
    reference_signal=reference_signal,
)

# Создаём PID-регулятор
pid = PID(env=env, kp=-0.1, ki=-0.01, kd=-0.05, dt=dt)

# Цикл управления
obs, info = env.reset()
for k in range(number_time_steps):
    reference = float(reference_signal[0, k])
    measurement = obs[3]  # theta (угол тангажа)
    action = pid.select_action(reference, measurement)
    obs, reward, terminated, truncated, info = env.step([action])
    if terminated or truncated:
        break

Автоматический подбор в стиле MATLAB

Метод tune_matlab_style() автоматически находит оптимальные коэффициенты PID с помощью глобальной оптимизации, аналогично PID Tuner в MATLAB Simulink.

Как это работает

  1. Извлекает модель пространства состояний (матрицы A, B, C, D) из окружения
  2. Автоматически определяет знак контура используя анализ статического коэффициента усиления (DC gain)
  3. Запускает дифференциальную эволюцию для минимизации функции стоимости
  4. Оптимизирует на робастность: учитывает и переходную характеристику, И качество слежения

Режимы настройки

Оптимизирует чистую переходную характеристику с быстрым временем установления и минимальным перерегулированием.

pid = PID(env=env)
result = pid.tune_matlab_style(
    track_state_idx=3,      # Индекс состояния theta
    mode="step_response",
    target_settling_time=5.0,
    target_overshoot=10.0,
    n_iterations=100
)
print(result)
# MATLABTuneResult(Kp=-0.1234, Ki=-0.0456, Kd=-0.0789, ...)

Функция стоимости минимизирует: - Время установления (время достижения ±2% от конечного значения) - Перерегулирование выше целевого порога - Статическую ошибку - Интеграл квадрата ошибки (ISE) - Затраты на управление и насыщение

Также учитывает качество слежения как вторичную цель (вес 25%), чтобы настроенный PID не отказывал на синусоидальных сигналах.

Оптимизирует точное слежение за изменяющимися во времени сигналами (синусоиды, рампы).

pid = PID(env=env)
result = pid.tune_matlab_style(
    track_state_idx=3,
    mode="tracking",
    n_iterations=100
)

Функция стоимости минимизирует: - Среднеквадратичную ошибку (RMSE) - Интеграл абсолютной ошибки (IAE) - Фазовое запаздывание - Затраты на управление и насыщение

Также учитывает переходную характеристику как вторичную цель (вес 25%), чтобы обеспечить устойчивость при резких изменениях уставки.

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

import gymnasium as gym
import numpy as np
from tensoraerospace.agent.pid import PID
from tensoraerospace.signals.standard import unit_step
from tensoraerospace.utils import generate_time_period

# Настройка
dt = 0.01
tp = generate_time_period(tn=20, dt=dt)
n_steps = len(tp)

# Создаём ступенчатый сигнал задания (5 градусов)
reference = unit_step(degree=5, tp=tp, time_step=100, output_rad=False)

env = gym.make(
    'LinearLongitudinalB747-v0',
    number_time_steps=n_steps,
    initial_state=np.array([[0], [0], [0], [0]]),
    reference_signal=reference.reshape(1, -1),
    track_state='theta'
)

# Создаём и настраиваем PID
pid = PID(env=env, dt=dt)
result = pid.tune_matlab_style(
    track_state_idx=3,        # индекс theta
    mode="step_response",
    target_settling_time=5.0,
    target_overshoot=10.0,
    n_iterations=150,
    verbose=True
)

print(f"Настроенный PID: Kp={pid.kp:.4f}, Ki={pid.ki:.4f}, Kd={pid.kd:.4f}")
print(f"Время установления: {result.settling_time:.2f}с")
print(f"Перерегулирование: {result.overshoot:.1f}%")

Пример вывода

📊 MATLAB-Style PID Optimization (Step Response)
------------------------------------------------------------
   System dimension: 4 states
   Matrices: A=(4, 4), B=(4, 1), C=(4, 4), D=(4, 1)
   Simulation steps: 2000, dt: 0.01s
   Mode: Step Response
   Target settling time: 5.0s
   Target overshoot: 10.0%
   DC Gain: -0.0421

   🔄 Running optimization (150 iterations)...
   Optimization: 100%|██████████| 150/150 [00:45<00:00]

    Optimization completed!
   Kp=-0.1523, Ki=-0.0234, Kd=-0.0891
   [Primary step] Settling time: 4.32s
   [Primary step] Overshoot: 8.45%
   [Primary step] Static error: 0.0012
   [Secondary sine] RMSE: 0.3421

Основные параметры

Параметр Описание По умолчанию
kp Пропорциональный коэффициент 1.0
ki Интегральный коэффициент 1.0
kd Дифференциальный коэффициент 0.5
dt Шаг времени (секунды) 0.01
env Gymnasium окружение None

Параметры tune_matlab_style()

Параметр Описание По умолчанию
track_state_idx Индекс управляемого состояния Обязательный
mode "step_response" или "tracking" "step_response"
target_settling_time Желаемое время установления (с) Авто
target_overshoot Максимальное допустимое перерегулирование (%) 10.0
n_iterations Итерации оптимизации 100
verbose Выводить прогресс True

Сравнение с другими методами

Метод Плюсы Минусы Лучше всего для
PID Простой, быстрый, понятный Ограниченная производительность на сложной динамике Линейные системы, быстрое прототипирование
MPC Учитывает ограничения, оптимальный Вычислительно затратный Системы с ограничениями, траектории
RL (SAC/PPO) Адаптируется к нелинейной динамике Требует обучения, менее интерпретируемый Сложные нелинейные системы

Практические советы

Когда использовать PID vs другие методы

  • Используйте PID когда система приблизительно линейна и нужен простой, интерпретируемый регулятор
  • Используйте MPC когда есть явные ограничения на состояния или управления
  • Используйте RL когда динамика сильно нелинейна или неизвестна

Согласованность единиц

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

Начальная точка

Для большинства аэрокосмических систем начните с mode="step_response" и target_overshoot=10.0. Это даёт хороший баланс между скоростью и устойчивостью.

Документация API

PID(env=None, kp=1.0, ki=1.0, kd=0.5, dt=0.01)

Bases: BaseRLModel

PID controller implementation for control systems.

This class implements a PID (Proportional-Integral-Derivative) controller for automatic control systems. The PID controller uses proportional (P), integral (I), and derivative (D) components to compute the control signal.

Parameters:

Name Type Description Default
env Env | None

Gymnasium environment. Defaults to None.

None
kp float

Proportional gain. Defaults to 1.

1.0
ki float

Integral gain. Defaults to 1.

1.0
kd float

Derivative gain. Defaults to 0.5.

0.5
dt float

Time step (time difference between consecutive updates). Defaults to 0.01.

0.01

Attributes:

Name Type Description
kp float

Proportional gain.

ki float

Integral gain.

kd float

Derivative gain.

dt float

Time step.

integral float

Accumulated integral value.

prev_error float

Previous error value for derivative computation.

env

Gymnasium environment.

Example

pid = PID(env=env, kp=0.1, ki=0.01, kd=0.05, dt=1) control_signal = pid.select_action(10, 7)

Initialize PID controller parameters.

select_action(setpoint, measurement)

Compute and return control signal based on setpoint and measurement.

This method uses the current measurement and setpoint to compute the error, then applies the PID algorithm to compute the control signal.

Parameters:

Name Type Description Default
setpoint float

Desired value that the system should reach.

required
measurement float

Current measured value.

required

Returns:

Name Type Description
float float

Control signal computed by the PID controller.

Example

pid = PID(env=env, kp=0.1, ki=0.01, kd=0.05, dt=1) control_signal = pid.select_action(10, 7) print(control_signal)

reset()

Reset PID controller internal state.

Resets integral accumulator and previous error to zero. Should be called before starting a new control episode.

tune_matlab_style(track_state_idx=0, target_settling_time=None, target_overshoot=10.0, n_iterations=100, verbose=True, mode='step_response', control_input_idx=0)

MATLAB-style PID tuning using state-space model optimization.

This method implements PID tuning similar to MATLAB Simulink PID Tuner. It requires the environment to have a model with state-space matrices (A, B, C, D).

Two optimization modes are available: - "step_response": Primary objective is step response (settling time, overshoot), with an additional secondary check on tracking (sinusoid) to avoid oscillatory controllers. - "tracking": Primary objective is tracking (RMSE), with an additional secondary check on step response to avoid controllers that behave poorly on setpoint steps.

Parameters:

Name Type Description Default
track_state_idx int

Index of the state to track (in output vector). Defaults to 0.

0
target_settling_time float

Target settling time in seconds. If None, uses 50% of simulation time. Only used in "step_response" mode.

None
target_overshoot float

Target maximum overshoot in percent. Defaults to 10.0. Only used in "step_response" mode.

10.0
n_iterations int

Number of optimization iterations. Defaults to 100.

100
verbose bool

Whether to print progress. Defaults to True.

True
mode str

Optimization mode. Options: - "step_response": Minimize settling time, overshoot, static error - "tracking": Minimize RMSE and phase lag for signal tracking Defaults to "step_response".

'step_response'
control_input_idx int

Index of the control input column of B used to compute the DC gain. For MIMO plants where the tracked output is not controlled by the first input, set this to the correct column. Defaults to 0 (backward compatible).

0

Returns:

Name Type Description
MATLABTuneResult MATLABTuneResult

Optimized PID parameters and performance metrics.

Raises:

Type Description
StateSpaceNotAvailable

If environment does not have state-space matrices.

ValueError

If environment is not set or invalid mode.

Example

Step response optimization

result = pid.tune_matlab_style(track_state_idx=0, mode="step_response")

Tracking optimization (for sinusoids, etc.)

result = pid.tune_matlab_style(track_state_idx=0, mode="tracking")

get_param_env()

Get environment and agent parameters for saving.

Returns:

Name Type Description
dict Dict[str, Dict[str, Any]]

Dictionary with environment and agent policy parameters.

save(path=None)

Save PID model to the specified directory.

If path is not specified, creates a directory with current date and time.

Parameters:

Name Type Description Default
path str

Path where the model will be saved. If None, creates a directory with current date and time.

None

Returns:

Name Type Description
Path Path

Path to the directory with saved model.

__load(path) classmethod

Load PID model from the specified directory.

Parameters:

Name Type Description Default
path str or Path

Path to directory with saved model.

required

Returns:

Name Type Description
PID 'PID'

Loaded PID model instance.

Raises:

Type Description
TheEnvironmentDoesNotMatch

If agent type does not match expected.

from_pretrained(repo_name, access_token=None, version=None) classmethod

Load pretrained model from local path or Hugging Face Hub.

Parameters:

Name Type Description Default
repo_name str

Repository name or local path to model.

required
access_token str

Access token for Hugging Face Hub.

None
version str

Model version to load.

None

Returns:

Name Type Description
PID 'PID'

Loaded PID model instance.

MATLABTuneResult(kp, ki, kd, settling_time, overshoot, ise, method='MATLAB-Style') dataclass

Result of MATLAB-style PID tuning.

Attributes:

Name Type Description
kp float

Proportional gain.

ki float

Integral gain.

kd float

Derivative gain.

settling_time float

Achieved settling time in seconds.

overshoot float

Achieved overshoot in percent.

ise float

Integral Squared Error.

method str

Tuning method name.

StateSpaceNotAvailable

Bases: Exception

Exception raised when state-space matrices are not available.

This exception is raised when trying to use MATLAB-style tuning methods on an environment that does not provide state-space matrices (A, B, C, D).