[开发进程]实验六、绕圈圈与绕8字走
本实验的目:让小车苯苯的一直绕圈子走
实验背景:小车源代码中,已经实现了小车绕原地转弯、前进以及后退。绕原地转弯就是一个轮子转动速率很少,另外一个转动速率相对大,就能实现绕原地转弯的效果。假如自己另外设置代码,使得小车前进的同时,又转弯,就可以实现简单的例如绕圈圈在走这样的效果。当然也感谢小车的开源代码!没有代码的开源,本试验也不能完成。
实验原理以及相关代码:
智能小车相关程序运行过程:
各部分模块初始化->每5ms进入一次中断计算相关代码让车子运行(包括前进、后退、左转、右转)[通过配置定时器3实现]
定时器3中断子程序执行代码主中跟本实验有关的就是:
int turn(int encoder_left,int encoder_right,float gyro);//转向控制
以及
int velocity(int encoder_left,int encoder_right);
个人认为,其中MiniBalance.c的第120行代码中,Turn_Amplitude明显就是转向的速度。另外velocity子程序中第72到74行代码中的Movement就是前进后退的速度。
如果想要走8字,前进速度以及转弯速度必须要控制好。两个速度影响着绕的8字的形状。
相关代码:
注意:本代码在Mini Balance V2.5 标准版源码的基础上修改。
修改1 :
Main.c第六行:
u8 Way_Angle=2;
修改原因:=1的话,电机运行以后,OLED就不会刷新了,我不想,所以我喜欢改为2。
修改2:
MiniBalance.c中,第21行开始到TIM1_UP_TIM16_IRQHandler函数结束,改为以下内容。
int FiveMsCount=0;
void TIM1_UP_TIM16_IRQHandler(void)
{
if(TIM1->SR&0X0001)//5ms定时中断
{
if(FiveMsCount<500)
{
Flag_Qian=1,Flag_Hou=0,Flag_Left=0,Flag_Right=1;
}
else if(FiveMsCount==500)
{
Flag_Qian=0,Flag_Hou=0,Flag_Left=0,Flag_Right=0;
}
else if(FiveMsCount<1000)
{
Flag_Qian=1,Flag_Hou=0,Flag_Left=1,Flag_Right=0;
}
else if(FiveMsCount>=1000)
{
FiveMsCount=0;
Flag_Qian=0,Flag_Hou=0,Flag_Left=0,Flag_Right=0;
}
FiveMsCount++;
TIM1->SR&=~(1<<0); //===清除定时器1中断标志位
readEncoder(); //===读取编码器的值
Led_Flash(400); //===LED闪烁;
Get_battery_volt(); //===获取电池电压
key(100); //===扫描按键状态
Get_Angle(Way_Angle); //===更新姿态
Balance_Pwm =balance(Angle_Balance,Gyro_Balance); //===平衡PID控制
Velocity_Pwm=velocity(Encoder_Left,Encoder_Right); //===速度环PID控制
Turn_Pwm =turn(Encoder_Left,Encoder_Right,Gyro_Turn); //===转向环PID控制
Moto1=Balance_Pwm+Velocity_Pwm-Turn_Pwm; //===计算左轮电机最终PWM
Moto2=Balance_Pwm+Velocity_Pwm+Turn_Pwm; //===计算右轮电机最终PWM
Xianfu_Pwm(); //===PWM限幅
if(Turn_Off(Angle_Balance,Voltage)==0) //===如果不存在异常
Set_Pwm(Moto1,Moto2); //===赋值给PWM寄存器
}
}
原理:中断程序每5ms执行一次,这里就按照500*5ms的时间改变一次转弯的方向,这里500*5ms差不多绕着0字转了刚刚好的一圈。
假如需要绕着圈圈走,那就直接使用
Flag_Qian=1,Flag_Hou=0,Flag_Left=0,Flag_Right=1;
而不必往另外一个方向绕圈圈了。
修改3:
MiniBalance.c中,在int turn(int encoder_left,int encoder_right,float
gyro);函数内的
Turn_Amplitude=1500/Way_Angle+800;
改为:
Turn_Amplitude=300/Way_Angle;
减慢转弯速度。主要是我不喜欢小车走太快。。。
代码修改就这么简单。。
修改4:另外也可以通过手机来控制实现小车绕圈圈走,方法:
将Usart3.c内Usart3中断子程序中的内容部分(下面代码已注释掉的部分),改为下面没有注释的代码:
/*original
if(uart_receive==0x00) Flag_Qian=0,Flag_Hou=0,Flag_Left=0,Flag_Right=0;//////////////刹车
if(uart_receive==0x01) Flag_Qian=1,Flag_Hou=0,Flag_Left=0,Flag_Right=0;//////////////前
if(uart_receive==0x05) Flag_Qian=0,Flag_Hou=1,Flag_Left=0,Flag_Right=0;//////////////后
else if(uart_receive==0x02||uart_receive==0x03||uart_receive==0x04)
Flag_Qian=0,Flag_Hou=0,Flag_Left=0,Flag_Right=1;
else if(uart_receive==0x06||uart_receive==0x07||uart_receive==0x08)
Flag_Qian=0,Flag_Hou=0,Flag_Left=1,Flag_Right=0;
*/
if(uart_receive==0x00) Flag_Qian=0,Flag_Hou=0,Flag_Left=0,Flag_Right=0;//////////////刹车
if(uart_receive==0x01) Flag_Qian=1,Flag_Hou=0,Flag_Left=0,Flag_Right=0;//////////////前
else if(uart_receive==0x02) Flag_Qian=1,Flag_Hou=0,Flag_Left=0,Flag_Right=1;//////////////前转右
else if(uart_receive==0x03) Flag_Qian=0,Flag_Hou=0,Flag_Left=0,Flag_Right=1;//////////////原地转右
else if(uart_receive==0x04) Flag_Qian=0,Flag_Hou=1,Flag_Left=0,Flag_Right=1;//////////////后转右
else if(uart_receive==0x05) Flag_Qian=0,Flag_Hou=1,Flag_Left=0,Flag_Right=0;//////////////后
else if(uart_receive==0x06) Flag_Qian=0,Flag_Hou=1,Flag_Left=1,Flag_Right=0;//////////////后转左
else if(uart_receive==0x07) Flag_Qian=0,Flag_Hou=0,Flag_Left=1,Flag_Right=0;//////////////原地转左
else if(uart_receive==0x08) Flag_Qian=1,Flag_Hou=0,Flag_Left=1,Flag_Right=0;//////////////前转左
视频地址:http://player.youku.com/player.php/sid/XMTI1MjQ4Mzc5Mg==/v.swf