Заметки о 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
Вывод будет таким:

Выведем список топиков:
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