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

有同学可能正在做为做飞思卡尔小车苦恼着,现在我就把当年我做小车的一些经验告诉大家吧,我是在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模块采集小车实时数据,包括摄像头采集到的图像和小车速度方向数据,通过对数据的分析模拟可以进一步改进小车的速度。
我参加的是第七届飞思卡尔

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值