Построение систем

# ControlSystemsBase.appendFunction

append(systems::StateSpace...), append(systems::TransferFunction...)

Добавляет системы в блочно-диагональной форме.

# ControlSystemsBase.c2dFunction

sysd = c2d(sys::AbstractStateSpace{<:Continuous}, Ts, method=:zoh; w_prewarp=0)
Gd = c2d(G::TransferFunction{<:Continuous}, Ts, method=:zoh)

Преобразует систему с непрерывным временем sys в систему с дискретным временем с интервалом дискретизации Ts с помощью указанного метода method (:zoh, :foh, :fwdeuler или :tustin).

method = :tustin выполняет билинейное преобразование с частотой предварительного искажения w_prewarp.

  • w_prewarp: частота предварительного искажения (рад/с) при использовании метода Тастина; для других методов не действует.

См. также описание c2d_x0map.

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

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

Дискретизация FoH является точной для линейных систем с кусочно-заданными линейными входами (инвариантное линейное изменение). Это хороший вариант для моделирования систем с плавными непрерывными входными сигналами.

Для качественной аппроксимации поведения системы с непрерывным временем в частотном диапазоне лучше всего может подойти метод :tustin (трапецеидальный билинейный). В этом случае с помощью аргумента предварительного искажения можно обеспечить соответствие частотной характеристики системы с дискретным временем этому же параметру системы с непрерывным временем при заданной частоте. При преобразовании методом Тастина смысл компонентов состояния меняется, а при преобразованиях ZoH и FoH — сохраняется. Метод Тастина широко применяется для дискретизации регулятора с непрерывным временем.

Прямой метод Эйлера, как правило, требует очень небольшого интервала дискретизации относительно постоянных времени системы, поэтому использовать его обычно не рекомендуется.

Согласно классическому правилу выбора интервала дискретизации для расчета системы управления значение Ts должно быть в диапазоне , где  — это частота единичного усиления (рад/с).

Qd     = c2d(sys::StateSpace{Continuous}, Qc::Matrix, Ts;             opt=:o)
Qd, Rd = c2d(sys::StateSpace{Continuous}, Qc::Matrix, Rc::Matrix, Ts; opt=:o)
Qd     = c2d(sys::StateSpace{Discrete},   Qc::Matrix;                 opt=:o)
Qd, Rd = c2d(sys::StateSpace{Discrete},   Qc::Matrix, Rc::Matrix;     opt=:o)

Выбирайте непрерывную во времени ковариацию или матрицу стоимости ЛКР так, чтобы они соответствовали предоставленной системе с дискретным временем.

Если opt = :o (по умолчанию), матрица считается ковариационной. Также можно предоставить ковариацию измерений R. Если же opt = :c, матрица считается матрицей стоимости для задачи ЛКР.

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

Применяемый метод взят из теоремы 5 в указанном ниже источнике.

Источник: Discrete-time Solutions to the Continuous-time Differential Lyapunov Equation With Applications to Kalman Filtering, Патрик Аксельссон (Patrik Axelsson) и Фредрик Густафссон (Fredrik Gustafsson)

В случае с сингулярными ковариационными матрицами традиционный двойной интегратор с ковариационной матрицей Q = diagm([0,σ²]) нельзя дискретизировать этим методом. Вместо этого необходимо вручную отслеживать входную матрицу («множитель Холецкого») Q, например на предмет того, вводится ли шум дисперсии σ² как N = [0, 1], в результате чего он дискретизируется методом ZoH и становится Nd = [1/2 Ts^2; Ts], что дает ковариационную матрицу σ² * Nd * Nd'.

Пример:

В следующем примере синтезируется регулятор ЛКР с непрерывным временем для колебательной системы. Он моделируется с помощью OrdinaryDiffEq, чтобы интегратор ОДУ мог также проинтегрировать стоимость ЛКР с непрерывным временем (стоимость добавляется как дополнительная переменная состояния). Затем мы дискретизируем как систему, так и матрицы стоимости, чтобы смоделировать то же самое. Подобная дискретизация контроллера ЛКР иногда называется lqrd.

using ControlSystemsBase, LinearAlgebra, OrdinaryDiffEq, Test
sysc = DemoSystems.resonant()
x0 = ones(sysc.nx)
Qc = [1 0.01; 0.01 2] # Матрица стоимости с непрерывным временем для состояния
Rc = I(1)             # Матрица стоимости с непрерывным временем для входа

L = lqr(sysc, Qc, Rc)
dynamics = function (xc, p, t)
    x = xc[1:sysc.nx]
    u = -L*x
    dx = sysc.A*x + sysc.B*u
    dc = dot(x, Qc, x) + dot(u, Rc, u)
    return [dx; dc]
end
prob = ODEProblem(dynamics, [x0; 0], (0.0, 10.0))
sol = solve(prob, Tsit5(), reltol=1e-8, abstol=1e-8)
cc = sol.u[end][end] # Стоимость с непрерывным временем

# Вариант с дискретным временем
Ts = 0.01
sysd = c2d(sysc, Ts)
Ld = lqr(sysd, Qd, Rd)
sold = lsim(sysd, (x, t) -> -Ld*x, 0:Ts:10, x0 = x0)
function cost(x, u, Q, R)
    dot(x, Q, x) + dot(u, R, u)
end
cd = cost(sold.x, sold.u, Qd, Rd) # Стоимость с дискретным временем
@test cc ≈ cd rtol=0.01           # Результат должен быть аналогичным
c2d(G::DelayLtiSystem, Ts, method=:zoh)

# ControlSystemsBase.feedbackFunction

feedback(sys)
feedback(sys1, sys2)

Для общей системы ЛПП feedback образует соединение с отрицательной обратной связью.

>-+ sys1 +-->
  |      |
 (-)sys2 +

Если вторая система не задана, предполагается отрицательная тождественная обратная связь.

feedback(sys1::AbstractStateSpace, sys2::AbstractStateSpace;
         U1=:, Y1=:, U2=:, Y2=:, W1=:, Z1=:, W2=Int[], Z2=Int[],
         Wperm=:, Zperm=:, pos_feedback::Bool=false)

Базовое использование: feedback(sys1, sys2) образует соединение с (отрицательной) обратной связью.

           ┌──────────────┐
◄──────────┤     sys1     │◄──── Σ ◄──────
    │      │              │      │
    │      └──────────────┘      -1
    │                            |
    │      ┌──────────────┐      │
    └─────►│     sys2     ├──────┘
           │              │
           └──────────────┘

Если вторая система sys2 не задана, предполагается отрицательная тождественная обратная связь (sys2 = 1).

Расширенное использование: feedback также поддерживает более гибкое использование, как показано на рисунке ниже.

              ┌──────────────┐
      z1◄─────┤     sys1     │◄──────w1
 ┌─── y1◄─────┤              │◄──────u1 ◄─┐
 │            └──────────────┘            │
 │                                        α
 │            ┌──────────────┐            │
 └──► u2─────►│     sys2     ├───────►y2──┘
      w2─────►│              ├───────►z2
              └──────────────┘

U1, W1 — индексы входных сигналов sys1, соответствующие u1 и w1. Y1, Z1 — индексы выходных сигналов sys1, соответствующие y1 и z1. U2, W2, Y2, Z2 — соответствующие сигналы sys2.

Укажите Wperm и Zperm, чтобы изменить порядок входов (соответствующих [w1; w2]) и выходов (соответствующих [z1; z2]) в итоговой модели пространства состояний.

По умолчанию обратная связь отрицательная (α = -1). Для положительной обратной связи (α = 1) укажите pos_feedback=true.

См. также lft, starprod, sensitivity, input_sensitivity, output_sensitivity, comp_sensitivity, input_comp_sensitivity, output_comp_sensitivity, G_PS, G_CS.

В разделе руководства От блок-схем к коду содержатся более подробные инструкции по использованию этой функции.

Схожие (но немного менее симметричные) формулы см. в работе Чжоу (Zhou), Дойла (Doyle), Гловера (Glover) (1996).

# ControlSystemsBase.feedback2dofFunction

feedback2dof(P,R,S,T)
feedback2dof(B,A,R,S,T)
  • Возвращает BT/(AR+ST), где B и A — соответственно многочлен-числитель и многочлен-знаменатель P.

  • Возвращает BT/(AR+ST).

feedback2dof(P::TransferFunction, C::TransferFunction, F::TransferFunction)

Возвращает передаточную функцию, P(F+C)/(1+PC) которая представляет замкнутую систему с процессом P, регулятором C и фильтром прямой обратной связи F от опорного сигнала к управляющему (с обходом C).

         +-------+
         |       |
   +----->   F   +----+
   |     |       |    |
   |     +-------+    |
   |     +-------+    |    +-------+
r  |  -  |       |    |    |       |    y
+--+----->   C   +----+---->   P   +---+-->
      |  |       |         |       |   |
      |  +-------+         +-------+   |
      |                                |
      +--------------------------------+

# ControlSystemsBase.minrealFunction

minreal(tf::TransferFunction, eps=sqrt(eps()))

Создание минимального представления каждой передаточной функции в tf путем отмены полюсов и нулей приведет систему к соответствующему числовому типу.

minreal(sys::T; fast=false, kwargs...)

Алгоритм минимальной реализации см. в документе «The generalized eigenstructure problem in linear system theory, IEEE Transactions on Automatic Control», автор — П. Ван Доорен (P. Van Dooreen).

Сведения о параметрах см. в описании ?ControlSystemsBase.MatrixPencils.lsminreal.

См. также описание функции sminreal, которая является одновременно численно точной и существенно более быстрой, чем minreal, но имеет гораздо более ограниченные возможности по устранению неминимальной динамики.

# ControlSystemsBase.parallelFunction

parallel(sys1::LTISystem, sys2::LTISystem)

Соединяет системы параллельно; эквивалентно sys2+sys1.

# ControlSystemsBase.seriesFunction

series(sys1::LTISystem, sys2::LTISystem)

Соединяет системы последовательно; эквивалентно sys2*sys1.

# ControlSystemsBase.sminrealFunction

sminreal(sys)

Вычисляет структурно минимальную реализацию системы пространства состояний sys. Структурно минимальной является такая реализация, в которой удаляются только те состояния, которые можно определить как неконтролируемые и ненаблюдаемые на основе положения 0s в sys.

Системы с числовым шумом в коэффициентах, например шумом в порядке eps, требуют усечения до нуля, чтобы было возможным структурное упрощение, например:

trunc_zero!(A) = A[abs.(A) .< 10eps(maximum(abs, A))] .= 0
trunc_zero!(sys.A); trunc_zero!(sys.B); trunc_zero!(sys.C)
sminreal(sys)

В отличие от функции minreal, которая производит устранение нулевых значений сигнала с использованием операций линейной алгебры, имеет сложность xD835__xDC42(nₓ{caret}3) и допускает числовые погрешности, функция sminreal требует очень низких вычислительных затрат и обладает числовой точностью (работает с целыми числами). Однако sminreal имеет гораздо меньшую способность к сокращению порядка модели.

См. также описание функции minreal.

# ControlSystemsBase.ssFunction

sys = ss(A, B, C, D)      # Непрерывное
sys = ss(A, B, C, D, Ts)  # Дискретное

Создает модель пространства состояний sys::StateSpace{TE, T} с типом матричного элемента T, и TE является Continuous или <:Discrete.

Если опустить Ts, то это модель с непрерывным временем. В противном случае это модель с дискретным временем с периодом дискретизации Ts.

D можно задать как 0, в этом случае автоматически строится нулевая матрица соответствующего размера. sys = ss(D [, Ts]) задает статическую матрицу усиления D.

Сведения о связывании имен с состояниями, входами и выходами см. в описании named_ss.

# ControlSystemsBase.tfFunction

sys = tf(num, den[, Ts])
sys = tf(gain[, Ts])

Создает в виде доли многочленов:

  • sys::TransferFunction{SisoRational{T,TR}} = numerator/denominator

где T — это тип коэффициентов в многочлене.

  • num: коэффициенты многочлена-числителя. Либо скаляр или вектор для создания систем SISO,

либо массив векторов для создания системы MIMO.

  • den: коэффициенты многочлена-знаменателя. Либо вектор для создания систем SISO,

либо массив векторов для создания системы MIMO.

  • Ts: интервал дискретизации в системе с дискретным временем.

Коэффициенты многочлена упорядочиваются начиная с члена высшего порядка.

Другие варианты использования:

  • tf(sys): преобразует sys в форму tf.

  • tf("s"), tf("z"): создает передаточную функцию с непрерывным временем s или передаточную функцию с дискретным временем z.

  • numpoly(sys), denpoly(sys): получает многочлен-числитель и многочлен-знаменатель для sys в виде матрицы векторов, где внешняя матрица имеет размер n_output × n_inputs.

См. также описание zpk, ss.

# ControlSystemsBase.zpkFunction

zpk(gain[, Ts])
zpk(num, den, k[, Ts])
zpk(sys)

Создает передаточную функцию в виде коэффициента усиления с нулевым полюсом. Числитель и знаменатель представлены своими полюсами и нулями.

  • sys::TransferFunction{SisoZpk{T,TR}} = k*numerator/denominator

, где T — это тип k, а TR — это тип нулей или полюсов, как правило, Float64 и Complex{Float64}.

  • num: корни многочлена-числителя. Либо скаляр или вектор для создания систем SISO,

либо массив векторов для создания системы MIMO.

  • den: корни многочлена-знаменателя. Либо вектор для создания систем SISO,

либо массив векторов для создания системы MIMO.

  • k: коэффициент усиления системы. Не то же самое, что dcgain.

  • Ts: интервал дискретизации в системе с дискретным временем.

Другие варианты использования:

  • zpk(sys): преобразует sys в форму zpk.

  • zpk("s"): создает передаточную функцию s.

# ControlSystemsBase.delayFunction

delay(tau)
delay(tau, Ts)
delay(T::Type{<:Number}, tau)
delay(T::Type{<:Number}, tau, Ts)

Создает чистое временное запаздывание длиной τ типа T.

Типом T по умолчанию является promote_type(Float64, typeof(tau)).

Если задано Ts, запаздывание дискретизируется с временем дискретизации Ts и возвращается объект StateSpace с дискретным временем.

Пример:

Создает LTI-систему с входным запаздыванием L.

L = 1
tf(1, [1, 1])*delay(L)
s = tf("s")
tf(1, [1, 1])*exp(-s*L) # Эквивалентно варианту выше.

# ControlSystemsBase.padeFunction

pade(τ::Real, N::Int)

Вычисляет аппроксимацию Паде N-го порядка для временного запаздывания длиной τ.

pade(G::DelayLtiSystem, N)

Аппроксимирует все временные запаздывания в G аппроксимациями Паде степени N.

# ControlSystemsBase.ssdataFunction

A, B, C, D = ssdata(sys)

Деструктор, выводящий матрицы пространства состояний.

# ControlSystemsBase.seriesformFunction

Gs, k = seriesform(G::TransferFunction{Discrete})

Преобразует передаточную функцию G в вектор передаточных функций второго порядка и скалярный коэффициент усиления k, произведение которых равно G.