1

我正在开发一个简单的机器人(有 4 个轮式底座),它向前移动并通过距离传感器检测物体,用手臂捡起它。对象是一个带有某种向上方向手柄的盒子,因此手臂放在所谓的对象手柄下方并将其向上抬起。我想要实现的任务是机器人应该向前移动并将对象放在放置在某个指定位置的容器(它也是物理对象)中。

机器人通过其底座轮子中的 4 个直流电机移动,手臂由单独的直流电机控制。

我想要的是:

机器人应该向前移动,直到它检测到物体。
当检测到物体时,它应该停止轮子并启动手臂将物体向上抬起。
然后它应该向前移动,直到它检测到第二个对象,即容器。
当检测到第二个物体(容器)时,应停止轮子并激活手臂以将物体放入容器中。

为此,我编写了以下代码

#define mp1 3
#define mp2 4
#define m2p1 5
#define m2p2 6

#define echoPin 7 // Echo Pin
#define trigPin 8 // Trigger Pin
#define LEDPin 13 // Onboard LED

#define armPin1 9  // Pin 1 of arm
#define armPin2 10  // Pin 2 of arm

int maximumRange = 200; // Maximum range needed
int minimumRange = 18; // Minimum range needed
long duration, distance; // Duration used to calculate distance

int first = 0;

void setup()
{
  Serial.begin(9600);

 //Setting the pins of motors
 pinMode(mp1, OUTPUT);
 pinMode(mp2, OUTPUT);
 pinMode(m2p1, OUTPUT);
 pinMode(m2p2, OUTPUT);

 //Setting the pins of distance sensor
 pinMode(trigPin, OUTPUT);
 pinMode(echoPin, INPUT);

 pinMode(LEDPin, OUTPUT); // Use LED indicator (if required)

 pinMode(armPin1, OUTPUT);
 pinMode(armPin2, OUTPUT);
}// end setup method

long calculateDistance(){
  //Code of distance sensor
  digitalWrite(trigPin, LOW); 
  delayMicroseconds(2); 

  digitalWrite(trigPin, HIGH);
  delayMicroseconds(20); 

  digitalWrite(trigPin, LOW);
  duration = pulseIn(echoPin, HIGH);

 //Calculate the distance (in cm) based on the speed of sound.
 return duration/58.2;
}

void loop()
{
  distance = calculateDistance();

  while(distance > minimumRange) {
    forward();
    distance = calculateDistance();
  }

  while(distance <= minimumRange && first == 0){
    stopMotors();

    pickObject();

    distance = calculateDistance();
  }

  while(distance > minimumRange) {
    forward();
    distance = calculateDistance();
  }

  while(distance <= minimumRange && first == 1){
    stopMotors();

    putObject();

    distance = calculateDistance();
  }// end second while copied 

  first = 1;

}// end loop function

void pickObject(){
  digitalWrite(armPin1, LOW);
  digitalWrite(armPin2, HIGH);
}

void putObject(){
  digitalWrite(armPin1, HIGH);
  digitalWrite(armPin2, LOW);
}

void stopMotors(){
  digitalWrite(mp1, LOW);
  digitalWrite(mp2, LOW);
  digitalWrite(m2p1, LOW);
  digitalWrite(m2p2, LOW);
}

void forward(){
  digitalWrite(mp1, LOW);
  digitalWrite(mp2, HIGH);
  digitalWrite(m2p1, HIGH);
  digitalWrite(m2p2, LOW);
}

但是代码不能像我想要的那样工作。它实际上是向下移动手臂。可能是因为我没有理解loop()函数的流程。

谁能说出我的代码中有什么问题以及我的代码应该是什么才能获得所需的结果?

4

4 回答 4

2

我的原始答案与@Bmoore 在其诊断中的答案一致,但我现在相信您的算法loop()基本上是正确的。这是发生的事情:

  1. 我们处于第一次迭代中,first==0. 您输入while(distance > minimumRange),您将一直停留到条件中断。distance现在是<= minimumRangefirst == 0
  2. 你输入while(distance <= minimumRange && first == 0). 你呆在那里,不断地停止驱动引擎并进行测量,直到物体从超声波传感器中清除。distance现在是> minimumRangefirst == 0
  3. 你输入while(distance > minimumRange). 你一直呆在里面,直到条件破裂。 distance现在是<= minimumRangefirst == 0
  4. 进入while(distance <= minimumRange && first == 1)是因为first == 0.
  5. 您设置first = 1并结束迭代。
  6. 您现在处于第二次迭代中。再次,distance是现在<= minimumRangefirst == 1。因此,您不会输入前三个whiles。
  7. 您进入while(distance <= minimumRange && first == 1)并停留在其中,while直到宇宙热死(或直到您的 Arduino 的电源耗尽,以先到者为准)。

因此,该算法是可靠的。因此,其他地方肯定有问题。这是我看到的可疑情况:

  • pickObject()并且putObject()被颠倒。你留在第二while。这可能与无效的起始位置相结合:如果您的机器人可以从起始状态向上向下移动其手臂,那么您的假设可能有问题。
  • 无论出于何种原因,distance总是小于minimumRange 遇到第一个物体后(传感器故障,触发脉冲和回波之间缺少等待等)。然后,您将停留在第一个迭代中,在第二个while. 请注意,这需要先前的错误条件与观察结果一致。

您的代码中还有几处不完全正确:

  • digitalWrite()锁存器,即如果您在引脚上LOWHIGH引脚上设置,该值将保持设置,直到您更改它。您一直在不必要地编写这些值。
  • 正如其他答案指出的那样,loop()是一个......循环。它重复自己。您应该将whiles 重写为ifs (当然要更新条件)。
  • 您还通过不断测量距离直到手臂移动,一遍又一遍地发送脉冲,使您的算法依赖于忙碌等待的方法。电能不是免费的,尤其是在嵌入式平台上。delay()在这些情况下,您应该添加一个。

也可能还有其他故障(我当然希望你没有停止你的手臂驱动引擎,因为你从来没有真正停止过它!)。

因此,一般来说,您应该像这样解决此类问题:

  1. 在您的代码中添加Serial.Write()语句,使其信息丰富,描述发生了哪些步骤以及关键参数的值。
  2. 通过 USB 将您的 Arduino 连接到 IDE,或使用与 SD 卡配合使用的日志屏蔽。
  3. 根据这些日志,确定算法中的故障所在。

以这种方式使用日志记录将为您省去很多麻烦。

于 2013-09-10T12:58:19.930 回答
1

这是你的问题:

循环函数不断运行,每次结束时都会重新启动。您将 first 设置为 1,但您从未将其重新设置为 0,因此它首先经过的每个循环都是 1。

while(distance <= minimumRange && first == 1){
    stopMotors();

    putObject();

    distance = calculateDistance();
  }// end second while copied 

  first = 1;
于 2013-09-10T12:42:00.113 回答
1

loop方法不断重复,一遍又一遍,直到电池耗尽或关闭机器人。

我没有您的机器人,因此很难测试您的代码,但恕我直言,您的方法可能并不完全正确。

对于我的机器人,我去behavior-based。每个循环(每秒数百次)机器人都会询问有关环境及其内部状态的问题。使用答案,它选择正确的行为。

您使用的方法是基于行为的机器人的良好开端。这里有一些幻灯片解释了所有这些:基于行为的机器人

希望能帮助到你 !

于 2013-09-10T12:58:02.500 回答
0

循环函数不断运行,每次结束时都会重新启动。您将 first 设置为 1,但您从未将其重新设置为 0,因此它首先经过的每个循环都是 1。

while(distance <= minimumRange && first == 1){
    stopMotors();

    putObject();

    distance = calculateDistance();
}// end second while copied 

first = 1;
于 2013-09-17T07:50:10.090 回答