STM32平衡车标准库开源详解

一、前言

1.本项目主要参考:

B站Up主:会飞的鱿鱼03,

然后mpu6050姿态解算参考了[小学生都会的]MPU6050DMP库移植(stm32标准库)_哔哩哔哩_bilibili

2.大致思路:

先简单讲下,pid直立环和速度环,直立环是让小车能够站着,速度环是让小车能够停住

二、单独模块

1.mpu6050:

大致原理:

通过I2C向芯片发送指令,使回传三轴加速度(Accelerometer)和三轴角速度(Gyroscope)。再将该数据丢进dmp库中,可解析出滚转角(Roll)、俯仰角(Pitch)、偏航角(Yaw)。

其中偏航角决定的是前进的方向,然后滚转角(Roll)俯仰角(Pitch)与mpu6050的放置位置有关,调取其中的数据来反映当前位置。

使用方式:

1.导入文件(两个都要,注意添加路径)

2.改引脚(在MPU6050_I2C.h文件中)

由于题主使用PB3、4引脚,使用复用引脚,还需在MPU6050_I2C.c进行相关修改

3.初始化
MPU6050_Init();
MPU6050_DMP_Init();
4.在循环中进行数据提取即可
MPU6050_DMP_Get_Data(&Pitch,&Roll,&Yaw);
MPU_Get_Gyroscope(&Gx, &Gy, &Gz);

(该文件在文章最后开源,可参考[小学生都会的]MPU6050DMP库移植(stm32标准库)_哔哩哔哩_bilibili)

2.霍尔编码器:

大致原理:

通过脉冲的速度,即可计算车轮转速

通过判断A、B相相对位置,即可判断正反转

使用方式:

编码器在stm32中有专门的模式,可节省软件资源,但每个编码器要用掉1个定时器。

1.初始化(见开源文件)
TIM_EncoderInterfaceConfig(TIM2,TIM_EncoderMode_TI12,TIM_ICPolarity_Rising,TIM_ICPolarity_Rising);
2.读取计数
TIM_GetCounter(TIM2);TIM_SetCounter(TIM2,0);

读取当前计数,再将当前计数归零。只要定时执行该程序,即可得到速度

3.tb6612

大致原理:

通过给入PWM控制速度

通过AIN12,BIN12控制方向

三、PID算法

其中e(t)为偏差,Kp、Ki、Kd分别为比例、积分、微分的系数

三个系数分别起到的作用

Kp:回调速度。但过大会产生过冲

Kd:抑制Kd。类似阻尼效应

Ki:消除静态误差。

pid的目的:

是对偏差e(t)进行处理,使偏差趋近于0的过程

为了方便数据处理,常见的是离散pid

直立环:

通常采用PD控制器

输入 :目标角度(Middle_angle),实际角度,X轴角加速度(由于角度微分)

输出:PWM

int Vertical(float Med_Angle,float Angle,float gyro_X)
{
	int PWM_out;
	
	PWM_out = Vertical_Kp*(Angle-Med_Angle) + Vertical_Kd*(gyro_Y-0);
	return PWM_out;
}

速度环:

通常采用PI控制器,并且为减缓速度差值对减少对平衡的影响,所以在速度环中,使用用了一阶低通滤波

输入 :目标速度(=0),当前速度(由编码器测得的数据反映)

输出:PWM

int Velocity(int Target,int encoder_left,int encoder_right)
{
	static int Encoder_S, EnC_Err_Lowout_last, PWM_out,Encoder_Err, EnC_Err_Lowout;
	float a = 0.7;
	
	//1.计算速度偏差
	Encoder_Err = ((encoder_left+encoder_right)-Target);
	//2.对速度偏差进行低通滤波
	//low_out=(1-a)*Ek+a*low_out_last;
	EnC_Err_Lowout = (1-a)*Encoder_Err + a*EnC_Err_Lowout_last;
	EnC_Err_Lowout_last = EnC_Err_Lowout;
	//3.对速度偏差积分,积分出位移
	Encoder_S += EnC_Err_Lowout;
	//4.积分限幅
	Encoder_S = Encoder_S>10000 ? 10000:(Encoder_S<(-10000)?(-10000):Encoder_S);
	
	//5.速度环控制输出计算
	PWM_out = Velocity_Kp*EnC_Err_Lowout + Velocity_Ki*Encoder_S;
	return PWM_out;
}

转向环:

与PD控制器直立环相似,但直立环有目标角度,也就是平衡的时候,因此需要实际与目标角度进行拟合。而转向环是旋转的变量,没有所谓的目标

 输入:旋转角度,z轴角速度 

输出:PWM

int Turn(int gyro_Z,int Angle)
{
	int PWM_out;
	PWM_out=Turn_Kd*gyro_Z + Turn_Kp*Angle;
	return PWM_out;
}

PID调节技巧:

1.根据设定电机定时器的ARR,角度大致范围,速度大致范围估计Kp、Ki、Kd大致数量级。然后随便带入几个值,判断不同pid的极性。

2.优先调直立环。先只调Kp,逐渐调大,找到出现低频大幅震动的阈值,且不要过大;再加入Ki,逐渐调大,找到出现高频小幅震动的阈值。(短暂观察,避免电机烧了)

3.将上述的值分别乘以0.6,然后开始调速度环。速度环的Kp:Kd 大致是 200:1。

可参考:【电赛】PID算法的常用组合和调参步骤 (串级/并级/舵机环/速度环/直立环/转向环/距离环…)_哔哩哔哩_bilibili

代码开源:

通过百度网盘分享的文件:stm32平衡车(终).7z
链接:https://pan.baidu.com/s/1iUyFSLq2sGnFLweCSq3KJQ 
提取码:zndp

PID参考资料:

通过百度网盘分享的文件:PID参考文档.zip
链接:https://pan.baidu.com/s/1_HOKx0UVQazHtLzZmwZqzg 
提取码:sg0c

作者:空nk.

物联沃分享整理
物联沃-IOTWORD物联网 » STM32平衡车标准库开源详解

发表回复