Движение по линии с обходом препятствия: нужен совет!

Как собрать и запрограммировать робота на Arduino(Freeduino, Roboduino, Seeduino ...). Используем Wiring и Processing.

Движение по линии с обходом препятствия: нужен совет!

Сообщение lotsman » 27 мар 2019, 20:31

Веду кружок (в том числе) робототехники на ардуино. Постепенно развиваемся, в этом учебном году вплотную занялись отработкой задач с движущимися машинками. В основном всё получается, но иногда встречаются грабли.
Вот задача довольно стандартная для разных соревнований (которые большей частью на лего): робот движется по чёрной линии, на пути препятствие (или другой робот), и его нужно обойти (или хотя бы остановиться и подождать). Используем аналоговые датчики линии (2 штуки) и ультразвуковой дальномер.
Проблема: без использования дальномера движение по линии идёт нормально. Но как только включаю функцию измерения расстояния - машинка начинает сильно сбиваться. Как я понимаю, проблема в том, что отслеживание линии критично к времени: чуть отвлёкся (на дальномер) - и сорвался. А УЗ дальномер измеряет не мгновенно. Может кто-то посоветовать алгоритм, свободный от этой проблемы? Хотя бы идеи. Наверняка эта задача имеет какое-то красивое решение.
Основа скетча у меня примерно такая:
Код: Выделить всё
 
//сначала - цикл нормального движения по линии. в условии проверяется, что хотя бы один из датчиков не на белом и нет препятствия ближе 30 см.
while (((analogRead(A0) > WHITEL) || (analogRead(A1) > WHITER))&&(distance()>30)) {
    float x = analogRead(A0) - analogRead(A1);
    u = K1 * x + K2 * x * x * x;
    //движение с поправкой
    forward(70 - u, 70 + u);//эта функция включает движение с заданными скоростями для каждого колеса.
  }
// дальше цикл обработки случайного ухода с линии. Оба датчика на белом, препятствия не видно.
  while (((analogRead(A0) < WHITEL) && (analogRead(A1) < WHITER))&&(distance()>30)) {
    if (u > 0) {
      forward(-50, 50);
    }
    if (u < 0) {
      forward(50, -50);
    }
  }
if(distance()<=30){
//тут какая-то обработка обнаружения препятствия: объезд или остановка
  }

Если убрать проверку расстояния из циклов while - ездит по линии нормально.
lotsman
 
Сообщения: 4
Зарегистрирован: 27 мар 2019, 19:57

Re: Движение по линии с обходом препятствия: нужен совет!

Сообщение dimamichev » 28 мар 2019, 18:53

lotsman писал(а):Если убрать проверку расстояния из циклов while - ездит по линии нормально.

Может сначала уменьшить скорость движения по трассе и убедиться окончательно в своих догадках?
Аватара пользователя
dimamichev
 
Сообщения: 1386
Зарегистрирован: 03 янв 2013, 16:27

Re: Движение по линии с обходом препятствия: нужен совет!

Сообщение lotsman » 28 мар 2019, 20:29

dimamichev писал(а):Может сначала уменьшить скорость движения по трассе и убедиться окончательно в своих догадках?

Не совсем понял вашу мысль. "Догадка" о том, что обращение к дальномеру приводит к постоянным сходам с линии основана на том, что сходы прекращаются, если это обращение из программы убрать. Изменять скорость в некоторых пределах пробовали, это не помогает. Без дальномера на всех рассматриваемых скоростях (50, 70, 100) движение по линии происходит достаточно надёжно. Наверное, можно пытаться уменьшить скорость до предела и получить какой-то результат, но это не решение, так как скорость в таких заданиях тоже важна, если рассчитывать на какие-то соревнования. На данный момент она у нас и так едет медленнее чем хотелось бы.
lotsman
 
Сообщения: 4
Зарегистрирован: 27 мар 2019, 19:57

Re: Движение по линии с обходом препятствия: нужен совет!

Сообщение dimamichev » 28 мар 2019, 21:19

Тогда можно ограничить в функции pulseIn(pin, value, timeout) значение 3 аргумента до времени возврата на дистанцию не более 40 см и убирать
delay (); из скетча. Или прерывания попробовать использовать. Или спросить на профильном форуме.
Аватара пользователя
dimamichev
 
Сообщения: 1386
Зарегистрирован: 03 янв 2013, 16:27

Re: Движение по линии с обходом препятствия: нужен совет!

Сообщение esisl » 28 мар 2019, 23:30

Нужно по прерываниям.
esisl
 
Сообщения: 1480
Зарегистрирован: 23 июл 2012, 15:24

Re: Движение по линии с обходом препятствия: нужен совет!

Сообщение lotsman » 29 мар 2019, 12:48

dimamichev писал(а):Тогда можно ограничить в функции pulseIn(pin, value, timeout) значение 3 аргумента до времени возврата на дистанцию не более 40 см и убирать
delay (); из скетча. Или прерывания попробовать использовать.


Да, точно, с таймаутом надо поэкспериментировать... Только нули нужно будет отсекать.
Про прерывания думал. Но не придумал как их использовать, ведь прерывание обрабатывает ограниченный набор событий, связанных с изменением сигнала на цифровом порте. А дальномер этого не даёт. Есть идея как можно сделать?
dimamichev писал(а):Или спросить на профильном форуме.

А какой форум более профильный? Я тут пока плохо ориентируюсь, показалось, что этот самый подходящий, так как про ардуино. :)

Добавлено спустя 1 минуту 7 секунд:
esisl писал(а):Нужно по прерываниям.

Есть идея как это сделать? Может, я туплю, но я не придумал как сделать, ведь прерывание обрабатывает ограниченный набор событий, связанных с изменением сигнала на цифровом порте. А дальномер такого типа сигналов не даёт. Найти бы что-то типа цифрового дальномера, который просто сам выдаёт HIGH при расстоянии меньше заданного. Но я не встречал таких. С другой стороны, все пользуются обычными HC-SR04 и вроде, не жалуются. Должно же быть решение...

Добавлено спустя 1 час 33 минуты 21 секунду:
dimamichev писал(а):Тогда можно ограничить в функции pulseIn(pin, value, timeout) значение 3 аргумента до времени возврата на дистанцию не более 40 см и убирать
delay (); из скетча. Или прерывания попробовать использовать. Или спросить на профильном форуме.

Попробовал уменьшить таймаут до примерного соответствия 40 см (при большем расстоянии функция даёт ноль, он заменяется на 100). Действительно, стало гораздо лучше! Теперь линию не теряет, хотя всё же виляет немного больше, чем без обращения к дальномеру. Спасибо за совет, что-то я сам не догадался. :)
Но всё же если как-то придумать с прерыванием - было бы, наверное, ещё лучше.
Кстати, в прошлый раз забыл ответить про delay. Какой delay вы имели в виду? У меня в скетче вроде бы и нет delay.
lotsman
 
Сообщения: 4
Зарегистрирован: 27 мар 2019, 19:57

Re: Движение по линии с обходом препятствия: нужен совет!

Сообщение dimamichev » 29 мар 2019, 13:38

Вот тут можно спросить.
http://arduino.ru/forum
Про delay(); - это извечная тема, скетч желательно полностью приводить, а не часть. Вряд ли это "зло" совсем удастся победить :)
А развить успех можно ища компромисс между скоростью прохождения и "дальностью взгляда робота".
Аватара пользователя
dimamichev
 
Сообщения: 1386
Зарегистрирован: 03 янв 2013, 16:27

Re: Движение по линии с обходом препятствия: нужен совет!

Сообщение dimamichev » 30 мар 2019, 19:41

А ещё, нужно уменьшить в скетче число опросов дистанции до потенциальной преграды по сравнению с числом опросов датчиков линии...
Мысль вдогонку.
Аватара пользователя
dimamichev
 
Сообщения: 1386
Зарегистрирован: 03 янв 2013, 16:27

Re: Движение по линии с обходом препятствия: нужен совет!

Сообщение lotsman » 30 мар 2019, 20:53

dimamichev писал(а):А ещё, нужно уменьшить в скетче число опросов дистанции до потенциальной преграды по сравнению с числом опросов датчиков линии...
Мысль вдогонку.

А как? Может, в цикл while вставить не одно, а 2-3 вычисления поправки с последующим движением? Или лучше сделать опрос дальномера стабильно раз в 100-200 миллисекунд и записывать в переменную. Видимо, для этого нужно использовать прерывание по таймеру. Я с ним ещё не разбирался, плохо представляю как это работает, наверняка сделаю неправильно. :) Но надо будет попробовать.
lotsman
 
Сообщения: 4
Зарегистрирован: 27 мар 2019, 19:57

Re: Движение по линии с обходом препятствия: нужен совет!

Сообщение dimamichev » 30 мар 2019, 22:54

Мне кажется прерывания не обязательно использовать совсем. Просто, используя "миллис" можно опрашивать дальномер раз в ... миллисекунд.
Аватара пользователя
dimamichev
 
Сообщения: 1386
Зарегистрирован: 03 янв 2013, 16:27

Re: Движение по линии с обходом препятствия: нужен совет!

Сообщение HarryStar » 05 апр 2020, 18:00

УЗ датчики очень тормозные. А учитывая что их иногда плющит и они не слышат отражение и соотв ждут максимальный таймаут, то использование их тут нежелательно. Вы можете добавить еще одну ардуину, которая будет только тем и заниматься, что опрашивать УЗ. А первая будет с ней связываться например по I2C и получать последние данные почти мгновенно.
Аватара пользователя
HarryStar
 
Сообщения: 995
Зарегистрирован: 15 ноя 2010, 13:56
Откуда: Нижний Новгород
прог. языки: С, С++, РНР


Вернуться в Arduino и другие Xduino

Кто сейчас на конференции

Сейчас этот форум просматривают: нет зарегистрированных пользователей и гости: 7