Skip to content

Commit fa48d81

Browse files
committed
added : linearize NonLinModel with ForwardDiff
1 parent 96c20ca commit fa48d81

File tree

3 files changed

+37
-3
lines changed

3 files changed

+37
-3
lines changed

src/model/conversion.jl

Lines changed: 33 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,33 @@
1+
2+
@doc raw"""
3+
LinModel(model::NonLinModel; x=model.x, u=model.uop, d=model.dop)
4+
5+
Linearize `model` around the operating points `x`, `u` and `d`.
6+
7+
The arguments `x`, `u` and `d` are the linearization points for the state ``\mathbf{x}``,
8+
manipulated input ``\mathbf{u}`` and measured disturbance ``\mathbf{d}``, respectively. The
9+
Jacobians of ``\mathbf{f}`` and ``\mathbf{h}`` functions are automatically computed with
10+
[`ForwardDiff.jl`](https://github.com/JuliaDiff/ForwardDiff.jl).
11+
12+
## Examples
13+
```jldoctest
14+
julia> model = NonLinModel((x,u,_)->x.^3+u, (x,_)->x, 0.1, 1, 1, 1);
15+
16+
julia> linmodel = LinModel(model, x=[1.0]); linmodel.A
17+
1×1 Matrix{Float64}:
18+
3.0
19+
```
20+
"""
21+
function LinModel(model::NonLinModel; x=model.x, u=model.uop, d=model.dop)
22+
nu, nx, ny, nd = model.nu, model.nx, model.ny, model.nd
23+
u0, d0 = u - model.uop, d - model.dop
24+
y = model.h(x, d0) + model.yop
25+
A = ForwardDiff.jacobian(x -> model.f(x, u0, d0), x)
26+
Bu = ForwardDiff.jacobian(u0 -> model.f(x, u0, d0), u0)
27+
Bd = ForwardDiff.jacobian(d0 -> model.f(x, u0, d0), d0)
28+
C = ForwardDiff.jacobian(x -> model.h(x, d0), x)
29+
Dd = ForwardDiff.jacobian(d0 -> model.h(x, d0), d0)
30+
linmodel = LinModel(A, Bu, C, Bd, Dd, model.Ts, nu, nx, ny, nd)
31+
setop!(linmodel, uop=u, yop=y, dop=d)
32+
return linmodel
33+
end

src/plot_sim.jl

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -163,7 +163,7 @@ vectors. The simulated sensor and process noises of `plant` are specified by `y_
163163
- `d_step = zeros(plant.nd)` : step on measured disturbances ``\mathbf{d}``.
164164
- `d_noise = zeros(plant.nd)` : additive gaussian noise on measured dist. ``\mathbf{d}``.
165165
- `x_noise = zeros(plant.nx)` : additive gaussian noise on plant states ``\mathbf{x}``.
166-
- `x0 = zeros(plant.nx)` : plant initial state ``\mathbf{x}(0)``.
166+
- `x0 = plant.x` : plant initial state ``\mathbf{x}(0)``.
167167
- `x̂0 = nothing` : initial estimate ``\mathbf{x̂}(0)``, [`initstate!`](@ref) is used if `nothing`.
168168
- `lastu = plant.uop` : last plant input ``\mathbf{u}`` for ``\mathbf{x̂}`` initialization.
169169
@@ -245,7 +245,7 @@ function sim_closedloop!(
245245
d_step ::Vector = zeros(plant.nd),
246246
d_noise::Vector = zeros(plant.nd),
247247
x_noise::Vector = zeros(plant.nx),
248-
x0 = zeros(plant.nx),
248+
x0 = plant.x,
249249
x̂0 = nothing,
250250
lastu = plant.uop,
251251
)

src/sim_model.jl

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -168,4 +168,5 @@ evaloutput(model::SimModel, d=empty(model.x)) = h(model, model.x, d - model.dop)
168168
(model::SimModel)(d=empty(model.x)) = evaloutput(model::SimModel, d)
169169

170170
include("model/linmodel.jl")
171-
include("model/nonlinmodel.jl")
171+
include("model/nonlinmodel.jl")
172+
include("model/conversion.jl")

0 commit comments

Comments
 (0)