Заметки о 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 
#include 
#include 
#include 
#include 
 
 
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("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


  
    
        This nodelet receives a message and publishes it.
    
  

Добавим следующую строку в файл package.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


  
 
  

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

roslaunch nodelet_basics hello_world_launch.launch

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

rosnode list

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

f1a5d657ad66cacd55a67e1f15003a62.png

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

rostopic list

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

62b3f7965805155feb5766ff7a0571df.png

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

rostopic echo /Hello_World/ros_out

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

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

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

580dff8e8413a5ea47b2942c06c2f648.png

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

rqt_graph

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

60fbf9cb9e44acc2f59465811ea66c6e.png

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

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

http://wiki.ros.org/nodelet

© Habrahabr.ru