为什么我的小车能上3m/s

来源:互联网 发布:linux tomcat部署mvc 编辑:程序博客网 时间:2024/04/30 01:38

有同学可能正在做为做飞思卡尔小车苦恼着,现在我就把当年我做小车的一些经验告诉大家吧,我是在2013年参加的第七届飞思卡尔竞赛,在下面这个跑到上小车能很轻松跑到3m以上。
在这个场地上很轻松的跑到3.14m/s
现在已经研究生了,回想起当时做小车还是挺有感触的,小车包括三大部分,机械、硬件、软件。
首先,机械部分是小车能否跑到3m以上很关键的一部分,小车的机械部分的改进需要参考赛车的一些设计,比如要尽量贴地,要向前倾,轮距要合适,舵机转幅要大等等,小车一定要做的精致,能够做小的地方就要做小,轮子要用使用过一段时间的轮子,摄像头的前探距离要够长,范围要广(使用广角镜),用采集卡采集的画面要清晰等等。
小车的机械是做的最完美的地方
其次,小车的硬件设计也是很关键的部分,如果同学们自己不能设计核心板可以购买现成的核心板,但是底板要尽量小,散热要好(散热主要跟程序有关),布线要合理,尽量不用跳线,不用杜邦线,要保证小车不会因为硬件的问题而烧CPU,发热导致电路板保护,电机保护。
最后,程序显而易见是重中之重,摄像头的采集程序要做到精简,因为我们的摄像头采集很多是通过中断的方式采集,如果中断服务程序过长的话就会一直进入中断,影响小车判断终点等,摄像头的采集我这儿用的是硬件二值化的方式:

/********************************************************** ISR_Sample_Up* 上升沿(即白到黑的跳变)采集中断的中断服务程序**************************************/ISR_Sample_Up()  {     INT16U cnt_up_tmp ;   cnt_up_tmp = READ_Camera_Timer();  CLR_UpInt();     /*清中断标志*/   if(Flag_Down - Flag_Up == 1)        {      v_point_up[Line_Save][Flag_Up] = cnt_up_tmp;            Flag_Up ++;                                            }  }/********************************************************** ISR_Sample_Down* 下降沿(即黑到白的跳变)采集中断的中断服务程序**************************************/ISR_Sample_Down()  {    INT16U cnt_down_tmp;  cnt_down_tmp = READ_Camera_Timer();        CLR_DownInt();   /*清中断标志*/   if(Flag_Down - Flag_Up == 0)    {        v_point_down[Line_Save][Flag_Down] = cnt_down_tmp;            Flag_Down ++;                                            }}/********************************************************** ISR_Sample_Point* 上升/下降沿采集中断的中断服务程序  (当CPU的外部中断口较少时,只能使用一个中断同时采集上升下降沿)**************************************/ISR_Sample_Point(){  INT16U cnt_tmp;  cnt_tmp = READ_Camera_Timer();        CLR_PointInt();   /*清中断标志*/   NEG_PointInt();   /*对触发方式取反*/  if(Flag_Down - Flag_Up == 0)  {    v_point_down[Line_Save][Flag_Down] = cnt_tmp;           Flag_Down ++;  }  else  {    v_point_up[Line_Save][Flag_Up] = cnt_tmp;               Flag_Up ++;     }}/********************************************************** _INT_Field* 场中断的中断服务程序**************************************/ISR_Field(){     CLR_FieldInt();   /*清中断标志*/     EN_LineInt();     /*使能行中断*/  DIS_FieldInt();   /*关闭场中断*/   NEG_FieldInt();   /*调整场中断的触发条件*/   CntField++;       /*场计数变量加1*/ } /********************************************************** ISR_Line* 行中断的中断服务程序  (行中断之后要保证处理时间小于行消隐区的时间)**************************************/ ISR_Line()  {     CLR_LineInt();                       /*清中断标志*/   START_Camera_Timer();                /*开启定时器*/ /*注意定时器的初始化必须放在一开始,从而保证定时起始时刻相对于行中断到来时刻的时间差为定值*/  DIS_PointInt();                      /*关上升/下降沿中断*/  LineCCD++;  if(LineCCD == LineCCD_End)           /***本场采样结束***/   {     LineCCD = 0;    PointNum[Line_Save++] = (INT8U)Flag_Down;   /*记录最后一行的边沿数*/     DIS_LineInt();                              /*关行中断*/    CLR_FieldInt();                             /*清场中断标志*/    EN_FieldInt();                              /*使能场中断*/  }    else if(LineCCD > LineCCD_Start)     /***正常采样行***/  {     if(Flag_Pick != 0)    {      PointNum[Line_Save++] = (INT8U)Flag_Down; /*记录上一行的边沿数*/      Flag_Pick = 0;      }    if(Ptr_LineCfg[Line_Save] == LineCCD)       /*查表判定是否需要采样*/     {         Flag_Down = 0;      Flag_Up = 0;      Flag_Pick = 1;    #if CAR_PointIntMode == 1      Set_PointInt_Down();    #endif          CLR_PointInt();                           /*清上升(下降)沿中断标志*/      EN_PointInt();                            /*开上升/下降沿中断*/          }    }   else if(LineCCD == LineCCD_Start)    /***一场的开始***/                {       #if EN_Check_TimeOut != 0      if(Line_Process != NUM_Line)    {                                           /*处理超时判定*/      TimeOutFlag = 1;      Cnt_TimeOut++;    }  #endif      Line_Process = 0;     Line_Save = 0;       Flag_Down = 0;    Flag_Up = 0;    Flag_Pick = 1;    #if CAR_PointIntMode == 1    Set_PointInt_Down();  #endif          CLR_PointInt();                             /*清上升(下降)沿中断标志*/        EN_PointInt();                              /*开上升/下降沿中断*/    }}

将摄像头采集到的数据处理之后就能够知道小车在跑到上的位置了,接下来要做的是将小车的位置对应到小车舵机的转向上去,这里不同的采集方案对应不同的舵机控制,但是小车舵机的控制一定要考虑并处理好盲区的问题,也就是小车摄像头照在跑到之外舵机的转向也必须正确!!如果能够正确的转向(建议转向的幅度跟小车偏差的位置成线性变化),那么就可以增加策略并且控制速度了,这里提供增量式PID算法:

/**************************内部函数**************************/#if EN_ClosedLoop != 0/********************************************************** Speed_PID* 增量式速度PID控制**************************************/static void Speed_PID(void){   INT32S pwmdelta;   /*PID运算*/  pwmdelta  = (KP_Speed+KI_Speed+KD_Speed)*((INT32S)SpeedErr);  pwmdelta -= (KP_Speed+2*KD_Speed)*((INT32S)His_SpeedErr);  pwmdelta += KD_Speed*((INT32S)His2_SpeedErr);   /*设定电机PWM*/    SetMotorPWM(MotorPWM+(INT16S)(pwmdelta/20L));}#endif

至此,你可以完成一辆小车的基本功能了,在这个环境下你要让你的小车达到2.5m/s以上,接下来,你可以开发一个上位机程序通过外接蓝牙或者wifi模块采集小车实时数据,包括摄像头采集到的图像和小车速度方向数据,通过对数据的分析模拟可以进一步改进小车的速度。
我参加的是第七届飞思卡尔

0 0
原创粉丝点击