diff --git a/docs/assets/ros.svg b/docs/assets/ros.svg
new file mode 100644
index 00000000..4462c8e0
--- /dev/null
+++ b/docs/assets/ros.svg
@@ -0,0 +1,183 @@
+
+
diff --git a/docs/en/ros.md b/docs/en/ros.md
index 298e6d9a..866e9f42 100644
--- a/docs/en/ros.md
+++ b/docs/en/ros.md
@@ -1,33 +1,28 @@
-ROS
-===
+# ROS
-Main article: http://wiki.ros.org
+
-ROS is a widely used framework for developing complex and distributed robotic systems.
+Main documentation: https://wiki.ros.org.
-Installation
----
+**ROS** is a widely used framework for developing complex and distributed robotic systems. The [Clover autonomous flights platform](programming.md) is based on ROS.
-Main article: http://wiki.ros.org/melodic/Installation/Ubuntu
+## Installation
ROS is already installed on [the RPi image](image.md).
-To use ROS on a PC, we recommend using Ubuntu Linux [or a virtual machine such as Parallels Desktop Lite](https://itunes.apple.com/ru/app/parallels-desktop-lite/id1085114709?mt=12) or [VirtualBox](https://www.virtualbox.org)).
+To install ROS on your PC you may address the [official installation documentation](https://wiki.ros.org/noetic/Installation/Ubuntu). For a quick start it's recommended to use [the virtual machine image with ROS and Clover simulator](simulation_vm.md).
-> **Note** For ROS Melodic distribution, we recommend using Ubuntu 18.04.
-
-Concepts
----
+## Concepts
### Nodes
-Main article: http://wiki.ros.org/Nodes
+Main article: https://wiki.ros.org/Nodes.
-ROS node is a special program (usually written in Python or C++) that communicates with other nodes via ROS topics and ROS services. Dividing complex robotic systems into isolated nodes provides certain advantages: reduced coupling of the code, increases re-usability and reliability.
+ROS node is a special program (usually written in Python or C++) that communicates with other nodes via ROS topics and ROS services. Dividing complex robotic systems into isolated nodes provides certain advantages: reduced coupling of the code, increased reusability and reliability.
-Many robotic libraries and the drivers are executed in the form of ROS-nodes.
+Many robotic libraries and drivers are made as ROS nodes.
-In order to turn an ordinary program into a ROS node, include a `rospy` or `roscpp` library, and insert the initialization code.
+In order to turn an ordinary program into a ROS node, include the `rospy` (Python) or `roscpp` (C++) library, and insert the initialization code.
An example of a ROS node in Python:
@@ -36,32 +31,52 @@ import rospy
rospy.init_node('my_ros_node') # the name of the ROS node
-rospy.spin() # entering an endless cycle...
+rospy.spin() # entering an infinite loop...
```
+> **Info** Any [autonomous flight script](programming.md) for Clover is a ROS node.
+
### Topics
-Main article: http://wiki.ros.org/Topics
+Main article: https://wiki.ros.org/Topics
-A topic is a named data bus used by the nodes for exchanging messages. Any node can *post* a message in a random topic, and *subscribe* to an arbitrary topic.
+A topic is a named data bus used by the nodes for exchanging messages. Any node can *publish* a message to any topic, and *subscribe* to any topic.
-An example of [`std_msgs/String`](http://docs.ros.org/api/std_msgs/html/msg/String.html) (line) message type posting in topic `/foo` in Python:
+Для каждого созданного топика должен быть задан тип сообщений, которые по нему передаются. ROS включает в себя большое количество стандартных типов сообщений, покрывающих различные аспекты робототехники, но при необходимости возможно создание собственных типов сообщений. Примеры стандартных типов сообщений:
+
+Each topic has the a of messages it passes. ROS include a lot of standard message types, covering different aspects of robotics. Creating custom message types is also possible. Example of standard message types:
+
+|Message type|Description|
+|-|-|
+|[`std_msgs/Int64`](https://docs.ros.org/api/std_msgs/html/msg/Int64.html)|Integer number.|
+|[`std_msgs/Float64`](https://docs.ros.org/api/std_msgs/html/msg/Float64.html)|Double-precision floating-point number|
+|[`std_msgs/String`](https://docs.ros.org/api/std_msgs/html/msg/String.html)|String.|
+|[`geometry_msgs/PoseStamped`](https://docs.ros.org/api/geometry_msgs/html/msg/PoseStamped.html)|Position and orientation of an object in a given [coordinate system](frames.md) and a time stamp (widely used for passing the robot pose or some robot's part pose).|
+|[`geometry_msgs/TwistStamped`](https://docs.ros.org/api/geometry_msgs/html/msg/TwistStamped.html)|Linear and angular velocity of an object in a given coordinate system and a time stamp.|
+|[`sensor_msgs/Image`](https://docs.ros.org/api/sensor_msgs/html/msg/Image.html)|Image (see the [article on working with the camera](camera.md)).|
+
+> **Info** See the rest of standard message types in packages: [`common_msgs`](http://wiki.ros.org/common_msgs), [`std_msgs`](https://wiki.ros.org/std_msgs), [`geometry_msgs`](https://wiki.ros.org/geometry_msgs), [`sensor_msgs`](https://wiki.ros.org/sensor_msgs), and others.
+
+Example of publishing a message of type [`String`]((https://docs.ros.org/api/std_msgs/html/msg/String.html)) in a topic `/foo` in Python:
```python
from std_msgs.msg import String
-# ...
+rospy.init_node('my_ros_node')
foo_pub = rospy.Publisher('/foo', String, queue_size=1) # creating a Publisher
-# ...
-
-foo_pub.publish(data='Hello, world!') # posting the message
+foo_pub.publish(data='Hello, world!') # publishing the message
```
-An example of subscription to topic `/foo`:
+Example of subscription to a topic `/foo`:
```python
+import rospy
+from std_msgs.msg import String
+
+rospy.init_node('my_ros_node')
+
def foo_callback(msg):
print(msg.data)
@@ -69,7 +84,13 @@ def foo_callback(msg):
rospy.Subscriber('/foo', String, foo_callback)
```
-You can also work with topics using the the `rostopic` utility. For example, using the following command, you can view messages published in topic `/mavros/state`:
+You can read a topic message once, using `wait_for_message` function:
+
+```python
+msg = rospy.wait_for_message('/foo', String, timeout=3) # wait for a message in /foo topic with timeout of 3 seconds
+```
+
+You can also work with topics using the `rostopic` utility. For example, using the following command, you can view messages published in topic `/mavros/state`:
```bash
rostopic echo /mavros/state
@@ -77,36 +98,87 @@ rostopic echo /mavros/state
The `rostopic info` command shows the type of messages in the topic, and `rostopic hz` shows frequency of published messages.
+Also you can monitor and visualize topics using [graphical tools of ROS](rviz.md).
+
### Services
-Main article: http://wiki.ros.org/Services
+Main article: https://wiki.ros.org/Services
A service can be assimilated to the a function that can be called from one node, and processed in another one. The service has a name that is similar to the name of the topic, and 2 message types: request type and response type.
-An example ROS service invoking from Python:
+Thus, ROS services implement [remote procedure call (RPC)](https://en.wikipedia.org/wiki/Remote_procedure_call) pattern.
+
+Example of invoking a ROS service in Python:
```python
+import rospy
from clover.srv import GetTelemetry
-# ...
+rospy.init_node('my_ros_node')
# Creating a wrapper for the get_telemetry service of the clover package with the GetTelemetry type:
get_telemetry = rospy.ServiceProxy('get_telemetry', srv.GetTelemetry)
-# Invoking the service, and receiving the quadcopter telemetry:
+# Invoking the service, and getting the quadcopter telemetry:
telemetry = get_telemetry()
```
You can also work with the services using the `rosservice` utility. For instance, you can call service `/get_telemetry` from the command line:
-```(bash)
+```bash
rosservice call /get_telemetry "{frame_id: ''}"
```
More examples of using the services for Clover quadcopter autonomous flights are available in the [documentation for node simple_offboard](simple_offboard.md).
-Working on several PCs
----
+### Names
+
+Main article: https://wiki.ros.org/Names.
+
+Any topic, service or a parameter is identified with a unique name. A ROS name is hierarchical structure with a `/` symbol as a separator (which is close to a file name in a file system).
+
+Examples of ROS names:
+
+* `/` (global namespace)
+* `/foo`
+* `/stanford/robot/name`
+* `/wg/node1`
+
+This names are global (close to global names in a file system). In practice, it's recommended to use *private* or *relative* names.
+
+#### Private name
+
+Each node can use its own private namespace (corresponding its name) for its resources. For example, `aruco_detect` node may publish such topics:
+
+* `/aruco_detect/markers`
+* `/aruco_detect/visualization`
+* `/aruco_detect/debug`
+
+When a node is referring its private resource, instead of `/aruco_detect/` namespace it may use `~` symbol:
+
+* `~markers`
+* `~visualization`
+* `~debug`
+
+Thus, creating a `foo` topic and the private namespace would look like this:
+
+```python
+private_foo_pub = rospy.Publisher('~foo', String, queue_size=1)
+```
+
+#### Relative name
+
+Several nodes may group into a common namespace (for example, when there are several robots in the network). For referring topics and services in the current namespace, the opening `/` symbol is omitted.
+
+Example of create a `foo` topic in the current namespace:
+
+```python
+relative_foo_pub = rospy.Publisher('foo', String, queue_size=1)
+```
+
+> **Hint** Generally, it's recommended to use private or relative names instead of global ones.
+
+### Working on several PCs
Main article: http://wiki.ros.org/ROS/Tutorials/MultipleMachines.
diff --git a/docs/ru/ros.md b/docs/ru/ros.md
index a803cf74..b268da95 100644
--- a/docs/ru/ros.md
+++ b/docs/ru/ros.md
@@ -1,33 +1,28 @@
-ROS
-===
+# ROS
-Основная статья: http://wiki.ros.org
+
-ROS – это широко используемый фреймворк для создания сложных и распределенных робототехнических систем.
+Основная документация: https://wiki.ros.org.
-Установка
----
+**ROS** – это широко используемый фреймворк для создания сложных, распределенных робототехнических систем. На ROS основана [программная платформа Клевера](programming.md).
-Основная статья: http://wiki.ros.org/melodic/Installation/Ubuntu
+## Установка
-ROS уже установлен на [образе для RPi](image.md).
+ROS уже установлен на [образе для RPi для Клевера](image.md).
-Для использования ROS на компьютере рекомендуется ОС Ubuntu Linux (либо виртуальная машина, например [Parallels Desktop Lite](https://itunes.apple.com/ru/app/parallels-desktop-lite/id1085114709?mt=12) или [VirtualBox](https://www.virtualbox.org)).
+Для установки инструментов ROS на компьютере вы можете обратиться к [официальной документации](https://wiki.ros.org/noetic/Installation/Ubuntu) по установке. Для быстрого старта рекомендуется воспользоваться [образом виртуальной машины с ROS и симулятором Клевера](simulation_vm.md).
-> **Note** Для дистрибутива ROS Melodic рекомендуется Ubuntu версии 18.04.
-
-Концепции
----
+## Концепции
### Ноды
-Основная статья: http://wiki.ros.org/Nodes
+Основная статья: https://wiki.ros.org/Nodes.
-ROS-нода – это специальная программа (обычно написанная на Python или C++), которая взаимодействует с другими нодами посредством ROS-топиков и ROS-сервисов. Разделение сложных робототехнических систем на изолированные ноды дает определенные преимущества: понижается связанность кода, повышается переиспользуемость и надежность.
+ROS-нода[^1] – это специальная программа (обычно написанная на Python или C++), которая взаимодействует с другими нодами посредством ROS-топиков и ROS-сервисов. Разделение сложных робототехнических систем на изолированные ноды дает определенные преимущества: понижается связанность кода, повышается переиспользуемость и надежность.
Очень многие робототехнические библиотеки и драйвера выполнены именно в виде ROS-нод.
-Для того, чтобы превратить обычную программу в ROS-ноду, необходимо подключить к ней библиотеку `rospy` или `roscpp` и добавить инициализирующий код.
+Для того, чтобы превратить обычную программу в ROS-ноду, необходимо подключить к ней библиотеку `rospy` (Python) или `roscpp` (C++) и добавить инициализирующий код.
Пример ROS-ноды на языке Python:
@@ -39,22 +34,36 @@ rospy.init_node('my_ros_node') # имя ROS-ноды
rospy.spin() # входим в бесконечный цикл...
```
+> **Info** Любая [программа для автономного полета Клевера](programming.md) является ROS-нодой.
+
### Топики
-Основная статья: http://wiki.ros.org/Topics
+Основная статья: https://wiki.ros.org/Topics.
Топик – это именованная шина данных, по которой ноды обмениваются сообщениями. Любая нода может *опубликовать* сообщение в произвольный топик, а также *подписаться* на произвольный топик.
-Пример публикации сообщения типа [`std_msgs/String`](http://docs.ros.org/api/std_msgs/html/msg/String.html) (строка) в топик `/foo` на языке Python:
+Для каждого созданного топика должен быть задан тип сообщений, которые по нему передаются. ROS включает в себя большое количество стандартных типов сообщений, покрывающих различные аспекты робототехники, но при необходимости возможно создание собственных типов сообщений. Примеры стандартных типов сообщений:
+
+|Тип сообщения|Описание|
+|-|-|
+|[`std_msgs/Int64`](https://docs.ros.org/api/std_msgs/html/msg/Int64.html)|Целое число.|
+|[`std_msgs/Float64`](https://docs.ros.org/api/std_msgs/html/msg/Float64.html)|Число с плавающей точкой (дробное) двойной точности.|
+|[`std_msgs/String`](https://docs.ros.org/api/std_msgs/html/msg/String.html)|Строка.|
+|[`geometry_msgs/PoseStamped`](https://docs.ros.org/api/geometry_msgs/html/msg/PoseStamped.html)|Позиция и ориентация объекта с заданной [системой координат](frames.md) и временной меткой (широко используется для передачи текущей позиции робота и его частей).|
+|[`geometry_msgs/TwistStamped`](https://docs.ros.org/api/geometry_msgs/html/msg/TwistStamped.html)|Линейная и угловая скорость объекта с заданной системой координат и временной меткой.|
+|[`sensor_msgs/Image`](https://docs.ros.org/api/sensor_msgs/html/msg/Image.html)|Изображение (см. [статью о работе с камерой](camera.md))|
+
+> **Info** Смотрите остальные стандартные типы сообщений в пакетах [`common_msgs`](http://wiki.ros.org/common_msgs), [`std_msgs`](https://wiki.ros.org/std_msgs), [`geometry_msgs`](https://wiki.ros.org/geometry_msgs), [`sensor_msgs`](https://wiki.ros.org/sensor_msgs) и других.
+
+Пример публикации сообщения типа [`std_msgs/String`](https://docs.ros.org/api/std_msgs/html/msg/String.html) (строка) в топик `/foo` на языке Python:
```python
+import rospy
from std_msgs.msg import String
-# ...
+rospy.init_node('my_ros_node')
-foo_pub = rospy.Publisher('/foo', String, queue_size=1) # создаем Publisher'а
-
-# ...
+foo_pub = rospy.Publisher('/foo', String, queue_size=1) # создаем Publisher
foo_pub.publish(data='Hello, world!') # публикуем сообщение
```
@@ -62,14 +71,27 @@ foo_pub.publish(data='Hello, world!') # публикуем сообщение
Пример подписки на топик `/foo`:
```python
+import rospy
+from std_msgs.msg import String
+
+rospy.init_node('my_ros_node')
+
def foo_callback(msg):
print(msg.data)
# Подписываемся. При получении сообщения в топик /foo будет вызвана функция foo_callback.
rospy.Subscriber('/foo', String, foo_callback)
+
+rospy.spin() # входим в бесконечный цикл, чтобы программа не завершила работу
```
-Также, существует возможность работы с топиками с помощью утилиты `rostopic`. Например, с помощью следующей команды можно просматривать сообщения, публикуемые в топик `/mavros/state`:
+Вы можете прочитать данные из топика однократно, используя функцию `wait_for_message`:
+
+```python
+msg = rospy.wait_for_message('/foo', String, timeout=3) # ждать сообщения в топике /foo в таймаутом 3 с
+```
+
+Также существует возможность работы с топиками с помощью утилиты `rostopic`. Например, с помощью следующей команды можно просматривать сообщения, публикуемые в топик `/mavros/state`:
```bash
rostopic echo /mavros/state
@@ -77,18 +99,23 @@ rostopic echo /mavros/state
Команда `rostopic info` позволяет узнать тип сообщений в топике, команда `rostopic hz` — частоту публикуемых в топике сообщений.
+Также данные в топиках можно визуализировать и в [графических инструментах ROS](rviz.md).
+
### Сервисы
-Основная статья: http://wiki.ros.org/Services
+Основная статья: https://wiki.ros.org/Services.
Сервис – это некоторый аналог функции, которая может быть вызвана из одной ноды, а обработана в другой. У сервиса есть имя, аналогичное имени топика, и 2 типа сообщений: тип запроса и тип ответа.
+Таким образом, сервисы реализуют паттерн [*удаленного вызова процедур*](https://ru.wikipedia.org/wiki/Удалённый_вызов_процедур).
+
Пример вызова ROS-сервиса из языка Python:
```python
+import rospy
from clover.srv import GetTelemetry
-# ...
+rospy.init_node('my_ros_node')
# Создаем обертку над сервисом get_telemetry пакета clover с типом GetTelemetry:
get_telemetry = rospy.ServiceProxy('get_telemetry', srv.GetTelemetry)
@@ -105,9 +132,62 @@ rosservice call /get_telemetry "{frame_id: ''}"
Больше примеров использования сервисов для автономных полетов квадрокоптера Клевер можно посмотреть в [документации ноды simple_offboard](simple_offboard.md).
-Работа на нескольких машинах
----
+### Имена
-Основная статья: http://wiki.ros.org/ROS/Tutorials/MultipleMachines.
+Основная статья: https://wiki.ros.org/Names.
+
+Любой топик, сервис или параметр идентифицируется с помощью уникального имени. ROS-имя представляет собой иерархическую структуру с символом `/` в качестве разделителя (сходно с именами в файловой системе).
+
+Примеры ROS-имен:
+
+* `/` (глобальное пространство имен)
+* `/foo`
+* `/stanford/robot/name`
+* `/wg/node1`
+
+Эти имена является глобальными (аналогично полному пути в файлу в файловой системе). На практике рекомендуется использование *приватных* или *относительных* имен.
+
+#### Приватное имя
+
+Каждая нода может использовать собственное приватное пространство имен (соответствующее имени ноды) для своих ресурсов. Например, нода `aruco_detect` может публиковать такие топики:
+
+* `/aruco_detect/markers`
+* `/aruco_detect/visualization`
+* `/aruco_detect/debug`
+
+Когда нода ссылается на свой приватный ресурс, вместо пространства имен (`/aruco_detect/`) используется символ `~`, например:
+
+* `~markers`
+* `~visualization`
+* `~debug`
+
+Таким образом, создание топика `foo` в приватном пространство имен из Python будет выглядеть так:
+
+```python
+private_foo_pub = rospy.Publisher('~foo', String, queue_size=1)
+```
+
+#### Относительное имя
+
+Несколько нод также могут объединяться в общее пространство имен (например, при одновременной работе нескольких роботов). Для того, чтобы ссылаться на топики с учетом общего пространства имен, в названии ресурса опускается начальный символ `/`.
+
+Пример создание топика `foo` с учетом общего пространства имен:
+
+```python
+relative_foo_pub = rospy.Publisher('foo', String, queue_size=1)
+```
+
+> **Hint** В общем случае всегда рекомендуется использовать приватные или относительные имена ресурсов и никогда не использовать глобальные.
+
+## Работа на нескольких машинах
+
+Основная статья: https://wiki.ros.org/ROS/Tutorials/MultipleMachines.
Преимуществом использования ROS является возможность распределения нод на несколько машин в сети. Например, ноду, осуществляющую распознавание образом на изображении можно запустить на более мощном компьютере; ноду, управляющую коптером можно запустить непосредственно на Raspberry Pi, подключенном к полетному контроллеру и т. д.
+
+## Дополнительные материалы
+
+* Учебник по ROS от Voltbro - http://docs.voltbro.ru/starting-ros/.
+* Другие книги по ROS - https://wiki.ros.org/Books.
+
+[^1]: Также встречается перевод "узел".