..
差不大。但是从原理来讲,由于普通PID积累了比较大的误差,所以如果不添加保护,普通PID的响应更迅速。干扰后回归原位的时间上,两者相差很
大,这说明积分分离PID在抗干扰的能力上强于普通PID。在应用与实际系统中的效果也很好,不至于使系统崩溃。
四,结语
双轮自平衡智能车的控制属于典型的自动控制系统。本文研究了双轮自平衡机器人的系统模型,PID参数的优化以及使用积分分离PID用来抵抗干扰。总体说来,得到了一个很好的控制方式。经过实验室的实践,得到了很好的实际效果。车模能在赛道上快速的前进,能越过障碍,能上下桥。双轮智能车的控制可以为双轮机器人打下基础。
参考文献
[1] 孙亮,双轮自平衡机器人行走伺服控制算法[J],控制工程,2009,16(3): 1。 [2]胡寿松,自动控制原理简明教程(第二版)[M],:科学出版社,2008.2。 [3]刘金琨,先进PID控制matlab仿真(第三版)[M],:电子工业出版社,2011,.3。 [4]飞思卡尔竞赛秘书处,电磁组直立行车参考设计方案[J],2012,3。
附件1:
PID参数研究m程序:
%程序目的:研究PID参数的作用 %author:程顺均 %时间:2013.8.31 %积分分离式PID仿真 clear all; clear all;
ts = 0.005; %控制周期为5ms sys = tf([1],[1 5 100]);%建立系统 dsys = c2d(sys,ts,'z');
%添加'v'可以让输出的值由元胞数组改为数组直接输出 [num, den] = tfdata(dsys,'v'); u1 = 0;u2 = 0; %控制器的输出 y1 = 0;y2 = 0; %实际的输出值
a
..
error1 = 0; %上次上次误差 ei = 0; %误差积累
Kp = 100; Ki = 1500; Kd = 50;
for k=1:1:500 time(k) = k * ts; yd(k) = 1;
y(k) = - den(2)*y1 - den(3)*y2 + num(2)*u1 + num(3)*u2;
error(k) = yd(k) - y(k); %变化率的计算 ei = ei + error(k)*ts; %误差累积计算
u(k) = Kp * error(k) + Ki * ei + Kd * (error(k) - error1)/ts; %PID控制
if u(k) >= 20000 u(k) = 20000; end
if u(k) <= -20000 u(k) = -20000; end
u2 = u1;u1 = u(k);%记录上次的值 y2 = y1;y1 = y(k); error1 = error(k); end figure(1);
plot(time,yd,'r',time,y,'b'); grid on;
legend('理想输出','位置跟踪');
附件2:
路障干扰仿真m程序:
%程序目的:对比积分分离PID和普通PID %的不同 %author:程顺均 %时间:2013.8.31 %积分分离式PID仿真
a
..
clear all; clear all;
ts = 0.005; %控制周期为5ms sys = tf([1],[1 5 100]);%建立系统 dsys = c2d(sys,ts,'z');
%添加'v'可以让输出的值由元胞数组改为数组直接输出 [num, den] = tfdata(dsys,'v'); u1 = 0;u2 = 0; %控制器的输出 y1 = 0;y2 = 0; %实际的输出值 error1 = 0; %上次上次误差 ei = 0; %误差积累
M = 1; %选择是否使用积分分离
Kp = 1000; Ki = 3000; Kd = 50;
for k=1:1:500 time(k) = k * ts; if k < 120 & k > 100 yd(k) = 200; %输出期望值 else yd(k) = 40; end
y(k) = - den(2)*y1 - den(3)*y2 + num(2)*u1 + num(3)*u2;
error(k) = yd(k) - y(k); %变化率的计算 ei = ei + error(k)*ts; %误差累积计算
if 1 == M %使用积分分离 if abs(error(k)) >= 6
beta = 0; %积分分离
elseif abs(error(k)) >= 2 & abs(error(k)) < 4 beta = 0.2; %积分分离 else
beta = 1.0; end elseif 0 == M beta = 1.0; end
u(k) = Kp * error(k) + beta * Ki * ei + Kd * (error(k) - error1)/ts; %PID控制
a
..
if u(k) >= 20000 u(k) = 20000; end
if u(k) <= -20000 u(k) = -20000; end
u2 = u1;u1 = u(k);%记录上次的值 y2 = y1;y1 = y(k); error1 = error(k); end figure(1);
plot(time,yd,'r',time,y,'b'); grid on;
legend('理想输出','位置跟踪');
附件3:
普通PID 算法C语言实现代码:
#include \#include \
int VV_MAX =4400; //电机PID输出上限 int VV_MIN =2000; //电机PID输出下限 PID sPID;
void v_PIDInit () {
//速度设定值
//速度反馈值
sPID.vi_Ref = 0 ;
sPID.vi_PreError = 0 ;
sPID.v_Kp =20; //d_error 第一次偏差 500 sPID.v_Ki =14; // error 最初反馈值 600 sPID.v_Kd =10; //dd_error 第二次偏差 100 sPID.motor_PreU = 2400; }
//电机控制输出值
//前一次,速度误差,,vi_Ref - vi_FeedBack
sPID.vi_PreDerror = 0 ; //前一次,速度误差之差,d_error-PreDerror;
sPID.vi_FeedBack = 0 ;
a
..
int v_PIDCalc( PID *pp ) {
int error,d_error,dd_error;
error =(int)(pp->vi_Ref) - ( int)(pp->vi_FeedBack) ; // 偏差计算 d_error = error - (int)(pp->vi_PreError); dd_error = d_error - (int)pp->vi_PreDerror;
pp->vi_PreError = error;
if( ( error < VV_DEADLINE ) && ( error > -VV_DEADLINE ) );
else {
pp->motor_PreU += (int)(pp -> v_Kp * d_error+ pp -> v_Ki * error+ pp->v_Kd*dd_error)/10; }
if( pp->motor_PreU >= VV_MAX ) {
pp->motor_PreU = VV_MAX; }
else if( pp->motor_PreU <= VV_MIN) //速度PID,防止调节最低溢出 {
pp->motor_PreU =VV_MIN; }
return (pp->motor_PreU); }
// 返回预调节占空比
//速度PID,防止调节最高溢出
//速度PID计算
//设置调节死区
//存储当前偏差
pp->vi_PreDerror = d_error;
a