Skip to content
Занятия 1–2. Платформа, ТБ и HAL: фундамент, который переживёт смену железа

Занятия 1–2. Платформа, ТБ и HAL: фундамент, который переживёт смену железа

Занятия 1–2. Платформа, ТБ и HAL

Цель занятия 1: обучающиеся измеряют и документируют свою платформу картой конфигурации. Цель занятия 2: обучающиеся оборачивают своё железо в 6 функций HAL и проверяют их тестовой программой.

Почему начинаем не с езды. Все формулы модуля (путь, повороты, остановки) опираются на три числа: диаметр колеса D, колея B, тиков на оборот N — и на единый программный интерфейс. Час, потраченный здесь, экономит недели: при замене мотора или датчика переписываются 6 функций, а не 30 программ. Это и есть управление когнитивной нагрузкой: новичок в занятии 5 думает про геометрию поворота, а не про то, каким пином дёргать драйвер.

Техника безопасности

ЛиПо/Li-ion аккумуляторы:

  • заряд — только в присутствии человека, на негорючей поверхности, штатным ЗУ с балансиром;
  • вздутый, пробитый, горячий аккумулятор → немедленно к тренеру, не заряжать, не втыкать;
  • не разряжать ниже 3,3 В/банку (ставим индикатор напряжения или пищалку);
  • короткое замыкание силовых проводов = пожар: силовые разъёмы только с защитой от переполюсовки (XT30/XT60), никаких «крокодилов» на батарее.

Механика и электрика:

  • пальцы, волосы, шнурки — вне зоны колёс и редукторов при поданном питании; отладка захвата — только на подставке, колёса в воздухе;
  • перепрошивка — при выключенном силовом питании моторов;
  • ESP32 — 3,3-вольтовая логика: выход 5-вольтового датчика (например, echo УЗ-дальномера) подключается через делитель напряжения, иначе порт выгорает;
  • пайка: 30 сек проветривание рабочей зоны, подставка под паяльник, не паять на весу над коленями.

Разбор (worked example): карта конфигурации

Эталонная карта (значения — примерные, каждая пара заполняет свою):

ПараметрОбозн.Как измеритьПример
Диаметр колесаDштангенциркулем по резине (не по диску!), 3 замера, среднее65,0 мм
КолеяBмежду серединами пятен контакта колёс142 мм
Прорезей энкодерного дискаNпосчитать; если ловим оба фронта — ×220
Тиков на оборот колесаN_тN × передаточное число, если диск не на оси колеса20
мм на тикmπD / N_т (проверяется калибровкой, зан. 4)10,2 мм
База датчиков линииL_дот оси колёс до датчиков линии (вперёд — «+»)68 мм
Вылет дальномераL_уот передней кромки корпуса до датчика12 мм
ПитаниеUноминал и тип батареи2S Li-ion 7,4 В
Драйвер моторовмодель, макс. токTB6612, 1,2 А

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

  • D измерен по ободу без резины → систематическая недоезд/переезд ~3–5%;
  • B измерена между внутренними краями колёс → все повороты «перекручены»;
  • энкодерный диск стоит на валу мотора до редуктора, а N_т посчитан как для колеса → путь врёт в «передаточное число» раз;
  • датчики линии прикручены «на глаз» не симметрично оси → робот «ведёт» на линии, и это не лечится программой.

HAL: 6 функций, на которых стоит весь модуль

Контракт интерфейса. Реализация под конкретный драйвер/датчик — отдельная задача (код под своё железо запрашивается и пишется точечно), алгоритмы модуля используют только эти вызовы:

// ===== HAL: единственное место, где живёт конкретное железо =====

void drive(int pwmL, int pwmR);   // -255..255; знак = направление; 0 = стоп
void stopBrake();                 // активное торможение (замыкание обмоток)
void stopCoast();                 // свободный выбег

long ticksL();  long ticksR();    // счётчики энкодеров (наращиваются в прерываниях)
void resetTicks();

int  lineRaw(int i);              // сырое значение датчика линии i (0..4095 на ESP32)
bool touch();                     // датчик касания: true = нажат
int  distMM();                    // дистанция, мм: медиана из 5 замеров УЗ или ToF

Правила слоя:

  1. Энкодеры считаются только в прерываниях (attachInterrupt), никогда опросом в цикле — иначе тики теряются на скорости.
  2. distMM() всегда возвращает медиану из 5 замеров: одиночные выбросы УЗ-датчика (эхо от угла, мягкая поверхность) — норма, а не поломка.
  3. Полярность: drive(100,100) обязан везти вперёд, тики обязаны расти при движении вперёд. Если нет — меняем провода/знаки внутри HAL, не в алгоритмах.
  4. Смена датчика (УЗ → лазерный ToF) меняет только тело distMM(). Смена драйвера — только drive/stop*.

Практика

Измерить и заполнить карту конфигурации

Каждая пара — свою. Карта вклеивается в журнал заездов и обновляется при любой доработке робота.

Реализовать HAL под своё железо

По одной функции за раз, после каждой — проверка. Порядок: drivestop* → энкодеры → датчики.

Прогнать тест-программу HAL

Эталонный смоук-тест (worked example, разобрать построчно перед запуском):

void setup() {
  Serial.begin(115200);
  halInit();

  drive(120, 120); delay(1000); stopBrake();      // 1. едет вперёд? ровно-ли — неважно
  Serial.printf("L=%ld R=%ld\n", ticksL(), ticksR()); // 2. тики выросли? примерно равны?

  drive(-120, -120); delay(1000); stopCoast();    // 3. назад; сравнить выбег с торможением

  while (!touch()) delay(10);                      // 4. нажать кнопку рукой
  Serial.println("touch OK");

  for (int i = 0; i < 20; i++) {                   // 5. поводить ладонью перед дальномером
    Serial.println(distMM()); delay(200);
  }
  for (int i = 0; i < 5; i++)                      // 6. датчики линии: рука/чёрное/белое
    Serial.printf("S%d=%d ", i, lineRaw(i));
}

Зафиксировать полярности

В карту: какой мотор левый, знаки, направление роста тиков. Это спасает после каждой пересборки.

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

  1. Робот пары проезжает вперёд и назад через drive(), тики обоих колёс растут при движении вперёд — показ тренеру.
  2. Вопрос: «завтра меняем УЗ-дальномер на лазерный — какие файлы/функции трогаем?» (правильный ответ: только distMM() в HAL).

Над-образовательная активность (Такман: формирование)

Знакомство пар, договорённость о ролях (пилот/программист, роли меняются каждые 2 занятия), общие правила: заезды по протоколу, журнал ведём всегда, батарея на зарядке = записка с временем постановки.