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

Revision history [back]

click to hide/show revision 1
initial version

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.

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 previously described are called when calling the constructors of your different classes (especially onInit() which will then call the subscribe function or directly execute the same instructions).