Scorpio писал(а):Удобно ли писать программы под ROS? Что там со средой разработки?
Собственной среды разработки в ROS нет, можете пользоваться любыми другими IDE.
Scorpio писал(а):как то напрягает постоянная необходимость пользоваться командной строкой. На набивание команд уходит куча времени по крайней мере у меня.
Командной строкой придется пользоваться, по крайней мере на этапах отладки вашего робота.
Scorpio писал(а):Хотелось просто общего описания простым человеческим языком еще, до того, как вдаваться в детали. Типа "программы пишутся на питоне в текстовом редакторе, без всякой автоматической проверки синтаксиса с кучей дополнительных ограничений, зато легко и надежно можно обмениваться данными между параллельными потоками".
Можно писать и в текстовом редакторе, можно пользоваться специализированными средами программирования, только при этом нужно будет ее настроить на работу с ROS, прописать пути, библиотеки и пр. На самом деле одна из идеологий ROS это разбиение общего процесса обработки и уход от огромного и плохо читаемого программного кода к написанию не больших по объему и функционалу узлов (программ) каждый из которых будет отвечать за свою конкретную функцию, например - чтение датчика, обработка данных от датчика, принятие решения, управление мотором и т.п.
Scorpio писал(а):Жду, что кто-нибудь скажет во вступительном слове, что в ROS работать легко, быстро и приятно. Стоит только в него въехать.
Именно так. Вообще, работа с пакетами ROS напоминает мне некий процесс юстировки, "подкручивания" всяких там параметров, настройки всевозможных переменных. На самом деле интересно и совсем не сложно.
Добавлено спустя 3 часа 24 минуты 12 секунд:
Продолжим. Рассмотрим архитектуру ROS. Здесь будет немного теории, без понимания которой вы не сможете работать с ROS. В общем, это достаточно сложная тема для первоначального осознания, и я рекомендовал бы вам периодически возвращаться сюда, когда будет не понятно что то в структуре пакетов ROS. Должен сказать, что если до этого момента было мало что понятно, то после прочтения этого раздела не станет понятно вообще ничего. Как правило все начинающие изучать ROS спотыкаются как раз на теме архитектуры ROS. Но прошу вас, не торопитесь бросать, ознакомьтесь со следующим разделом, пусть сейчас мало что ясно, со временем прояснится
Итак.
Архитектура ROS
В архитектуре ROS можно выделить три концептуальных уровня:
∙ Уровень файловой системы (Filesystem level), или, если проще сказать, где и какие файлы и папки расположены для успешного запуска и работы пакетов и стеков.
∙ Уровень вычислительного графа (Computation Graph level), или тот самый граф работы создаваемого робота, на подобии того, что я публиковал в начале темы
∙ Уровень сообщества (Community level), или просто люди создающие в ROS свои проекты и как то общающиеся друг с другом
Первый уровень — это уровень файловой системы. На этом уровне расположена внутренняя структура ROS — структура папок, файлы, необходимые для работы.
Второй уровень — это уровень вычислительного графа, на котором происходит взаимодействие между процессами и системами. На этом уровне находятся концепции и модули, которые имеются в ROS для создания систем, обработки всех процессов, коммуникации с более чем одним компьютером и так далее.
Третий уровень — это уровень сообщества. Этот уровень содержит инструменты и концепции для обмена знаниями, алгоритмы и код от любого разработчика. Этот уровень очень важен, поскольку ROS быстро растет при мощной поддержке со стороны сообщества.
Файловая система ROS
Первым уровнем в архитектуре ROS является уровень файловой системы. Как только мы начинаем использовать или же разрабатывать проекты на ROS, мы сразу же видим эту концепцию, которая вначале может показаться достаточно странной, но в дальнейшем все становится понятно. Как и в случае обычной операционной системы, программы в ROS разделены на папки, в которых содержатся некоторые файлы, описывающие ее функциональность:
∙ Пакеты (Packages): формируют атомарный уровень ROS. Пакет имеет минимальную структуру и содержимое, чтобы создать программу в ROS. Он может иметь выполняемые процессы (узлы или node), файлы конфигурации и так далее.
∙ Декларации (Manifests): содержится информация о пакетах, лицензионная информация, зависимости, флаги компиляции и прочее. Управление декларациями осуществляется через файл manifests.xml.
∙ Стеки (Stacks): когда вы собираете вместе несколько пакетов для получения некоторой функциональности, то получите стек. В ROS, существует много таких стеков для различных целей, например, стек навигации.
∙ Декларации стеков (Stack manifests): предоставляют данные о стеке, включая его лицензионную информацию и его зависимости от других стеков. Файл stack.xml.
∙ Типы сообщений (Message types, msg): сообщение является информацией, которую процесс отправляет другим процессам. В ROS имеется множество стандартных типов сообщений. Описание сообщения сохраняется в my_package/msg/MyMessageType.msg
∙ Типы сервисов (Service types, src): описания сервисов хранятся в my_package/srv/MyServiceType.srv Определяют в ROS структуры данных запросов и ответов для сервисов.
Пакеты
Обычно, когда мы говорим о пакетах, то имеем ввиду типичную структуру папок и файлов. Эта структура выглядит следующим образом:
∙ bin/ Это папка, где сохраняются наши скомпилированные программы
∙ include/package_name Эта директория включает заголовки библиотек, которые понадобятся. Не забудьте экспортировать декларацию, так как она используется другими пакетами
∙ msg/ Если вы разработали нестандартное сообщение, то помещайте его сюда
∙ scripts/ Здесь находятся исполняемые скрипты. Это могут быть скрипты оболочки Bash, Python’а или какие-либо еще
∙ src/ Здесь располагаются исходные файлы вашей программы. Вы можете создать папку для узлов и разрешений для узлов, либо организовать, так как вы хотите
∙ srv/ Здесь представлены типы сервисов
∙ CMakeLists.txt Это файл построения CMake
∙ manifest.xml Это файл декларации пакета
Для создания, редактирования или другой работы с пакетами, в ROS имеется несколько вспомогательных инструментов:
∙ rospack Эта команда используется для получения информации или поиска пакетов в системе
∙ roscreate-pkg Если вы хотите создать новый пакет, то воспользуйтесь этой командой
∙ rosmake Эта команда используется для компиляции пакета
∙ rosdep Эта команда устанавливает системные зависимости для пакета
∙ rxdeps Эта команда используется, если вы хотите посмотреть зависимости пакета в виде графа
Для перемещения между пакетами и их папками, в ROS имеется очень полезный инструмент, называемый rosbash, в котором имеется несколько команд, очень сильно похожих на команды Linux. Вот несколько примеров:
∙ roscd Эта команда помогает сменить директорию — аналог команды cd в Linux
∙ rosed Команда используется для редактирования файла
∙ roscp Команда используется для копирования файла из некоторого пакета
∙ rosd Эта команда выдает список директорий пакета
∙ rosls Список файлов пакета — аналог команды ls в Linux
Файл manifest.xml обязательно должен присутствовать в пакете. Он содержит специфическую информацию о конкретном пакете. Если вы найдете этот файл в папке, то возможно, эта папка является пакетом.
Если открыть файл manifest.xml, то вы увидите информацию о названии пакета, зависимостях и так далее. Все это упрощает установку и распространение этого пакета.
Два типичных тега, которые используются в файле декларации — это <depend> и <export>. Тег <depend> показывает, какие пакеты должны быть установлены до того, как будет установлен выбранный пакет. Это сделано из-за того, что новый пакет пользуется некоторой функциональностью других пакетов. Тег <export> говорит системе, какие флаги должны быть использованы для компиляции пакета, какие заголовки должны быть включены и так далее. Ниже приведен пример этого файла.
- Код: Выделить всё
<package>
<description brief="short description">
long description,
</description>
<author>Ivanov Ivan Ivanovich</author>
<license>BSD</license>
<url>http://example.com/</url>
<depend package="roscpp"/>
<depend package="common"/>
<depend package="otherPackage"/>
<versioncontrol type="svn" url="https://urlofpackage/trunk"/>
<export>
<cpp cflags="-I${prefix}/include" lflags="-L${prefix}/lib -lros"/>
</package>
Пакеты в ROS организуются в стеки. В то время, как целью пакетов является создание минимального набора кода, для облегчения его повторного использования, целью стеков является упрощение процесса совместного использования кода. Стеку необходима базовая структура файлов и папок. Ее можно создать вручную, однако, в ROS для этого имеется инструмент в виде команды roscreate-stack. Для стека необходимы следующие три файла: CMakeList.txt, Makefile и stack.xml. Если в папке вам попадется файл stack.xml, вы можете быть уверены, что это стек. Ниже приведен пример этого файла.
- Код: Выделить всё
<stack>
<description brief="Sample_Stack">Sample_Stack1</description>
<author>Ivanov Ivan Ivanovich</author>
<license>BSD,LGPL,proprietary</license>
<review status="unreviewed" notes=""/>
<url>http://someurl.blablabla</url>
<depend stack="common_msgs" /> <!-- nav_msgs, sensor_msgs, geometry_msgs -->
<depend stack="ros_tutorials" /> <!-- turtlesim -->
</stack>
Сообщения
ROS использует упрощенный язык описания сообщений для характеристики значений данных, которые выдают узлы ROS. Используя это описание, ROS может создать правильный источник кода для этих типов сообщений для нескольких языков программирования. ROS имеет множество предопределенных сообщений, но если вы разрабатываете новое сообщение, оно будет в папке msg/ вашего пакета. Внутри этой папки, некоторые файлы с расширением .msg определяют сообщения. Сообщение должно иметь две основные части: поля и константы. Поля определяют тип данных, передаваемых в сообщении. например, int32, float32 и string, или же новые типы, которые вы могли создать до этого, например, типы type1 и type2. Константы определяют имена полей.
Пример файла msg:
- Код: Выделить всё
int32 id
float32 vel
string name
В ROS имеется множество стандартных типов для использования в сообщениях.
- Код: Выделить всё
Простой тип данных Описание C++ Python
bool Unsigned 8-bit int uint8_t bool
int8 Signed 8-bit int int8_t int
uint8 Unsigned 8-bit int uint8_t int
int16 Signed 16-bit int int16_t int
uint16 Unsigned 16-bit int uint16_t int
int32 Signed 32-bit int int32_t int
uint32 Unsigned 32-bit int uint32_t int
int64 Signed 64-bit int int64_t long
uint64 Unsigned 64-bit int uint64_t long
float32 32-bit IEEE float float float
float64 64-bit IEEE float double float
string ASCII string (4 bit) std::string string
time Secs/nsecs signed ros::Time rospy.Time
32 bit int
duration Secs/nsecs signed ros::Duration ros::Duration
32 bit int rospy.Duration
Специальным типом в ROS является Header. Он используется для добавления временных меток, кадров и так далее. Этот тип позволяет сообщениям быть пронумерованными, таким образом, мы можем знать, кто отправил сообщение. Могут быть добавлены другие функции, прозрачные для пользователя, но управляемые ROS.
Тип Header содержит следующие поля:
- Код: Выделить всё
uint32 seq
time stamp
string frame_id
Сервисы
ROS использует упрощенный язык описания сервисов для характеристики типов сервисов. Он создается непосредственно из формата msg для обеспечения связи запрос/ответ между узлами. Описания сервиса хранятся в .srv файлах в поддиректории srv/ пакета.
Для вызова сервиса необходимо использовать имя пакета вместе с именем сервиса. Например, файлу sample_package1/srv/sample1.srv соответствует sample_package1/sample1.
Есть несколько инструментов для работы с сервисами. Инструмент rossrv выводит описание сервиса, пакет содержащий .srv файлы и может найти файлы источников, которые используют этот тип сервиса.
Если вы хотите создать сервис, ROS может помочь вам генератором сервисов. Эти инструменты генерируют код для начального определения сервиса. Вам только нужно добавить строку gensrv() в ваш файл CMakeLists.txt.
Продолжение следует.