Skip to content

ПР03. Первая нода: поза и команда ​

Рассчитывайте на одну лабораторную пару и примерно 2 часа самостоятельной доработки.

Входные данные ​

Workspace и пакет запуска turtle_bringup из ПР02, граф и разобранный на лекции каркас hello_ros. Сохраните прежний пакет; рядом создайте свой пакет patrol с исполняемой командой patrol; используйте ament_python, rclpy, geometry_msgs и пакет типа Pose вашей дистрибуции. Тип узнайте через ros2 topic type /turtle1/pose: turtlesim/msg/Pose (Jazzy) или turtlesim_msgs/msg/Pose (Lyrical).

Нужен course kit текущей недели с манифестом PR03.

Цель ​

Написать ноду с подпиской и таймером и проверить её обычными инструментами графа.

Критерии зачтено ​

СтадияЧто требуется
1 · СобратьПодписка хранит последнюю позу; таймер с периодом 0,1 с публикует Twist
2 · СломатьПубликация идёт в относительный cmd_vel, не соединённый с /turtle1/cmd_vel
3 · ДоказатьRemap исправляет связь; поза поступает, поток команды измерен
Автопроверкаcheck_practice.py PR03 проверяет файлы манифеста и заявления public_tests_passed, defect_reproduced, defect_fixed

Что сделать ​

  1. Сначала соберите и запустите минимальную ноду по пути из лекции: ros2 pkg create --build-type ament_python --node-name patrol patrol --dependencies rclpy geometry_msgs. Добавьте в package.xml зависимость на пакет Pose выбранной дистрибуции.
  2. После появления /patrol добавьте подписку на /turtle1/pose. Callback только сохраняет последнее сообщение. Сохраните подписку как поле объекта.
  3. Добавьте таймер 0.1 с и издатель geometry_msgs/msg/Twist в относительный cmd_vel. До первой позы выдавайте нулевую команду; после — linear.x=0.5, angular.z=0.3. Динамические параметры и автопланировщик пока не нужны.
  4. Вынесите выбор команды из последней позы в чистую функцию и проверьте как минимум случай отсутствующей позы и обычного сообщения.
  5. Покажите разрыв имени, исправьте через -r cmd_vel:=/turtle1/cmd_vel и измерьте реальную частоту команды за 10 секунд. В demo.md объясните роли init, spin, callback и Ctrl+C. После остановки ноды дождитесь остановки turtlesim; не считайте исчезновение процесса мгновенной командой торможения.

Проверка ​

Обязательные файлы сдачи ​

  • В корне репозитория — AI_USAGE.md, с отдельной записью для PR03: модель, инструмент, характер помощи и способ проверки. Если ИИ не использовался, напишите это явно и поставьте ai_used: false в отчёте; файл всё равно нужен. Предыдущие записи сохраняйте. Правила и пример.
  • В evidence/pr03/report.json поле commit — SHA уже созданного коммита реализации. Отчёт фиксируется следующим коммитом; его SHA указывается при сдаче вместе со ссылкой на CI. Пошаговый пример двух коммитов.
bash
colcon build --symlink-install --packages-select patrol
source install/setup.bash
python3 -m pytest src/patrol/test
# Запуск — в отдельном терминале:
# ros2 run patrol patrol --ros-args -r cmd_vel:=/turtle1/cmd_vel
python3 .course-kit/v1/tools/check_practice.py PR03 --submission .

Сохраните src/patrol/package.xml, evidence/pr03/demo.md, evidence/pr03/tests.txt и evidence/pr03/report.json. Checker проверяет состав отчёта, а поведение подтверждается вашими тестами и повторением опыта.

Как работаем на лабораторной ​

Сначала повторите минимальный исправный запуск из лекции. Покажите один наблюдаемый результат, затем внесите указанный дефект и проверьте ту же гипотезу до и после исправления. Если исправный запуск ещё не работает, завершите его вместо добавления дополнительных возможностей.

Дополнительно: добавьте ограничение команды в чистой функции. Изменение параметров во время работы появится в ПР04.

Необязательное расширение: маршрут мышью ​

Нарисуйте маршрут мышью в отдельном окне рядом с turtlesim. По кнопке «Запустить» черепашка должна пройти его, используя свою текущую позу и команды Twist. Телепортация не используется.

Расширение можно начать после обязательной части ПР03. Оно не влияет на зачёт, не добавляет обязательных файлов или claims и не требуется для ПР04. Ориентир для первой версии — ещё 2–4 часа по желанию; улучшения интерфейса можно отложить.

Первая работающая версия ​

  1. Создайте отдельную команду запуска, например ros2 run patrol draw_route, чтобы обычный patrol по-прежнему выполнял основную работу. Оставьте один издатель /turtle1/cmd_vel: остановите teleop и прежний patrol.
  2. Покажите холст с координатной сеткой и кнопками «Запустить», «Стоп», «Очистить». Зажатая левая кнопка мыши рисует одну ломаную. После отпускания зафиксируйте список точек; запуск разрешён только при непустом маршруте и полученной позе. Во время движения редактирование отключено.
  3. Сопоставьте холст с рабочей областью turtlesim: x ∈ [1, 10], y ∈ [1, 10]. Для локальных координат мыши (u, v) в прямоугольнике шириной W и высотой H: x = 1 + 9u/W, y = 10 - 9v/H. У мыши y направлен вниз, у turtlesim — вверх. Клики вне холста игнорируйте; поля окна и панель кнопок не входят в W/H.
  4. Храните последнюю позу из /turtle1/pose. По таймеру выбирайте очередную точку маршрута и двигайтесь к ней. Сначала подойдите к первой точке; этот соединительный участок не является нарисованным маршрутом.
  5. Когда расстояние до текущей цели меньше 0.1 единицы turtlesim, переходите к следующей. После последней точки, по «Стоп», при очистке или потере позы выдавайте нулевой Twist и прекращайте исполнение. При потере позы не продолжайте автоматически: потребуется новый «Запустить». Для первой версии используйте таймаут получения позы 0.5 с, измеренный монотонными часами приложения.

Не нужно воспроизводить каждый пиксель: уберите соседние дубликаты и оставьте точки примерно через 0.1–0.2 единицы длины. При редких событиях мыши добавьте промежуточные точки на длинных сегментах; конечную точку сохраните всегда. Маршрут можно проходить медленнее, чем он был нарисован.

Подсказка для управления ​

Для текущей позы (x, y, theta) и цели (gx, gy) вычислите:

  • расстояние d = hypot(gx - x, gy - y);
  • желаемое направление target = atan2(gy - y, gx - x);
  • ошибку угла e = atan2(sin(target - theta), cos(target - theta)).

Начните с простого поведения: при большой ошибке угла поворачивайтесь на месте, затем двигайтесь вперёд с небольшой скоростью, продолжая корректировать угол. Ограничьте linear.x диапазоном [0, 0.5], а angular.z — [-1, 1]. Остальные поля Twist оставьте нулевыми. Для turtlesim это допустимо; будущий Ackermann-робот не сможет разворачиваться на месте.

Окно должно отвечать на мышь и «Стоп» во время движения. Например, в Tkinter можно вызывать короткий rclpy.spin_once(node, timeout_sec=0) через after, сохраняя GUI в основном потоке. Не запускайте бесконечный rclpy.spin внутри обработчика кнопки и не проходите весь маршрут в одном callback таймера. При штатном закрытии окна отправьте нулевую команду до уничтожения ноды.

Как проверить результат ​

  • Нарисуйте горизонтальный отрезок, «Г» и плавную дугу: точки проходятся по порядку; допустимая ошибка достижения каждой цели — 0.1 единицы.
  • Проверьте чистыми тестами преобразование углов холста, знак оси y, переход угла через −π/π, пустой маршрут и завершение последней точки.
  • Нажмите «Стоп» на середине пути: в /turtle1/cmd_vel появляется нулевая команда, новые ненулевые команды не выдаются до следующего запуска.
  • Остановите turtlesim: окно остаётся отзывчивым, после таймаута маршрут останавливается. После возврата позы он сам не возобновляется.
  • В копии преобразования намеренно уберите переворот y. Покажите зеркальный маршрут, затем исправление и тот же тест координат.

По желанию сохраните маршрут в JSON, короткое видео двух окон и описание ошибки в evidence/pr03/mouse-route.md. Повтор из JSON позволит проверить контроллер без нового рисования. В ПР04 можно добавить параметры управления.

Общий порядок: runbook · troubleshooting. Декларация AI_USAGE.md оформляется по правилам курса, в том числе без ИИ.

Учебные материалы: CC BY 4.0 · Код: Apache-2.0