> For the complete documentation index, see [llms.txt](https://voltbro.gitbook.io/new_bazovyi-kurs-po-ros/llms.txt). Markdown versions of documentation pages are available by appending `.md` to page URLs; this page is available as [Markdown](https://voltbro.gitbook.io/new_bazovyi-kurs-po-ros/lesson3/robot-publisher.md).

# Издатель команд для робота

{% embed url="<https://youtu.be/ZFB5oourBfg>" %}

### Введение

В отличие от прошлой программы, где наши сигналы не несли какой-то технической смысловой нагрузки и были просто сообщениями “**Hello ROS**”, сейчас мы будем отправлять реальные команды для робота. Однако как вы увидите, принципы построения программы при этом останутся такими же. Для сохранения преемственности мы даже используем нашу прошлую программу Издатель (*publisher.py*) в качестве заготовки.

### Пишем код

{% hint style="info" %}
Писать новую программу вы можете как на компьютере в ранее созданной папке */ros\_course* или же используя расширение [Remote-SSH](/new_bazovyi-kurs-po-ros/lesson1/nastroika-vscode.md)[ ](broken://pages/fUoNje70ynTEsPDe8LyE)подключиться к файловой системе робота, создать там папку */ros\_course* и писать программу там.
{% endhint %}

Назовем нашу программу: *publisher\_for\_robot.py* и перейдем непосредственно к программированию.&#x20;

Сформулируем нашу задачу - заставим робота двигаться вперед в течение 1 секунды со скоростью 5 сантиметров в секунду, затем поворачивать направо в течение 2-х секунд с угловой скоростью 0.5 радиана в секунду, и дальше двигаться налево по дуге с угловой скоростью 1 радиан в секунду и линейной скоростью 10 сантиметров в секунду.

Итак, как мы и говорили давайте возьмем программу *Издатель* из нашего прошлого занятия и немного ее модифицируем:

```python
#прошлая программа publisher.py

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

import rospy
from std_msgs.msg import String

rospy.init_node("welcome_node")
pub = rospy.Publisher("welcome_topic", String, queue_size=10)

s = String()
s.data = "Hello ROS"

while not rospy.is_shutdown():
    pub.publish(s)
    rospy.sleep(1)
```

Импорт библиотеки **rospy** - остается. Это неизменный атрибут любой программы под ROS.

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

import rospy
```

А вот вместо *String*, который мы использовали, чтобы публиковать “**Hello ROS**”, мы будем импортировать структуру данных для управления скоростями - *Twist*:

```python
from geometry_msgs.msg import Twist
```

Для создания *ноды* мы используем стандартный метод *init\_node()*, но давайте назовем ее, например - **moving\_node**:

```python
rospy.init_node("moving_node")
```

Ну а раз управляем параметрами угловой скорости мы через публикацию структуры данных *Twist* в топик **/cmd\_vel**, то и Издатель сконфигурируем на этот топик и эту структуру данных. Вот так:

```python
pub = rospy.Publisher("cmd_vel", Twist, queue_size=10)
```

Теперь вместо объекта *String*, создадим объект *Twist*, который и будем публиковать:

```python
vel = Twist()
```

Мы не будем использовать стандартный цикл *while not rospy.is\_shutdown():* потому что хотим, чтобы робот произвел последовательность передвижений только один раз, а не повторял ее бесконечно. Так что цикл - стираем.

А вот дальше, построчно, мы будем заполнять нашу структуру данных - *vel*, значениями угловых и линейных скоростей и публиковать ее при помощи созданного нами Издателя **pub** с той временной задержкой, которая нам нужна.

Заставим робота двигаться вперед в течение 1 секунды со скоростью 5 сантиметров в секунду.  Перед тем, как поехать, сделаем небольшую задержку в 1 секунду. Заполним значение линейной скорости по Х нашей структуры данных *vel*, значением 0.05. Опубликуем ее и сделаем паузу на 1 секунду:

```python
rospy.sleep(1)
vel.linear.x = 0.05
pub.publish(vel)
rospy.sleep(1)
```

Теперь, дадим роботу команду поворачивать направо в течение 2-х секунд с угловой скоростью 0.5 радиана в секунду. Обратите внимание, что нам надо обнулить линейное значение скорости, иначе оно останется равным 0.05 и робот поедет по дуге, а не будет разворачиваться на месте как мы этого хотим. Снова опубликуем *vel* при помощи того же паблишера **pub** и сделаем паузу на 2 секунды:

```python
vel.linear.x = 0.00
vel.angular.z = -0.5
pub.publish(vel)
rospy.sleep(2)
```

И последнее - дуга налево.

Линейная скорость по Х: 0,1 метр в секунду, а угловая по Z: 1 радиан в секунду. Заполняем значения и публикуем.&#x20;

```python
vel.linear.x = 0.1
vel.angular.z = 1
pub.publish(vel)
rospy.sleep(2)
```

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

```python
vel.linear.x = 0
vel.angular.z = 0
pub.publish(vel)
```

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

Вот и все, сохраним нашу программу. Теперь нам надо запустить это все на роботе и посмотреть как оно будет работать.

{% hint style="info" %}
В случае, если вы сохранили программу на компьютере, то вам необходимо перенести её на робота. Для этого можно воспользоваться командой **scp:**

`scp /home/$USER/ros_course/publisher_for_robot.py pi@turtlebro37.local:/home/pi/ros_course/publisher_for_robot.py`

При копировании файла робот запросит пароль, по умолчанию, на наших роботах пароль ***brobro***
{% endhint %}

Теперь зайдем на самого робота и запустим файл. Перед запуском убедитесь, что перед роботом достаточно места и он не стоит на столе.&#x20;

```python
ssh pi@turtlebro37.local

python3 ros_course/publisher_for_robot.py
```

Все работает так как мы хотели !
