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

nodelet: can't add argument to constructor

asked 2023-03-14 13:46:29 -0600

robo_ninja gravatar image

updated 2023-03-15 03:31:11 -0600

gvdhoorn gravatar image

I am writing a ROS nodelet in which I have a GetInstance() method. I am trying to parse a string argument and it's throwing me the error. Can someone point out how this error can be fixed?? Any help is appreciated.

Following is the build error -

In file included from /opt/ros/noetic/include/class_loader/class_loader_core.hpp:45,
                 from /opt/ros/noetic/include/class_loader/class_loader.hpp:46,
                 from /opt/ros/noetic/include/pluginlib/./class_list_macros.hpp:40,
                 from /opt/ros/noetic/include/pluginlib/class_list_macros.h:35,
                 from /home/robo/test_ws/src/blob_detect/src/blob_detect/blob_detect_nodelet.cpp:3:
/opt/ros/noetic/include/class_loader/meta_object.hpp: In instantiation of ‘B* class_loader::impl::MetaObject<C, B>::create() const [with C = blob_detect::BlobDetectNodelet; B = nodelet::Nodelet]’:
/opt/ros/noetic/include/class_loader/meta_object.hpp:196:7:   required from here
/opt/ros/noetic/include/class_loader/meta_object.hpp:198:12: error: no matching function for call to ‘blob_detect::BlobDetectNodelet::BlobDetectNodelet()’
  198 |     return new C;
      |            ^~~~~
In file included from /home/robo/test_ws/src/blob_detect/src/blob_detect/blob_detect_nodelet.cpp:1:
/home/robo/test_ws/src/blob_detect/include/blob_detect/blob_detect_nodelet.h:22:3: note: candidate: ‘blob_detect::BlobDetectNodelet::BlobDetectNodelet(const string&)’
   22 |   BlobDetectNodelet(const std::string& cameraName) : nodelet::Nodelet() {}
      |   ^~~~~~~~~~~~~~~~~~~~~~
/home/robo/test_ws/src/blob_detect/include/blob_detect/blob_detect_nodelet.h:22:3: note:   candidate expects 1 argument, 0 provided
make[2]: *** [CMakeFiles/blob_detect.dir/build.make:63: CMakeFiles/blob_detect.dir/src/blob_detect/blob_detect_nodelet.cpp.o] Error 1
make[1]: *** [CMakeFiles/Makefile2:183: CMakeFiles/blob_detect.dir/all] Error 2
make: *** [Makefile:141: all] Error 2

My blob_detect_nodelet.h file looks like the following -

#ifndef BLOB_DETECT_NODELET_H
#define BLOB_DETECT_NODELET_H

#include <cv_bridge/cv_bridge.h>
#include <ros/ros.h>
#include <sensor_msgs/Image.h>
#include <sensor_msgs/RegionOfInterest.h>
#include <sensor_msgs/image_encodings.h>
#include <boost/geometry.hpp>
#include <boost/range/irange.hpp>
#include <opencv2/opencv.hpp>
#include "nodelet/nodelet.h"

namespace blob_detect {

class BlobDetectNodelet : public nodelet::Nodelet {
 public:
  BlobDetectNodelet(const std::string& cameraName) : nodelet::Nodelet(){}
  static BlobDetectNodelet& GetInstance(const std::string& cameraName = "");
  inline const cv::Mat GetCurrentImage(void) const { return currentImage; }
  inline void SetCurrentImage(const cv::Mat& image) { currentImage = image; }

 private:
  void onInit() override;
  void imageCb(const sensor_msgs::Image::ConstPtr& msg);
  ros::NodeHandle nh;
  ros::NodeHandle private_nh;
  ros::Subscriber imageSub;
  ros::Publisher roiImagePub;
  const std::string cameraName;
  cv::Mat currentImage;

}

And following is my blob_detect_nodelet.cpp file -

#include <blob_detect/blob_detect_nodelet.h>
#include "pluginlib/class_list_macros.h"

namespace blob_detect {
void BlobDetectNodelet::onInit() {
  nh = getNodeHandle();
  private_nh = getPrivateNodeHandle();

  roiImagePub = nh.advertise<sensor_msgs::Image>("/camera_1/output_image", 100);
  imageSub = nh.subscribe("/camera_1/image_raw", 10, &BlobDetectNodelet::imageCb, this);
}

BlobDetectNodelet& BlobDetectNodelet::getInstance(const std::string& cameraName) {
  static BlobDetectNodelet instance(cameraName);
  return instance;
}

void BlobDetectNodelet::imageCb(const sensor_msgs::Image::ConstPtr& image) {
  cv_bridge::CvImageConstPtr cv_image = cv_bridge::toCvShare(image, "mono8");
}
}  // namespace blob_detect

PLUGINLIB_EXPORT_CLASS(blob_detect::BlobDetectNodelet, nodelet::Nodelet);
edit retag flag offensive close merge delete

Comments

I'm unsure where the getInstance(..) method in your nodelet comes from. That's not something required by Nodelet's contract.


Edit: I've updated the title of your question, as "getInstance()" is not something that's known in the context of nodelets. What you really try to be doing is adding an argument to your ctor.

gvdhoorn gravatar image gvdhoorn  ( 2023-03-15 02:57:35 -0600 )edit

1 Answer

Sort by » oldest newest most voted
1

answered 2023-03-15 02:53:45 -0600

gvdhoorn gravatar image

updated 2023-03-15 02:58:25 -0600

The problem is likely this:

class BlobDetectNodelet : public nodelet::Nodelet {
 public:
  BlobDetectNodelet(const std::string& cameraName) : nodelet::Nodelet(){}
  ...

With a nodelet, the constructor of your class is not allowed to have any arguments.

Think about it: nodelets are loaded as plugins, and the loader / registration code (ie: PLUGINLIB_EXPORT_CLASS(..)) is generic (ie: it must be able to load all subclasses of nodelet::Nodelet, not just yours). How would the generic loader code "know" what arguments to supply for your specific subclass?

The compiler error is pretty clear about it (clear as in: it tells you what the problem it encounters is, not what the root cause is):

/opt/ros/noetic/include/class_loader/meta_object.hpp:198:12: error: no matching function for call to ‘blob_detect::BlobDetectNodelet::BlobDetectNodelet()’
  198 |     return new C;
      |            ^~~~~

this basically says: "I tried instantiating BlobDetectNodelet using a zero-argument ctor, as I am instructed to do by the code underlying PLUGINLIB_EXPORT_CLASS(..), but there is no such ctor, so I'm giving up".

The idea for nodelets is to read in their "ROS parameters" (and do everything else needed to initialise the nodelet) when the nodelet::onInit(..) method is called. If you need a "camera name" parameter, onInit(..) would be the place to retrieve it from the parameter server.

I would expect things to work if you remove the const std::string& cameraName argument from the ctor.

edit flag offensive delete link more

Question Tools

1 follower

Stats

Asked: 2023-03-14 13:46:29 -0600

Seen: 135 times

Last updated: Mar 15 '23