Adaptive PID Controller for Speed Control

22 次查看(过去 30 天)
Mnh
Mnh 2025-10-18
编辑: Mnh 2025-10-18
I am currently encountering some issues with the motor control algorithm with Adaptive PID ConTroller in the real-world implementation. As you can see, at a speed of 5 rad/s, the plant does not accurately track the model and exhibits significant instability. This behavior similarly occurs within the speed range of 5–25 rad/s. When I set the speed to 30 rad/s, the motor initially overshoots and then experiences a severe drop in speed (sometimes even reaching zero or negative values, resulting in a brief reversal). Could you please provide me with some suggestions?
%% MRAS Adaptive PID (MIT rule) for DC Motor (MATLAB–Arduino Serial)
% Hardware:
% - Arduino UNO R3 + L298N + Encoder 334x34
% - The Arduino code transmits the motor speed (rad/s) via Serial communication
% - MATLAB performs the control computation and sends the PWM signal (0–255)
clc; clear; close all;
%% --- Serial Setup ---
port = "COM4"; baud = 115200;
s = serialport(port, baud);
configureTerminator(s, "LF");
flush(s);
disp('✅ Arduino Serial connection successful.');
pause(1);
%% --- MRAS-PID parameters ---
T = 0.05; % Control period (s)
setpoint = 5; % rad/s
am = 6.0; bm = 6.0; % Reference model
ym = 0;
gamma_p = 0.01; gamma_i = 0.003; gamma_d = 0.002;
norm_p = 0.08; norm_i = 0.02; norm_d = 0.05;
Kp = 1.8; Ki = 0.8; Kd = 0.05;
Kp_min=0.2; Kp_max=6.0; Ki_min=0; Ki_max=2.5; Kd_min=0; Kd_max=0.2;
I = 0; e_prev = 0; yp = 0; d_filt = 0;
deriv_alpha = 0.5; speed_alpha = 0.7;
PWM_MAX = 255; PWM_DEAD = 8; MAX_SPEED = 31;
%% --- Initialize plot ---
figure('Color','w');
subplot(2,1,1);
h1=animatedline('Color','r','LineWidth',1.5);
h2=animatedline('Color','b','LineWidth',1.5);
h3=animatedline('Color',[.7 .7 .7],'LineWidth',1,'LineStyle','--');
xlabel('Time (s)'); ylabel('Speed (rad/s)');
title('MRAS Adaptive PID Tracking');
legend({'Plant','Model','Ref'},'Location','best'); grid on;
subplot(2,1,2);
hKp=animatedline('Color','r'); hKi=animatedline('Color','b'); hKd=animatedline('Color','g');
xlabel('Time (s)'); ylabel('Gain'); grid on;
%% --- loop ---
disp('Starting control... Press Ctrl+C to stop');
t0 = tic;
while ishandle(h1)
t = toc(t0);
% --- Read speed from Arduino ---
if s.NumBytesAvailable > 0
line = readline(s);
yp_new = str2double(line);
if ~isnan(yp_new)
yp = speed_alpha*yp + (1-speed_alpha)*yp_new;
end
end
% --- Reference model ---
ym = ym + T*(-am*ym + bm*setpoint);
% --- error ---
e = setpoint - yp;
em = ym - yp;
% --- Basic PID ---
d_raw = (e - e_prev)/T;
d_filt = deriv_alpha*d_filt + (1-deriv_alpha)*d_raw;
I = I + e*T;
uP = Kp*e + Kd*d_filt;
u_tent = uP + Ki*I;
% Saturation and anti-windup
if (u_tent>=PWM_MAX && e>0) || (u_tent<=0 && e<0)
I = I*0.999;
end
u = uP + Ki*I;
pwmOut = min(max(u,0),PWM_MAX);
if pwmOut>0 && pwmOut<PWM_DEAD
pwmOut = PWM_DEAD;
end
% --- Send PWM to Arduino ---
writeline(s, string(round(pwmOut)));
% --- MRAS adaptation ---
freeze = ((pwmOut>=PWM_MAX && em>0) || (pwmOut<=0 && em<0));
if ~freeze
phi_p=e; phi_i=I; phi_d=d_filt;
Kp = Kp + gamma_p*em*phi_p/(1+norm_p*phi_p^2);
Ki = Ki + gamma_i*em*phi_i/(1+norm_i*phi_i^2);
Kd = Kd + gamma_d*em*phi_d/(1+norm_d*phi_d^2);
Kp = min(max(Kp,Kp_min),Kp_max);
Ki = min(max(Ki,Ki_min),Ki_max);
Kd = min(max(Kd,Kd_min),Kd_max);
end
% --- Real-time plotting ---
addpoints(h1,t,yp);
addpoints(h2,t,ym);
addpoints(h3,t,setpoint);
addpoints(hKp,t,Kp); addpoints(hKi,t,Ki); addpoints(hKd,t,Kd);
drawnow limitrate;
e_prev = e;
pause(T);
end
disp('⏹ STOP.'); clear s;

回答(0 个)

类别

Help CenterFile Exchange 中查找有关 PID Controller Tuning 的更多信息

产品


版本

R2024b

Community Treasure Hunt

Find the treasures in MATLAB Central and discover how the community can help you!

Start Hunting!

Translated by