这些小活动你都参加了吗?快来围观一下吧!>>
电子产品世界 » 论坛首页 » DIY与开源设计 » 电子DIY » STM32平衡小车学习进程 ——liushidesuiyue

共14条 2/2 1 2 跳转至
助工
2015-10-05 17:13:26     打赏
11楼

PID参数的调试

P 就是比例,就是输入偏差乘以一个系数;

I 就是积分,就是对输入偏差进行积分运算;

D就是微分,就是对输入偏差进行微分运算;

而小车pid分为直立环、速度环和转向环,在调试直立过程中,转向环可以屏蔽掉。

直立环控制函数中:

int balance(float Angle,float Gyro)

{

float Bias;

int balance;

Bias=Angle-0;

balance=58*Bias+Gyro*0.115;

return balance;

}

Bias=Angle-0;这行代码中,Bias为“相对重心角“,可能每部小车都不一样(装的模块数量也不同),所以具体按实际情况加减。

速度环的代码主要就是这两个参数


调试也有视屏教学,链接如下,很不错,但是我调节不到那么好






视频地址:http://player.youku.com/player.php/sid/XMTMwMDAxMTY4OA==/v.swf

    在直立环中,先比例后微分,意思就是先让微分参数为0,慢慢增大比例参数到能立稳并来回摆动,在慢慢增大微分参数,直到小车在外力推动的情况下比较稳定不抖动,最后我们在根据小车运动现象在刚刚得到的数字附近进行粗调

      比例参数在整个平衡系统中相当于倒立摆的回复力。这个参数需要大于重力加速度所产生的效果才能够使得车模保持直立。随着这个参数逐步增大,车模开始能够保持直立。该参数进一步加大,车模开始出现来回的摆动现象。

       微分参数在整个平衡系统中相当于倒立摆中的阻尼力,它可以有效的抑制车模的摆动。当该参数过大时,会引起车模本身的震动。这是由于车模本身不是一个刚体,车体具有一定的共振频率。微分参数过大时会使得车模在电机的驱动下产生车体的共振。



在调速度环的时候,要先积分再比例,顺序和之前颠倒过来,并且调大速度环的时候可以等比例稍微调小一些直立环参数。


整定PID需要耐心,慢慢调吧,下面是楼主的结果,也不是很理想。



视频地址:http://player.youku.com/player.php/sid/XMTM1MjUyMjk4OA==/v.swf

助工
2015-10-05 18:45:28     打赏
12楼

直立时小车保持静止

       小车要在直立时保持静止,有难度,除非PID整定的比较好,但是我调的效果一般。

效果如下:


视频地址:http://player.youku.com/player.php/sid/XMTM1MjUxOTk4MA==/v.swf



助工
2015-10-05 20:44:42     打赏
13楼

三.小车绕8字行走

要使得小车实现绕8字行走,设置代码,使得小车前进的同时,又转弯,就可以实现简单的绕8字行走。8字,前进速度以及转弯速度必须要控制好,根据自身的代码修改转弯的时间,以自身的代码为例子,需要修改的有一下文件:

1.MiniBalance.c中,TIM1_UP_TIM16_IRQHandler函数中增加为





void TIM1_UP_TIM16_IRQHandler(void)  
{  
//fivems++;  
	if(TIM1->SR&0X0001)//5ms
	{   
		if(FiveMsCount<250) { Flag_Qian=1,Flag_Hou=0,Flag_Left=0,Flag_Right=1; } else if(FiveMsCount==250) { Flag_Qian=0,Flag_Hou=0,Flag_Left=0,Flag_Right=0; } else if(FiveMsCount<500) { Flag_Qian=1,Flag_Hou=0,Flag_Left=1,Flag_Right=0; } else if(FiveMsCount>=500) 
            {  
                FiveMsCount=0;  
                Flag_Qian=0,Flag_Hou=0,Flag_Left=0,Flag_Right=0;  
            }  
            FiveMsCount++;  
		  TIM1->SR&=~(1<<0); readEncoder(); Led_Flash(400); Get_battery_volt(); key(100); Get_Angle(Way_Angle); Balance_Pwm =balance(Angle_Balance,Gyro_Balance); Velocity_Pwm=velocity(Encoder_Left,Encoder_Right); Turn_Pwm =turn(Encoder_Left,Encoder_Right,Gyro_Turn); Moto1=Balance_Pwm+Velocity_Pwm-Turn_Pwm; Moto2=Balance_Pwm+Velocity_Pwm+Turn_Pwm; Xianfu_Pwm(); if(Turn_Off(Angle_Balance,Voltage)==0) Set_Pwm(Moto1,Moto2); } } 



中断程序每5ms执行一次,250*5ms改变一次转弯的方向。


2.int turn(int encoder_left,int encoder_right,float gyro)函数修改为

Turn_Amplitude=300/Way_Angle; 




300这个值越大,半径越小,速度越快,反之则相反效果,速度不是很快转弯效果才比较好,所以这里我们改为300


小车绕8字行走的效果如下:



视频地址:http://player.youku.com/player.php/sid/XMTM1MjYyNTg4OA==/v.swf


助工
2015-10-05 22:08:02     打赏
14楼

四.多传感器数据融合

MPU6050 自带了数字运动处理器, 即 DMP, 结合 MPU6050 DMP, 可以将我们的原始数据,直接转换成四元数输出,而得到四元数之后,就可以很方便的计算出欧拉角,从而得到 yawroll pitch们是做平衡小车而不是四轴飞行器,所以,仅仅使用pitch就行了。其他两个角度直接在程序中屏蔽了,因为反三角函数运算在STM32F1中还是需要不少时间的。这里使用到了模拟IIC内置的DMP,解算出四元数。

使用 MPU6050 的 DMP 输出的四元数是 q30 格式的, 也就是浮点数放大了 2 的 30 次方倍。在换算成欧拉角之前,必须先将其转换为浮点数,也就是除以 2 的30 次方,然后再进行计算,

计算公式为:

q0=quat[0] / q30; //q30 格式转换为浮点数

q1=quat[1] / q30;

q2=quat[2] / q30;

q3=quat[3] / q30;

//计算得到俯仰角/横滚角/航向角

pitch=asin(-2 * q1 * q3 + 2 * q0* q2)* 57.3; //俯仰角

roll=atan2(2 * q2 * q3 + 2 * q0 * q1, -2 * q1 * q1 - 2 * q2* q2 + 1)* 57.3; //横滚角

yaw=atan2(2*(q1*q2 + q0*q3),q0*q0+q1*q1-q2*q2-q3*q3) * 57.3; //航向角

我们使用到了usart1向上位机发送pitch角度,所以在

void Read_DMP(void)函数里面,添加串口打印语句

printf("%f\r\n",Pitch)

void Read_DMP(void)  
  
{   
  
 unsigned long sensor_timestamp;  
  
 unsigned char more;  
  
 long quat[4];  
  
   dmp_read_fifo(gyro, accel, quat, &sensor_timestamp, &sensors, &more);    
  
   if (sensors & INV_WXYZ_QUAT )  
  
   {      
  
     q0=quat[0] / q30;  
  
     q1=quat[1] / q30;  
  
     q2=quat[2] / q30;  
  
     q3=quat[3] / q30;  
  
     Pitch = asin(-2 * q1 * q3 + 2 * q0* q2)* 57.3;    
  
     printf("%f\r\n",Pitch);  
  
   }  
  
}  


MPU6050连接STM32的IO,因为是模拟IIC,所以可以随便接,只要IO初始化合适就行了


连接串口转接线,通过上位机软件可以读取角度值如图


注意设置好波特率,我这里用到的是115200

     多传感器数据融合实验结束




共14条 2/2 1 2 跳转至

回复

匿名不能发帖!请先 [ 登陆 注册 ]