一板网电子技术论坛

风筝
发表于: 2019-9-9 22:05:52 | 显示全部楼层

通过使用超声波传感器添加跟随物体功能,了解如何将机器人提升到新的水平.


在学会制作循迹机器人后,制作可以避障机器人通常是推荐机器人爱好者和准工程师的首选项目之一。如果我们想要将这两个想法结合起来让机器人跟随物体怎么样呢?在本篇文章中,让我们向您介绍如何做到这一点!


使用超声波传感器

循迹机器人通常配备有颜色传感器,以区分它们所跟随的路线和地板。避障机器人利用红外或超声波传感器确保它们前面没有任何东西并且保持穿过预编程的路线。然而,关注单个物体并计算其轨迹是另一种问题。


将发射器连接到物体和跟随器上的接收器是通常的解决方案,但我们将仅使用一个超声波传感器来应对挑战。通过使伺服电机以30度弧度左右摆动传感器,我们可以测量物体与两个可视边缘的距离。假设我们正在追踪具有平坦表面的物体,我们可以通过相互测量这些值来知道物体是向左还是向右转动。

object of interest .jpg

当超声波传感器(蓝色)测量边缘距离时,对象(灰色)向右转。


有了这些信息,我们可以指示机器人相应转动,避免丢失目标物体。


对于这个项目,我们只需要一个带有相应电机驱动器的四轮机器人、Arduino Uno开发板、微型伺服电机和HC-SR04超声波传感器。


所需的组件

●    Arduino UNO开发板

●    四轮机器人

●    微伺服电机

●    HC-SR04

●    Arduino IDE


设置硬件

由于该项目的难点部分是代码,因此硬件相对简单。


我在这个项目中使用了Elegoo智能机器人车v3,但是任何带有旋转超声波传感器的四轮驱动机器人车都可以使用。您可能需要略微调整草图的某些部分,但为方便起见,我已经标记了它们。

Expected motor layout.png

预期的电机布局


超声波传感器将放置在机器人的前部。如果从Scratch开始制作自己的机器人,请考虑这一点。

ultrasonic sensor.png

超声波传感器相对于机器人其余部分的位置。

make your robot work.jpg

为了使您的机器人正常工作,请务必将超声波传感器安装在机器人的正面。


Arduino IDE代码

我们将使用的唯一库是Arduino IDE内置的Servo库。有关Follower Robot草图的副本,请查看GitHub存储库。现在,我们来看看代码是如何工作的。


  1.    
  2. #include <Servo.h>  //servo library
  3. Servo myservo;      // create servo object to control servo

  4. //Ultrasonic sensor variables
  5. int Echo = A4;  
  6. int Trig = A5;

  7. //motor controller pins
  8. #define ENA 5
  9. #define ENB 6
  10. #define IN1 7
  11. #define IN2 8
  12. #define IN3 9
  13. #define IN4 11
  14. #define carSpeed 150
  15. #define carSpeed2 150
  16. int rightDistance = 0, leftDistance = 0;
复制代码

您会注意到的第一件事是伺服电机。这将用于旋转超声波传感器。接下来,您将看到我分配给超声波传感器的引脚。本文使用模拟引脚4和5,但如果您打算使用不同的引脚,请务必更改这些。如果您愿意,可以使用数字引脚。


我正在使用A4和A5,因为这是Elegoo Car的默认配置。 EN和IN引脚分别用于分配电机速度值和电机方向。如果您不使用与我相同的小车,则需要更改这些值以适合您的电机引脚。


carSpeed(0-255) 是电机的最大模拟值。 carSpeed2可用于使车辆转速更快或更慢,同时保持相同的前进和后退carSpeed值。较大的carSpeed值将使您的机器人更快,但也消耗更多的能量。


在最后一行代码初始化的两个整数存储从目标到超声波传感器的厘米距离。


  1. void forward(){
  2.   analogWrite(ENA, carSpeed);
  3.   analogWrite(ENB, carSpeed);
  4.   digitalWrite(IN1, HIGH);
  5.   digitalWrite(IN2, LOW);
  6.   digitalWrite(IN3, LOW);
  7.   digitalWrite(IN4, HIGH);
  8.   Serial.println("Forward");
  9. }

  10. void back() {
  11.   analogWrite(ENA, carSpeed);
  12.   analogWrite(ENB, carSpeed);
  13.   digitalWrite(IN1, LOW);
  14.   digitalWrite(IN2, HIGH);
  15.   digitalWrite(IN3, HIGH);
  16.   digitalWrite(IN4, LOW);
  17.   Serial.println("Back");
  18. }
  19. void left() {
  20.   analogWrite(ENA, carSpeed2);
  21.   analogWrite(ENB, carSpeed2);
  22.   digitalWrite(IN1, LOW);
  23.   digitalWrite(IN2, HIGH);
  24.   digitalWrite(IN3, LOW);
  25.   digitalWrite(IN4, HIGH);
  26.   Serial.println("Left");
  27. }
  28. void right() {
  29.   analogWrite(ENA, carSpeed2);
  30.   analogWrite(ENB, carSpeed2);
  31.   digitalWrite(IN1, HIGH);
  32.   digitalWrite(IN2, LOW);
  33.   digitalWrite(IN3, HIGH);
  34.   digitalWrite(IN4, LOW);
  35.   Serial.println("Right");
  36. }
  37. void stop() {
  38.   digitalWrite(ENA, LOW);
  39.   digitalWrite(ENB, LOW);
  40.   Serial.println("Stop!");
  41. }
复制代码

这个机器人有五个移动命令,forward()、back()、left()、right()stop()


每个动作都采用forward()格式(如上图所示),并沿指定方向移动机器人。 在这里,ENA和ENB,机器人的前半部分和后半部分,被命令在carSpeed移动。 IN1和IN4,左侧电机的方向引脚被命令逆时针转动为HIGH值。 IN2和IN3,右侧电机的方向引脚被命令顺时针转动。 这样即使我们的电机倒置,我们的机器人也可以直线移动。


如果电机的两侧都朝同一方向移动,我们的机器人就会旋转一圈。


  1. //Ultrasonic distance measurement method
  2. int Distance_test() {
  3.   digitalWrite(Trig, LOW);   
  4.   delayMicroseconds(2);
  5.   digitalWrite(Trig, HIGH);  
  6.   delayMicroseconds(20);
  7.   digitalWrite(Trig, LOW);   
  8.   float Fdistance = pulseIn(Echo, HIGH);  
  9.   Fdistance= Fdistance / 58;      
  10.   return (int)Fdistance;
  11. }
复制代码

该方法从超声波传感器发出脉冲。 然后它使用声速和脉冲返回的时间来计算距离。 这是使用超声波传感器的最常用方法之一,因此我在此不再赘述。

  1. void setup() {
  2.   myservo.attach(3);  // attach servo on pin 3 to servo object
  3.   Serial.begin(9600);     
  4.   pinMode(Echo, INPUT);   
  5.   pinMode(Trig, OUTPUT);  
  6.   pinMode(IN1, OUTPUT);
  7.   pinMode(IN2, OUTPUT);
  8.   pinMode(IN3, OUTPUT);
  9.   pinMode(IN4, OUTPUT);
  10.   pinMode(ENA, OUTPUT);
  11.   pinMode(ENB, OUTPUT);
  12.   stop();
  13. }
复制代码

在setup()函数中,我们确保传感器和电机准备就绪。 stop()用于确保电机在接收任何命令之前停止移动。


  1. void loop() {
  2.   
  3.     myservo.write(60);  //setservo position to right side
  4.     delay(200);
  5.     rightDistance = Distance_test();

  6.     myservo.write(120);  //setservo position to left side
  7.     delay(200);
  8.     leftDistance = Distance_test();


  9.     if((rightDistance > 70)&&(leftDistance > 70)){
  10.       stop();
  11.     }else if((rightDistance >= 20) && (leftDistance >= 20)) {     
  12.       forward();
  13.     }else if((rightDistance <= 10) && (leftDistance <= 10)) {
  14.         back();
  15.         delay(100);
  16.     }else if(rightDistance - 3 > leftDistance) {
  17.         left();
  18.         delay(100);
  19.     }else if(rightDistance + 3 < leftDistance) {
  20.         right();
  21.         delay(100);
  22.     }else{
  23.       stop();
  24.     }
  25.    
  26. }
复制代码

loop()中,首先我们将伺服设置为60度,计算到物体的距离,然后将伺服向左移动60度。下面是我们的对象跟踪逻辑。如果机器人前面没有任何东西长达70厘米,它将停止移动,直到它前面有东西。这样做是为了防止远离目标物体的墙壁或物体的干扰。


我们的机器人将试图在目标物体后面保持10厘米,根据目标的位置向前和向后移动。如果任一侧比另一侧更远三厘米,机器人将沿该方向转动以跟随其预测路径。


请记住,超声波传感器的60度弧以及转动的3厘米阈值可根据项目进行更改。如果您的目标物体很长,您可能会需要更宽的弧度和更小的转弯阈值。

跳转到指定楼层
您需要登录后才可以回帖 登录 | 立即注册

本版积分规则

主题 373 | 回复: 667



手机版|

GMT+8, 2019-9-22 17:47 , Processed in 0.140626 second(s), 31 queries . Powered by Discuz! X3.4

YiBoard一板网 © 2015-2018 地址:河北省石家庄市长安区高营大街 ( 冀ICP备18020117号 )

快速回复 返回顶部 返回列表