⛄
new_Базовый курс по ROS
  • Обложка
  • Урок 1. Введение в ROS
    • Что такое ROS ?
    • Знакомство с роботом TurtleBro
    • Настройка ПК
    • Установка ROS
    • Настройка робота TurtleBro
    • Настройка VSCode
    • Практические задания
  • Урок 2. Базовый понятия ROS
    • Основы теории управления
    • Сущности ROS как элементы ТАУ
    • Базовые утилиты ROS
    • Практические задания
  • Урок 3. Издатель
    • Издатель (Publisher)
    • Издатель команд для робота
    • Практические задания
  • Урок 4. Подписчик
    • Подписчик (Subscriber)
    • Подписчик на данные робота
    • Практические задания
  • Урок 5. Подписчик и Издатель
    • Взаимодействие Подписчика и Издателя в рамках одной ноды. Часть 1
    • Практические задания
    • Взаимодействие Подписчика и Издателя в рамках одной ноды. Часть 2
    • Практические задания
      • Решение
  • Урок 6. Работа с Arduino
    • Работа с Arduino
    • Создание Издателя
    • Создание Подписчика
    • Практические задания
  • Курсовая работа
    • Задание
  • Итог
    • Заключение
Powered by GitBook
On this page
  • Введение
  • Пишем код
  • Запускаем и тестируем

Was this helpful?

  1. Урок 4. Подписчик

Подписчик (Subscriber)

PreviousПрактические заданияNextПодписчик на данные робота

Last updated 1 year ago

Was this helpful?

Введение

Подписчик - это инструмент, который принимает сигналы, передающиеся внутри системы управления.

Вне зависимости от того, какие это сигналы: данные лидара, одометрия, видео с камеры, положения сервоприводов или любые другие, их всегда передает, т.е. публикует Издатель, а принимает, т.е. подписывается на них Подписчик.

Например, лидар детектирует препятствия вокруг робота и при помощи Издателя передает данные об этом в ROS в топик /scan. Очевидно, что нам надо как-то получить эти данные для использования в наших программах. Так вот, инструмент, которым мы считываем эти данные из сообщений, это и есть Подписчик.

Пишем код

Назовем нашу программу: subscriber.py и сохраним ее в папку ros-cource в корневой папке.

Итак начнем: Как мы помним у нас есть Издатель, который публикует строку “Hello ROS” в топик с именем “welcome_topic”.

Для того, чтобы использовать сущность Подписчика ROS в Python, нам надо подключить библиотеку rospy.

#! /usr/bin/env python3
# -*- coding: utf-8 -*-

import rospy

Теперь давайте определим тип и структуру данных, которые мы будем принимать при помощи нашего Подписчика. Тут все просто: имя топика и тип данных определяется Издателем, который публикует сообщения для нас.

Вспоминая нашего уже написанного Издателя, мы определим тип данных как строка, так как передаётся сообщение “Hello ROS” с типом данных String. Топик будет “welcome_topic”, потому что так мы написали в нашей прошлой программе.

from std_msgs.msg import String

Теперь создадим и зарегистрируем в ROS нашу ноду стандартным методом init_node():

rospy.init_node("subscriber_node")
rospy.Subscriber

Теперь, нам необходимо указать название топика из которого Подписчик будет получать данные и название структуры этих данных:

rospy.Subscriber("/welcome_topic", String, callback)

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

В общем случае это функция, которая вызывается каждый раз, когда в топике на который подписан Подписчик появляются сообщения, то есть, каждый раз когда Издатель публикует сообщение, ROS оповещает об этом Подписчика и передает ему сообщение от Издателя с заполненной структурой данных. Объект Подписчик же в свою очередь принимает это сообщение, вызывает функцию обратного вызова внутри нашей программы, и передает в нее полученную структуру данных в качестве аргумента.

Давайте напишем функцию обратного вызова, которая будет выводить на экран всю переданную в нее в качестве аргумента структуру данных:

def callback(msg): 
    print(msg)

Функция принимает объект структуры данных в качестве аргумента и просто печатает его при помощи функции print().

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

Теперь давайте напишем основной цикл нашей программы.

Используем стандартный ROS цикл:

while not rospy.is_shutdown():

А в самом цикле используем метод библиотеки rospy - spin. Сам метод ничего не делает, кроме того, что не даёт нашему Подписчику закрыться пока мы не выйдем из цикла:

while not rospy.is_shutdown(): 
    rospy.spin()

Вот и все! Мы с вами написали программу Подписчика! Давайте сохраним её, запустим и посмотрим как она работает.

Запускаем и тестируем

Запустим roscore и оставим его запущенным в терминале.

Откроем новый терминал напишем python3 и полный путь до файла с нашей программой:

python3 ros_course/subscriber.py

Запустилось. Но ничего не происходит… Правильно, ведь публикация-то сообщений не идет. И наша программа начнет выводить данные на экран, только тогда когда мы запустим программу Издателя (publisher.py).

Давайте откроем еще один терминал и запустим нашего Издателя:

python3 ros_course/publisher.py

Наш Подписчик начал принимать сообщения от нашего Издателя! Всё работает так как надо!

#! /usr/bin/env python3
# -*- coding: utf-8 -*-

import rospy
from std_msgs.msg import String

rospy.init_node("subscriber_node")

def callback(msg): 
    print(msg)

rospy.Subscriber("/welcome_topic", String, callback)

while not rospy.is_shutdown(): 
    rospy.spin()

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

Чтобы продолжить то, что мы делали ранее (), сигнал, который мы будем считывать сейчас это будет сообщение “Hello ROS” от, уже написанного нами Издателя.

Теперь давайте создадим объект Подписчик. В отличие от урока про при создании объекта Издатель, мы пользовались его методом publish для публикации наших сообщений. У Подписчика мы не будем пользоваться его методами и поэтому, мы можем не передавать ссылку на экземпляр Подписчика ни в какую переменную:

урок про Издателя
Издателя
.