Skip to content

Commit 14766cb

Browse files
authored
Merge pull request #239 from JuliaControl/debug_linearize
debug: `linearize!` on `NonLinModel` with non-zero operating points now works
2 parents ffc3bda + 345c605 commit 14766cb

File tree

2 files changed

+32
-13
lines changed

2 files changed

+32
-13
lines changed

src/model/linearization.jl

Lines changed: 16 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -157,9 +157,9 @@ julia> linearize!(linmodel, model, x=[20.0], u=[0.0]); linmodel.A
157157
```
158158
"""
159159
function linearize!(
160-
linmodel::LinModel{NT}, model::SimModel;
160+
linmodel::LinModel, model::SimModel;
161161
x=(model.buffer.x.=model.x0.+model.xop), u=model.uop, d=model.dop
162-
) where NT<:Real
162+
)
163163
nonlinmodel = model
164164
buffer = nonlinmodel.buffer
165165
# --- remove the operating points of the nonlinear model (typically zeros) ---
@@ -172,16 +172,19 @@ function linearize!(
172172
# --- compute the nonlinear model output at operating points ---
173173
x0next, y0 = linmodel.buffer.x, linmodel.buffer.y
174174
h!(y0, nonlinmodel, x0, d0, model.p)
175-
y = y0
176-
y .= y0 .+ nonlinmodel.yop
175+
y0 .+= nonlinmodel.yop
176+
y = y0
177177
# --- compute the nonlinear model next state at operating points ---
178178
f!(x0next, k0, nonlinmodel, x0, u0, d0, model.p)
179-
xnext = x0next
180-
xnext .= x0next .+ nonlinmodel.fop .- nonlinmodel.xop
179+
x0next .+= nonlinmodel.fop
180+
xnext = x0next # xnext = f(x0,u0,d0) + fop - xop + xop = f(x0,u0,d0) + fop
181+
# --- recompute x since it was modified in buffer.x ---
182+
x0 .+= nonlinmodel.xop
183+
x = x0
181184
# --- modify the linear model operating points ---
182185
linmodel.uop .= u
183-
linmodel.yop .= y
184186
linmodel.dop .= d
187+
linmodel.yop .= y
185188
linmodel.xop .= x
186189
linmodel.fop .= xnext
187190
# --- reset the state of the linear model ---
@@ -190,14 +193,14 @@ function linearize!(
190193
end
191194

192195
"Call `linfunc!` function to compute the Jacobians of `model` at the linearization point."
193-
function linearize_core!(linmodel::LinModel, model::SimModel, x0, u0, d0)
194-
x0next, y0 = linmodel.buffer.x, linmodel.buffer.y
196+
function linearize_core!(linmodel::LinModel, model::SimModel, x, u, d)
197+
xnext, y = linmodel.buffer.x, linmodel.buffer.y
195198
A, Bu, C, Bd, Dd = linmodel.A, linmodel.Bu, linmodel.C, linmodel.Bd, linmodel.Dd
196-
cst_x = Constant(x0)
197-
cst_u = Constant(u0)
198-
cst_d = Constant(d0)
199+
cst_x = Constant(x)
200+
cst_u = Constant(u)
201+
cst_d = Constant(d)
199202
backend = model.jacobian
200-
model.linfunc!(x0next, y0, A, Bu, C, Bd, Dd, backend, x0, u0, d0, cst_x, cst_u, cst_d)
203+
model.linfunc!(xnext, y, A, Bu, C, Bd, Dd, backend, x, u, d, cst_x, cst_u, cst_d)
201204
return nothing
202205
end
203206

test/1_test_sim_model.jl

Lines changed: 16 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -371,6 +371,22 @@ end
371371
h2!(y0, x0, _, _) = (y0 .= x0)
372372
nonlinmodel4 = NonLinModel(f2!,h2!,Ts,1,1,1,0,solver=nothing,jacobian=AutoFiniteDiff())
373373
@test_nowarn linearize(nonlinmodel4, x=[1], u=[2])
374+
375+
# test linearization with nonzero operating points in the NonLinModel object:
376+
linmodel_op = LinModel(tf(2, [10, 1]),1)
377+
linmodel_op = setop!(linmodel_op, uop=[10], yop=[20], xop=[-2], fop=[5])
378+
f3!(xnext, x, u, _, p) = (xnext .= p.A*x .+ p.Bu*u)
379+
h3!(y, x, _, p) = (y .= p.C*x)
380+
nonlinmodel_op = NonLinModel(f3!, h3!, 1.0, 1, 1, 1, p=linmodel_op, solver=nothing)
381+
nonlinmodel_op = setop!(linmodel_op, uop=[10], yop=[20], xop=[-2], fop=[5])
382+
linmodel_op_2 = linearize(nonlinmodel_op)
383+
@test linmodel_op.A linmodel_op_2.A
384+
@test linmodel_op.Bu linmodel_op_2.Bu
385+
@test linmodel_op.C linmodel_op_2.C
386+
@test linmodel_op.uop linmodel_op_2.uop
387+
@test linmodel_op.yop linmodel_op_2.yop
388+
@test linmodel_op.xop linmodel_op_2.xop
389+
@test linmodel_op.fop linmodel_op_2.fop
374390
end
375391

376392
@testitem "NonLinModel real time simulations" setup=[SetupMPCtests] begin

0 commit comments

Comments
 (0)