Лабиринт

Сделаем машинку-робота, который выбирается из лабиринта.

Мы уже писали, как сделать машинку-робота, двигающегося по полосе вот здесь projects/plata1/28-run-over. Теперь, с этими знаниями мы двигаемся вперед.

Из предыдущего проекта у нас есть все: машинка с двумя двигателями, плата Марсоход, свето-чувствительные датчики.

Мы изменим мозги нашего робота, чтобы он мог выполнять новую задачу - поиск выхода из лабиринта.

Для начала займемся "рисованием". Дело это творческое. Нужно придумать рисунок лабиринта и нарисовать его на большом листе бумаги. Следует сразу учесть, что тупики в лабиринтах должны быть такой ширины, чтобы наш робот мог спокойно там развернуться и ехать назад. Таким образом, от размера робота зависит размер лабиринта.

Когда эскиз лабиринта готов - приступаем к его "рисованию" в натуральную величину. Нам понадобятся большие листы белой бумаги, например ватман или что-то такое. Склеиваем их в одно большое полотно и рисуем:

draw_labirint1

Лучше всего рисовать гуашью. Сохнет быстро и достаточно черная.

draw_labirint2

Чем больше "рисовальщиков", тем быстрее идут дела. Smile

draw_labirint3

Вот что получается в результате нашей работы:

labirint

Алгоритм выхода из лабиринта выбираем самый простой: если идти вдоль стены и держаться за нее всегда только одной рукой, то ВСЕГДА выйдешь к выходу. Не важно какой стены придерживаться правой или левой все равно выйдешь. Мы будем делать леворукого робота.

Прикрепляем имеющиеся у нас два свето-чувствительных датчика к машинке с левой стороны:

left_eyes

Вид на машинку с двумя датчиками сверху:

left_eyes2

Теперь продумываем алгоритм. Он будет примерно такой:


Если под левым датчиком черно, а под правым бело,

            то едем прямо. //значит слева от нас - стена, черная полоса и мы держимся за нее

Иначе, если под левым датчиком бело и под правым датчиком бело,

            то поворачиваем налево. //стена закончилась и есть проход налево.

Иначе, если под левым датчиком черно и под правым датчиком темно

            то поворачиваем направо. //уперлись в стену, возможен только поворот направо.


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

Теперь, когда с алгоритмом разобрались, напишем то же самое на языке аппаратуры, на Verilog.


module ctrl(
    input wire right_eye,    //правый глаз
    input wire left_eye,     //левый глаз
    output reg right_motor1,
    output reg right_motor2,
    output reg left_motor1,
    output reg left_motor2
);

always @*
begin
    case
( {left_eye,right_eye} )
    2'b00:
    begin
       //уперлись в стенку, делаем энергичный разворот вправо
       left_motor1 = 1'b1;    //включить левый мотор
       left_motor2 = 1'b0;
       right_motor1 = 1'b0;    //включить правый мотор в обратную сторону
       right_motor2 = 1'b1;
    end
    2'b01:
    begin
       //слева черная полоса, справа бело, едем прямо
       left_motor1  = 1'b1;    //включить левый мотор
       left_motor2  = 1'b0;
       right_motor1 = 1'b1;    //включить правый мотор
       right_motor2 = 1'b0;
    end
    2'b10:
    begin
       //слева бело, а справа черная полоса.
       //такое вообще-то не должно случаться, если не отрывать руку от стены

       left_motor1 = 1'b1;    //включить левый мотор
       left_motor2 = 1'b0;
       right_motor1 = 1'b0;    //выключить двигатель
       right_motor2 = 1'b0;
    end
    2'b11:
    begin
       //под обоими датчиками бело. Стена слева закончилась, нужно повернуть налево.
       left_motor1 = 1'b0;    //выключить двигатель
       left_motor2 = 1'b0;
       right_motor1 = 1'b1;    //включить правый мотор
       right_motor2 = 1'b0;
    end
    endcase
end


Обратите внимание, что поворот можно осуществлять разными способами. Самый простой способ - выключить один двигатель, а второй включить. Тогда машинка поворачивается в сторону выключенного двигателя. Второй способ более энергичный - включить один двигатель вперед, а второй назад, в противоположную сторону. Направление вращения двигателя определается полярностью питания. Поэтому мы программируем к каждому двигателю два сигнала.

Полный исходный текст проекта можно скачать на нашем сайте здесь:

. К сожалению, в этом проекте логика работы машинки немножно сложнее, чем в описанном выше алгоритме. Мы столкнулись с проблемой, что наша машинка не может развернуться в тесном тупике не наезжая на стены. Их нужно было рисовать чуть пошире. Из-за этого наш алгоритм немного другой. Когда Марсоход видит впереди стену, он на некоторое время (подбирали экспериментально) "закрывает глаза" и делает поворот направо "вслепую". После этого опять включается обычный алгоритм.
Ну а теперь, после сборки проекта и "заливки" его в плату начинаем пробовать:

Ну чтож.. Если не придираться, что кое-где машинка наезжает на стены, то вполне так прилично Smile.

Надеюсь у Вас тоже получится, и даже еще лучше!

Экспериментируйте!

 


Добавить комментарий