Заметки о ROS: нодлеты

от автора

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

Нодлеты это расширенный способ запуска узлов в ROS. Нодлеты позволяют запускать сразу несколько узлов ROS в одном процессе без ущерба производительности (zero copy). По сути нодлеты это потоки, которые могут общаться друг с другом не используя традиционный сетевой стек ROS.

Тем не менее у нодлетов есть недостатки. Если нодлет падает, то падают и все запущенные внутри него процессы. Кроме того, нодлеты можно реализовывать только на C++. К сожалению, для языка Python они не поддерживаются.

Практика

Создадим нодлет. Нодлеты создаются аналогично узлам в ROS. Выполним команду:

cd ~/catkin_ws/src catkin_create_pkg nodelet_basics nodelet roscpp std_msgs

Единственное отличие здесь в том, что мы указываем в списке зависимостей пакет nodelet.

Создадим файл hello_world.cpp в папке src с таким содержимым:

// Add the necessary includes #include <ros/ros.h> #include <std_msgs/String.h> #include <nodelet/nodelet.h> #include <pluginlib/class_list_macros.h> #include <stdio.h>     namespace nodelet_basics {     /*********     * Nodelet     **********/       // This code here means the class needs to inherit from      // nodelet::Nodelet     class Hello_World : public nodelet::Nodelet     {               public:             Hello_World()             {             }           private:             // The onInit method is called by nodelet manager.              // It is responsible for initializing the nodelet.             virtual void onInit()             {                 // Create a NodeHandle object                 ros::NodeHandle& private_nh = getPrivateNodeHandle();                 NODELET_DEBUG("Initializing nodelet...");                               // Create a publisher topic                 pub = private_nh.advertise<std_msgs::String>("ros_out",10);                                // Create a subscriber topic                 sub = private_nh.subscribe("ros_in",10, &Hello_World::callback, this);               }               ros::Publisher pub;             ros::Subscriber sub;                   // Display messages from /ros_in topic to the terminal window.             // Publish to /ros_out topic             void callback(const std_msgs::String::ConstPtr& input)             {                   std_msgs::String output;                 output.data = input->data;                 NODELET_DEBUG("msg data = %s",output.data.c_str());                 ROS_INFO("msg data = %s",output.data.c_str());                 pub.publish(output);                     }     };     // Export the Hello_World class as a plugin using the     // PLUGINLIB_EXPORT_CLASS macro.     PLUGINLIB_EXPORT_CLASS(nodelet_basics::Hello_World, nodelet::Nodelet); }

Нодлет реализуется в виде класса производного от nodelet::Nodelet.

В классе реализуется два метода (onInit и callback). Метод onInit инициализирует нодлет. Внутри метода мы создаем объект NodeHandle, паблишера и подписчика. Метод callback вызывается при получении нового сообщения в топике.

Создадим файл nodelet_plugins.xml

<library path="lib/libnodelet_basics">   <class name="nodelet_basics/Hello_World"          type="nodelet_basics::Hello_World"          base_class_type="nodelet::Nodelet">     <description>         This nodelet receives a message and publishes it.     </description>   </class> </library>

Добавим следующую строку в файл package.xml

<nodelet plugin="${prefix}/nodelet_plugins.xml" />

Добавим следующие строки в файл CMakeLists.txt:

## Declare C++ library add_library(nodelet_basics src/hello_world.cpp)   ## Link libraries target_link_libraries(nodelet_basics ${catkin_LIBRARIES}) 

Скомпилируем воркспейс:

catkin_make

После успешной компиляции мы увидим что появился новый файл libnodelet_basics.co.

Создадим файл hello_world_launch.launch

<launch>   <node pkg="nodelet"         type="nodelet"         name="standalone_nodelet"          args="manager"         output="screen"   />     <node pkg="nodelet"         type="nodelet"         name="Hello_World"         args="load nodelet_basics/Hello_World standalone_nodelet"         output="screen"   /> </launch>

Запустим нодлет с помощью команды roslaunch

roslaunch nodelet_basics hello_world_launch.launch

Выведем список активных узлов:

rosnode list

Вывод будет таким:

Выведем список топиков:

rostopic list

Вывод будет таким:

В новом терминале выполним команду:

rostopic echo /Hello_World/ros_out

Опубликуем сообщение в топике:

rostopic pub /Hello_World/ros_in std_msgs/String "Hi ROS"

В терминале с нодлетом получим такой вывод

Выполним команду:

rqt_graph

Откроется окно со схемой (графом) активных узлов и топиков.

На этом все! Более подробно можно прочитать о нодлетах на официальной странице.

https://automaticaddison.com/working-with-ros-nodelets-in-ros-noetic/

http://wiki.ros.org/nodelet


ссылка на оригинал статьи https://habr.com/ru/articles/876192/


Комментарии

Добавить комментарий

Ваш адрес email не будет опубликован. Обязательные поля помечены *