При использовании одного датчика света достаточно часто происходит потеря линии, после чего модель становится неуправляемой. Программирование обнаружения потери линии и реакции на это представляет определённые сложности для начинающих, по причине чего его отдельно не рассматривают. Предлагается методом проб и ошибок найти значения параметров движения, при которых это не случится. Но такой подход не даёт ответ на вопрос, а что делать, если данная ситуация произошла? Попробуем на него ответить.
Существует несколько вариантов реагирования на потерю тележкой линии:
Первый вариант можно выбрать в целях упрощения программирования. Последствия потери линии несопоставимо малы по сравнению с вылетом гоночного автомобиля с трассы или сбоя движения робота на производстве, и поэтому ими можно пренебречь в ознакомительном игровом процессе. Это так, но с другой стороны в окружающей жизни постоянно происходят разные ситуации, для минимизации ущерба которых нужно совершать определённые действия. Есть ситуации, когда бездействие также может привести к положительному решению вопроса, но в целом данный подход не позволяет сформировать правильное понимание взаимосвязи между определёнными действиями и возникающими от этого последствиями. А бездумные действия могут привести к весьма плачевным последствиям. С другой стороны, если мы программируем модель с целью её автономного движения, то следует также запрограммировать о обработку ошибочных ситуаций.
При выборе второго варианта делается упор на надёжность прохождения дистанции за счёт потери в скорости. Методом проб и ошибок производится поиск значений параметров движения, при которых происходит надёжное следование вдоль линии данной конфигурации трассы.
Третий вариант неплох, но мы хотим научиться обрабатывать ошибочные ситуации, а посему выбираем последний вариант.
Потеря линии означает то, что датчик света в течении длительного времени находился над фоном и, соответственно, отсутствовал над областью линии. Если переместить тележку на фон и запустить любую из программ, рассмотренных на предыдущем занятии, то она будет либо вращаться вокруг точки касания одного из колёс, в случае использования в программе резких поворотов, либо двигаться по кругу при использовании плавных поворотов. В обоих случаях повороты будут происходить только в одну сторону, что является особенностью составления программ при использовании одного датчика света. Поворот в одну сторону приводит к тому, что при нахождении датчика с одной стороны линии тележка будет поворачивать к ней, а при нахождении с другой стороны - от неё, что как раз и вызывает уход с линии. Если радиус, описываемый датчиком света, больше расстояния до линии, то вернуться на линию тележка уже не сможет. Отсюда следует два возможных варианта действий после обнаружения потери линии - попытаться вернуться на линию для продолжения движения в нужном направлении, выполнив поворот в обратную сторону, или не возвращаться и просто остановиться. В случае выбора остановки модели можно использовать медленную реакцию на потерю линии. Если же необходимо вернуться на неё, то скорость реакции должна быть относительно высокой, чтобы модель не отъехала слишком далеко от линии или для её возврата не тратилось слишком много времени. В обоих случаях следует предусмотреть защиту от ложных срабатываний.
При наличии на трассе резких поворотов датчик света также может долгое время находиться вне линии, что может привести к этому. В реальных условиях придётся учесть ещё больше факторов - инерционность движения, отклонения в показаниях датчика света из-за недостаточно точной его фиксации или колебаний над уровнем поверхности, рывки в движении и др.
Длительное отсутствия датчика над линией означает то, что он в течении этого времени не находился над заданной областью серого цвета, которую можно условно назвать рабочей областью. Обнаружить это можно разными способами. Можно создать массив значений освещённости, в который будут заноситься значения, а через определённые интервалы времени производить поиск в нём минимального значения. Если это значение не в ходит в рабочую область, то произошла потеря. Это вариант нам не подходит по причине крайне ограниченной функциональности блоков при работе с массивами, что сделает программу слишком громоздкой..
Другой способ - определение превышения на заданную величину значения энкодера одного мотора по сравнению с энкодером другого мотора, что будет говорить о слишком долгом повороте модели. Этот вариант проще в реализации, но он не подойдёт для трассы с резкими поворотами, когда также создаётся большая разность значений энкодеров.
Третий способ - добавить ещё одного граничное условие. Для этого нужно произвести нормализацию значений исходного диапазона яркостей и задать рабочий диапазон, нахождение в котором значения датчика света будет означать следование вдоль линии. В случае превышения значения датчика света верхней границы рабочего диапазона, устанавливается флаг потери и включается таймер. Если за время работы таймера значение датчика света попало в рабочий диапазон, то флаг потери линии сбрасывается. Через заданное время таймер выключается, и производится проверка состояния флага потери линии. Если он всё ещё установлен, то линия потеряна, если сброшен, то подпрограмма завершает свою работу.
Использование таймера означает паузу в потоке выполнения команд. Если её сделать в главном потоке, который отвечает за движение тележки, то это приведёт к остановке движения. Нам же требуется движение и проверку выполнять одновременно, что требует двух потоков.
Пример подпрограммы остановки тележки через 2 секунды после потери линии показан ниже.
Для новой границы out выбрано значение яркости равным 90. Если значение датчика света превышает это значение, то включается флаг check, который будет проверен через 2 секунды. Для сброса флага check в основной поток программы добавлен блок отправки сообщения, сбрасывающий его.
После запуска программы тележка на белом фоне должна остановиться через 2 секунды. Если перед тележкой нарисовать черную лини так, чтобы тележка пересекала её в течение этих двух секунд, то при пересечении её датчиков подпрограмма обнаружения выключится и включится вновь при обнаружении датчиком белого фона. В результате тележка остановится примерно через 4 секунды.
Если после обнаружения потери линии тележку нужно вернуть обратно, то это можно сделать при помощи подпрограммы поворота в противоположную сторону, что производится путём изменения знака переменных, сравниваемых в условии. Для этого условие записывается в виде dir*sensorA1 < dir*значение границы, где dir принимает значение 1 или -1 (что на предыдущем занятии уже рассматривалось). Для исключения одновременного получения моторами противоречивых команд от двух потоков в программу добавляется ещё одна переменная, указывающая на активность выполнения подпрограммы возврата на линию. Если эта подпрограмма неактивна, то моторы получают команды из главного потока, в противном случае - из вспомогательного.
Для улучшения увеличения надёжности работы программы её необходимо дополнить калибровкой и нормализацией, что ранее мы также рассматривали.