Skip to content

Commit 10b3e51

Browse files
authored
Merge pull request #967 from JuliaControl/bwdeuler
add backward euler discretization
2 parents b3310f4 + e28eafc commit 10b3e51

File tree

2 files changed

+15
-3
lines changed

2 files changed

+15
-3
lines changed

lib/ControlSystemsBase/src/discrete.jl

Lines changed: 13 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -67,6 +67,13 @@ function c2d_x0map(sys::AbstractStateSpace{<:Continuous}, Ts::Real, method::Symb
6767
elseif method === :fwdeuler
6868
Ad, Bd, Cd, Dd = (I+Ts*A), Ts*B, C, D
6969
x0map = I(nx)
70+
elseif method === :bwdeuler
71+
Ad = inv(I - Ts*A)
72+
TsB = Ts*B
73+
Bd = (Ad * TsB)
74+
Cd = C*Ad
75+
Dd = Cd * TsB + D
76+
x0map = I(nx)
7077
elseif method === :tustin
7178
a = w_prewarp == 0 ? Ts/2 : tan(w_prewarp*Ts/2)/w_prewarp
7279
a > 0 || throw(DomainError("A positive w_prewarp must be provided for method Tustin"))
@@ -77,7 +84,7 @@ function c2d_x0map(sys::AbstractStateSpace{<:Continuous}, Ts::Real, method::Symb
7784
Dd = a*Cd*B + D
7885
x0map = Matrix{T}(I, nx, nx)
7986
elseif method === :matched
80-
error("NotImplemented: Only `:zoh`, `:foh`, :tustin and `:fwdeuler` implemented so far")
87+
error("NotImplemented: Only `:zoh`, `:foh`, :tustin, `:fwdeuler` and `bwdeuler` implemented so far")
8188
else
8289
error("Unsupported method: ", method)
8390
end
@@ -111,6 +118,11 @@ function d2c(sys::AbstractStateSpace{<:Discrete}, method::Symbol=:zoh; w_prewarp
111118
Ac = (A-I)./sys.Ts
112119
Bc = B./sys.Ts
113120
Cc, Dc = C, D
121+
elseif method === :bwdeuler
122+
Ac = (I - inv(A))/sys.Ts
123+
Bc = (A\B) ./ sys.Ts
124+
Cc = C/A
125+
Dc = D - sys.Ts*C*Bc
114126
elseif method === :tustin
115127
a = w_prewarp == 0 ? sys.Ts/2 : tan(w_prewarp*sys.Ts/2)/w_prewarp
116128
a > 0 || throw(DomainError("A positive w_prewarp must be provided for method Tustin"))

lib/ControlSystemsBase/test/test_discrete.jl

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -77,9 +77,9 @@ sysd = c2d(sys, 1)
7777
@test d2c(sysd) sys
7878

7979

80-
# forward euler / tustin
80+
# forward euler / tustin / backward euler
8181
@test c2d(C_111, 1, :fwdeuler).A == I + C_111.A
82-
for method in (:fwdeuler, :tustin)
82+
for method in (:fwdeuler, :tustin, :bwdeuler)
8383
@test d2c(c2d(C_111, 0.01, method), method) C_111 atol = sqrt(eps())
8484
@test d2c(c2d(C_212, 0.01, method), method) C_212 atol = sqrt(eps())
8585
@test d2c(c2d(C_221, 0.01, method), method) C_221 atol = sqrt(eps())

0 commit comments

Comments
 (0)