一种双灰度传感器巡黑线方案:完美解决小车循迹时左右摇摆的问题

背景

在使用灰度传感器制作巡迹小车时,传统循迹方法通常采用三灰度循迹,即在小车车体的左中右三个位置分别放置三个灰度传感器,根据传感器是否触发或是传感器返回的数值大小来判断车体的三种位置状态:中正、偏左、偏右,但是这样的循迹方式有一个很大的缺点,当车体发生一次歪斜之后,继续巡线过程中车体左右摇摆严重,非常影响小车前进速度以及前进方向的稳定。
本文提出一种双灰度传感器巡黑线的方案,经过实际验证,该方案很好的解决了上述问题。

传统的三灰度循迹传感器放置方案

注意: 在下面的图中,棕色的方形块和四个蓝色的圆柱表示一个小车的车体,眼睛表示灰度传感器,黑色的半透明阴影表示黑色的循迹线。
图1.直行状态(从底部向上看)
在这里插入图片描述
图2.左偏状态(从底部向上看)
通常情况下,当车体歪斜一个不小的角度时,小车右边的传感器才能检测到黑色,然后执行右转的代码,使车体回正,如下图所示;
在这里插入图片描述
图3.执行回正代码后小车状态(从底部向上看)
在回正的过程中,代码逻辑是要小车转向直到中间传感器检测到黑色,完成转向后,小车的状态通常是这样;此时中间传感器检测到黑线,判断为中正,保持直行,但是这样走一小段距离,小车左边传感器就检测到了黑线,又要往左转向,然后车体再次歪斜,再往右转向;如此周而复始,就造成了小车循迹过程中左右摇摆的现象。
在这里插入图片描述
图4.传统循迹方法下的小车轨迹
在这里插入图片描述

尝试新的传感器放置方案

为解决上述问题,我想了很多种方案,比如:

  • 在车体前部两侧放置两个传感器
    图5.双灰度并排两侧放置(从底部向上看)
    在这里插入图片描述
  • 在车体前部放置五个传感器
    图6.五灰度并排放置(从底部向上看)
    在这里插入图片描述
  • 在车体前部中间放一个传感器,后面两侧放两个传感器
    图7.三灰度三角形放置(从底部向上看)
    在这里插入图片描述
  • 在车体前部中间放一个传感器,中部两侧放两个传感器,后部中间放一个传感器
    图8.四灰度四边形放置(从底部向上看)
    在这里插入图片描述
    以上方案经过测试,都没有很好的解决左右摇摆的问题。
    最终在测试中,发现了下面的双灰度传感器并排中置方案,经过实际测试,发现巡线效果大幅提升,车体运行十分平稳。

双灰度传感器并排中置方案

注意: 在下面的图中,棕色的方形块和四个蓝色的圆柱表示一个小车的车体,两个眼睛表示两个灰度传感器,黑色的半透明阴影表示黑色的线。

  • 如图9所示,两个灰度传感器均能检测到黑色,此时车体中正,保持直行。
    图9.直行状态(从底部向上看)
    在这里插入图片描述
    图10:对应的俯视图
    在这里插入图片描述
  • 如图11所示,小车右边的传感器(对应仰视图的左边)检测不到黑线,而左边传感器(对应仰视图的右边)检测到了黑线,此时小车向右偏,应该左转。
    图11.左转状态(从底部向上看)
    在这里插入图片描述
    图12.对应的俯视图
    在这里插入图片描述
  • 如图13所示,小车左边的传感器(对应仰视图的右边)检测不到黑线,而右边传感器(对应仰视图的左边)检测到了黑线,此时小车向左偏,应该右转。
    图13.右转状态(从底部向上看)
    在这里插入图片描述
    图14.对应的俯视图
    在这里插入图片描述
    由于两传感器距离黑线边界较近,且传感器位置放置在车头处,车体稍稍发生一点偏斜,就立即触发转向程序,因而能及时纠正车体位置,不至于当车体偏离很大的角度后才触发转向,避免了左右摇摆的现象。
    图15.循迹效果示意
    在这里插入图片描述

2019.11.23 完善
注: 这里其实只提出了一个思路,因为是软硬件结合的,不同的硬件结构的代码也完全不一样,在实际操作的时候还是会遇到很多问题;
比如这种循迹方法只能巡直线和弯度不大的转弯,如果要过直角弯还需要增加两个灰度传感器进行辅助判断;
反正,就是具体问题具体解决嘛。。。
这里给出我的代码,仅供参考:) 希望能帮到你~

#include <Servo.h>

int sensor_pin[4] = {A0,A4,A2,A3};
int sensor_value[4] = {0,0,0,0};
const int LEFT = 0;//normal left
const int RIGHT = 1;//normal right
const int LEFT_RightAngle = 2;//right angle left
const int RIGHT_RightAngle = 3;//right angle right
const int STRAIGHT = 4;
const int BlackLimit_ML = 680;
const int BlackLimit_MR = 550;
const int BlackLimit_L = 500;
const int BlackLimit_R = 500;
const int HIGH_RIGHT = 234;
Servo myservo;
boolean isobstacle = 0;

void setup(){
  pinMode(5,OUTPUT);//motor out
  pinMode(6,OUTPUT);
  pinMode(9,OUTPUT);//motor out
  pinMode(10,OUTPUT);
  pinMode(8,INPUT);//touch sensor
  
  myservo.attach(11);
  Serial.begin(9600);
}

//judge whether an obstacle in front of us,return true when it is 
boolean is_obstacle(){
  isobstacle = digitalRead(8);
  return isobstacle;
}

//read sensor value
void read_value(){
  for(int i = 0;i < 4;i++){
    sensor_value[i] = analogRead(sensor_pin[i]);
  }
}

//turn to a direction
void turn(const int direction_){
  switch(direction_){
    case LEFT:
      analogWrite(5,LOW);
      digitalWrite(6,HIGH_RIGHT);//right wheel
      digitalWrite(9,LOW);
      digitalWrite(10,LOW);//left wheel
      while(sensor_value[2] > BlackLimit_MR){//sensor_value[1] > BlackLimit_M     
        read_value();
        delay(5);
      }
      break;
    case RIGHT:
      digitalWrite(5,LOW);
      analogWrite(6,LOW);//right wheel
      digitalWrite(9,LOW);
      digitalWrite(10,HIGH);//left wheel
      while(sensor_value[1] > BlackLimit_ML){//sensor_value[1] > BlackLimit_M        
        read_value();
        delay(5);
      }
      break;
    case LEFT_RightAngle:
      digitalWrite(5,LOW);
      analogWrite(6,HIGH_RIGHT);//right wheel
      digitalWrite(9,HIGH);
      digitalWrite(10,LOW);//left wheel
      while(sensor_value[1] > BlackLimit_ML){//sensor_value[1] > BlackLimit_M        
        read_value();
        if(sensor_value[3] < BlackLimit_R)
           break;
        delay(5);
      }
      break;
    case RIGHT_RightAngle:
      digitalWrite(5,HIGH_RIGHT);
      analogWrite(6,LOW);//right wheel
      digitalWrite(9,LOW);
      digitalWrite(10,HIGH);//left wheel
      while(sensor_value[2] > BlackLimit_MR){//sensor_value[1] > BlackLimit_M        
        read_value();
        if(sensor_value[0] < BlackLimit_L)
           break;
        delay(5);
      }
      break;
    case STRAIGHT:
      digitalWrite(5,LOW);
      analogWrite(6,HIGH_RIGHT);//right wheel
      digitalWrite(9,LOW);
      digitalWrite(10,HIGH);//left wheel
      break;
    default:
      digitalWrite(5,LOW);
      analogWrite(6,HIGH_RIGHT);//right wheel
      digitalWrite(9,LOW);
      digitalWrite(10,HIGH);//left wheel
      break;
  }
}

//judge what direction to turn with sensor value
void judge_turn(){
  read_value();
  if(sensor_value[0] < BlackLimit_L && sensor_value[3] > BlackLimit_R){//turn left right tangle
    Serial.println(LEFT_RightAngle); 
    turn(LEFT_RightAngle);
  }
  else if(sensor_value[0] > BlackLimit_L && sensor_value[3] < BlackLimit_R){//turn right right tangle
    Serial.println(RIGHT_RightAngle);
    turn(RIGHT_RightAngle);
  }
  else if(sensor_value[1] > BlackLimit_ML && sensor_value[2] < BlackLimit_MR){
    Serial.println(RIGHT); 
    turn(RIGHT);
  }
  else if(sensor_value[1] < BlackLimit_ML && sensor_value[2] > BlackLimit_MR){
    Serial.println(LEFT); 
    turn(LEFT);
  }
  else{
    Serial.println(STRAIGHT);
    turn(STRAIGHT);   
  }
}

void run(){
   judge_turn();
   delay(10);
}

void loop(){
 run();  
}
  • 68
    点赞
  • 542
    收藏
    觉得还不错? 一键收藏
  • 17
    评论
循迹小车左右摇摆问题可以通过改变传感器的放置方案解决。传统的三灰度循迹传感器放置方案存在车体歪斜后左右摇摆问题一种解决方案是采用灰度传感器黑线方案。该方案通过在小车车体的左右两个位置分别放置灰度传感器,根据传感器是否触发或传感器返回的数值大小来判断车体的位置状态。当车体歪斜,只有一个传感器能够检测到黑色,然后执行相应的代码使车体回正。这样可以避免传统方案中车体在回正过程中左右摇摆问题。经过实际验证,灰度传感器黑线方案能够很好地解决左右摇摆问题。\[1\] 在代码实现方面,可以根据传感器的检测结果来控制小车的运动。例如,可以使用电机控制代码来实现小车的前进、后退、左转、右转和停止等功能。通过合理的控制电机的转动,可以使小车保持稳定的前进方向,避免左右摇摆问题。\[3\] #### 引用[.reference_title] - *1* *2* [一种灰度传感器黑线方案完美解决小车循迹左右摇摆问题](https://blog.csdn.net/qq_41748900/article/details/102641330)[target="_blank" data-report-click={"spm":"1018.2226.3001.9630","extra":{"utm_source":"vip_chatgpt_common_search_pc_result","utm_medium":"distribute.pc_search_result.none-task-cask-2~all~insert_cask~default-1-null.142^v91^koosearch_v1,239^v3^insert_chatgpt"}} ] [.reference_item] - *3* [循迹小车基本原理和代码实现](https://blog.csdn.net/l_z_y_000/article/details/128679887)[target="_blank" data-report-click={"spm":"1018.2226.3001.9630","extra":{"utm_source":"vip_chatgpt_common_search_pc_result","utm_medium":"distribute.pc_search_result.none-task-cask-2~all~insert_cask~default-1-null.142^v91^koosearch_v1,239^v3^insert_chatgpt"}} ] [.reference_item] [ .reference_list ]
评论 17
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值