基于Matlab的Lsqnonlin和Arduino硬件在环
我在Matlab上使用函数“lsqnonlin”时遇到一些问题。我试图通过使用这个函数来优化Arduino内部的PID控制器,该函数将PID的系数(Kp,Ki,Kd)作为决策变量,目标函数是最小化响应减去参考值的最小平方差 此链接更好地解释了我正在做的事情: 这个例子和我的问题之间的区别在于,我想执行一种半实物仿真,用我设计的实际系统取代Simulink执行的仿真,在该系统上,与Arduino接口的传感器通过串行通信向Matlab提供响应“yout” 问题是Matlab上的算法改变变量(Kp,Ki,Kd)的步长非常小(10^-8或类似的值),因此我看不到实际响应的任何变化。经过几次迭代后,算法停止说:“lsqnonlin停止,因为当前步长小于 步长公差的选定值” 我不明白为什么台阶这么小,为什么会停下来。我的代码如下基于Matlab的Lsqnonlin和Arduino硬件在环,matlab,arduino,Matlab,Arduino,我在Matlab上使用函数“lsqnonlin”时遇到一些问题。我试图通过使用这个函数来优化Arduino内部的PID控制器,该函数将PID的系数(Kp,Ki,Kd)作为决策变量,目标函数是最小化响应减去参考值的最小平方差 此链接更好地解释了我正在做的事情: 这个例子和我的问题之间的区别在于,我想执行一种半实物仿真,用我设计的实际系统取代Simulink执行的仿真,在该系统上,与Arduino接口的传感器通过串行通信向Matlab提供响应“yout” 问题是Matlab上的算法改变变量(Kp,K
pid0 = [10 0 0]; %inizialization of PID parameters
options = optimset('LargeScale','off','Display','iter',...
'TolX',0.001,'TolFun',0.001);
pid = lsqnonlin(@trackpid, pid0, [0 0 0], [], options)
Kp = pid(1); Ki = pid(2); Kd = pid(3);
trackpid功能是:
function F = trackpid(pid)
% Serial communication
s = serial('/dev/cu.usbmodemFD131');
set(s,'BaudRate', 9600);
set(s,'DataBits', 8);
set(s,'StopBits', 1);
% Global Variables
numberOfDatas = 700;
Kp = pid(1)
Ki = pid(2)
Kd = pid(3)
i = 1;
fopen(s);
pause(1.7); %i need to wait 1.7s in order to read the values
%Send to Arduino the PID coefficients
fprintf(s,num2str(Kp));
fprintf(s,num2str(Ki));
fprintf(s,num2str(Kd));
while (fscanf(s,'%c') ~= 't') %Wait for Arduino to start the simulation
end
%Scan
while(i <= numberOfDatas)
yout(i) = fscanf(s,'%f');
i = i + 1;
end
fclose(s);
yout
F = yout - 21; %evaluate the difference between the response and the reference
函数F=trackpid(pid)
%串行通信
s=串行('/dev/cu.usbmodemFD131');
设置“波特率”,9600;
集(s,'DataBits',8);
设置(s,'停止位',1);
%全局变量
numberOfDatas=700;
Kp=pid(1)
Ki=pid(2)
Kd=pid(3)
i=1;
福彭(s);
暂停(1.7);%我需要等待1.7秒才能读取值
%将PID系数发送给Arduino
fprintf(s,num2str(Kp));
fprintf(s,num2str(Ki));
fprintf(s,num2str(Kd));
而(fscanf(s,'%c')~='t')%等待Arduino启动模拟
结束
%扫描
而