воскресенье, 21 ноября 2010 г.

Алгоритмы: черно-белое движение

Сенсор освещенности (или цветовой сенсор) из набора Lego Mindstorms NXT, один из наиболее используемых сенсоров при конструировании и программировании Lego-роботов.

По внутреннему устройству, он не такой сложный как сенсор расстояния. Основным элементом в нем является светочувствительный элемент (фоторезистор или фототранзистор).

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

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

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


Допустим, необходимо написать программу, которая перемещает робота из светлой в темную область на следующей карте:


Перед началом программирования, необходимо провести калибровку сенсора освещенности. После чего, измерить, что показывает сенсор на разных частях картыс ветлой и темной части карты. Пусть после калибровки, показания сенсора будут 10% на темной стороне и 90% процентов на светлой. Следовательно, условием, когда можно рассматривать, что робот уже на темной стороне – значение на сенсоре стало меньше 30%.

Тогда программа может быть сформулирована следующим образом:
1. Начать движение прямо (поскольку неизвестно, сколько нужно проехать работу до темной области, нужно задать "бесконечное" движение)
2. Ехать до тех пор, пока значение на сенсоре не станет меньше 30%.
3. Остановиться.

На NXT-G программа будет выглядеть, следующим образом:


Давайте, усложним программу, чтобы робот возвращался еще и назад, на белую область. Условием, что робот уже на светлой стороне, являются показания сенсора большие 70%.
1. Начать движение прямо
2. Ехать до тех пор, пока значение на сенсоре не станет меньше 30%.
3. Остановиться.
4. Начать движение назад.
5. Ехать до тех пор, пока значение на сенсоре не станет больше 70%.
6. Остановиться.



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


У этой программы есть очень интересное свойство: даже если перед ее запуском робот поставлен на черную область карты, робот сразу же поедет назад.
Это связано с работой пары блоков Движение и Ожидание. Как только робот поедет (после запуска моторов блоком Движение), первый блок Ожидания сразу же обнаружит, что значение освещенности очень мало (робот уже на черной области), тогда движение вперед остановится и начнется движение назад. Все это произойдет практически мгновенно и создастся ощущение, что робот понял, что ему вперед ехать не надо, и поехал сразу назад.

А насколько изменится программа, если условие задачи еще немного изменится? Допустим, карта теперь также состоит из двух частей: темной и светлой, но размеры этих частей увеличились и роботу теперь нужно добраться от одного края карты, до другого, совершая движения "ёлочкой".


Видно, что характер самого движения не изменился – робот опять должен двигаться поочередно из области одного цвета в другой. Однако, изменилось направление движения, раньше робот у нас ездил вперед и назад, сейчас же движение должно быть все время вперед, только меняется направление поворота. Итак, программа должна состоять из следующих действий:
1. Начать поворот налево.
2. Ехать до тех пор, пока значение на сенсоре не станет меньше 30%.
3. Остановиться.
4. Начать поворот направо.
5. Ехать до тех пор, пока значение на сенсоре не станет больше 70%.
6. Остановиться.
7. Повторить действия, начиная с шага 1.



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

Если кто-то уже попытался применить программы, описанные здесь, к реальному роботу на реальной карте, то тот заметил, что робот останавливается не на середине белой и черной области, а недалеко (почти) границе, где одна область переходит в другую. Поэтому повороты робота длятся крайне маленький промежуток времени и складывается впечатление, что робот не ездит с черной области на белую, а движется по их границе. Все верно! Это поведение умышленно не изменялось, чтобы программа с минимальными изменениями стала работать на следующей карте:


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

Если попробовать запустить робота с программой, приведенной выше, на новой карте. То, возможно, на некоторых частях линии (например, где линия выполняет резкий поворот) робот будет терять ее. Поэтому внесем небольшие изменения в программу так, чтобы робот выполнял каждый поворот только одним колесом, второе бы в этот момент бездействовало – это сделает "шажки" робота еще более маленькими и уменьшит вероятность потери линии.



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

Естественно, приведенная выше реализация небезупречна. Основной ее недостаток – итоговая скорость движения робота вдоль линии. Можно сказать, что эта реализация базовая – с нее стоит начать изучение этого сложного алгоритма. К тому же, она позволяет довольно быстро (маленькое количество действий в программе) и с минимальным количеством деталей (два мотора и один светочувствительный сенсор) показать, на что способен робот.

12 комментариев:

  1. Эти статьи собственные ваши наработки или переводы каких-нибудь англоязычных ресурсов? Просто интересно откуда такие замечательные иллюстрации?

    ОтветитьУдалить
    Ответы
    1. Это мои собственные наработки, рожденные в ходе подготовки школьников ко всяким робототехническим состязаниям. Иллюстрации делаю сам в PowerPoint. Поэтому на каждую статью уходить много времени. Если просто текст писать, то получалось бы достаточно быстро, но достаточно бестолково.

      Удалить
  2. Александр, текст хорош и написан понятно. Именно поэтому шероховатости бросаются в глаза. Хорошо бы поправить опечатки и знаки препинания. Если текст еще раз прочитать, то найдутся и стилистические ошибки.

    "По внутреннему устройству, он не такой сложный как сенсор расстояния" -- запятая не нужна.

    "В режиме измерения окружающей освещенности, количество ..." запятая не нужна

    "Например, с датчиком, работающем в этом режиме..." нажно писать "работающИм"

    Дальше есть еще. Хорошо бы Вам перечитать. Образовательные ресурсы для школьников -- дело ответственное.

    Спасибо!

    ОтветитьУдалить
    Ответы
    1. Спасибо за вычитку. Многие статьи пишутся по ночам, поэтому усталость трудового дня и рассредоточенность внимания делают свое дело.

      Удалить
  3. Главный результат! а маленькие ошибки у кого не бывает. Спасибо Вам Александр

    ОтветитьУдалить
  4. Cпасибо большое, особенно за линки с программами и за книгу на английском.
    Сергей

    ОтветитьУдалить
  5. Спасибо за замечательную стаью))

    ОтветитьУдалить
  6. Спасибо за интересный подход. Я использовал переключатель для определения яркости света. Не думал о линейной программе.

    ОтветитьУдалить

Related Posts Plugin for WordPress, Blogger...