Более быстрый робот в первом задании MTS True Tech Champ

Tagged as hackathon, mtstruetech, commonlisp, robotics

Written on 2025-11-20

Как я писал в предыдущей заметке, первая моя попытка провести робота через две комнаты из первого задания хакатона МТС True Tech была неудачной. Робот ехал медленно и сбивался с пути. Но в какой-то момент один из участников подсказал мне в чате, что нужно действовать иначе.

Первая моя ошибка была в том, как я пытался вывести робота из тупика, откуда он начинает свой путь. Я сначала делал разворот на 180 градусов. И это было медленно. Чертовски медленно. На разворот уходила почти минута. А надо было просто выезжать задом!

Причем задом можно было проехать весь путь от начальной точки до конечной. Разницы никакой не было. Робот ехал что вперед, что назад одинаково быстро. Так я начал выезжать из тупика задним ходом.

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

Когда условие выполнялось, робот переходил к следующему шагу. Мог изменить скорость, угол разворота и проверял новые условия, которые должны наступить, чтобы перейти к дальнейшему шагу. Для того, чтобы это было удобно описывать в коде, я написал маленький макрос, который позволял указать параметры движения и условия выхода. Причем в условии выхода можно было написать любой лисп-код, в том числе логирование или какие-то сложные вычисления.

В дальнейшем я даже усовершенствовал этот макрос и сделал так, что и скорость с углом поворота тоже можно вычислять на каждом шаге. Вот пример такого кода, которому следовал робот. Каждый блок go-until соответствует шагу, который выполняется до тех пор, пока тело макроса не вернет true. Под капотом у каждого из таких блоков лежит цикл:

;; Выезжаем из тупика
(go-until (2.0)
  (log-step 1)
  ;; Меряем расстояние по центрально точке лидара
  (> front 4.5))

;; Начинаем поворачивать вправо
(go-until (2.0 :turn-angle 45.0)
  (log-step 2)
  ;; Используем крайние точки лидара
  (and (around left 2.80)
       (around right 4.35)))

;; Движемся по прямой до стены
(go-until (2.0)
  (log-step 3)
  (around front 8.0))

;; Поворачиваем налево, к мосту
(go-until (2.0 :turn-angle -30.0)
  (log-step 4)
  (and (around left 2.71 :delta 0.2)
       (around front 3.49 :delta 0.2)
       (around right 6.26 :delta 0.2)))

То есть робот в цикле, роботу отправляется команда ехать с указанной скоростью и углом разворота. И в цикле же проверяется условие выхода из цикла. Вот и всё! На такой простой идее получилось достичь достаточно стабильных результатов и проехать уровень не сбавляя скорости.

Как я это отлаживал? Запускал в симуляторе робота и смотрел по крайним точкам лидара на расстояния. В момент, когда мне нужно было, например, перейти из прямолинейного движения робота в поворот, я смотрел примерное положение, которое показывает лидар и вносил эти значения в условия выхода из последнего блока робота. Следом за ним добавлял следующий блок с измененными характеристиками движения. И смотрел дальше, какие параметры мне нужно отследить, чтобы посчитать условия выхода для этого нового блока.

Так получилось проложить всю траекторию от начала до конца. На видео, которое приложено выше, как раз и показано, как робот проходит весь путь из комнаты 1 в комнату 2, обходя все препятствия.

В следующем посте расскажу, как обстояли дела со вторым заданием хакатона MTS True Tech Champ 2025.


Created with passion by 40Ants