PID-регулятор¶
PID (Пропорционально-Интегрально-Дифференциальный) регулятор — классический алгоритм управления с обратной связью, широко применяемый в аэрокосмической отрасли, робототехнике и промышленной автоматизации. Наша реализация следует соглашениям MATLAB/Simulink и включает автоматический подбор коэффициентов в стиле MATLAB.
Теория¶
PID-регулятор вычисляет управляющий сигнал \(u(t)\) на основе ошибки \(e(t) = r(t) - y(t)\) между уставкой \(r(t)\) и измеренным выходом \(y(t)\):
Компоненты¶
| Составляющая | Роль | Эффект |
|---|---|---|
| Пропорциональная (P) | Реагирует на текущую ошибку | Быстрый отклик, может давать статическую ошибку |
| Интегральная (I) | Накапливает прошлую ошибку | Устраняет статическую ошибку, может вызывать перерегулирование |
| Дифференциальная (D) | Предсказывает будущую ошибку | Демпфирует колебания, чувствительна к шуму |
Дискретная реализация¶
В дискретном времени с шагом \(\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.
Как это работает¶
- Извлекает модель пространства состояний (матрицы A, B, C, D) из окружения
- Автоматически определяет знак контура используя анализ статического коэффициента усиления (DC gain)
- Запускает дифференциальную эволюцию для минимизации функции стоимости
- Оптимизирует на робастность: учитывает и переходную характеристику, И качество слежения
Режимы настройки¶
Оптимизирует чистую переходную характеристику с быстрым временем установления и минимальным перерегулированием.
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. |
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).