Appearance
ПР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 |
Что сделать
- Сначала соберите и запустите минимальную ноду по пути из лекции:
ros2 pkg create --build-type ament_python --node-name patrol patrol --dependencies rclpy geometry_msgs. Добавьте вpackage.xmlзависимость на пакет Pose выбранной дистрибуции. - После появления
/patrolдобавьте подписку на/turtle1/pose. Callback только сохраняет последнее сообщение. Сохраните подписку как поле объекта. - Добавьте таймер
0.1 си издательgeometry_msgs/msg/Twistв относительныйcmd_vel. До первой позы выдавайте нулевую команду; после —linear.x=0.5,angular.z=0.3. Динамические параметры и автопланировщик пока не нужны. - Вынесите выбор команды из последней позы в чистую функцию и проверьте как минимум случай отсутствующей позы и обычного сообщения.
- Покажите разрыв имени, исправьте через
-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 часа по желанию; улучшения интерфейса можно отложить.
Первая работающая версия
- Создайте отдельную команду запуска, например
ros2 run patrol draw_route, чтобы обычныйpatrolпо-прежнему выполнял основную работу. Оставьте один издатель/turtle1/cmd_vel: остановите teleop и прежний patrol. - Покажите холст с координатной сеткой и кнопками «Запустить», «Стоп», «Очистить». Зажатая левая кнопка мыши рисует одну ломаную. После отпускания зафиксируйте список точек; запуск разрешён только при непустом маршруте и полученной позе. Во время движения редактирование отключено.
- Сопоставьте холст с рабочей областью turtlesim:
x ∈ [1, 10],y ∈ [1, 10]. Для локальных координат мыши(u, v)в прямоугольнике ширинойWи высотойH:x = 1 + 9u/W,y = 10 - 9v/H. У мыши y направлен вниз, у turtlesim — вверх. Клики вне холста игнорируйте; поля окна и панель кнопок не входят в W/H. - Храните последнюю позу из
/turtle1/pose. По таймеру выбирайте очередную точку маршрута и двигайтесь к ней. Сначала подойдите к первой точке; этот соединительный участок не является нарисованным маршрутом. - Когда расстояние до текущей цели меньше
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 оформляется по правилам курса, в том числе без ИИ.