Skip to content

Commit a5de747

Browse files
authored
Merge pull request #22 from JuliaComputing/smc
add sliding mode control example
2 parents 2652dce + b57339d commit a5de747

File tree

3 files changed

+95
-1
lines changed

3 files changed

+95
-1
lines changed

docs/make.jl

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -33,6 +33,7 @@ makedocs(;
3333
"Examples" => [
3434
"Controlled DC motor" => "examples/dc_motor_pi.md",
3535
"On-off controller" => "examples/onoffcontroller.md",
36+
"Sliding-mode control" => "examples/sliding_mode_control.md",
3637
],
3738
"Library API" => "blocks.md",
3839
],
Lines changed: 93 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,93 @@
1+
# Sliding-mode control
2+
This example demonstrates how to model a system with a discrete-time sliding-mode controller using ModelingToolkit. The system consists of a second-order plant with a disturbance and a super-twisting sliding-mode controller. The controller is implemented as a discrete-time system, and the plant is modeled as a continuous-time system.
3+
4+
When designing an SMC controller, we must choose a _switching function_ ``σ`` that produces the sliding variable ``s = σ(x, p, t)``. The sliding surface ``s=0`` must be chosen such that the sliding variable ``s`` exhibits desireable properties, i.e., converges to the desired state with stable dynamics. The control law is chosen to drive the system from any state ``x : s ≠ 0`` to the sliding surface ``s=0``. The sliding surface is commonly chosen as an asymptotically stable system with order equal to the ``n_x-n_u``, where ``n_x`` is the dimension of the state in the system to be controlled, and ``n_u`` is the number of inputs.
5+
6+
Since the dynamics in this example is of relative degree ``r=2``, we will choose a switching surface corresponding to a stable first-order system (``r-1=1``). We will choose the system
7+
```math
8+
ė = -e
9+
```
10+
which yields the switching variable ``s = ė + e``, encoded in the function ``s = σ(x, t)``
11+
12+
```@example ONOFF
13+
using ModelingToolkit, ModelingToolkitSampledData, OrdinaryDiffEq, Plots
14+
using ModelingToolkit: t_nounits as t, D_nounits as D
15+
using ModelingToolkitStandardLibrary.Blocks
16+
using JuliaSimCompiler
17+
dt = 0.01
18+
clock = Clock(dt)
19+
z = ShiftIndex(clock)
20+
21+
qr(t) = 1sin(2t) # reference position
22+
qdr(t) = 2cos(2t) # reference velocity
23+
24+
function σ(x, t)
25+
q, qd = x
26+
e = q - qr(t)
27+
ė = qd - qdr(t)
28+
ė + e
29+
end
30+
31+
@register_symbolic σ(x, t::Real)
32+
33+
@mtkmodel SuperTwistingSMC begin
34+
@structural_parameters begin
35+
z = ShiftIndex()
36+
Ts = SampleTime()
37+
nin
38+
end
39+
@components begin
40+
input = RealInput(; nin)
41+
output = RealOutput()
42+
end
43+
@parameters begin
44+
k = 1, [description = "Control gain"]
45+
k2 = 1.1, [description = "Tuning parameter, often set to 1.1"]
46+
end
47+
@variables begin
48+
s(t) = 0.0, [description = "Sliding surface"]
49+
p(t) = 0.0
50+
y(t) = 0.0, [description = "Control signal output"]
51+
x(t) = 0.0
52+
xd(t) = 0.0
53+
end
54+
@equations begin
55+
s(z) ~ σ(input.u, t)
56+
p ~ -√(k*abs(s))*sign(s)
57+
xd ~ -k2*k*sign(s)
58+
x(z) ~ x(z-1) + Ts*xd # Fwd Euler integration
59+
y ~ p + x
60+
output.u ~ y
61+
end
62+
end
63+
64+
65+
@mtkmodel ClosedLoopModel begin
66+
@components begin
67+
plant = SecondOrder(;)
68+
zoh = ZeroOrderHold()
69+
controller = SuperTwistingSMC(nin = 2, k=50)
70+
end
71+
@variables begin
72+
disturbance(t) = 0.0
73+
end
74+
@equations begin
75+
controller.input.u ~ [Sample(dt)(plant.x), Sample(dt)(plant.xd)]
76+
disturbance ~ 2 + 2sin(3t) + sin(5t)
77+
connect(controller.output, zoh.input)
78+
zoh.output.u + disturbance ~ plant.input.u
79+
end
80+
end
81+
@named m = ClosedLoopModel()
82+
m = complete(m)
83+
ssys = structural_simplify(IRSystem(m))
84+
prob = ODEProblem(ssys, [m.plant.x => -1, m.plant.xd => 0, m.controller.x(z-1) => 0], (0.0, 2π))
85+
sol = solve(prob, Tsit5(), dtmax=0.01)
86+
figy = plot(sol, idxs=[m.plant.x])
87+
plot!(sol.t, qr.(sol.t), label="Reference")
88+
figu = plot(sol, idxs=[m.zoh.y, m.disturbance], label=["Control signal" "Disturbance"])
89+
plot(figy, figu, layout=(2,1))
90+
```
91+
92+
The simulation indicates that the controller is able to track the reference signal despite the presence of the disturbance. The control signal exhibits a small degree of high-frequency chattering, a common characteristic of sliding-mode controllers.
93+

src/discrete_blocks.jl

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -987,7 +987,7 @@ Discrete-time On-Off controller with hysteresis. The controller switches between
987987
# Parameters:
988988
- `b`: Bandwidth around reference signal within which the controller does not react
989989
- `bool`: (structural) If true (default), the controller switches between 0 and 1. If false, the controller switches between -1 and 1.
990-
- `k`: Controller gain. The output of the contorller is scaled by this gain, i.e., `k = 2, bool = false` will result in an output of -2 or 2.
990+
- `k`: Controller gain. The output of the controller is scaled by this gain, i.e., `k = 2, bool = false` will result in an output of -2 or 2.
991991
"""
992992
@mtkmodel DiscreteOnOffController begin
993993
@extend u, y = siso = SISO()

0 commit comments

Comments
 (0)