Как заставить моего робота двигаться по прямоугольному пути вдоль черной ленты? - PullRequest
4 голосов
/ 11 июня 2010

Я работаю над роботом, это часть летнего семинара по робототехнике в нашем колледже. Мы используем микроконтроллеры C-STAMP от A-WIT. Я смог заставить его двигаться, повернуть налево, повернуть направо, двигаться назад. Мне даже удалось заставить это идти по черной ленте, используя датчик контраста.

Я посылаю робота под углом 30-45 градусов к черной ленте на столе, и он выравнивается и начинает двигаться по черной ленте. Он немного дергается, возможно, из-за моей логики программирования, приведенной ниже, он выполняет цикл while и постоянно проверяет операторы if, поэтому в конечном итоге он пытается поворачиваться влево и вправо каждые несколько миллисекунд, что объясняет часть рывков. Но все в порядке, работает, не так гладко, как я хочу, чтобы это работало, но это работает! Проблема в том, что я не могу заставить своего робота идти по прямоугольному пути из черной ленты. Как только он достигает угла черной ленты, он продолжает идти прямо, вместо того, чтобы поворачивать налево или направо.

Мои 2 датчика расположены прямо под роботом, рядом с передним колесом, почти на уровне пола. Он имеет значение «index» в диапазоне от 0 до 8. Восемь - самый яркий контраст, а ноль - самый темный контраст. Поэтому, когда робот перемещается в зону черной ленты, значение индекса падает, и на основании этого у меня есть оператор if, указывающий роботу повернуть налево или направо.

Вот моя попытка. Чтобы избежать путаницы, я не опубликовал весь исходный код, а только логическую часть, отвечающую за движение моего робота по черной ленте.

while(1) {

    // don't worry about these.
    // 10 and 9 represent Sensor's PIN location on the motherboard
    V = ANALOGIN(10, 1, 0, 0, 0);
    V2 = ANALOGIN(9, 1, 0, 0, 0);

    // i got this "formula" from the example in my Manual. 
    // V stands for voltage of the sensor.
    // it gives me the index value of the sensor. 0 = darkest, 8 = lightest.
    index = ((-(V - 5) / 5) * 8 + 0.5);
    index2 = ((-(V2 - 5) / 5) * 8 + 0.5);

    // i've tweaked the position of the sensors so index > 7 is just right number.
    // the robot will move anywhere on the table just fine with index > 7. 
    // as soon as it drops to or below 7 (i.e. finds black tape), the robot will 
    // either turn left or right and then go forward.

    // lp & rp represent left-wheel pin and right-wheel pin, 1 means run forever.
    // if i change it from 1 to 100, it will go forward for 100ms.
    if (index > 7 && index2 > 7)
        goForward(lp, rp, 1);

    if (index <= 7) {
        turnLeft(lp, rp, 1);
        goForward(lp, rp, 1);
        // this is the tricky part. i've added this code last minute
            // trying to make my robot turn, but i didn't work.
        if (index > 4) {
            turnLeft(lp, rp, 1);
            goForward(lp, rp, 1);
        }
    }

    else if (index2 <= 7) {
        turnRight(lp, rp, 1);
        goForward(lp, rp, 1);
            // this is also the last minute addition. it's same code as above
            // but it's for the 2nd sensor.
        if (index2 > 4) {
            turnRight(lp, rp, 1);
            goForward(lp, rp, 1);
        }
    }
}

Я провел весь день, пытаясь понять это. Я почти исчерпал все возможности. Запрашивать решение для stackoverflow - это мой самый последний вариант.

Заранее спасибо! Если у вас есть какие-либо вопросы по поводу кода, дайте мне знать, но комментарии должны быть понятны.

Это моя функция goForward, если кому-то интересно:

void goForward(BYTE lp, BYTE rp, WORD t)
{
    WORD i;

    for(i = 0; i < t; i = i + 1){
        PULSOUT(lp, 400, 1, 1);
        PULSOUT(rp, 800, 1, 1);
        PAUSE(17);
    }
}

ОБНОВЛЕНИЕ: Вот что я придумал до сих пор. Я удалил все свои операторы if, которые я разместил ранее, и решил написать логику с нуля:

// if there's enough bright light in both sensors at the same time
    // robot will move forward forever.
    if (index > 7 && index2 > 7)
        goForward(lp, rp, 1);

    // but if there's not enough bright light anymore (i.e. reached black tape)
    // proceed to the else-statement.
    else {
        // if left sensor detects the black tape then turn right
        // if doesn't detect the black tape then keep going forward
        if (index2 <= 7)
            turnRight(lp, rp, 1);
        else
            goForward(lp, rp, 1);

        // if right sensor detects the black tape then turn left
        // if it doesn't detect the black tape then keep going forward
        if (index <= 7) 
            turnLeft(lp, rp, 1);
        else 
            goForward(lp, rp, 1);
    }

    // The reason for turnLeft and turnRight is to keep robot re-alligning
    // to the black tape. It will happen so fast (every 1ms) that the jerking
    // shouldn't even be noticeable.

Ответы [ 5 ]

3 голосов
/ 11 июня 2010

Вам нужно отследить внезапное возникновение: [цикл n] «Я вижу ленту» -> [цикл n + 1] «Я не вижу ленту», который происходит, когда вы сталкиваетесь с углом.

A конечный автомат является хорошим способом решения этого типа проблемы.С конечным автоматом код для конкретного состояния изолирован, он запускается только тогда, когда состояние истинно.Эта изоляция предотвращает перекрестные помехи и дает вам один известный блок кода для каждого состояния.

Учитывая ваш пример, поток может выглядеть примерно так:

:Loop

State == Moving forward and on tape.
  read sensors
  delta = abs(valueLastCycle - valueThisCycle);
  if (delta >= bigChangeValue){
    // the tape was just gone. 
    // change state and handle this situation.
    CurrentState = suddenValueChange;
  }else
    if (index <= 7) {
        turnLeft(lp, rp, 1);
        goForward(lp, rp, 1);
    else if (index2 <= 7) {
        turnRight(lp, rp, 1);
        goForward(lp, rp, 1);
    }
   ...
State == suddenValueChange
 ...
 code that handles sudden value change event
 maybe:
 Stop Robot;
 Move backwards slowly until on tape or distance x
 etc...

Goto Loop

Может показаться, что увеличение скорости сканирования поможет… но чем быстрее робот перемещается, тем выше скорость сканирования...ie Вы все еще можете прыгать с ленты -> с ленты, в этом случае ваш текущий код колеблется.

2 голосов
/ 11 июня 2010

Убедитесь, что ваш "план" имеет смысл, прежде чем беспокоиться о коде.

Начните с перемещения робота вокруг рукой и наблюдения, когда датчики проходят через черные и белые области. Попробуйте придумать поведение и смоделировать его вручную. Если это не работает так, как вы хотите, вам нужно пересмотреть поведение.

Предложение: Вы можете добавить еще несколько петель, чтобы гарантировать, что если что-то кажется неправильным, робот исправляет себя, прежде чем возобновить нормальное поведение. (Например, вместо того, чтобы поворачивать направо / налево в течение 100 мс, делайте это, пока датчики не увидят правильную вещь.)

2 голосов
/ 11 июня 2010

Ваш цикл while работает достаточно быстро, чтобы поймать угол?Если оба датчика сообщают, что они находятся на ленте, и в следующем цикле оба датчика с ленты, вы не можете обнаружить это, верно?Датчик сообщает одинаковые значения (8) для того, чтобы быть на ленте и на ленте?

Попробуйте сделать свой код быстрее.Не видя весь код, сложно дать рекомендацию, но кажется, что вы можете оценивать, если нет необходимости в утверждениях.Добавьте ELSE после первого IF, если вы знаете, что идете прямо.

Кажется, что ваша реализация goforward блокирует цикл слишком долго.1 не означает «работать вечно», он делает один проход цикла for, а затем вы ПАУЗА 17 (мс?).Для чего нужна пауза?Убери это.Это, вероятно, вызывает рывки и предотвращает поступление следующего набора значений датчика.

2 голосов
/ 11 июня 2010

Мне кажется, что goForward сразу после turnLeft / TurnRight "отменяет" поворот? Зависит от того, как реализован токарный поворот

1 голос
/ 11 июня 2010

Прямо сейчас, судя по вашему коду, каждый раз, когда робот видит черный, он движется вперед навсегда. Я не совсем уверен, как продвигаться вперед.

В псевдокоде ваш код говорит:

if you see black
 go forward forever
if you don't see black
 turn left or right

Вы видите, как ваш робот будет двигаться вперед с такой логикой? Опять же, я понятия не имею, как реализовано движение вперед, поэтому я могу ошибаться.

...