├── LICENSE ├── MainL1_ODE1_v1.m ├── MainL1_ODE1_v2.m └── README.md /LICENSE: -------------------------------------------------------------------------------- 1 | MIT License 2 | 3 | Copyright (c) 2022 Xuan Khai Nguyen 4 | 5 | Permission is hereby granted, free of charge, to any person obtaining a copy 6 | of this software and associated documentation files (the "Software"), to deal 7 | in the Software without restriction, including without limitation the rights 8 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 9 | copies of the Software, and to permit persons to whom the Software is 10 | furnished to do so, subject to the following conditions: 11 | 12 | The above copyright notice and this permission notice shall be included in all 13 | copies or substantial portions of the Software. 14 | 15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 16 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 17 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 18 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 19 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 20 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 21 | SOFTWARE. 22 | -------------------------------------------------------------------------------- /MainL1_ODE1_v1.m: -------------------------------------------------------------------------------- 1 | % Only adaptive law are sampled with Ts 2 | clc 3 | close all; 4 | clear all; 5 | 6 | params.dt = 0.0001; % plant interval 7 | params.Ts = 0.01; % adaptive sampling time 8 | Tf = 0.2; % simulation time 9 | t = 0:params.dt:Tf; 10 | ts = 0:params.Ts:Tf; 11 | 12 | params.a = 1; params.am = params.a; params.b = params.a; % system matrix 13 | params.kr = params.am/params.b; params.r = 0; 14 | 15 | u = zeros(1, length(t)); 16 | x = zeros(1, length(t)); 17 | dx = zeros(1, length(t)); 18 | x_hat = zeros(1, length(t)); 19 | dx_hat = zeros(1, length(t)); 20 | x_tilde = zeros(1, length(t)); 21 | d = zeros(1, length(t)); 22 | sigma_hat = zeros(1, length(ts)); 23 | x(1) = 0; x_hat(1) = 0; 24 | 25 | global u_prev 26 | u_prev = 0; 27 | 28 | % Piecewise-Constant Adaptive Laws Setting 29 | params.Phi_Ts = (1 - exp(-params.am*params.Ts))/params.am; 30 | params.tau = 0.1; 31 | 32 | j = 1; 33 | 34 | for i=1:length(t) % Real time 35 | x_tilde(i) = x_hat(i) - x(i); 36 | 37 | if ~mod(i-1,round(params.Ts/params.dt)) % Sampling 38 | sigma_hat(j) = estimator(x_tilde(i), params); % Adaptive Law 39 | j = j + 1; 40 | end 41 | 42 | u(i) = controller(sigma_hat(j-1), params); % Controller + Filter 43 | 44 | if (i == length(t)) % last time 45 | [~, dx(i), d(i)] = plant(x(i), u(i), t(i), params); % Real system 46 | [~, dx_hat(i)] = predictor(x_hat(i), u(i), sigma_hat(j-1), params); % Predicted system 47 | else 48 | [x(i+1), dx(i), d(i)] = plant(x(i), u(i), t(i), params); % Real system 49 | [x_hat(i+1), dx_hat(i)] = predictor(x_hat(i), u(i), sigma_hat(j-1), params); % Predicted system 50 | end 51 | end 52 | 53 | 54 | %% 55 | plot(t,x); title('x'); 56 | figure 57 | stairs(ts,sigma_hat); hold on; plot(t,d,'--r'); title('Estimation'); 58 | figure 59 | plot(t,u); title('u control'); 60 | figure 61 | plot(t,x_tilde); title('x^~'); 62 | %% 63 | 64 | %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% 65 | %%%%%%%%%%%%%%%%%% F U N C T I O N S %%%%%%%%%%%%%%%%%% 66 | %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% 67 | 68 | function [x, dx, d] = plant(x_prev, u, t, params) 69 | d = 100*(step(t - 0.01) - step(t - 0.02))... 70 | + (300 + 500*sin(500*t))*(step(t - 0.04) - step(t - 0.05))... 71 | + (500*sin(1000*t) - 500)*(step(t - 0.07) - step(t - 0.08)); 72 | 73 | dx = -params.a*x_prev + params.b*(u + d); 74 | 75 | x = x_prev + dx*params.dt; 76 | end 77 | 78 | function u_f = controller(sigma_hat, params) 79 | global u_prev 80 | u = params.kr*params.r - sigma_hat; 81 | u_f = (params.Ts/params.tau)*u + (1-params.Ts/params.tau)*u_prev; 82 | u_prev = u_f; 83 | end 84 | 85 | function [x_hat, dx_hat] = predictor(x_hat_prev, u, sigma_hat, params) 86 | dx_hat = -params.am*x_hat_prev + params.b*(u + sigma_hat); 87 | x_hat = x_hat_prev + dx_hat*params.dt; 88 | end 89 | 90 | function sigma_hat = estimator(x_tilde, params) 91 | muy = exp(-params.am*params.Ts)*x_tilde; 92 | sigma_hat = -params.Phi_Ts\muy/params.b; 93 | end 94 | 95 | function out = step(t) 96 | if t<=0 97 | out = 0; 98 | else 99 | out = 1; 100 | end 101 | end -------------------------------------------------------------------------------- /MainL1_ODE1_v2.m: -------------------------------------------------------------------------------- 1 | clc 2 | close all; 3 | clear all; 4 | 5 | params.dt = 0.0001; % plant interval 6 | params.Ts = 0.01; % adaptive sampling time 7 | Tf = 0.1; % simulation time 8 | t = 0:params.dt:Tf; 9 | ts = 0:params.Ts:Tf; 10 | 11 | params.a = 1; params.am = params.a; params.b = params.a; % system matrix 12 | params.kr = params.am/params.b; params.r = 0; 13 | 14 | % Initialization 15 | u = zeros(1, length(ts)); 16 | x = zeros(1, length(t)); 17 | dx = zeros(1, length(t)); 18 | x_hat = zeros(1, length(ts)); 19 | dx_hat = zeros(1, length(ts)); 20 | x_tilde = zeros(1, length(ts)); 21 | d = zeros(1, length(t)); 22 | sigma_hat = zeros(1, length(ts)); 23 | x(1) = 0; x_hat(1) = 0; 24 | 25 | global u_prev 26 | u_prev = 0; 27 | 28 | % Piecewise-Constant Adaptive Laws Setting 29 | params.Phi_Ts = (1 - exp(-params.am*params.Ts))/params.am; 30 | params.tau = 0.1; 31 | 32 | j = 0; 33 | 34 | for i=1:length(t) % Real time 35 | if (~mod(i-1,round(params.Ts/params.dt))) %Sampling 36 | j = j + 1; 37 | x_tilde(j) = x_hat(j) - x(i); 38 | 39 | sigma_hat(j) = estimator(x_tilde(j), params); % Adaptive Law 40 | 41 | u(j) = controller(sigma_hat(j), params); % Controller + Filter 42 | 43 | if (j == length(ts)) % last time 44 | [~, dx_hat(j)] = predictor(x_hat(j), u(j), sigma_hat(j), params); % Predicted system 45 | else 46 | [x_hat(j+1), dx_hat(j)] = predictor(x_hat(j), u(j), sigma_hat(j), params); % Predicted system 47 | % Predictor uses different sampling time then x_tilde varies 48 | end 49 | 50 | end 51 | 52 | if (i == length(t)) % last time 53 | [~, dx(i), d(i)] = plant(x(i), u(j), t(i), params); % Real system 54 | else 55 | [x(i+1), dx(i), d(i)] = plant(x(i), u(j), t(i), params); % Real system 56 | end 57 | end 58 | 59 | 60 | %% 61 | plot(t,x); title('x'); 62 | figure 63 | stairs(ts,sigma_hat); hold on ;plot(t,d,'--r'); title('Estimation'); 64 | figure 65 | plot(ts,u); title('u control'); 66 | figure 67 | plot(ts,x_tilde); title('x^~'); 68 | %% 69 | figure 70 | plot(ts,u);hold on;stairs(ts,sigma_hat); title('Filter'); 71 | %% 72 | 73 | %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% 74 | %%%%%%%%%%%%%%%%%% F U N C T I O N S %%%%%%%%%%%%%%%%%% 75 | %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% 76 | 77 | function [x, dx, d] = plant(x_prev, u, t, params) 78 | d = 100*(step(t - 0.01) - step(t - 0.02))... 79 | + (300 + 500*sin(500*t))*(step(t - 0.04) - step(t - 0.05))... 80 | + (500*sin(1000*t) - 500)*(step(t - 0.07) - step(t - 0.08)); 81 | 82 | dx = -params.a*x_prev + params.b*(u + d); 83 | 84 | x = x_prev + dx*params.dt; 85 | end 86 | 87 | function [x_hat, dx_hat] = predictor(x_hat_prev, u, sigma_hat, params) 88 | dx_hat = -params.am*x_hat_prev + params.b*(u + sigma_hat); 89 | x_hat = x_hat_prev + dx_hat*params.Ts; 90 | end 91 | 92 | function u_f = controller(sigma_hat, params) 93 | global u_prev 94 | u = params.kr*params.r - sigma_hat; 95 | u_f = (params.Ts/params.tau)*u + (1-params.Ts/params.tau)*u_prev; 96 | u_prev = u_f; 97 | end 98 | 99 | function sigma_hat = estimator(x_tilde, params) 100 | muy = exp(-params.am*params.Ts)*x_tilde; 101 | sigma_hat = -params.Phi_Ts\muy/params.b; 102 | end 103 | 104 | function out = step(t) 105 | if t<0 106 | out = 0; 107 | else 108 | out = 1; 109 | end 110 | end -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # L1 Adaptive Control 2 | ## By [Xuan Khai Nguyen](https://www.linkedin.com/in/khainx/) 3 | I implemented L1 Adaptive Control using MATLAB. This is very basic and I made it as similar as possible to the paper results. I hope that you can understand how to implement this interesting control algorithm. 4 | 5 | Based on section III.C of Comparison of Several Adaptive Controllers According to Their Robustness Metrics 6 | 7 | Paper at https://arc.aiaa.org/doi/10.2514/6.2010-8047 8 | 9 | Please give me a ⭐ if you find it useful. 10 | --------------------------------------------------------------------------------