How to add disturbance to system to check robustness of my MPC controller
5 次查看(过去 30 天)
显示 更早的评论
I'm a newcomer to MATLAB and Control Theory, and I'm currently working on my university project, which involves implementing Model Predictive Control (MPC) for a 2-wheel self-balancing robot. To assess the controller's robustness, I'm aiming to introduce an input impulse disturbance. However, I'm encountering difficulties in doing so. I'm including my code here kindly suggest me fix, thank you.
clear; close all; clc;
%% Inverted Pendulum Model Parameters
M = 0.5;
m = 0.2;
b = 0.1;
I = 0.006;
g = 9.8;
l = 0.3;
p = I*(M+m)+M*m*l^2; %denominator for the A and B matrices
A = [0 1 0 0;
0 -(I+m*l^2)*b/p (m^2*g*l^2)/p 0;
0 0 0 1;
0 -(m*l*b)/p m*g*l*(M+m)/p 0];
B = [ 0;
(I+m*l^2)/p;
0;
m*l/p];
C = [1 0 0 0;
0 0 1 0];
D = [0;
0];
%% Discretize the system
Ts = 0.1; % Sampling time [s]
sys = ss(A, B, C, D);
sys_d = c2d(sys, Ts, 'zoh'); % Discretized system
Ad = sys_d.a;
Bd = sys_d.b;
Cd = sys_d.c;
%% Design MPC Controller
N = 20; % Prediction horizon
Nu = 5; % Control horizon
Q = diag([10, 1, 100, 1]); % State weighting matrix
R = 0.1; % Control input weighting
% Create MPC controller object
mpcobj = mpc(sys_d, Ts);
mpcobj.PredictionHorizon = N;
mpcobj.ControlHorizon = Nu;
mpcobj.Weights.OutputVariables = [1000, 100];
mpcobj.Weights.ManipulatedVariables = R;
mpcobj.Weights.ManipulatedVariablesRate = 0.1;
% Constraints
mpcobj.MV(1).Min = -10; % Force min [N]
mpcobj.MV(1).Max = 10; % Force max [N]
%% Simulation
Nsim = 100; % Number of simulation steps
x0 = [0.2; 0; 0.1; 0]; % Initial state
% Preallocate arrays for simulation results
nx = size(Ad, 1);
nu = size(Bd, 2);
ny = size(Cd, 1);
x = zeros(nx, Nsim);
y = zeros(ny, Nsim);
u = zeros(nu, Nsim);
x(:,1) = x0;
y(:,1) = Cd * x0;
% Create initial MPC state
mpcstate = mpcstate(mpcobj, x(:,1));
% Main simulation loop
for k = 1:Nsim-1
% Measure the current output
ymeas = y(:,k);
% Compute the control action using the MPC controller
[u(:,k), mpc_info] = mpcmove(mpcobj, mpcstate, ymeas, []);
% Apply the control action to the system and obtain the next state
x(:,k+1) = Ad * x(:,k) + Bd * u(:,k);
% Calculate the output
y(:,k+1) = Cd * x(:,k+1);
% Update MPC state
mpcstate.Plant = x(:,k+1);
end
% Plot the results
figure(1)
subplot(3,1,1);
t = (0:Nsim-1) * Ts;
figure(1);
plot(t, y(1,:), 'LineWidth', 2);
ylabel('Cart Position (m)');
title('Inverted Pendulum MPC Control');
grid on;
subplot(3,1,2);
plot(t, y(2,:), 'LineWidth', 2);
ylabel('Pendulum Angle (rad)');
grid on;
subplot(3,1,3);
plot(t, u(:,1:Nsim), 'LineWidth', 2); % Corrected dimensions of u
xlabel('Time (s)');
ylabel('Force (N)');
grid on;
0 个评论
回答(1 个)
Sam Chak
2023-10-13
Hi @Ashutosh
I seldom employ MPC due to the challenges associated with deterministically controlling the controller's behavior from the Applied Mathematician's point of view. Nevertheless, I believe you can try describing the expected unmeasured input disturbance using setmpcsignals() and mpcobj.Model.Disturbance.
In the pendulum case, where the input disturbance is assumed to enter the system through the same channel as the control input, denoted as 'u' or the "Manipulated Variable" in MPC terminology, you will observe an additional column introduced in the state-space representation.
%% Inverted Pendulum
% Parameters
M = 0.5;
m = 0.2;
b = 0.1;
I = 0.006;
g = 9.8;
l = 0.3;
p = I*(M + m) + M*m*l^2; % denominator for the A and B matrices
% State-space representation
A = [0 1 0 0;
0 -(I+m*l^2)*b/p (m^2*g*l^2)/p 0;
0 0 0 1;
0 -(m*l*b)/p m*g*l*(M+m)/p 0];
B = [ 0 0; % Added one column for the input disturbance
(I+m*l^2)/p (I+m*l^2)/p;
0 0;
m*l/p m*l/p];
C = [1 0 0 0;
0 0 1 0];
D = 0*C*B;
sys = ss(A, B, C, D)
%% Discretize the system
Ts = 0.1; % Sampling time [s]
sys_d = c2d(sys, Ts, 'zoh'); % Discretized system
Ad = sys_d.a;
Bd = sys_d.b;
Cd = sys_d.c;
%% Design MPC Controller
N = 20; % Prediction horizon
Nu = 5; % Control horizon
Q = diag([10, 1, 100, 1]); % State weighting matrix
R = 0.1; % Control input weighting
% Create MPC controller object
sys_d = setmpcsignals(sys_d, MV=[1], UD=[2]);
mpcobj = mpc(sys_d, Ts);
mpcobj.PredictionHorizon = N;
mpcobj.ControlHorizon = Nu;
mpcobj.Weights.OutputVariables = [1000, 100];
mpcobj.Weights.ManipulatedVariables = R;
mpcobj.Weights.ManipulatedVariablesRate = 0.1;
% Constraints
mpcobj.MV(1).Min = -10; % Force min [N]
mpcobj.MV(1).Max = 10; % Force max [N]
% Input Disturbance
mpcobj.Model.Disturbance = tf(1) % Laplace transform of Dirac delta function is 1
indist = tf(getindist(mpcobj))
%% Simulation
Nsim = 100; % Number of simulation steps
x0 = [0.2; 0; 0.1; 0]; % Initial state
% Preallocate arrays for simulation results
nx = size(Ad, 1);
nu = size(Bd, 2);
ny = size(Cd, 1);
x = zeros(nx, Nsim);
y = zeros(ny, Nsim);
u = zeros(nu, Nsim);
x(:,1) = x0;
y(:,1) = Cd*x0;
% Create initial MPC state
mpcstate = mpcstate(mpcobj, x(:,1));
%% Main simulation loop
for k = 1:Nsim-1
% Measure the current output
ymeas = y(:,k);
% Compute the control action using the MPC controller
[u(:,k), mpc_info] = mpcmove(mpcobj, mpcstate, ymeas, []);
% Apply the control action to the system and obtain the next state
x(:,k+1) = Ad*x(:,k) + Bd*u(:,k);
% Calculate the output
y(:,k+1) = Cd*x(:,k+1);
% Update MPC state
mpcstate.Plant = x(:,k+1);
end
%% Plot the results
figure(1)
subplot(3,1,1);
t = (0:Nsim-1)*Ts;
plot(t, y(1,:), 'LineWidth', 2);
ylabel('Cart Position (m)');
title('Inverted Pendulum MPC Control');
grid on;
subplot(3,1,2);
plot(t, y(2,:), 'LineWidth', 2);
ylabel('Pendulum Angle (rad)');
grid on;
subplot(3,1,3);
plot(t, u(:,1:Nsim), 'LineWidth', 2); % Corrected dimensions of u
xlabel('Time (s)');
ylabel('Force (N)');
grid on;
0 个评论
另请参阅
类别
在 Help Center 和 File Exchange 中查找有关 Controller Creation 的更多信息
Community Treasure Hunt
Find the treasures in MATLAB Central and discover how the community can help you!
Start Hunting!