Skip to content

Commit 1af4cd7

Browse files
authored
Merge pull request #41 from baggepinnen/rel
prepare for release
2 parents e8d6619 + 45c585c commit 1af4cd7

File tree

3 files changed

+48
-7
lines changed

3 files changed

+48
-7
lines changed

Project.toml

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -16,13 +16,13 @@ Symbolics = "0c5d862f-8b57-4792-8d23-62f2024744c7"
1616
UnPack = "3a884ed6-31ef-47d7-9d2a-63182c4928ed"
1717

1818
[compat]
19-
ControlSystemIdentification = "2"
20-
ControlSystemsBase = "1"
19+
ControlSystemIdentification = "2.4.1"
20+
ControlSystemsBase = "1.0.1"
2121
ModelingToolkit = "8.18"
2222
ModelingToolkitStandardLibrary = "1.5"
2323
Optim = "1"
2424
OrdinaryDiffEq = "6"
25-
RobustAndOptimalControl = "0.4.13"
25+
RobustAndOptimalControl = "0.4.14"
2626
SymbolicControlSystems = "0.1.3"
2727
Symbolics = "4.10"
2828
UnPack = "1"

README.md

Lines changed: 23 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -100,4 +100,26 @@ ModelingToolkit tends to give weird names to states etc., to access variables ea
100100
julia> P02_named.x
101101
1-element Vector{Symbol}:
102102
Symbol("x[1](t)")
103-
```
103+
```
104+
105+
106+
### Internals: Transformation of non-proper models to proper statespace form
107+
For some models, ModelingToolkit will fail to produce a proper statespace model (a non-proper model is differentiating the inputs, i.e., it has a numerator degree higher than the denominator degree if represented as a transfer function) when calling `linearize`. For such models, given on the form
108+
$$\dot x = Ax + Bu + \bar B \dot u$$
109+
we create the following augmented descriptor model
110+
```math
111+
\begin{aligned}
112+
sX &= Ax + BU + s\bar B U \\
113+
[X_u &= U]\\
114+
s(X - \bar B X_u) &= AX + BU \\
115+
s \begin{bmatrix}I & -\bar B \\ 0 & 0 \end{bmatrix} &=
116+
\begin{bmatrix} A & 0 \\ 0 & -I\end{bmatrix}
117+
\begin{bmatrix}X \\ X_u \end{bmatrix} +
118+
\begin{bmatrix} B \\ I_u\end{bmatrix} U \\
119+
sE &= A_e x_e + B_e u
120+
\end{aligned}
121+
```
122+
where $X_u$ is a new algebraic state variable and $I_u$ is a selector matrix that picks out the differentiated inputs appearing in $\dot u$ (if all inputs appear, $I_u = I$).
123+
124+
This model may be converted to a proper statespace model (if the system is indeed proper) using `DescriptorSystems.dss2ss`.
125+
All of this is handled automatically by `named_ss(sys)`.

src/ode_system.jl

Lines changed: 22 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -206,12 +206,31 @@ function RobustAndOptimalControl.named_ss(
206206
matrices, ssys = ModelingToolkit.linearize(sys, inputs, outputs; kwargs...)
207207
symstr(x) = Symbol(string(x))
208208
unames = symstr.(inputs)
209-
if size(matrices.B, 2) == 2length(inputs)
209+
nu = length(inputs)
210+
ny = length(outputs)
211+
if size(matrices.B, 2) == 2nu
212+
nx = size(matrices.A, 1)
210213
# This indicates that input derivatives are present
211-
unames = [unames; Symbol.("der_" .* string.(unames))]
214+
duinds = findall(any(!iszero, eachcol(matrices.B[:, nu+1:end])))
215+
= matrices.B[:, duinds .+ nu]
216+
ndu = length(duinds)
217+
B = matrices.B[:, 1:nu]
218+
Iu = duinds .== (1:nu)'
219+
E = [I(nx) -B̄; zeros(ndu, nx+ndu)]
220+
221+
Ae = cat(matrices.A, -I(ndu), dims=(1,2))
222+
Be = [B; Iu]
223+
Ce = [matrices.C zeros(ny, ndu)]
224+
De = matrices.D[:, 1:nu]
225+
dsys = dss(Ae, E, Be, Ce, De)
226+
sys = ss(RobustAndOptimalControl.DescriptorSystems.dss2ss(dsys)[1])
227+
# unames = [unames; Symbol.("der_" .* string.(unames))]
228+
# sys = ss(matrices...)
229+
else
230+
sys = ss(matrices...)
212231
end
213232
named_ss(
214-
ss(matrices...);
233+
sys;
215234
x = symstr.(states(ssys)),
216235
u = unames,
217236
y = symstr.(outputs),

0 commit comments

Comments
 (0)