ROS Resources: Documentation | Support | Discussion Forum | Index | Service Status | ros @ Robotics Stack Exchange
Ask Your Question
0

How .launch file uses "onInit" and "subscribe" of class(nodelet) in pcl_ros

asked 2019-01-14 22:13:43 -0500

Gabbar gravatar image

updated 2019-01-16 00:57:56 -0500

Hi,

I have gone through the pcl_ros source code and understand all things how it is using PCL. I have cleared understanding regarding the pcl_ros - PCL but not understand how .launch file using its "oninit" and "subscribe" functions in nodelet without calling it (or without any specific main/application file).

For example, In the sample_voxel_grid.launch file mentioned that it is using voxel_grid nodelet but not understand, how it is operating the nodelet.

Anyone can please describe how .launch uses "onInit" and "Subscribe" of nodelet?

Edit:

Hi @Delb

Example: If you see filter.cpp in pcl_ros, you will find the following functions.

void pcl_ros::Filter::computePublish (const PointCloud2::ConstPtr &input, const IndicesPtr &indices) 
void pcl_ros::Filter::subscribe()
void pcl_ros::Filter::unsubscribe()
void pcl_ros::Filter::onInit ()
void pcl_ros::Filter::config_callback (pcl_ros::FilterConfig &config, uint32_t level)
void pcl_ros::Filter::input_indices_callback (const PointCloud2::ConstPtr &cloud, const PointIndicesConstPtr &indices)

Flow is like onInit -> config_callback and

subscribe -> input_indices_callback -> computePublish.

So, when call subscribe, it will operate other operations. My question is onit is load by nodelet manager (via .launch file) but here I can see subscribe also operated when I run .launch file. How subscribe function called by nodelet manager/.launch?

edit retag flag offensive close merge delete

1 Answer

Sort by ยป oldest newest most voted
1

answered 2019-01-15 03:42:10 -0500

Delb gravatar image

updated 2019-01-16 03:22:00 -0500

From the nodelet wiki :

void init (const std::string& name, const ros::M_string& remapping_args, const std::vector<std::string>& my_argv); 
// This method is how a nodelet should be started.  The arguments are what is required from the manager to start the nodelet.  This will initialize the nodelet base class and then call the subclass's onInit() method.

In your launch file there is :

  <node name="voxel_grid"
        pkg="nodelet" type="nodelet"
        args="standalone pcl/VoxelGrid">
    <remap from="~input" to="points" />
    <rosparam subst_value="true">
      filter_field_name: ''
      leaf_size: $(arg leaf_size)
    </rosparam>
</node>

This will launch the node nodelet, which means running the executable built from nodelet.cpp. In the main of nodelet.cpp, the nodelet is loaded using the method load of the class Loader (line 305) which will then call the method init described above (line 318). You can also go deeper in nodelet_core.cpp to see the detail of this init function, there is the call of onInit line 134 and see that the method in the header is only defined like this :

virtual void onInit() = 0;

This definition allows you to overload the method from a derived class (i.e. your class since it inherits from the class Nodelet). So you have to make sure you have overloaded the function onInit to use a nodelet and it will be directly launched from the launch file.

I don't really get what you mean with the subscribe part, but you can create subscribers and publishers directly in the onInit function if that's what you asked.

EDIT :

The source file you mentionned (filter.cpp) doesn't have all the functions you listed, especially subscribe() and unsubscribe(), there is a filter.cpp with those functions from the official ros-perception package. The subscribe() function is this :

pcl_ros::Filter::subscribe()
{
  // If we're supposed to look for PointIndices (indices)
  if (use_indices_)
  {
    // Subscribe to the input using a filter
    sub_input_filter_.subscribe (*pnh_, "input", max_queue_size_);
    sub_indices_filter_.subscribe (*pnh_, "indices", max_queue_size_);

    if (approximate_sync_)
    {
      sync_input_indices_a_ = boost::make_shared <message_filters::Synchronizer<sync_policies::ApproximateTime<PointCloud2, pcl_msgs::PointIndices> > >(max_queue_size_);
      sync_input_indices_a_->connectInput (sub_input_filter_, sub_indices_filter_);
      sync_input_indices_a_->registerCallback (bind (&Filter::input_indices_callback, this, _1, _2));
    }
    else
    {
      sync_input_indices_e_ = boost::make_shared <message_filters::Synchronizer<sync_policies::ExactTime<PointCloud2, pcl_msgs::PointIndices> > >(max_queue_size_);
      sync_input_indices_e_->connectInput (sub_input_filter_, sub_indices_filter_);
      sync_input_indices_e_->registerCallback (bind (&Filter::input_indices_callback, this, _1, _2));
    }
  }
  else
    // Subscribe in an old fashion to input only (no filters)
    sub_input_ = pnh_->subscribe<sensor_msgs::PointCloud2> ("input", max_queue_size_,  bind (&Filter::input_indices_callback, this, _1, pcl_msgs::PointIndicesConstPtr ()));
}

You can find all these instructions directly in the onInit() function of the unofficial filter.cpp file line 128. Those instructions can also be found in the official package, but slightly different, in feature.cpp line 89, and it's still in the onInit() function.

So if you want to use this function you can call it directly from onInit() or copy and paste the content directly inside the function.

My question is onit is load by nodelet manager

No it's not, the nodelet manager allows you to load one or multiple nodelets and when you load a nodelet all the functions ... (more)

edit flag offensive delete link more

Comments

+1 for the extensive answer, but to summarise: "launch" does not use "onInit" and "Subscribe" from nodelet, as the OP asked :)

gvdhoorn gravatar image gvdhoorn  ( 2019-01-15 03:56:15 -0500 )edit

Oops, you're right i forgot the conclusion !

Delb gravatar image Delb  ( 2019-01-15 04:07:07 -0500 )edit

You mean to say roslaunch(.launch) is only initializing nodelet and after that nodelet manager handles the rest of the things, Right?

Gabbar gravatar image Gabbar  ( 2019-01-15 04:09:52 -0500 )edit

@Delb Another thing, in voxel_grid or other pcl_ros nodelets, there is one function called subscribe (ex. in filter.cpp) which handles other operation. How it will handle by nodelet manager?

Gabbar gravatar image Gabbar  ( 2019-01-15 04:14:52 -0500 )edit

The nodelet manager allows you to load your nodelets (in launchfile or with rosrun). When loading a nodelet there is a call to the function onInit() that you have overloaded to do whatever you want (as described previously). The manager handles the link between different nodelets.

Delb gravatar image Delb  ( 2019-01-15 09:24:41 -0500 )edit

And I still don't get your function subscribe, what is bothering you ? Where is it used ?

Delb gravatar image Delb  ( 2019-01-15 09:26:08 -0500 )edit

@Delb I have updated the question regarding subscribe.

Gabbar gravatar image Gabbar  ( 2019-01-16 00:58:59 -0500 )edit

@Delb OK, Thanks for the prompt reply. I understand the whole things.

Gabbar gravatar image Gabbar  ( 2019-01-16 03:26:22 -0500 )edit

Question Tools

2 followers

Stats

Asked: 2019-01-14 22:13:43 -0500

Seen: 578 times

Last updated: Jan 16 '19