7.8 Туда и обратно, используя одометрию
Last updated
Was this helpful?
Last updated
Was this helpful?
Теперь, когда мы понимаем, как информация об одометрии представлена в ROS, мы можем быть более точными в отношении перемещения нашего робота в прямом и обратном направлении. Вместо того, чтобы угадывать расстояния и углы на основе времени и скорости, наш следующий скрипт будет отслеживать положение и ориентацию робота, как сообщается в результате преобразования между кадрами / odom и / base_link.
Новый файл называется odom_out_and_back.py в каталоге rbx1_nav / node. Прежде чем смотреть на код, давайте сравним результаты между симулятором и реальным роботом.
Если у вас уже запущен симулированный робот, сначала нажмите Ctrl-C, чтобы мы могли начать измерения одометрии с нуля. Затем снова вызовите смоделированного робота, запустите RViz, затем запустите сценарий odom_out_and_back.py следующим образом:
Типичный результат показан ниже:
Как видите, использование одометрии в идеальном симуляторе без физики дает в основном идеальные результаты. Это не должно быть ужасно удивительно. Так что же случится, когда мы попробуем это на реальном роботе?
Если у вас есть TurtleBot или другой ROS-совместимый робот, вы можете попробовать реальный сценарий на основе одометрии в реальном мире.
Сначала убедитесь, что вы прекратили все запущенные симуляции. Затем откройте файл запуска запуска вашего робота. Для TurtleBot вы должны запустить:
(Или используйте свой собственный файл запуска, если вы создали его для хранения параметров калибровки.)
Убедитесь, что у вашего робота достаточно места для работы - по крайней мере, на 1,5 метра впереди и на метр с каждой стороны.
Если вы используете TurtleBot, мы также запустим сценарий odom_ekf.py (входит в пакет rbx1_bringup), чтобы мы могли видеть комбинированный кадр одометрии TurtleBot в RViz. Вы можете пропустить это, если вы не используете TurtleBot. Этот файл запуска должен быть запущен на ноутбуке TurtleBot:
Если у вас уже запущен RViz из предыдущего теста, вы можете просто отменить проверку дисплея Odometry и проверить дисплей EKF Odometry, а затем пропустить следующий шаг.
Если RViz еще не запущен, запустите его сейчас на рабочей станции с помощью файла конфигурации nav_ekf. Этот файл просто предварительно выбирает тему / odom_ekf для отображения комбинированных данных одометрии:
Наконец, запустите сценарий одометрии, как мы это делали в симуляции. Вы можете запустить следующую команду на своей рабочей станции или на ноутбуке робота после входа в систему с помощью ssh:
Вот результат для моего собственного TurtleBot при работе на ковре с низким слоем:
Как вы можете видеть на картинке, результат намного лучше, чем тайм-аут. Фактически, в реальном мире результат был даже лучше, чем показанный в RViz. (Помните, что стрелки одометрии в RViz не будут точно совпадать с фактическим положением и ориентацией робота в реальном мире.) В этом конкретном пробеге робот оказался на расстоянии менее 1 см от исходного положения и всего несколько градусов от правильной ориентации. Конечно, чтобы получить результаты, даже такие хорошие, вам нужно потратить некоторое время на тщательную калибровку одометрии вашего робота, как описано ранее.
Вот теперь полный сценарий, основанный на одометрии. Встроенные комментарии должны сделать сценарий достаточно понятным, но мы опишем ключевые строки более подробно после перечисления.
Ссылка на источник: odom_out_and_back.py
Давайте теперь посмотрим на ключевые строки в скрипте.
Нам понадобятся типы данных Twist, Point и Quaternion из пакета geometry_msgs. Нам также понадобится библиотека tf для мониторинга преобразования между фреймами / odom и / base_link (или / base_footprint). Библиотека transform_utils представляет собой небольшой модуль, который можно найти в каталоге rbx1_nav / src / rbx1_nav, и содержит несколько удобных функций, заимствованных из пакета TurtleBot. Функция quat_to_angle преобразует кватернион в угол Эйлера (yaw), а функция normalize_angle устраняет неоднозначность между 180 и -180 градусами, а также 0 и 360 градусов.
Здесь мы определяем angular_tolerance для вращений. Причина в том, что с реальным роботом очень легко обойти вращение, и даже небольшая угловая ошибка может отвести робота подальше от следующего места. Опытным путем было обнаружено, что допуск около 2,5 градусов дает приемлемые результаты.
Затем мы создаем объект TransformListener для мониторинга преобразования кадров. Обратите внимание, что tf требуется немного времени, чтобы заполнить буфер слушателя, поэтому мы добавляем вызов rospy.sleep (2). Чтобы получить положение и ориентацию робота, нам нужно преобразование между фреймом / odom и фреймом / base_footprint, используемым TurtleBot, или фреймом / base_link, используемым Pi Robot и Maxwell. Сначала мы проверяем фрейм / base_footprint, и если мы его не найдем, мы тестируем кадр / base_link. Результат сохраняется в переменной self.base_frame для последующего использования в скрипте.
Как и в случае с таймером «назад и обратно», мы проходим через два этапа поездки: сначала перемещаем робота на 1 метр вперед, затем поворачиваем его на 180 градусов.
В начале каждого этапа мы записываем начальную позицию и ориентацию с помощью функции get_odom (). Давайте посмотрим на это дальше, чтобы мы поняли, как это работает.
Функция get_odom () сначала использует объект tf_listener для поиска текущего преобразования между одометрией и базовыми кадрами. Если есть проблема с поиском, мы выдаем исключение. В противном случае мы возвращаем точечное представление трансляции и представление квотернизации. Переменные * infrontofthetransandrot - это нотация Python для передачи списка чисел в функцию, и мы используем его здесь, поскольку trans - это список координат x, y и z, а rot - список компонентов кватернионов x, y, z и w.
Теперь вернемся к основной части скрипта:
Это просто наша петля, чтобы двигать робота вперед, пока мы не пройдем 1,0 метра.
И это наш цикл для поворота на 180 градусов в пределах углового допуска, который мы установили в начале сценария
Читателю может быть интересно, почему мы использовали TransformListener в предыдущем скрипте для доступа к информации об одометрии, а не просто для подписки на тему / odom. Причина в том, что данные, опубликованные по теме / odom, не всегда являются полной историей. Например, TurtleBot использует одноосный гироскоп для дополнительной оценки вращения робота. Это объединено с данными от колесных кодеров узлом robot_pose_ekf (который запускается в файле запуска TurtleBot), чтобы получить лучшую оценку вращения, чем один из источников в отдельности.
Однако узел robot_pose_ekf не публикует свои данные обратно в теме / odom, которая зарезервирована для данных колесного энкодера. Вместо этого он публикует его в теме / odom_combined. Кроме того, данные публикуются не как сообщение одометрии, а как сообщение PoseWithCovarianceStamped. Тем не менее, он публикует преобразование из фрейма / odom в фрейм / base_link (или / base_footprint), который предоставляет необходимую нам информацию. В результате, как правило, безопаснее использовать tf для мониторинга преобразования между фреймами / odom и / base_link (или / base_footprint), чем полагаться на тему сообщения / odom.
В каталоге rbx1_bringup / hosts вы найдете узел с именем odom_ekf.py, который повторно публикует сообщение PoseWithCovarianceStamped, найденное в теме / odom_combined, как сообщение типа Odometry в теме под названием / odom_ekf. Это сделано только для того, чтобы мы могли просматривать темы / odom и / odom_ekf в RViz, чтобы сравнить одометрию на основе колеса TurtleBot с комбинированной одометрией, включающей гироскопические данные.