Skip to content
Занятие 11. Перекрёстки: обнаружение, проезд, повороты, разворот (задачи 3.1–3.5)

Занятие 11. Перекрёстки: обнаружение, проезд, повороты, разворот (задачи 3.1–3.5)

Занятие 11. Перекрёстки (мини-задачи 3.1–3.5)

Цель занятия: обучающиеся обнаруживают перекрёсток, проезжают его прямо, поворачивают направо/налево на 90° и разворачиваются — каждый манёвр завершается устойчивым продолжением езды по линии.

Разминка-вспоминание (5 мин)

  1. Формула PD-поправки. Что даёт D?
  2. Порядок настройки коэффициентов (3 шага)?
  3. Зачем нормализация датчиков?
  4. Из карты конфигурации: чему равна L_д — база датчиков (датчики → ось колёс)?

Теория: перекрёсток — это событие, манёвр — это последовательность

Обнаружение. На линии шириной ~18–20 мм чёрное видят центральные датчики. Перекрёсток = чёрное одновременно на крайних датчиках (левом И правом): v_left > 700 && v_right > 700. Подтверждаем событием на протяжении ≥5 мм пути (по энкодерам) — защита от клякс и стыков изоленты. Один датчик чёрный — это не перекрёсток, а возможное ответвление/острый угол: фиксируем, но не реагируем как на крест.

Довод (ключ ко всем манёврам). В момент детекта на перекрёстке стоят датчики, а не робот: ось колёс — позади на L_д. Прежде чем поворачивать, проезжаем driveMM(L_д) — центр вращения встаёт на середину перекрёстка. Без довода поворот «съезжает» с креста, и робот теряет линию.

Поворот «до захвата линии» — а не на слепые 90°. Танковый поворот на энкодерные 90° накапливает ошибку k и стартовой ориентации. Надёжнее гибрид: энкодерами крутим первые ~60° (чтобы гарантированно сойти со своей линии), дальше крутимся, пока центральный датчик не поймает чёрное новой ветки — линия сама останавливает поворот с точностью до ширины датчика. Разворот (3.5) = то же на ~150° + захват.

Разбор (worked example)

bool crossHere() {                       // событие «перекрёсток», с подтверждением по пути
  if (norm(0) > 700 && norm(K-1) > 700) {
    long t0 = (ticksL()+ticksR())/2;
    while ((ticksL()+ticksR())/2 - t0 < TICKS_5MM)
      { lineStep(); if (norm(0)<600 || norm(K-1)<600) return false; }
    return true;
  }
  return false;
}

void followToCross() { while (!crossHere()) lineStep(); stopBrake(); }  // 3.1

void crossForward()  { driveMM(L_D + 30); }        // 3.2: довод + перескок креста,
                                                    // дальше снова lineStep()
void crossTurn(int dir) {                           // 3.3 / 3.4: dir=+1 напр., -1 нал.
  driveMM(L_D);                                     // центр вращения на крест
  tankTurn(dir * 60);                               // слепая фаза: сойти со старой линии
  resetTicks();
  while (normCenter() < 700) {                      // фаза захвата: до чёрного в центре
    drive(dir*90, -dir*90);
    if ((ticksL()+ticksR())/2 > TICKS_120DEG) break;  // предохранитель от вечного вращения
  }
  stopBrake();                                      // дальше — lineStep()
}

void crossUturn() {                                  // 3.5: разворот
  driveMM(L_D);
  tankTurn(150);
  while (normCenter() < 700) drive(90, -90);
  stopBrake();
}

Разобрать вслух предохранитель TICKS_120DEG: на турнире датчик может проскочить узкую линию на скорости — без ограничителя робот крутится вечно и сжигает попытку. Любой «поворот до события» обязан иметь выход по таймауту/пути.

Практика

3.1: линия до перекрёстка

PD-езда, стоп на кресте. Судья ставит старт на разных ветках — детект обязан работать с любого захода.

3.2: проезд перекрёстка

Проехать крест, продолжить по линии, остановиться на следующем. Следить: PD-контур не должен «дёрнуться» на кресте (на время перескока регулятор выключен — едем прямо энкодерами).

3.3–3.5: лотерея манёвров

Карточки {прямо | направо | налево | разворот} × 4 подряд на поле-решётке. Зачёт: все 4 манёвра, после каждого — устойчивая езда по линии не менее 20 см.

Подбор слепого угла

Если после 60° датчик всё ещё на старой линии (широкая линия, малая L_д) — увеличить до 70–75°. Значение — в карту калибровки.

Типичные ошибки:

  • поворот без довода driveMM(L_д) — самый массовый провал занятия: робот крутится не на кресте и ловит свою же линию под 90°;
  • детект по времени («крайние чёрные дольше 50 мс») вместо пути — на разной скорости порог врёт; путь по энкодерам инвариантен;
  • после манёвра сразу полный BASE — ошибка захвата ещё велика, первые 10 см после поворота ехать на пониженной скорости;
  • стык изоленты/клякса считается перекрёстком — лечится подтверждением по пути (уже в worked example, проверить, что не выкинули «для простоты»).

Мини-проверка выхода

Лотерея из 4 манёвров сдана. Вопрос: «почему поворот “до захвата линии” точнее слепых 90° и зачем в нём предохранитель?»