从0开始的智能车代码(2)

速度控制函数使用增量式 PID 控制。在对编码器引脚和 PWM 输出引脚初始化后开始对速度的控制。

float P=1,I=0.8,D=0;

int16 speedL=ctimer_count_read(TIMER0_COUNT1_A2);
int16 speedR=ctimer_count_read(TIMER3_COUNT0_A4);

ctimer_count_clean(TIMER0_COUNT1_A2);
ctimer_count_clean(TIMER3_COUNT0_A4);

//判断旋转方向
speedL=gpio_get(A3)?speedL:-speedL;
speedR=gpio_get(A5)?-speedR:speedR;

int16 aimSpeed=240;

//data_conversion(speedL,speedR,aimSpeed,0,virtual_scope_data);//虚拟示波器显示

static uint32 powerL=0;
static uint32 powerR=0;

static int16 speedErrorL1=0;
static int16 speedErrorL2=0;
static int16 speedErrorL3=0;

static int16 speedErrorR1=0;
static int16 speedErrorR2=0;
static int16 speedErrorR3=0;

speedErrorL3=speedErrorL2;
speedErrorL2=speedErrorL1;
speedErrorL1=aimSpeed-speedL;

powerL+=(int32)(P*(speedErrorL1-speedErrorL2)+I*speedErrorL1+D*(speedErrorL1-2*speedErrorL2+speedErrorL3));//计算左电机占空比
powerL=(((powerL>0)?powerL:0)<2000)?powerL:2000;

speedErrorR3=speedErrorR2;
speedErrorR2=speedErrorR1;
speedErrorR1=aimSpeed-speedR;

powerR+=(int32)(P*(speedErrorR1-speedErrorR2)+I*speedErrorR1+D*(speedErrorR1-2*speedErrorR2+speedErrorR3));//计算右电机占空比
powerR=(((powerR>0)?powerR:0)<2000)?powerR:2000;

ctimer_pwm_duty(TIMER1_PWMCH0_A18,powerL);
ctimer_pwm_duty(TIMER2_PWMCH1_B4,powerR);

其中data_conversion(speedL,speedR,aimSpeed,0,virtual_scope_data); 的目的是将速度的波形显示在计算机端的虚拟示波器上。为此我在初始化时加入了 seekfree_wireless_init(); 来初始化无线调试串口并改写 data_conversion 函数将串口选择为无线调试串口。

关于 PID 的调节,应该先确定一个比较可靠的比例然后调整积分,我在调节时发现在积分和微分都为0的情况下仅仅调节比例很难使速度稳定在设定值附近,而积分的调节会使结果显著接近设定值,微分置零即可。

这个速度在跑起来之后比乌龟快点有限,我十分清楚提速之后的代码和这个完全不是一个概念,但是我选择不去考虑那些,先让小车跑下一圈。

posted @ 2020-07-20 10:12  stephen0829  阅读(1398)  评论(0)    收藏  举报