搁浅的风度 发表于 2014-8-20 19:36:11

2013年江西省自选赛A题:智跑机器车,想用作毕业设计,

http://www.tudou.com/programs/view/mWH46E_M6vE/



小车实现转弯的时候不是很明白,用到的传感器有颜色传感器,红外探测,和漫反射避障,大神们指导下小车转弯是如何实现的,是直接控制小车的转速?

tianheiGE 发表于 2014-8-20 20:27:39

这不正是我那三个好基友的作品吗{:lol:}{:lol:}

搁浅的风度 发表于 2014-8-20 20:35:49

tianheiGE 发表于 2014-8-20 20:27
这不正是我那三个好基友的作品吗

你是新余学院的?你认识肖峰?

jingshi_yun 发表于 2014-8-20 20:40:53

左右轮是分别驱动的,原理参考轮椅

xsh2005105326 发表于 2014-8-20 20:41:20

两个轮子转速不一样就转弯咯。左转则右轮加速(或者左轮减速),反之右转

papa0305 发表于 2014-8-20 20:44:04

好,支持      

搁浅的风度 发表于 2014-8-20 20:55:39

xsh2005105326 发表于 2014-8-20 20:41
两个轮子转速不一样就转弯咯。左转则右轮加速(或者左轮减速),反之右转 ...

通过PWM控制速度么?PWM不是很懂,

搁浅的风度 发表于 2014-8-20 20:55:58

papa0305 发表于 2014-8-20 20:44
好,支持

{:handshake:}

搁浅的风度 发表于 2014-8-20 20:57:03

jingshi_yun 发表于 2014-8-20 20:40
左右轮是分别驱动的,原理参考轮椅

原理知道,但是不知道怎么控制,PWM么?

jingshi_yun 发表于 2014-8-20 21:13:37

搁浅的风度 发表于 2014-8-20 20:57
原理知道,但是不知道怎么控制,PWM么?

这种应用,步进电机比较合适

搁浅的风度 发表于 2014-8-20 21:40:34

jingshi_yun 发表于 2014-8-20 21:13
这种应用,步进电机比较合适

步进电机是调频,直流电机可以调幅。

xsh2005105326 发表于 2014-8-20 21:44:38

搁浅的风度 发表于 2014-8-20 20:55
通过PWM控制速度么?PWM不是很懂,

最简单就是开关量控制,一个电机停,一个电机转,就是转弯咯

tianheiGE 发表于 2014-8-20 21:45:15

搁浅的风度 发表于 2014-8-20 20:35
你是新余学院的?你认识肖峰?

我们多是同班同学{:biggrin:}

搁浅的风度 发表于 2014-8-20 22:02:36

tianheiGE 发表于 2014-8-20 21:45
我们多是同班同学

好吧,这么巧,他是我同学的同学{:biggrin:}

搁浅的风度 发表于 2014-8-20 22:04:34

xsh2005105326 发表于 2014-8-20 21:44
最简单就是开关量控制,一个电机停,一个电机转,就是转弯咯

额,这个.....是比较简单,我看过别人的程序是可以控制左轮或右轮转过一个角度,不知道是怎么实现的

xsh2005105326 发表于 2014-8-20 22:32:08

搁浅的风度 发表于 2014-8-20 22:04
额,这个.....是比较简单,我看过别人的程序是可以控制左轮或右轮转过一个角度,不知道是怎么实现的 ...

一种是步进电机,脉冲数决定转过角度;还有一种是普通电机+码盘,实现闭环控制

搁浅的风度 发表于 2014-8-21 09:14:52

xsh2005105326 发表于 2014-8-20 22:32
一种是步进电机,脉冲数决定转过角度;还有一种是普通电机+码盘,实现闭环控制 ...

***************************************************/       
#include "INCLUDES.h"

sbit AOB_L = P3^7;
sbit BOB_L = P3^6;
sbit AOB_R = P3^0;
sbit BOB_R = P3^1;

sbit bianjie = P1^5;   //外边界检测
sbit led= P1^2;      //调试灯

uint cont;       //计数值
uint cont_old;   //前一次计数值

uchar direction_flag; //方向标示


//                           while(1)         //调试程序
//                                       {
//                   CAR_STOP();
//                                                                   led = 0;                                                          
//                }       
//                                                        


uchar a;         
uchar b;
uchar c;
uchar d;
uchar e;
uchar f;
uint s;

void first_one(void);
void obstacle_A_area(void);
void turn_B(void);
void turn_CC(void);
void last_vie(void);

void display_12864(uint time ,uint line);


void main(void)
{
       LCD12864_Init();
       print(0x80,0,"小车运动时间:");       //       第一行显示
       print(0x88,0,"小车行驶总路程:");               //       第三行显示
       
   control_Init();//计数初始化
       PWM_INIT();      //PWM配置
       exn_Init();      //外部中断配置
       
       clear_velue();
       
/***********调试参数****************/       
        a = 0;
        line_velue = 0;   
        b = 0;
        c = 0;
        d = 0;

                CCAP1L=0x33;
            CCAP1H=0x33;//pwm1,P1.4
                CCAP0L=0x33;//pwm0,p1.3
            CCAP0H=0x33;//越大低电平时间越久       

/**********************************/

       
        while(1)
        {
   switch (a)
    {
/**************第一段平整区******************/
             case 0 :                                      
                                   first_one();
                        break;
/****************第一个转弯区********************/                                       
             case 1 :                                   
                             turn_CC();
                        break;

/**************进入第一个障碍区***************/
                       case 2 :
                                  obstacle_A_area();
                              break;
/**************进入第二个转弯区**********************/
                       case 3 :
                                   turn_B();
                              break;
/***************进入第二个障碍区*********************************/
                       case 4 :
                                   obstacle_A_area();
                              break;
/****************进入第三个转弯区*************************************/
       case 5 :
                                   turn_CC();
                              break;
/****************进入第三个障碍区***************************************/                       
                       case 6 :
                                  obstacle_A_area();
                              break;
/*****************进入第四个转弯区****************************************************/
                       case 7 :
                                  turn_B();
                              break;
/*****************进入最后平整区**************************************************************/
                       case 8 :
                                  last_vie();
                              break;
/******************停止*******************/
                       case 9 :
                                  CAR_STOP();
                                  EA = 0;
                              break;

             default:
                   break;
    }
               
                if(time_flag == 0)
                {
                        s = velue_IN0();
                        display_12864(time_velue, s);//隔1秒刷屏一次
                        time_flag = 1;
                       
                }
               
}
       
}


/*******************子函数区*************************/

/***********第一个平整区*********/
void first_one(void)
{

switch (f)
{
        uchar n;
        case 0 :
                clear_velue();//为下个状态直走做准备
                f++;   
                break;
       
       case 1 :       
       if((right_A == 0) && (right_B == 0)
                               && (left_A == 0) && (left_B == 0))
      {
                                        control_direction(0,0);
                                }                                       
                           if((right_A == 1) ||(right_B == 1))   //右边检测到
                               {
            f = 2;
                                          cont_old = velue_IN1();
                               }
                       
                               if((left_A == 1) || (left_B == 1)) // 左边传感器检测到
                               {
            f = 3;
                                          cont_old = velue_IN1();
                               }
                               if(line_velue == 2)
                               {
                                                f = 4;
                                       CCAP1L=0x38;
         CCAP1H=0x38;//pwm1,P1.4
                 CCAP0L=0x38;//pwm0,p1.3
         CCAP0H=0x38;//越大低电平时间越久
                                       clear_velue();
                                       cont_old = velue_IN1();
         }
                  break;
                               
                case 2 :            
                               Left_back();   //左轮后退       
                           cont = velue_IN0();    //左转一个小角度
                           n = cont - cont_old;
                           if(n > 3)
                               {         
               f = 0;
         }          
                          break;
                          
                        case 3 :            
                               Right_back();   //右轮后退       
                           cont = velue_IN1();    //右转一个小角度
                           n = cont - cont_old;
                           if(n > 3)
                               {
            f = 0;
         }                                 
                  break;
                       case 4 :
                       control_direction(6,0);
                   cont = velue_IN0();   
                       n = cont - cont_old;
                       if(n > 7)
                       {
         a++;
                                   d = 0;
                       }
                               break;
                               
        default:
                break;
}
}


/*************进入第1个障碍物区域(A)***************/
void obstacle_A_area(void)
{
          uchar n;
                   switch (b)
   {
                        case 0 :
                                clear_velue();               
                          b++;
                                break;
                       
/**************判断障碍物和线*******************/                       
          case 1 :               
                                if((right_A == 0) && (right_B == 0)
                               && (left_A == 0) && (left_B == 0))
                                {
                                  b = 2;      //直走
      }                               
                          if((right_A == 1) ||(right_B == 1))
                                {   
                                          b = 5;
                                       cont_old = velue_IN0();
                                }
                                if((left_A == 1) || (left_B == 1))
                                {   
            b = 6;
         cont_old = velue_IN1();                                       
                                }                                                       
                  break;

                        case 2 :                 
      if((BOB_R == 1) && (BOB_L == 1)
                                   && (AOB_R == 1) && (AOB_L == 1))                       
                                {
                                   control_direction(0,0);
                                       b = 1;   //继续检测
      }                                       
                                if((BOB_L == 0) || (AOB_L == 0))                                
                                {
                                                b = 3;       //右边转弯
      }
                                if((BOB_R == 0) || (AOB_R == 0))            
                                {
            b = 4;      //左边转弯
      }                                       
                   break;
                               
                        case 3 :            //向右壁障
              control_direction(0,3);       
      b = 0;                       
                   break;

                        case 4:
                  control_direction(3,0); //向左壁障
                          b = 0;
                  break;
                               
                        case 5 :            
                               Left_back();   //左轮后退       
                           cont = velue_IN0();    //左转一个小角度
                           n = cont - cont_old;
                           if(n > 3)
                               {
            if((BOB_R == 1) && (BOB_L == 1)
                                      && (AOB_R == 1) && (AOB_L == 1))
                                                {
               b = 0;
            }
         }          
                          break;
                          
                        case 6 :            
                               Right_back();   //右轮后退       
                           cont = velue_IN1();    //左转一个小角度
                           n = cont - cont_old;
                           if(n > 3)
                               {
            if((BOB_R == 1) && (BOB_L == 1)
                                      && (AOB_R == 1) && (AOB_L == 1))
                                                {
               b = 0;
            }
         }                                 
                  break;
                               
                                       
          default:
                   break;
   }
               
               if((line_velue == 4) || (line_velue == 8) || (line_velue == 6))//进入转弯区
               {
                                a++;
                          c = 0;                          
                          d = 0;
   }
               
               
}

/**********第二个转弯区******************/
void turn_B(void)
{   
           uchar n;
   switch (c)
   {                                
                       case 0 :
                          c++;
                          clear_velue();
                               break;       
                       
                       case 1 :
       if((right_A == 0) && (right_B == 0)
                               && (left_A == 0) && (left_B == 0) && (bianjie == 0) )
                                {
                                   c = 2;      //直走
      }               
                                                               
                           if((right_A == 1) || (right_B == 1))   //右边检测到
                               {
            c = 5;
                                          cont_old = velue_IN1();
                               }
                           if(bianjie == 1)//中间传感器检测到
                               {
                                                c = 6;
                                       cont_old = velue_IN1();
                               }
                               if((left_A == 1) || (left_B == 1))// 左边传感器检测到
                               {
            c = 7;
                                       cont_old = velue_IN1();
                               }                       
                  break;       
                               
             case 2 :          //
      if((BOB_R == 1) && (BOB_L == 1)
                                  && (AOB_R == 1) && (AOB_L == 1))
                                {
                               c = 1;
                               control_direction(0,0);
                                }
                               if((BOB_L == 0) || (AOB_L == 0))                                
                                {
                                                c = 3;       //右边转弯
      }
                                if((BOB_R == 0) || (AOB_R == 0))            
                                {
            c = 4;      //左边转弯
      }               
                  break;
                               
                        case 3 :            //向右壁障
              control_direction(0,2);       
      c = 0;                       
                   break;

                        case 4:
                  control_direction(2,0); //向左壁障
                          c = 0;
                  break;
                                                               
             case 5 :
                           Right_back();   //右轮后退
                           cont = velue_IN1();    //右转一个大角度
                           n = cont - cont_old;
                           if(n > 15)
                               {
                                       if((BOB_R == 1) && (BOB_L == 1)
                                      && (AOB_R == 1) && (AOB_L == 1))
                                                {
               c = 0;
            }
         }                       
                  break;       
                               
                       case 6 :               
         Right_back();   //右轮后退       
                           cont = velue_IN1();    //右转一个中角度
                           n = cont - cont_old;
                           if(n > 9)
                               {
         if((BOB_R == 1) && (BOB_L == 1)
                                      && (AOB_R == 1) && (AOB_L == 1))
                                                {
               c = 0;
            }
         }                              
                  break;
                               
             case 7 :
                               Right_back();   //右轮后退       
                           cont = velue_IN1();    //右转一个小角度
                           n = cont - cont_old;
                           if(n > 5)
                               {
         if((BOB_R == 1) && (BOB_L == 1)
                                      && (AOB_R == 1) && (AOB_L == 1))
                                                {
               c = 0;
            }
         }
                  break;
                               
          default:
                  break;
   }       
               if((line_velue == 9) || (line_velue == 5))
               {
          a++;
                          b = 0;
                                        e = 0;   
   }
               
}

/***************第三个转弯区***********************/
void turn_CC(void)
{
      uchar n;

   switch (d)
   {
                       case 0 :
                          d++;
                          clear_velue();
                               break;       
                       case 1 :
       if((right_A == 0) && (right_B == 0)
                               && (left_A == 0) && (left_B == 0) && (bianjie == 0))
                                {
                                   d = 2;      //直走
      }               
                                if((left_A == 1)||(left_B == 1))   //左边检测到....
                               {
            d = 5;
                                          cont_old = velue_IN0();
                               }
                           if(bianjie == 1)//中间传感器检测到
                               {
                                                d = 6;
                                          cont_old = velue_IN0();
                               }
                               if((right_A == 1) || (right_B == 1))// 左边传感器检测到
                               {
            d = 7;
                                       cont_old = velue_IN0();
                               }
                  break;       
                                       
             case 2 :          //
      if((BOB_R == 1) && (BOB_L == 1)
                                  && (AOB_R == 1) && (AOB_L == 1))
                                {
                               d = 1;
                               control_direction(0,0);
                                }
                                if((BOB_L == 0) || (AOB_L == 0))                         //左边障碍物       
                                {
                                                d = 3;       //右边转弯
      }
                                if((BOB_R == 0) || (AOB_R == 0))            
                                {
            d = 4;      //左边转弯
      }                                               
                  break;
                               
                                case 3 :            //向右壁障
              control_direction(0,2);
      d = 0;                                       
                   break;

                        case 4:
                  control_direction(2,0); //向左壁障
                          d = 0;
      break;
                                                                                               
             case 5 :
                           Left_back();   //左轮后退
                           cont = velue_IN0();    //左转一个大角度
                           n = cont - cont_old;
                           if(n > 15)
                               {
                                       if((BOB_R == 1) && (BOB_L == 1)
                                      && (AOB_R == 1) && (AOB_L == 1))
                                                {
               d = 0;
            }
         }                       
                  break;       
                               
                       case 6 :               
         Left_back();   //左轮后退       
                           cont = velue_IN0();    //左转一个中角度
                           n = cont - cont_old;
                           if(n > 9)
                               {
         if((BOB_R == 1) && (BOB_L == 1)
                                      && (AOB_R == 1) && (AOB_L == 1))
                                                {
               d = 0;
            }
         }                              
                  break;
                               
             case 7 :
                               Left_back();   //右轮后退       
                           cont = velue_IN0();    //左转一个小角度
                           n = cont - cont_old;
                           if(n > 5)
                               {
            if((BOB_R == 1) && (BOB_L == 1)
                                      && (AOB_R == 1) && (AOB_L == 1))
                                                {
               d = 0;
            }
         }
                  break;
                               
          default:
                  break;
   }                       
               
                if((line_velue == 7) || (line_velue == 3))
               {
                                                a++;       
            b = 0;//进入避障区                                       
               }
}

/****************最后一个平整区*************************/
void last_vie(void)
{
          uchar n;
switch (e)
{
        case 0 :
                clear_velue();//为下个状态直走做准备
          CCAP1L=0x33;
    CCAP1H=0x33;//pwm1,P1.4
          CCAP0L=0x33;//pwm0,p1.3
    CCAP0H=0x33;//越大低电平时间越久
                e++;   
                break;
       
       case 1 :
       if((right_A == 0) && (right_B == 0)
                                && (left_A == 0) && (left_B == 0))
                     {
                control_direction(0,0);
                    }
                           if((right_A == 1) || (right_B == 1))//右边检测到
                               {
            e = 2;
                                          cont_old = velue_IN1();
                               }
                       
                               if((left_A == 1) ||(left_B == 1))   // 左边传感器检测到
                               {
            e = 3;
                                       cont_old = velue_IN1();
                               }
                               if(line_velue == 10)
                               {
                                                e = 4;
                                       clear_velue();
                                       cont_old =velue_IN1();
         }
                  break;
                case 2 :            
                                Left_back();   //左轮后退       
                           cont = velue_IN0();    //左转一个小角度
                           n = cont - cont_old;
                           if(n > 3)
                               {         
               e = 0;
         }          
                          break;
                          
                        case 3 :            
                                Right_back();   //右轮后退       
                           cont = velue_IN1();    //左转一个小角度
                           n = cont - cont_old;
                           if(n > 3)
                               {
            e = 0;
         }                                 
                  break;
   
                       
                case 4 :
                        control_direction(0,0);
                  cont = velue_IN0();    //最后冲过终点
                        n = cont - cont_old;
                  if(n > 25 )
                        {
                                a++;            
      }               
                break;
                       
        default:
                break;
}   
               

}


/***************************/
/***************12864显示函数******************/
void display_12864(uint time ,uint line)
{
               
                print(0x90,0," ");                           //          第二行显示
                LCD12864_WriteData(time/100+0x30);
                LCD12864_WriteData(time/10%10+0x30);
                LCD12864_WriteData(time%10+0x30);
                print(0x90,2,"秒");
          
       
          
                print(0x98,0," ");                                  //        第四行显示
          LCD12864_WriteData(line/1000+0x30);
                LCD12864_WriteData(line/100%10+0x30);
                LCD12864_WriteData(line/10%10+0x30);
                LCD12864_WriteData(line%10+0x30);
                print(0x98,3,"厘米");
          
}


搁浅的风度 发表于 2014-8-21 09:15:20

xsh2005105326 发表于 2014-8-20 22:32
一种是步进电机,脉冲数决定转过角度;还有一种是普通电机+码盘,实现闭环控制 ...

程序看不懂,不是我的
页: [1]
查看完整版本: 2013年江西省自选赛A题:智跑机器车,想用作毕业设计,