Подписчик (Subscriber)
Last updated
Was this helpful?
Last updated
Was this helpful?
Подписчик - это инструмент, который принимает сигналы, передающиеся внутри системы управления.
Вне зависимости от того, какие это сигналы: данные лидара, одометрия, видео с камеры, положения сервоприводов или любые другие, их всегда передает, т.е. публикует Издатель, а принимает, т.е. подписывается на них Подписчик.
Например, лидар детектирует препятствия вокруг робота и при помощи Издателя передает данные об этом в ROS в топик /scan. Очевидно, что нам надо как-то получить эти данные для использования в наших программах. Так вот, инструмент, которым мы считываем эти данные из сообщений, это и есть Подписчик.
Назовем нашу программу: subscriber.py и сохраним ее в папку ros-cource в корневой папке.
Итак начнем: Как мы помним у нас есть Издатель, который публикует строку “Hello ROS” в топик с именем “welcome_topic”.
Для того, чтобы использовать сущность Подписчика ROS в Python, нам надо подключить библиотеку rospy.
Теперь давайте определим тип и структуру данных, которые мы будем принимать при помощи нашего Подписчика. Тут все просто: имя топика и тип данных определяется Издателем, который публикует сообщения для нас.
Вспоминая нашего уже написанного Издателя, мы определим тип данных как строка, так как передаётся сообщение “Hello ROS” с типом данных String. Топик будет “welcome_topic”, потому что так мы написали в нашей прошлой программе.
Теперь создадим и зарегистрируем в ROS нашу ноду стандартным методом init_node():
Теперь, нам необходимо указать название топика из которого Подписчик будет получать данные и название структуры этих данных:
Третьим аргументом при инициализации Подписчика является имя функции обратного вызова. Разберём поподробнее, что такое функция обратного вызова для Подписчика.
В общем случае это функция, которая вызывается каждый раз, когда в топике на который подписан Подписчик появляются сообщения, то есть, каждый раз когда Издатель публикует сообщение, ROS оповещает об этом Подписчика и передает ему сообщение от Издателя с заполненной структурой данных. Объект Подписчик же в свою очередь принимает это сообщение, вызывает функцию обратного вызова внутри нашей программы, и передает в нее полученную структуру данных в качестве аргумента.
Давайте напишем функцию обратного вызова, которая будет выводить на экран всю переданную в нее в качестве аргумента структуру данных:
Функция принимает объект структуры данных в качестве аргумента и просто печатает его при помощи функции print()
.
Теперь давайте напишем основной цикл нашей программы.
Используем стандартный ROS цикл:
А в самом цикле используем метод библиотеки rospy - spin
. Сам метод ничего не делает, кроме того, что не даёт нашему Подписчику закрыться пока мы не выйдем из цикла:
Вот и все! Мы с вами написали программу Подписчика! Давайте сохраним её, запустим и посмотрим как она работает.
Запустим roscore
и оставим его запущенным в терминале.
Откроем новый терминал напишем python3 и полный путь до файла с нашей программой:
Запустилось. Но ничего не происходит… Правильно, ведь публикация-то сообщений не идет. И наша программа начнет выводить данные на экран, только тогда когда мы запустим программу Издателя (publisher.py).
Давайте откроем еще один терминал и запустим нашего Издателя:
Наш Подписчик начал принимать сообщения от нашего Издателя! Всё работает так как надо!
В этом примере мы ничего не делаем с теми данными, которые нам поступают от Издателя, если не считать, того, что мы выводим их на экран. На следующем уроке разберем программу, которая принимает данные с робота
Чтобы продолжить то, что мы делали ранее (), сигнал, который мы будем считывать сейчас это будет сообщение “Hello ROS” от, уже написанного нами Издателя.
Теперь давайте создадим объект Подписчик. В отличие от урока про при создании объекта Издатель, мы пользовались его методом publish
для публикации наших сообщений. У Подписчика мы не будем пользоваться его методами и поэтому, мы можем не передавать ссылку на экземпляр Подписчика ни в какую переменную: