Controllers¶
Controllers in OpenSMC integrate sliding surfaces and reaching laws to compute the actual control input \(u\) applied to the plant. OpenSMC includes 17 different controller types, from classical SMC to adaptive, fuzzy, and higher-order variants.
Usage Example¶
from opensmc.controllers import AdaptiveSMC
from opensmc.surfaces import LinearSurface
from opensmc.reaching import ConstantRate
# Compose an Adaptive SMC controller
surface = LinearSurface(c=5.0)
reaching = ConstantRate(k=2.0)
controller = AdaptiveSMC(surface, reaching, adaptation_gain=0.1)
# Compute control input for a given state
u = controller.compute(state=[1.0, 0.0], reference=[0.0, 0.0])
Available Controllers¶
controllers
¶
OpenSMC Controllers — 15 SMC + 2 baselines (PID, LQR).
Classes¶
AdaptiveSMC
¶
Bases: Controller
Adaptive SMC with online gain adaptation.
Parameters¶
surface : SlidingSurface or None Pluggable surface. If None, uses s = c*e + edot. reaching : ReachingLaw or None Pluggable reaching law (overrides internal logic if provided). c : float Surface slope. gamma : float Adaptation rate (eta_dot = gamma * |s|). eta0 : float Initial switching gain. eta_max : float Upper bound on eta (projection). lam : float Proportional sliding gain. dt : float Integration timestep for eta update (forward Euler). threshold : float Adaptation dead-zone: eta only adapts when |s| > threshold.
Source code in opensmc/controllers/adaptive.py
20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 | |
Functions¶
compute(t, x, xref, plant=None, **kwargs)
¶
Compute adaptive SMC control.
Parameters¶
t : float x : array [x1, x2] xref : array [xref1, xref2] plant : Plant or None
Returns¶
u : float info : dict with keys 's', 'eta', 'u_eq', 'u_rob'
Source code in opensmc/controllers/adaptive.py
AggregatedHSMC
¶
Bases: Controller
Aggregated Hierarchical SMC (Qian & Yi 2015, Sec 4.2).
Surfaces
s1 = c1e1 + e2 (trolley subsystem) s2 = c2e3 + e4 (swing subsystem) S = alpha*s1 + s2 (hierarchical combination)
Control
ueq1 = -(c1xdot + f1) / b1 ueq2 = -(c2thetadot + f2) / b2 den = alphab1 + b2 u = (alphab1ueq1 + b2ueq2 + kappaS + etasign(S)) / den
Parameters¶
c1 : float — trolley surface slope c2 : float — swing surface slope alpha : float — hierarchical weighting kappa : float — proportional reaching gain eta : float — switching gain u_max : float — control saturation
Source code in opensmc/controllers/hsmc.py
Functions¶
compute(t, x, xref, plant=None, **kwargs)
¶
Compute aggregated HSMC control.
Parameters¶
t : float x : array [x_trolley, xdot, theta, thetadot] xref : array [xref, xdot_ref, theta_ref, thetadot_ref] plant : Plant with get_fb(x) method or None
Returns¶
u : float info : dict with 's', 's1', 's2'
Source code in opensmc/controllers/hsmc.py
ClassicalSMC
¶
Bases: Controller
Classical SMC — generic surface + reaching law composition.
Parameters¶
surface : SlidingSurface or None Pluggable sliding surface. If None, uses s = ce + edot. reaching : ReachingLaw or None Pluggable reaching law. If None, uses -ks - etasign(s). c : float Surface slope (used when surface is None). k : float Exponential reaching gain (used when reaching is None). eta : float Switching gain (used when reaching is None). J : float Inertia / plant gain (u_eq = J(-c*edot + xref_ddot)). Set J=1 for a unit double integrator.
Source code in opensmc/controllers/classical.py
Functions¶
compute(t, x, xref, plant=None, **kwargs)
¶
Compute classical SMC control.
Parameters¶
t : float x : array [x1, x2] — current state xref : array [xref1, xref2] or [xref1, xref2, xref_ddot] plant : Plant or None **kwargs : xref_ddot : float — reference acceleration (default 0)
Returns¶
u : float info : dict with keys 's', 'u_eq', 'u_rob', 'e', 'edot'
Source code in opensmc/controllers/classical.py
CombiningHSMC
¶
Bases: Controller
Combining Hierarchical SMC (Qian & Yi 2015, Sec 4.4).
Intermediate variable with sign-switching (Eq 4.58): c_eff = |c| if e1*e3 >= 0, else -|c| z = e1 + c_eff * e3 zdot = e2 + c_eff * e4 s = alpha * z + zdot
Control
ueq = (alpha(e2 + c_effe4) - (f1 + c_efff2)) / (b1 + c_effb2) usw = (kappas + etasign(s)) / (b1 + c_eff*b2) u = ueq + usw
Tuning note: c must satisfy c << l (cable length) to avoid denominator discontinuity. For l=0.305, c=0.01 is stable.
Parameters¶
c : float — combining coefficient (|c| << cable length) alpha : float — surface parameter kappa : float — reaching gain eta : float — switching gain u_max : float — control saturation
Source code in opensmc/controllers/hsmc.py
209 210 211 212 213 214 215 216 217 218 219 220 221 222 223 224 225 226 227 228 229 230 231 232 233 234 235 236 237 238 239 240 241 242 243 244 245 246 247 248 249 250 251 252 253 254 255 256 257 258 259 260 261 262 263 264 265 266 267 268 269 270 271 272 273 274 275 276 277 278 279 280 281 282 283 284 285 286 287 288 289 290 291 292 293 294 | |
Functions¶
compute(t, x, xref, plant=None, **kwargs)
¶
Compute combining HSMC control.
Parameters¶
t : float x : array [x_trolley, xdot, theta, thetadot] xref : array [xref, xdot_ref, theta_ref, thetadot_ref] plant : Plant with get_fb(x) or None
Returns¶
u : float info : dict with 's', 'z', 'c_eff'
Source code in opensmc/controllers/hsmc.py
DiscreteSMC
¶
Bases: Controller
Discrete-time SMC with Gao reaching law.
Parameters¶
surface : SlidingSurface or None Pluggable surface. If None, uses s = ce + edot. reaching : ReachingLaw or None If provided, overrides internal Gao reaching law. c : float Surface slope. q_rate : float Exponential reaching rate (must satisfy qTs < 1). epsilon : float Constant reaching gain. Ts : float Sampling period. u_max : float Control saturation.
Source code in opensmc/controllers/discrete.py
Attributes¶
quasi_sliding_band
property
¶
Theoretical quasi-sliding band width.
Functions¶
compute(t, x, xref, plant=None, **kwargs)
¶
Compute discrete SMC control.
Parameters¶
t : float — current discrete time x : array [x1, x2] — current state xref : array [xref1, xref2] — reference state plant : Plant or None
Returns¶
u : float info : dict with 's', 'band'
Source code in opensmc/controllers/discrete.py
DynamicSMC
¶
Bases: Controller
Dynamic SMC — continuous control via integrated udot.
Parameters¶
surface : SlidingSurface or None Pluggable surface. If None, uses s = ce + edot. reaching : ReachingLaw or None If provided, used for the sigma-level reaching. c : float Surface slope. K : float Switching gain on sigma (lives in udot, not u). lam : float Dynamic surface parameter (sigma = sdot + lams). q : float Proportional gain on sigma. u_max : float Control saturation limit. dt : float Integration timestep for u update.
Source code in opensmc/controllers/dynamic.py
Functions¶
compute(t, x, xref, plant=None, **kwargs)
¶
Compute dynamic SMC control.
Parameters¶
t : float x : array [x1, x2] xref : array [xref1, xref2] plant : Plant or None
Returns¶
u : float info : dict with keys 's', 'sigma', 'udot'
Source code in opensmc/controllers/dynamic.py
FixedTimeSMC
¶
Bases: Controller
Fixed-time SMC with bi-power reaching law.
Parameters¶
surface : SlidingSurface or None Pluggable surface. If None, uses s = c*e + edot. reaching : ReachingLaw or None If provided, overrides bi-power reaching. c : float Surface slope. alpha : float Sub-linear reaching gain (handles small |s|). beta : float Super-linear reaching gain (handles large |s|). p : float Sub-linear power, 0 < p < 1. q : float Super-linear power, q > 1.
Source code in opensmc/controllers/fixed_time.py
Attributes¶
T_max
property
¶
Upper bound on settling time (independent of IC).
Functions¶
compute(t, x, xref, plant=None, **kwargs)
¶
Compute fixed-time SMC control.
Parameters¶
t : float x : array [x1, x2] xref : array [xref1, xref2] plant : Plant or None
Returns¶
u : float info : dict with 's', 'u_eq', 'u_ft', 'T_max'
Source code in opensmc/controllers/fixed_time.py
FuzzySMC
¶
Bases: Controller
Fuzzy SMC — smooth gain modulation via Mamdani inference.
Parameters¶
surface : SlidingSurface or None Pluggable surface. If None, uses s = c*e + edot. reaching : ReachingLaw or None If provided, overrides fuzzy reaching. c : float Surface slope. k : float Maximum switching gain. s_range : float Normalization range for s in fuzzy inference. sdot_range : float Normalization range for sdot in fuzzy inference. dt : float Timestep for numerical sdot estimation.
Source code in opensmc/controllers/fuzzy.py
115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 205 206 207 208 209 210 | |
Functions¶
compute(t, x, xref, plant=None, **kwargs)
¶
Compute fuzzy SMC control.
Parameters¶
t : float x : array [x1, x2] xref : array [xref1, xref2] plant : Plant or None
Returns¶
u : float info : dict with 's', 'k_fuzzy', 'sdot'
Source code in opensmc/controllers/fuzzy.py
ITSMC
¶
Bases: Controller
Integral Terminal SMC (Al Ghanimi 2026).
Parameters¶
surface : SlidingSurface or None If provided, overrides the built-in ITSMC surface. reaching : ReachingLaw or None If provided, overrides the built-in reaching law. c1 : float Linear error gain. c2 : float Integral terminal gain. p : int Numerator of fractional power (p < q). q : int Denominator of fractional power. K : float Saturation-based switching gain. lambda_s : float Proportional sliding gain. phi : float Boundary layer thickness for saturation. dt : float Integration timestep for integral state E.
Source code in opensmc/controllers/itsmc.py
35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 | |
Functions¶
compute(t, x, xref, plant=None, **kwargs)
¶
Compute ITSMC control.
Parameters¶
t : float x : array [x1, x2] xref : array [xref1, xref2] or [xref1, xref2, xref_ddot] plant : Plant or None **kwargs : xref_ddot : float — reference acceleration (default 0)
Returns¶
u : float info : dict with 's', 'E', 'u_eq', 'u_rob', 'e', 'edot'
Source code in opensmc/controllers/itsmc.py
IncrementalHSMC
¶
Bases: Controller
Incremental Hierarchical SMC (Qian & Yi 2015, Sec 4.3).
Three-layer incremental hierarchical sliding surface
Layer 1: s1 = c1e1 + e2 Layer 2: s2 = c2_effe3 + s1 Layer 3: s3 = c3*e4 + s2
Sign-switching rule (Eq 4.34): c2_eff = +|c2| if x[2]s1 <= 0 c2_eff = -|c2| if x[2]s1 > 0
Control (derived from sdot3 = 0): ueq = -(c3f2 + f1 + c2_effthetadot + c1xdot) / (c3b2 + b1) usw = +(kappas3 + etasign(s3)) / (c3*b2 + b1) u = ueq + usw
Parameters¶
c1 : float — layer 1 slope c2 : float — layer 2 coupling (absolute value; sign switches) c3 : float — layer 3 slope kappa : float — reaching gain eta : float — switching gain u_max : float — control saturation
Source code in opensmc/controllers/hsmc.py
119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 205 206 | |
Functions¶
compute(t, x, xref, plant=None, **kwargs)
¶
Compute incremental HSMC control.
Parameters¶
t : float x : array [x_trolley, xdot, theta, thetadot] xref : array [xref, xdot_ref, theta_ref, thetadot_ref] plant : Plant with get_fb(x) or None
Returns¶
u : float info : dict with 's' (=s3), 's1', 's2', 'c2_eff'
Source code in opensmc/controllers/hsmc.py
LQR
¶
Bases: Controller
Linear Quadratic Regulator for benchmark comparison.
u = -K @ (x - xref)
where K = R^{-1} B^T P and P solves the CARE.
Parameters¶
A : ndarray (n, n) State matrix of the linearized system. B : ndarray (n, m) Input matrix. Q : ndarray (n, n) or None State cost matrix. If None, uses identity. R : ndarray (m, m) or None Input cost matrix. If None, uses identity. u_max : float or None Control saturation limit.
Example¶
For a double integrator (xddot = u): A = [[0, 1], [0, 0]] B = [[0], [1]] Q = [[10, 0], [0, 1]] (penalize position more) R = [[1]]
Source code in opensmc/controllers/lqr.py
23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 | |
Functions¶
compute(t, x, xref, plant=None, **kwargs)
¶
Compute LQR control: u = -K @ (x - xref).
Parameters¶
t : float x : ndarray (n,) xref : ndarray (n,) — reference state (regulation target)
Returns¶
u : float or ndarray info : dict with 's' (= position error), 'K'
Source code in opensmc/controllers/lqr.py
NFTSMC
¶
Bases: Controller
Nonsingular Fast Terminal SMC (Al Ghanimi 2026).
Parameters¶
surface : SlidingSurface or None If provided, overrides the built-in NFTSMC surface. reaching : ReachingLaw or None If provided, overrides the built-in reaching law. alpha : float Linear error gain. beta : float Terminal error gain. gamma : float Terminal power (1 < gamma < 2, singularity-free). k1 : float Proportional reaching gain. k2 : float Power reaching gain. rho : float Reaching power (typically ~5/7). eta : float Continuous switching gain. delta : float Smoothing parameter for sn = s/(|s|+delta). kI : float Integral action gain (0 = disabled). g_input : float Input gain (for xddot = f + g*u, default g=1). dt : float Timestep for integral state update.
Source code in opensmc/controllers/nftsmc.py
25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 | |
Functions¶
compute(t, x, xref, plant=None, **kwargs)
¶
Compute NFTSMC control.
Parameters¶
t : float x : array [x1, x2] xref : array [xref1, xref2] — reference (constant or slow-varying) plant : Plant or None **kwargs : f_plant : float — plant nonlinearity f(x) if known (default 0)
Returns¶
u : float info : dict with 's', 'ds', 'sn', 'e', 'edot', 'e_int'
Source code in opensmc/controllers/nftsmc.py
NestedHOSMC
¶
Bases: Controller
Nested r-sliding mode controller (Levant 2003, Shtessel Sec 6.6.1).
Recursive definition
N_{i,r} = (Σ_{j=0}^{i-1} |σ^{(j)}|^{q/(r-j)})^{1/q} Ψ_{0,r} = sign(σ) Ψ_{i,r} = sign(σ^{(i)} + β_i · N_{i,r} · Ψ_{i-1,r}) u = -α · Ψ_{r-1,r}
where q = lcm(1, 2, ..., r) ensures integer exponents.
Special cases
r=1: u = -α · sign(σ) (relay control) r=2: u = -α · sign(σ̇ + β|σ|^½·sign(σ)) (prescribed convergence)
Parameters¶
order : int Sliding mode order r (= relative degree of the system). alpha : float Control magnitude. Must be large enough for convergence. betas : list of float or None Gains [β_1, ..., β_{r-1}]. Length must be r-1. If None, uses [1.0, 2.0, 3.0, ...] (heuristic defaults). c : float Surface slope for computing σ = c·e + edot when order=2 and no explicit sigma_derivs are provided. g_sign : float Sign of the input gain in σ^{(r)} = h + g·u. Default -1 for σ=e on standard plants where σ̈=-u.
Source code in opensmc/controllers/hosmc.py
37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 | |
Functions¶
compute(t, x, xref, plant=None, **kwargs)
¶
Compute nested HOSMC control.
Parameters¶
t : float x : ndarray — state vector xref : ndarray — reference sigma_derivs : list of float, optional [σ, σ̇, ..., σ^{(r-1)}]. If not provided, computed from (x, xref) assuming 2nd-order system with σ = c·e + edot.
Returns¶
u : float info : dict with 's', 'psi'
Source code in opensmc/controllers/hosmc.py
PID
¶
Bases: Controller
Standard PID controller for benchmark comparison.
u = Kp * e + Kd * edot + Ki * integral(e)
For multi-input systems (n_inputs > 1), applies independent PID per channel using diagonal gain matrices.
Parameters¶
Kp : float or ndarray Proportional gain. Kd : float or ndarray Derivative gain. Ki : float or ndarray Integral gain (default 0 = PD controller). dt : float Time step for integral accumulation. u_max : float or None Control saturation limit. If None, no saturation. n_channels : int Number of independent control channels (default 1).
Source code in opensmc/controllers/pid.py
Functions¶
compute(t, x, xref, plant=None, **kwargs)
¶
Compute PID control.
For a 2nd-order single-channel system
e = xref[0] - x[0], edot = xref[1] - x[1]
For multi-channel (e.g., 2-link arm): e = [xref[0]-x[0], xref[2]-x[2]], edot = [xref[1]-x[1], xref[3]-x[3]]
Returns¶
u : float or ndarray info : dict with 's' (= e for PID), 'e', 'edot'
Source code in opensmc/controllers/pid.py
QuasiContinuous2SMC
¶
Bases: Controller
Quasi-continuous 2-sliding mode controller (Levant 2005, Shtessel Eq 4.30).
u = -α · (σ̇ + β|σ|^{1/2} · sign(σ)) / (|σ̇| + β|σ|^{1/2})
Parameters¶
alpha : float Control magnitude. Must satisfy α·Km - C > β²/2 where Km is the minimum input gain and C is the disturbance bound. beta : float Convergence parameter. Larger β gives faster convergence but requires larger α. Typical: β = 1.0 to 5.0. c : float Surface slope for computing σ = c·e + edot (when no surface is provided). surface : SlidingSurface or None Optional pluggable surface for σ computation. epsilon : float Small positive constant to avoid division by zero when both σ and σ̇ are very close to zero. Default 1e-10.
Source code in opensmc/controllers/quasi_continuous.py
Functions¶
compute(t, x, xref, plant=None, **kwargs)
¶
Compute quasi-continuous 2-SM control.
Parameters¶
t : float Current time. x : ndarray State vector. For 2nd-order: [x1, x2]. xref : ndarray Reference. For 2nd-order: [xref1, xref2]. plant : Plant or None Not used (model-free controller).
Returns¶
u : float Control signal, bounded by |u| ≤ α. info : dict Contains 's' (σ), 'sdot' (σ̇), 'e', 'edot'.
Source code in opensmc/controllers/quasi_continuous.py
QuasiContinuousHOSMC
¶
Bases: Controller
Quasi-continuous r-sliding mode controller (Levant 2005, Shtessel Sec 6.6.2).
Recursive definition
φ_{0,r} = σ, N_{0,r} = |σ|, Ψ_{0,r} = sign(σ) φ_{i,r} = σ^{(i)} + β_i · N_{i-1,r}^{(r-i)/(r-i+1)} · Ψ_{i-1,r} N_{i,r} = |σ^{(i)}| + β_i · N_{i-1,r}^{(r-i)/(r-i+1)} Ψ_{i,r} = φ_{i,r} / N_{i,r} u = -α · Ψ_{r-1,r}
The controller is continuous everywhere except at σ = σ̇ = ... = σ^{(r-1)} = 0. In practice (with noise and discrete sampling), the control is always continuous.
Special cases
r=1: u = -α · sign(σ) r=2: u = -α · (σ̇+β|σ|^½sign(σ)) / (|σ̇|+β|σ|^½) (QC 2-SM, Eq 4.30)
Properties
- |u| ≤ α (bounded by design)
- Significantly reduced chattering compared to nested
- Same convergence guarantees (Theorem 6.3)
- Preferred by textbook authors (p.228)
Parameters¶
order : int Sliding mode order r (= relative degree). alpha : float Control magnitude bound. betas : list of float or None Gains [β_1, ..., β_{r-1}]. Length must be r-1. If None, uses [1.0, 2.0, 3.0, ...] (heuristic defaults). c : float Surface slope for default σ computation. g_sign : float Sign of input gain. Default -1 for σ=e systems. epsilon : float Small constant to avoid division by zero.
Source code in opensmc/controllers/hosmc.py
148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 205 206 207 208 209 210 211 212 213 214 215 216 217 218 219 220 221 222 223 224 225 226 227 228 229 230 231 232 233 234 235 236 237 238 239 240 241 242 243 244 245 246 247 248 249 250 251 252 253 254 255 256 257 258 259 260 261 | |
Functions¶
compute(t, x, xref, plant=None, **kwargs)
¶
Compute quasi-continuous HOSMC control.
Parameters¶
t : float x : ndarray — state vector xref : ndarray — reference sigma_derivs : list of float, optional [σ, σ̇, ..., σ^{(r-1)}]. If not provided, defaults to 2nd-order system with σ = c·e + edot, σ̇ = c·edot.
Returns¶
u : float, bounded by |u| ≤ α info : dict with 's', 'psi'
Source code in opensmc/controllers/hosmc.py
TwistingSMC
¶
Bases: Controller
Twisting 2-sliding mode controller (Levant 1993, Shtessel Eq 4.13).
u = -(r1 · sign(σ) + r2 · sign(σ̇))
For a 2nd-order system x = [x1, x2], with σ = c·e + edot (or any pluggable surface), and σ̇ available from the state.
Parameters¶
r1 : float Gain on sign(σ). Must satisfy r1 > r2 > 0. r2 : float Gain on sign(σ̇). Must satisfy r2 > 0. c : float Surface slope (used when no surface is provided): σ = c·e + edot. surface : SlidingSurface or None Optional pluggable surface for σ computation.
Source code in opensmc/controllers/twisting.py
45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 | |
Functions¶
compute(t, x, xref, plant=None, **kwargs)
¶
Compute twisting control.
Parameters¶
t : float Current time. x : ndarray State vector. For 2nd-order: [x1, x2]. xref : ndarray Reference. For 2nd-order: [xref1, xref2]. plant : Plant or None Not used (model-free controller).
Returns¶
u : float Control signal. info : dict Contains 's' (σ), 'sdot' (σ̇), 'e', 'edot'.