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

Функции: средства оценки состояний

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

Если вы планируете использовать средства оценки не в контексте данного пакета (например, для

фильтрации, оценки параметров и т. д.), при создании необходимо проявлять осторожность, так как интегральное действие может оказаться ненужным. Параметры nint_u=0 и nint_ym=0 отключают его.

Все средства оценки реализованы в форме предикторов (наблюдателей), то есть в каждый дискретный момент времени все они оценивают состояния в следующий период [1]. В отличие от этого, форма фильтра, оценивающая , иногда бывает немного точнее.

Форма предиктора оказывается удобной для управляющих систем, так как оценки производятся после вычислений контроллеров без дополнительных задержек. Более того, метод moveinput! прогнозирующих контроллеров не обновляет оценки с помощью updatestate! автоматически. Это позволяет применять вычисленные входы к реальному объекту перед началом вычислений оценки, которые могут оказаться затратными (примеры см. в руководстве).

Все средства оценки поддерживают измеряемые ( ) и неизмеряемые ( )

выходы модели, а относится ко всем выходам.

StateEstimator

# ModelPredictiveControl.StateEstimatorType

Абстрактный супертип всех средств оценки состояния.


(estim::StateEstimator)(d=[]) -> ŷ

Функтор, позволяющий использовать вызываемый объект StateEstimator как псевдоним для evaloutput.

Примеры

julia> kf = KalmanFilter(setop!(LinModel(tf(3, [10, 1]), 2), yop=[20]));

julia> ŷ = kf()
1-element Vector{Float64}:
 20.0

SteadyKalmanFilter

# ModelPredictiveControl.SteadyKalmanFilterType

SteadyKalmanFilter(model::LinModel; <keyword arguments>)

Создает установившийся фильтр Калмана с LinModel model.

Установившийся (или асимптотический) фильтр Калмана основан на модели процесса:

с шумами датчика и процесса в виде векторов белого шума с некоррелированным нулевым средним значением и соответствующей ковариацией и . Аргументы имеют среднеквадратичные отклонения σ, то есть единицы те же, что у выходов и состояний. Матрицы  — это матрицы модели model, расширенные с помощью стохастической модели, которая задается посредством числовых значений интеграторов nint\_u и nint\_ym (см. расширенную справку). Аналогичным образом, ковариационные матрицы расширяются посредством и . Матрицы  — это строки , соответствующие измеряемым выходам (а также неизмеряемым для ).

Аргументы

  • model::LinModel: модель для оценок (детерминированная).

  • i_ym=1:model.ny: индексы измеряемых выходов объекта model; остальные выходы являются неизмеряемыми.

  • σQ=fill(1/model.nx,model.nx): главная диагональ ковариации шума процесса объекта model, заданной в виде вектора среднеквадратичных отклонений.

  • σR=fill(1,length(i_ym)): главная диагональ ковариации шума датчика измеряемых выходов model, заданной в виде вектора среднеквадратичных отклонений.

  • nint_u=0: количество интеграторов для стохастической модели неизмеряемых возмущений на обрабатываемых входах (вектор); если интеграторов нет, используйте значение nint_u=0 (см. расширенную справку).

  • σQint_u=fill(1,sum(nint_u)): то же, что и σQ, но для неизмеряемых возмущений на измеряемых входах (составленных из интеграторов).

  • nint_ym=default_nint(model,i_ym,nint_u): то же, что и nint_u, но для неизмеряемых возмущений на измеряемых выходах; если интеграторов нет, используйте значение nint_ym=0 (см. расширенную справку).

  • σQint_ym=fill(1,sum(nint_ym)): то же, что и σQ, для неизмеряемых возмущений на измеряемых выходах (составленных из интеграторов).

Примеры

julia> model = LinModel([tf(3, [30, 1]); tf(-2, [5, 1])], 0.5);

julia> estim = SteadyKalmanFilter(model, i_ym=[2], σR=[1], σQint_ym=[0.01])
SteadyKalmanFilter estimator with a sample time Ts = 0.5 s, LinModel and:
 1 manipulated inputs u (0 integrating states)
 3 estimated states x̂
 1 measured outputs ym (1 integrating states)
 1 unmeasured outputs yu
 0 measured disturbances d

Расширенная справка

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

  • Используйте интегратор 0, если выход модели уже интегрируется (в противном случае он будет ненаблюдаемым).

  • Используйте интегратор 1, если возмущения на выходе обычно являются ступенчатыми.

  • Используйте интегратор 2, если возмущения на выходе обычно являются линейными.

Функция init_estimstoch создает стохастическую модель для оценки.

При увеличении значений σQint_u и σQint_ym возрастает «коэффициент усиления» интегрального действия.

Конструктор предварительно вычисляет установившийся коэффициент усиления Калмана с помощью функции kalman . Иногда при этом может происходить ошибка, например если матрицы model слабо обусловленные. В таком случае можно попробовать использовать альтернативный динамический фильтр KalmanFilter.

SteadyKalmanFilter(model, i_ym, nint_u, nint_ym, Q̂, R̂)

Создает средство оценки на основе расширенных ковариационных матриц и .

Этот синтаксис допускает ненулевые недиагональные элементы в .

KalmanFilter

# ModelPredictiveControl.KalmanFilterType

KalmanFilter(model::LinModel; <keyword arguments>)

Создает динамический фильтр Калмана с LinModel model.

Модель процесса идентична SteadyKalmanFilter. Матрица  — это оценочная ковариация погрешности состояний model, расширенных с помощью стохастических состояний (заданных посредством nint_u и nint_ym). Именованные аргументы изменяют ее начальное значение на .

Аргументы

  • model::LinModel: модель для оценок (детерминированная).

  • σP0=fill(1/model.nx,model.nx): главная диагональ ковариации начальной оценки , заданной в виде вектора среднеквадратичных отклонений.

  • σP0int_u=fill(1,sum(nint_u)): то же, что и σP0, но для неизмеряемых возмущений на измеряемых входах (составленных из интеграторов).

  • σP0int_ym=fill(1,sum(nint_ym)): то же, что и σP0, но для неизмеряемых возмущений на измеряемых выходах (составленных из интеграторов).

  • Именованные аргументы <keyword arguments> конструктора SteadyKalmanFilter.

Примеры

julia> model = LinModel([tf(3, [30, 1]); tf(-2, [5, 1])], 0.5);

julia> estim = KalmanFilter(model, i_ym=[2], σR=[1], σP0=[100, 100], σQint_ym=[0.01])
KalmanFilter estimator with a sample time Ts = 0.5 s, LinModel and:
 1 manipulated inputs u (0 integrating states)
 3 estimated states x̂
 1 measured outputs ym (1 integrating states)
 1 unmeasured outputs yu
 0 measured disturbances d
KalmanFilter(model, i_ym, nint_u, nint_ym, P̂0, Q̂, R̂)

Создает средство оценки на основе расширенных ковариационных матриц P̂0, и .

Этот синтаксис допускает ненулевые недиагональные элементы в .

Luenberger

# ModelPredictiveControl.LuenbergerType

Luenberger(
    model::LinModel;
    i_ym = 1:model.ny,
    nint_u  = 0,
    nint_ym = default_nint(model, i_ym),
    p̂ = 1e-3*(1:(model.nx + sum(nint_u) + sum(nint_ym))) .+ 0.5
)

Создает наблюдатель Люэнбергера с LinModel model.

i_ym содержит индексы измеряемых выходов объекта model; остальные выходы являются неизмеряемыми. Матрицы model расширяются с помощью стохастической модели, которая задается посредством числовых значений интеграторов nint_u и nint_ym (см. расширенную справку по SteadyKalmanFilter ). Аргумент  — это вектор из model.nx + sum(nint_u) + sum(nint_ym) элементов, определяющий полюса и собственные значения наблюдателя (по умолчанию в окрестности точки ). Метод вычисляет коэффициент усиления наблюдателя с помощью place.

Примеры

julia> model = LinModel([tf(3, [30, 1]); tf(-2, [5, 1])], 0.5);

julia> estim = Luenberger(model, nint_ym=[1, 1], p̂=[0.61, 0.62, 0.63, 0.64])
Luenberger estimator with a sample time Ts = 0.5 s, LinModel and:
 1 manipulated inputs u (0 integrating states)
 4 estimated states x̂
 2 measured outputs ym (2 integrating states)
 0 unmeasured outputs yu
 0 measured disturbances d

UnscentedKalmanFilter

# ModelPredictiveControl.UnscentedKalmanFilterType

UnscentedKalmanFilter(model::SimModel; <keyword arguments>)

Создает сигма-точечный фильтр Калмана с SimModel model.

Поддерживаются как LinModel, так и NonLinModel. Сигма-точечный фильтр Калмана основан на модели процесса:

В описании SteadyKalmanFilter приведены подробные сведения о шумах и ковариациях . Функции  — это функции пространства состояний модели model, расширенные с помощью стохастической модели, которая задается посредством числовых значений интеграторов nint_u и nint_ym (см. расширенную справку). Функция представляет измеряемые выходы функции (а также неизмеряемые для ).

Аргументы

  • model::SimModel: модель для оценок (детерминированная).

  • α=1e-3: параметр alpha, размах распределения состояний .

  • β=2: параметр beta, коэффициент асимметрии и куртозис распределения состояний .

  • κ=0: параметр kappa, еще один параметр размаха .

  • Именованные аргументы <keyword arguments> конструктора SteadyKalmanFilter.

  • Именованные аргументы <keyword arguments> конструктора KalmanFilter.

Примеры

julia> model = NonLinModel((x,u,_)->0.1x+u, (x,_)->2x, 10.0, 1, 1, 1);

julia> estim = UnscentedKalmanFilter(model, σR=[1], nint_ym=[2], σP0int_ym=[1, 1])
UnscentedKalmanFilter estimator with a sample time Ts = 10.0 s, NonLinModel and:
 1 manipulated inputs u (0 integrating states)
 3 estimated states x̂
 1 measured outputs ym (2 integrating states)
 0 unmeasured outputs yu
 0 measured disturbances d

Расширенная справка

В расширенной справке по SteadyKalmanFilter приводятся подробные сведения о расширении посредством аргументов nint_ym и nint_u. Обратите внимание, что конструктор не проверяет наблюдаемость получившейся расширенной модели NonLinModel. В таких случаях пользователь должен сам убедиться в том, что расширенная модель по-прежнему наблюдаемая.

UnscentedKalmanFilter(model, i_ym, nint_u, nint_ym, P̂0, Q̂, R̂, α, β, κ)

Создает средство оценки на основе расширенных ковариационных матриц P̂0, и .

Этот синтаксис допускает ненулевые недиагональные элементы в .

ExtendedKalmanFilter

# ModelPredictiveControl.ExtendedKalmanFilterType

ExtendedKalmanFilter(model::SimModel; <keyword arguments>)

Создает расширенный фильтр Калмана с SimModel model.

Поддерживаются как LinModel, так и NonLinModel. Модель процесса идентична UnscentedKalmanFilter. Якобианы расширенной модели вычисляются посредством ForwardDiff.jl автоматического дифференцирования.

Если возникает ошибка наподобие следующей, см. расширенную справку по функции linearize: MethodError: no method matching (::var"##")(::Vector{ForwardDiff.Dual}).

Аргументы

  • model::SimModel: модель для оценок (детерминированная).

  • Именованные аргументы <keyword arguments> конструктора SteadyKalmanFilter.

  • Именованные аргументы <keyword arguments> конструктора KalmanFilter.

Примеры

julia> model = NonLinModel((x,u,_)->0.2x+u, (x,_)->-3x, 5.0, 1, 1, 1);

julia> estim = ExtendedKalmanFilter(model, σQ=[2], σQint_ym=[2], σP0=[0.1], σP0int_ym=[0.1])
ExtendedKalmanFilter estimator with a sample time Ts = 5.0 s, NonLinModel and:
 1 manipulated inputs u (0 integrating states)
 2 estimated states x̂
 1 measured outputs ym (1 integrating states)
 0 unmeasured outputs yu
 0 measured disturbances d
ExtendedKalmanFilter(model, i_ym, nint_u, nint_ym, P̂0, Q̂, R̂)

Создает средство оценки на основе расширенных ковариационных матриц P̂0, и .

Этот синтаксис допускает ненулевые недиагональные элементы в .

MovingHorizonEstimator

# ModelPredictiveControl.MovingHorizonEstimatorType

MovingHorizonEstimator(model::SimModel; <keyword arguments>)

Создает средство оценки подвижного горизонта (MHE) на основе model (LinModel или NonLinModel).

Оно может обрабатывать налагаемые на оценки ограничения; см. описание setconstraint!. Кроме того, модель model не линеаризуется как ExtendedKalmanFilter, а вероятностное распределение не аппроксимируется как UnscentedKalmanFilter. Однако вычислительные затраты существенно выше, поскольку производится минимизация следующей целевой функции в каждый дискретный момент времени :

где конечные затраты вычисляются на основе состояний, оцененных в момент времени :

а ковариации повторяются раз:

Горизонт оценки ограничивает длину окна:

Векторы и охватывают оценочный шум процесса и шум датчика от до . В расширенной справке даны определения этих двух векторов и скалярной величины . В описании UnscentedKalmanFilter приводятся подробные сведения о расширенной модели процесса и ковариациях . Матрица оценивается с помощью ExtendedKalmanFilter.

Если возникает ошибка наподобие следующей, см. расширенную справку: MethodError: no method matching (::var"##")(::Vector{ForwardDiff.Dual}).

Аргументы

  • model::SimModel: модель для оценок (детерминированная).

  • He=nothing: горизонт прогнозирования ; должен быть указан.

  • Cwt=Inf: вес ослабляющей переменной ; по умолчанию имеет значение Inf, что соответствует только жестким ограничениям.

  • optim=default_optim_mhe(model): модель JuMP.Model с квадратичным или нелинейным оптимизатором для решения (по умолчанию Ipopt или OSQP, если объект model относится к типу LinModel).

  • Именованные аргументы <keyword arguments> конструктора SteadyKalmanFilter.

  • Именованные аргументы <keyword arguments> конструктора KalmanFilter.

Примеры

julia> model = NonLinModel((x,u,_)->0.1x+u, (x,_)->2x, 10.0, 1, 1, 1);

julia> estim = MovingHorizonEstimator(model, He=5, σR=[1], σP0=[0.01])
MovingHorizonEstimator estimator with a sample time Ts = 10.0 s, Ipopt optimizer, NonLinModel and:
 5 estimation steps He
 1 manipulated inputs u (0 integrating states)
 2 estimated states x̂
 1 measured outputs ym (1 integrating states)
 0 unmeasured outputs yu
 0 measured disturbances d

Расширенная справка

Оценочные шумы процесса и датчика определяются следующим образом:

на основе функций расширенной модели :

Ослабляющая переменная ослабляет ограничения, если она включена; см. описание функции setconstraint!. Для MHE она по умолчанию отключена (согласно Cwt=Inf), но должна быть включена для задач с границами двух или более типов с целью обеспечения применимости (например, для оценочного состояния и шума датчика).

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

Для оптимизации NonLinModel применяется автоматическое дифференцирование (AD). Оптимизаторы обычно лучше работают с точными производными, которые получаются при автоматическом дифференцировании. Однако функции f и h должны быть совместимы с этой возможностью. В разделе Автоматическое дифференцирование описываются распространенные ошибки, которые допускают при написании этих функций.

Обратите внимание, что если Cwt≠Inf, атрибут nlp_scaling_max_gradient оптимизатора Ipopt устанавливается в значение 10/Cwt (если это значение еще не задано) с целью масштабирования небольших значений .

MovingHorizonEstimator(model, He, i_ym, nint_u, nint_ym, P̂0, Q̂, R̂, Cwt, optim)

Создает средство оценки на основе расширенных ковариационных матриц P̂0, и .

Этот синтаксис допускает ненулевые недиагональные элементы в .

InternalModel

# ModelPredictiveControl.InternalModelType

InternalModel(model::SimModel; i_ym=1:model.ny, stoch_ym=ss(I,I,I,I,model.Ts))

Создает средство оценки внутренней модели на основе model (LinModel или NonLinModel).

i_ym содержит индексы измеряемых выходов объекта model; остальные выходы являются неизмеряемыми. model вычисляет детерминированные прогнозы и stoch_ym — стохастические прогнозы для измеряемых выходов (для неизмеряемых они равны ). Для прогнозируемых выходов оба значения суммируются: .

Средство оценки InternalModel не работает, если модель model является интегрирующей или неустойчивой. Конструктор проверяет эти аспекты для LinModel, но не для NonLinModel. В таких случаях используется любое другое средство оценки состояния.

Примеры

julia> estim = InternalModel(LinModel([tf(3, [30, 1]); tf(-2, [5, 1])], 0.5), i_ym=[2])
InternalModel estimator with a sample time Ts = 0.5 s, LinModel and:
 1 manipulated inputs u
 2 estimated states x̂
 1 measured outputs ym
 1 unmeasured outputs yu
 0 measured disturbances d

Расширенная справка

stoch_ym — это объект TransferFunction или StateSpace, который моделирует возмущения на . Его входом является гипотетический вектор белого шума с нулевым средним значением. stoch_ym по умолчанию предполагает, что на каждый измеряемый выход используется один интегратор, при условии, что текущая стохастическая оценка является постоянной в будущем. Это стратегия динамического матричного управления (DMC), которая отличается простотой, но иногда слишком агрессивна. Дополнительные полюсы и нули в stoch_ym позволяют смягчить ситуацию.

Расширение модели по умолчанию

# ModelPredictiveControl.default_nintFunction

default_nint(model::LinModel, i_ym=1:model.ny, nint_u=0) -> nint_ym

Возвращает используемое по умолчанию количество интеграторов на измеряемый выход nint_ym для LinModel.

Аргументы i_ym и nint_u — это соответственно индексы измеряемых выходов и количество интеграторов на каждом обрабатываемом входе. По умолчанию для каждого измеряемого выхода добавляется один интегратор. Если матрицы расширенной модели становятся ненаблюдаемыми, интегратор удаляется. Такой подход хорошо работает с устойчивыми, интегрирующими и неустойчивыми объектами model (см. примеры).

Примеры

julia> model = LinModel(append(tf(3, [10, 1]), tf(2, [1, 0]), tf(4,[-5, 1])), 1.0);

julia> nint_ym = default_nint(model)
3-element Vector{Int64}:
 1
 0
 1
default_nint(model::SimModel, i_ym=1:model.ny, nint_u=0)

По умолчанию один интегратор на каждый измеряемый выход, если объект model не относится к типу LinModel.

Если количество интеграторов на обрабатываемый вход nint_u ≠ 0, этот метод возвращает ноль интеграторов на каждый измеряемый выход.


1. Также обозначается как в других контекстах.