How to port a node to nodelet as easy as possible?
I have a problem where I am having to compare PointCloud2 where all my clouds are currently coming from a nodelet. As I understand nodelets pass data around with addresses rather than chewing memory and so for a structure such as many clouds, passing this data around nodelets in the same manager would be more efficient. Is there an easy way to take an existing node and write it as a nodelet?
Asked by PapaG on 2019-11-14 20:34:58 UTC
Answers
There are no "easy" ways, you just need to follow the different steps described in the wiki and it shouldn't be too difficult. I will expand on each point to make it clear because I already had some trouble with it in the past (you can also check this really simple example) :
add the necessary #includes :
#include <nodelet/nodelet.h> #include <pluginlib/class_list_macros.h>
get rid of int main()
You don't need it anymore since your program will be run via roslaunch and the different functions can be called from the the method onInit()
(which is described under).
- subclass nodelet::Nodelet
This means your class needs to inherit from nodelet::Nodelet
like this :
class TestNodelet : public nodelet::Nodelet
- move code from constructor to
onInit()
The method onInit
is called by the nodelet manager
to initialize every nodelet. This method is defined as virtual
in the Nodelet class API which means that you must declare this method every time you create a nodelet (in private). You will initialize everything in this method, like the nodehandle and your pub/sub or even your threads if you want.
- add the PLUGINLIB_EXPORT_CLASS macro
Just add this at the end of your file (but within the namespace if you have one) :
PLUGINLIB_EXPORT_CLASS(test::TestNodelet, nodelet::Nodelet);
- add
<build_depend>
and<run_depend>
dependencies on nodelet in the package manifest.
Just add this in package.xml
:
<build_depend>pluginlib</build_depend>
<build_depend>nodelet</build_depend>
<exec_depend>pluginlib</exec_depend>
<exec_depend>nodelet</exec_depend>
- add the
<nodelet>
item in the<export>
part of the package manifest
Still in package.cml, add this :
<export>
<nodelet plugin="${prefix}/plugins/nodelets.xml"/>
</export>
- create the .xml file to define the nodelet as a plugin
Create a folder plugins
and add into it the file nodelets.cml
:
<library path="lib/libtest_nodelet">
<class name="your_package/TestNodelet"
type="test::TestNodelet"
base_class_type="nodelet::Nodelet">
<description>
Node to nodelet test
</description>
</class>
</library>
- make the necessary changes to CMakeLists.txt (comment out a rosbuild_add_executable, add a rosbuild_add_library)
You need to add the same package as in the package.cml first :
find_package(catkin REQUIRED COMPONENTS
roscpp
pluginlib
nodelet
)
And then you just need to define the nodelet as a library and link it :
# Nodelet library
add_library(test_nodelet src/test.cpp)
add_dependencies(test_nodelet ${PROJECT_NAME})
target_link_libraries(test_nodelet ${catkin_LIBRARIES})
So your code should be like this :
#include "ros/ros.h"
#include "std_msgs/String.h"
#include <nodelet/nodelet.h>
#include <pluginlib/class_list_macros.h>
namespace test {
/*********************
** Nodelet
**********************/
class TestNodelet : public nodelet::Nodelet
{
public:
TestNodelet()
{
}
private:
virtual void onInit()
{
ros::NodeHandle& private_nh = getPrivateNodeHandle();
pub = private_nh.advertise<std_msgs::String>("out", 10);
sub = private_nh.subscribe("in", 10, &TestNodelet::callback, this);
}
ros::Publisher pub;
ros::Subscriber sub;
void callback(const std_msgs::String::ConstPtr& input)
{
std_msgs::String output;
output.data = input->data;
pub.publish(output);
}
};
PLUGINLIB_EXPORT_CLASS(test::TestNodelet, nodelet::Nodelet);
}
Now you just have to create a launch file with a nodelet manager and your nodelet :
<launch>
<node pkg="nodelet" type="nodelet" name="nodelet_manager" args="manager" output="screen"/>
<node pkg="nodelet" type="nodelet" name="test" args="load your_package/TestNodelet nodelet_manager" output="screen"/>
</launch>
Asked by Delb on 2019-11-15 05:21:46 UTC
Comments