调参日日夜夜,开窍只在哪一瞬间

平衡车

学习平衡车PID用到的资料:深度解析平衡车PID

一些比较好用的调参经验!调参经验

平衡车制作运动的问题以及解决方法

2.18 遇到编码器无法测速问题

2.19 记录自己第一次使用示波器

示波器的使用

关于之前编码器无法测速问题在我重新焊出第四块一模一样的板子后终于找到了答案(悲)

因为在焊接电路的时候电机端子焊反了,所以导致编码器电源正反反接了,无法正常给编码器供电,在制作平衡车过程中出了很多次硬件问题,下一个项目要好好检查硬件问题然后在写程序

2.2.20:出现想用vofa上位机进行PID调参,但是串口通信不知道怎么去实现的问题

2.21: 平衡车制作完毕!!!!!!

休息两天在开始下一个栏目

平衡车知识总结:关于平衡小车中使用的PID算法

展示连接:平衡车

核心控制函数:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
void Control(void) //核心控制函数

{
int PWM_out;
//读取编码器速度
Encoder_Left=Read_Speed(&htim2);
Encoder_Right=-Read_Speed(&htim4);
mpu_dmp_get_data(&pitch,&roll,&yaw);
MPU_Get_Gyroscope(&gyrox,&gyroy,&gyroz);
MPU_Get_Accelerometer(&aacx,&aacy,&aacz);

//遥控
if((Fore==0)&&(Back==0))Target_Speed=0;//没有接受到遥控指令,速度为零
if(Fore==1)
{
if(distance<50)
Target_Speed--;
else
Target_Speed++;
}
if(Back==1){Target_Speed--;}//
Target_Speed=Target_Speed>SPEED_Y?SPEED_Y:(Target_Speed<-SPEED_Y?(-SPEED_Y):Target_Speed);//??·ù

/*左右*/
if((Left==0)&&(Right==0))Target_turn=0;
if(Left==1)Target_turn-=30;//左转
if(Right==1)Target_turn+=30;=//右转
Target_turn=Target_turn>SPEED_Z?SPEED_Z:(Target_turn<-SPEED_Z?(-SPEED_Z):Target_turn);//??·ù( (20*100) * 100 )

//转向约束
if((Left==0)&&(Right==0))Turn_Kd=0.6;
else if((Left==1)||(Right==1))Turn_Kd=0;
//函数的核心,串极PID控制器
Velocity_out=Velocity(Target_Speed,Encoder_Left,Encoder_Right);//速度环输出
Vertical_out=Vertical(Velocity_out+Med_Angle,roll,gyrox);//直立环输出
Turn_out=Turn(gyroz,Target_turn);//转向环输出
PWM_out=Vertical_out;//PWM输出为直立环输出
MOTO1=PWM_out-Turn_out;//减去转向换的输出,得到电机1的PWM值
MOTO2=PWM_out+Turn_out;
Limit(&MOTO1,&MOTO2);
Load(MOTO1,~MOTO2);
}

关于平衡小车PID算法我的理解

直立环

1
2
3
4
5
6
int Vertical(float Med,float Angle,float gyro_Y)
{
int temp;
temp=Vertical_Kp*(Angle-Med)+Vertical_Kd*gyro_Y;
return temp;
}

**KP:**这个公式第一项就是在当前角度减去目标角度得到角度偏差,然后在乘以比例系数,输出PWM值给电机
如果只调Kp比如,车子向后倾斜,计算角度偏差后,如果没有调节Kd,车子就会向前加速,而加速到目标值后,车子并没有减速完成,因为惯性会继续向前运动过度,从而产生相反的速度偏差,就会产生震荡
Kd的作用:阅读第二项可以看到第二项kd×的是角速度,那么kp环节在控制车子运动时(类似于高中学习的版块模型),他就会产生一个同运动相反方向的阻尼力,然后产生对应的角速度,通过陀螺仪测量这个角速度,然后通过kd调节阻尼力的大小,从而达到减小震荡的目的
运动产生的阻尼力

速度环

代码展示:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17

int Velocity(int Target,int encoder_L,int encoder_R)
{
static int Err_LowOut_last,Encoder_S;//左右编码器读数
static float a=0.7;//滤波系数
int Err,Err_LowOut,temp;
Velocity_Ki=Velocity_Kp/200;
Err=(encoder_L+encoder_R)-Target;//速度偏差
Err_LowOut=(1-a)*Err+a*Err_LowOut_last;//低通滤波,用于消除平缓误差,减少噪音的的印象
Err_LowOut_last=Err_LowOut;
Encoder_S+=Err_LowOut;//进行积分计算
Encoder_S=Encoder_S>20000?20000:(Encoder_S<(-20000)?(-20000):Encoder_S);//积分限幅
if(stop==1)Encoder_S=0,stop=0;
temp=Velocity_Kp*Err_LowOut+Velocity_Ki*Encoder_S//PID控制
return temp;
}

Err_LawOut为比例增益,Encoder_S为积分增益,前者用来调节误差对控制输出的影响,后者用于调节误差的积累效应
关于速度环为什么用PI控制,而不是PID或者PD控制
这时候就要提到PI控制的好处,I的作用是用于消除稳态误差,,P是为了快速响应,因此采用PI控制起可以更快的打到目标速度,并且消除稳态误差

转向环

采用的串极PID控制的解释

PID的种类有:串极,并极,单极

串极PID更加稳定也更加复杂

主控制环也就是内环:位置环
从控制环也就是:速度环
串级PID控制的基本框架
外环PID 处理 大目标误差(如速度目标),并生成对 内环PID 的期望值。
内环PID 处理 小目标误差(位置目标),并控制 电机输出

关于这个平衡车采用的串极PID

串极PID控制
认真读上面的控制函数代码就可以发现,速度环给了直立环一个速度偏差,然后直立环用这个速度偏差去控制车子直立,这就是串极PID的控制方式
然后在通过转向环控制输出PWM值