Skip to content

Commit

Permalink
Merge pull request #22 from JuliaComputing/smc
Browse files Browse the repository at this point in the history
add sliding mode control example
  • Loading branch information
baggepinnen authored Sep 5, 2024
2 parents 2652dce + b57339d commit a5de747
Show file tree
Hide file tree
Showing 3 changed files with 95 additions and 1 deletion.
1 change: 1 addition & 0 deletions docs/make.jl
Original file line number Diff line number Diff line change
Expand Up @@ -33,6 +33,7 @@ makedocs(;
"Examples" => [
"Controlled DC motor" => "examples/dc_motor_pi.md",
"On-off controller" => "examples/onoffcontroller.md",
"Sliding-mode control" => "examples/sliding_mode_control.md",
],
"Library API" => "blocks.md",
],
Expand Down
93 changes: 93 additions & 0 deletions docs/src/examples/sliding_mode_control.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,93 @@
# Sliding-mode control
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.

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.

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
```math
ė = -e
```
which yields the switching variable ``s = ė + e``, encoded in the function ``s = σ(x, t)``

```@example ONOFF
using ModelingToolkit, ModelingToolkitSampledData, OrdinaryDiffEq, Plots
using ModelingToolkit: t_nounits as t, D_nounits as D
using ModelingToolkitStandardLibrary.Blocks
using JuliaSimCompiler
dt = 0.01
clock = Clock(dt)
z = ShiftIndex(clock)
qr(t) = 1sin(2t) # reference position
qdr(t) = 2cos(2t) # reference velocity
function σ(x, t)
q, qd = x
e = q - qr(t)
ė = qd - qdr(t)
ė + e
end
@register_symbolic σ(x, t::Real)
@mtkmodel SuperTwistingSMC begin
@structural_parameters begin
z = ShiftIndex()
Ts = SampleTime()
nin
end
@components begin
input = RealInput(; nin)
output = RealOutput()
end
@parameters begin
k = 1, [description = "Control gain"]
k2 = 1.1, [description = "Tuning parameter, often set to 1.1"]
end
@variables begin
s(t) = 0.0, [description = "Sliding surface"]
p(t) = 0.0
y(t) = 0.0, [description = "Control signal output"]
x(t) = 0.0
xd(t) = 0.0
end
@equations begin
s(z) ~ σ(input.u, t)
p ~ -√(k*abs(s))*sign(s)
xd ~ -k2*k*sign(s)
x(z) ~ x(z-1) + Ts*xd # Fwd Euler integration
y ~ p + x
output.u ~ y
end
end
@mtkmodel ClosedLoopModel begin
@components begin
plant = SecondOrder(;)
zoh = ZeroOrderHold()
controller = SuperTwistingSMC(nin = 2, k=50)
end
@variables begin
disturbance(t) = 0.0
end
@equations begin
controller.input.u ~ [Sample(dt)(plant.x), Sample(dt)(plant.xd)]
disturbance ~ 2 + 2sin(3t) + sin(5t)
connect(controller.output, zoh.input)
zoh.output.u + disturbance ~ plant.input.u
end
end
@named m = ClosedLoopModel()
m = complete(m)
ssys = structural_simplify(IRSystem(m))
prob = ODEProblem(ssys, [m.plant.x => -1, m.plant.xd => 0, m.controller.x(z-1) => 0], (0.0, 2π))
sol = solve(prob, Tsit5(), dtmax=0.01)
figy = plot(sol, idxs=[m.plant.x])
plot!(sol.t, qr.(sol.t), label="Reference")
figu = plot(sol, idxs=[m.zoh.y, m.disturbance], label=["Control signal" "Disturbance"])
plot(figy, figu, layout=(2,1))
```

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.

2 changes: 1 addition & 1 deletion src/discrete_blocks.jl
Original file line number Diff line number Diff line change
Expand Up @@ -987,7 +987,7 @@ Discrete-time On-Off controller with hysteresis. The controller switches between
# Parameters:
- `b`: Bandwidth around reference signal within which the controller does not react
- `bool`: (structural) If true (default), the controller switches between 0 and 1. If false, the controller switches between -1 and 1.
- `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.
- `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.
"""
@mtkmodel DiscreteOnOffController begin
@extend u, y = siso = SISO()
Expand Down

0 comments on commit a5de747

Please sign in to comment.