|
4. Написание и отладка программы.
В качестве среды программирования было решено
использовать язык C++. Чтобы программу было легче отлаживать, можно
на время отключить двигатели и подключить вместо них по паре светодиодов,
включенных встречно: в этом случае зажигание одного диода из пары
будет соответствовать вращению двигателя в прямом направлении, а другого
- в обратном.
Прежде всего, уточним алгоритм работы программы: при рассеянном освещении
- "свободный поиск", при появлении источника света - движение
к источнику, при столкновении с препятствием - отъезд.
Поскольку, как уже указывалось, выбранный контроллер поддерживает
обработку внешних прерываний, удобно сигналы от контактных датчиков
("бамперов") подключить на входы внешних прерываний (INT0,
INT1), а процедуру отъезда от препятствия оформить как программу обработки
соответствующего прерывания. Задачи "свободного поиска"
и "движения на свет" возложим на "основную" программу.
Реализация "свободного поиска"
С тем, чтобы наша конструкция "ожила"
как можно раньше, начнем со "свободного поиска".
В простейшем случае можно, используя генератор случайных чисел, выбирать
режим движения и его продолжительность действительно случайным образом.
Однако, на практике этот метод не слишком хорош по крайней мере по
двум причинам: во-первых, мы хотим добиться поведения робота, которое
бы выглядело "свободным", вряд ли поэтому беспорядочные
рывки и метания будут хорошо смотреться; во-вторых, некоторые сочетания
режимов (например, "полный назад" - "полный вперед")
могут быть опасны для самой конструкции.
Выйти из этого положения можно разными способами. Наилучший же, как
нам кажется, в данном случае подход - это сделать вероятность включения
того или иного режима зависимой от режима текущего. К примеру, можно
задать, что если в данный момент робот движется вперед, то в следующий
- он с наибольшей вероятностью будет продолжать движение, с несколько
меньшей - повернет направо или налево, либо остановится, но не сможет
(т.е. вероятность равна 0) двинуться назад. Блок отъезда от препятствия
реализовать очень просто: устанавливаем на модель передний и задний
контактные датчики - "бамперы" .Один из контактов обоих
датчиков подключаем к "земле", а другие контакты подключаем
к выводам контроллера INT0 и INT1 (PD2 и PD3). Программно подключаем
к этим линиям "подтягивающие" резисторы. Таким образом,
при отсутствии сигнала эти входы будут установлены в "1",
а при замыкании контакта - будут "сбрасываться" в "0",
что и вызовет прерывание. Программа обработки прерывания заставляет
робота отъехать от препятствия (т.е. при срабатывании переднего датчика
робот двинется назад), причем направление движения будет противоположным
тому, что привело к столкновению: так, если робот в момент столкновения
двигался "вперед-влево", то отъезд будет "назад-вправо".
Движение на свет также для начала реализуем в простейшем варианте:
подключим пару фоторезисторов между входами PD0, PD1 и "землей".
Программно подключим к этим входам "подтягивающие" резисторы.
По мере роста освещенности сопротивление резисторов будет падать,
и также падать будет напряжение на соответствующих входах, пока не
достигнет порога нижнего уровня. Когда это произойдет на данном входе
установится логичеcкий "0".
Тогда, если оказывается "засвеченным" один из датчиков,
программа дает команду на поворот в его сторону, пока не "сработает"
второй датчик. После этого робот начнет двигаться на источник. Если
в процессе один из датчиков "потеряет" источник света, робот
выполнит необходимую коррекцию курса. Если же источник перестанут
"видеть" оба датчика - робот вернется к свободному поиску.
Как уже отмечалось, программа отъезда имеет наивысший приоритет, поэтому
если столкновение произошло в процессе движения на свет, то робот
выполнит отъезд от препятствия, а затем вернется к движению на свет
или к "свободному поиску", в зависимости от показаний датчиков
освещенности.
При начале работы в программе производится установка режимов работы
портов, разрешаются прерывания по входам INT0 и INT1, устанавливается
режим запроса на прерывание по этим входам и разрешается обработка
прерываний.
После этого в бесконечном цикле запускается подпрограмма walk(), реализующая
"свободный поиск" и движение на свет.
Подпрограмма основного движения walk() работает так: пока нет сигнала
ни от одного из датчиков освещенности, производится запрос следующего
направления движения (подпрограмма next_move()), а затем дается команда
на движение в этом направлении (подпрограмма go()) в течение 2.5 секунд.
Если же появляется сигнал от датчика освещенности, то программа дает
такое направление движения, чтобы сигнал появился на обоих датчиках,
что означает движение к источнику. Если при этом сигнал от датчиков
пропадает, подпрограмма завершает свою работу, после чего главная
программа запускает ее вновь, и опять оказывается в режиме "свободного
блуждания". Наконец, программа go() "преобразует" требуемое
направление ("STOP" тоже условно считаем за "направление")
в сигналы, выдаваемые на двигатель.
5. Прошивка микроконтоллера с использованием
внутрисхемного программатора.
Программатор – устройство для прошивки микроконтроллера.
Мы использовали внутрисхемный программатор для программирования процессора
непосредственно на плате робота. Такой способ считается более простым
и удобным в экплуатации. При программировании с параллельного порта
компьютера посылается сигнал, который усиливается посредством прорамматора.
После этого микроконтроллер получает точный сигнал, который записывается
в его FLASH-память.
|