Введение в Robot Operating System
Антон Филатов, СПБГЭТУ “ЛЭТИ”
Что такое ROS (Robot Operating System)?
2
Где ROS используется
PR2 Turtlebot HERB STAIR
Автономное движение и взаимодействие
3
Установка ROS
Полная инструкция для установки
http://wiki.ros.org/ROS/Installation
4
Основы ROS
5
Как запустить ROS
Основная команда, запускающая мастер-процесс ROS
По команде roscore запустятся:
6
user@user-pc:~$ roscore
Структура каталогов рабочей области
example_ws/ -- Корень каталога
src/ -- Исходные коды
build/ -- Генерируется
devel/ -- автоматически
7
Структура каталогов пакетов
example_package/ -- Каталог пакета
include/ -- C++ headers
msg/ -- Директория для своих типов сообщений
src/ -- Директория для исходных кодов
srv/ -- Директория для своих типов сервисов
scripts/ -- Директория для исполнимых скриптов
CMakeLists.txt -- CMake файл пакета
Package.xml -- Файл с описанием зависимостей
8
Задача 1. Создать собственное рабочее пространство и пакет
Создать рабочее пространство и пакет с такой структурой:
/catkin_ws
/devel [генерируется командой catkin_make]� /build [генерируется командой catkin_make]
/src� /ros_exercises [Пустой пакет]�
9
Publishers, Subscribers, Topics
10
Nodes and topics.
Программная единица в ROS - нода.
Одна нода = один исполняемый файл.
У нод нет общей памяти.
Ноды обмениваются информацией через топики.
Топик - “канал” между нодами.
Единица переданной информации - сообщение
11
Node
Node
Node
Node
Topic
Topic
Topic
Topics
12
Topics.
Мастер процесс ROS знает, какие ноды подписаны на существующие в системе топики и передаёт им сообщения, когда кто-то публикует сообщение в топик.
Атрибуты топика:
13
Node
Node
Node
Node
Node
Publishers и subscribers.
Атрибуты subscriber-а:
Атрибуты publisher-а:
14
Node
Subscriber
Subscriber
Publisher
Запуск нод
Чтобы узнать, какие ноды запущены
Чтобы узнать информацию о ноде
Для запуска ноды
15
user@user-pc:~$ rosnode list
user@user-pc:~$ rosnode info <node name>
В новом терминале
user@user-pc:~$ rosrun <package> <node> [__name:=<node name>]
Publisher. Python example
#! /usr/bin/env python
import rospy
from geometry_msgs.msg import Twist
rospy.init_node('commander')
pub=rospy.Publisher('/command',
Twist,
queue_size=10)
msg=Twist()
msg.linear.x=1
pub.publish(msg)
16
Notes:
[пользоваться sleep()]
Subscriber. Python example.
#! /usr/bin/env python
import rospy
from geometry_msgs.msg import Twist
def callback(msg):
rospy.loginfo(msg)
rospy.init_node('command_listener')
rospy.Subscriber('/listener',
Twist,
callback)
rospy.spin()
17
Notes:
Сервисы.
18
Node#1
Node#2
Request
Response
Time
Топики | Сервисы |
многие-ко-многим | один-к-одному |
Не ждём ответа | Ждём ответа |
Не получаем ответа | Получаем ответ |
user@user-pc:~$ rosservice call <service name> <message>
user@user-pc:~$ rosservice info <service name>
user@user-pc:~$ rossrv show <service type>
Клиент Service. Python example.
#! /usr/bin/env python
import rospy
from turtlesim.srv import Spawn
rospy.init_node('spawn_caller')
rospy.wait_for_service('/spawn')
spawn_func=rospy.ServiceProxy('/spawn',Spawn)
res = spawn_func(4.0, 4.0, 0.0, 'victim')
# isinstance(res, SpawnResponse) == True
19
Spawn == turtlesim/Spawn
Service:
user@user-pc:~$ rosservice call /spawn "{x: 0.0, y: 0.0,
theta: 0.0, name: 'victim'}"
Сервер Service. Python example.
#! /usr/bin/env python
import rospy
from turtlesim.srv import Spawn
from turtlesim.srv import SpawnResponse
def callback(req):
# isinstance(req, SpawnRequest) == True
rospy.loginfo('spawn request: %s',str(req))
return SpawnResponse(req.name)
rospy.init_node('spawn_handler')
rospy.Service('/spawn',
Spawn,
callback)
rospy.spin()
20
Service:
Дополнительные возможности
21
Rqt_graph
22
user@user-pc:~$ rqt_graph
user@user-pc:~$ rosrun rqt_graph rqt_graph
Launch файлы.
23
user@user-pc:~$ roslaunch <package> <launch file name>
user@user-pc:~$ roslaunch <full path to launch file name>
Launch files. Body
24
<launch>
<param name="speed" value="5"/>
<arg name="external_arg" default="optional_val">
<node pkg="turtlesim"
type="turtlesim_node"
name="$(arg external_arg)"
output="screen"/>
<node pkg="my_package" type="program.py" name="exec">
<param name="speed" value="2"/>
<remap from="old_topic_name"
to="new_topic_name"/>
</node>
</launch>
Include in launch file
<launch>
<include file="/home/user/ex_ws/src/file.launch" />
<include file="$(find my_package)/other.launch" />
</launch>
25
Пример кода ноды, использующей параметры
#! /usr/bin/env python
#this is pointless example of program.py
import rospy
import time
from std_msgs.msg import String
rospy.init_node('pointless thing')
pub=rospy.Publisher('/old_topic_name',String,queue_size=10)
time.sleep(1)
msg=String()
msg.data=rospy.get_param('~private_param') + str(rospy.get_param('/global_param'))
pub.publish(msg)
26
Rosbag
Утилита для записи сообщений из топиков в файл
В launch-файле:
27
user@user-pc:~$ rosrun rosbag play <file.bag>
user@user-pc:~$ rosbag play <file.bag>
user@user-pc:~$ rosbag record -a -o <outfile.bag>
<node pkg=”rosbag” type=”record” name=”rec”
args=”-o <folder> /topic1 /topic2” />