0
$\begingroup$

Rosanswers logo

Hello,

I'm trying to build my own Controller with help of this page (http://wiki.ros.org/kobuki/Tutorials/Write%20your%20own%20controller%20for%20Kobuki) which helps you create a nodelet.

Now have I tried a few things:

Every time I get stuck on the same point, when I want to launch my nodelet I get this error:

Failed to load nodelet [/drive_controller] of type [kobuki_autonome/DriveControllerNodelet] even after refreshing the cache: According to the loaded plugin descriptions the class kobuki_autonome/DriveControllerNodelet with base class type nodelet::Nodelet does not exist. Declared types are  depth_image_proc/convert_metric depth_image_proc/crop_foremost depth_image_proc/disparity depth_image_proc/point_cloud_xyz depth_image_proc/point_cloud_xyz_radial depth_image_proc/point_cloud_xyzi depth_image_proc/point_cloud_xyzi_radial depth_image_proc/point_cloud_xyzrgb depth_image_proc/register image_proc/crop_decimate image_proc/crop_nonZero image_proc/crop_non_zero image_proc/debayer image_proc/rectify image_proc/resize image_publisher/image_publisher image_rotate/image_rotate image_view/disparity image_view/image kobuki_auto_docking/AutoDockingNodelet kobuki_bumper2pc/Bumper2PcNodelet kobuki_controller_tutorial/BumpBlinkControllerNodelet kobuki_node/KobukiNodelet kobuki_random_walker/RandomWalkerControllerNodelet kobuki_safety_controller/SafetyControllerNodelet nodelet_tutorial_math/Plus pcl/BAGReader pcl/BoundaryEstimation pcl/ConvexHull2D pcl/CropBox pcl/EuclideanClusterExtraction pcl/ExtractIndices pcl/ExtractPolygonalPrismData pcl/FPFHEstimation pcl/FPFHEstimationOMP pcl/MomentInvariantsEstimation pcl/MovingLeastSquares pcl/NodeletDEMUX pcl/NodeletMUX pcl/NormalEstimation pcl/NormalEstimationOMP pcl/NormalEstimationTBB pcl/PCDReader pcl/PCDWriter pcl/PFHEstimation pcl/PassThrough pcl/PointCloudConcatenateDataSynchronizer pcl/PointCloudConcatenateFieldsSynchronizer pcl/PrincipalCurvaturesEstimation pcl/ProjectInliers pcl/RadiusOutlierRemoval pcl/SACSegmentation pcl/SACSegmentationFromNormals pcl/SHOTEstimation pcl/SHOTEstimationOMP pcl/SegmentDifferences pcl/StatisticalOutlierRemoval pcl/VFHEstimation pcl/VoxelGrid stereo_image_proc/disparity stereo_image_proc/point_cloud2 yocs_cmd_vel_mux/CmdVelMuxNodelet yocs_velocity_smoother/VelocitySmootherNodelet

And I can't solve this. I have read about a mistaken path in the 'nodelet_plugins.xml', but that is not the case:

<library path="lib/libdrive_controller_nodelet">
<class name="kobuki_autonome/DriveControllerNodelet" type="kobuki::DriveControllerNodelet" base_class_type="nodelet::Nodelet">
    <description>
        Nodelet for a simple blink when bump controller
    </description>
</class>
</library>

So can somebody help me?

Platform: Kobuki Kinetic

Updated: Added the code from pastebin into my post

CMakeLists:

cmake_minimum_required(VERSION 2.8.3)
project(kobuki_autonome)
find_package(catkin REQUIRED COMPONENTS roscpp
                                        nodelet
                                        pluginlib
                                        std_msgs
                                        kobuki_msgs
                                        yocs_controllers)
 
catkin_package(INCLUDE_DIRS include
               LIBRARIES drive_controller_nodelet
               CATKIN_DEPENDS roscpp
                              nodelet
                              pluginlib
                              std_msgs
                              kobuki_msgs
                              yocs_controllers)
 
include_directories(include
                    ${catkin_INCLUDE_DIRS})
 
add_library(drive_controller_nodelet src/nodelet.cpp)
add_dependencies(drive_controller_nodelet ${catkin_EXPORTED_TARGETS})
target_link_libraries(drive_controller_nodelet ${catkin_LIBRARIES})
 
install(TARGETS drive_controller_nodelet
        DESTINATION ${CATKIN_PACKAGE_LIB_DESTINATION})
install(DIRECTORY include/${PROJECT_NAME}/
        DESTINATION ${CATKIN_PACKAGE_INCLUDE_DESTINATION})
 
install(DIRECTORY plugins
        DESTINATION ${CATKIN_PACKAGE_SHARE_DESTINATION})
 
install(DIRECTORY launch
        DESTINATION ${CATKIN_PACKAGE_SHARE_DESTINATION})

plugins/nodelet_plugins.xml:

<library path="lib/libdrive_controller_nodelet">
    <class name="kobuki_autonome/DriveControllerNodelet" type="kobuki::DriveControllerNodelet" base_class_type="nodelet::Nodelet">
        <description>
            Nodelet test
        </description>
    </class>
</library>

src/nodelet.cpp:

#include <nodelet/nodelet.h>
#include <pluginlib/class_list_macros.h>
#include "kobuki_autonome/drive_controller.hpp"
 
 
namespace kobuki
{
 
/**
 * @brief Nodelet-wrapper of the BumpBlinkController class
 */
class DriveControllerNodelet : public nodelet::Nodelet
{
public:
  DriveControllerNodelet(){};
  ~DriveControllerNodelet(){}
 
  /**
   * @brief Initialise the nodelet
   *
   * This function is called, when the nodelet manager loads the nodelet.
   */
  virtual void onInit()
  {
    ros::NodeHandle nh = this->getPrivateNodeHandle();
 
    // resolve node(let) name
    std::string name = nh.getUnresolvedNamespace();
    int pos = name.find_last_of('/');
    name = name.substr(pos + 1);
 
    NODELET_INFO_STREAM("Initialising nodelet... [" << name << "]");
    controller_.reset(new DriveController(nh, name));
 
    // Initialises the controller
    if (controller_->init())
    {
      NODELET_INFO_STREAM("Nodelet initialised. [" << name << "]");
    }
    else
    {
      NODELET_ERROR_STREAM("Couldn't initialise nodelet! Please restart. [" << name << "]");
    }
  }
private:
  boost::shared_ptr<DriveController> controller_;
};
 
} // namespace kobuki
 
PLUGINLIB_EXPORT_CLASS(kobuki::DriveControllerNodelet, nodelet::Nodelet);

include/kobuki_autonome/drive_controller.hpp:

#ifndef DRIVE_CONTROLLER_HPP_
#define DRIVE_CONTROLLER_HPP_
 
/*****************************************************************************
** Includes
*****************************************************************************/
// %Tag(FULLTEXT)%
#include <ros/ros.h>
#include <std_msgs/Empty.h>
#include <yocs_controllers/default_controller.hpp>
#include <kobuki_msgs/BumperEvent.h>
#include <kobuki_msgs/Led.h>
 
namespace kobuki
{
 
/**
 * @ brief A simple bump-blink-controller
 *
 * A simple nodelet-based controller for Kobuki, which makes one of Kobuki's LEDs blink, when a bumper is pressed.
 */
class DriveController : public yocs::Controller
{
public:
  DriveController(ros::NodeHandle& nh, std::string& name) : Controller(), nh_(nh), name_(name){};
  ~DriveController(){};
 
  /**
   * Set-up necessary publishers/subscribers
   * @return true, if successful
   */
  bool init()
  {
    enable_controller_subscriber_ = nh_.subscribe("enable", 10, &DriveController::enableCB, this);
    disable_controller_subscriber_ = nh_.subscribe("disable", 10, &DriveController::disableCB, this);
    bumper_event_subscriber_ = nh_.subscribe("events/bumper", 10, &DriveController::bumperEventCB, this);
    // choose between led1 and led2
    blink_publisher_ = nh_.advertise< kobuki_msgs::Led >("commands/led1", 10);
    return true;
  };
 
private:
  ros::NodeHandle nh_;
  std::string name_;
  ros::Subscriber enable_controller_subscriber_, disable_controller_subscriber_;
  ros::Subscriber bumper_event_subscriber_;
  ros::Publisher blink_publisher_;
 
  /**
   * @brief ROS logging output for enabling the controller
   * @param msg incoming topic message
   */
  void enableCB(const std_msgs::EmptyConstPtr msg);
 
  /**
   * @brief ROS logging output for disabling the controller
   * @param msg incoming topic message
   */
  void disableCB(const std_msgs::EmptyConstPtr msg);
 
  /**
   * @brief Turns on/off a LED, when a bumper is pressed/released
   * @param msg incoming topic message
   */
  void bumperEventCB(const kobuki_msgs::BumperEventConstPtr msg);
};
 
void DriveController::enableCB(const std_msgs::EmptyConstPtr msg)
{
  if (this->enable())
  {
    ROS_INFO_STREAM("Controller has been enabled. [" << name_ << "]");
  }
  else
  {
    ROS_INFO_STREAM("Controller was already enabled. [" << name_ <<"]");
  }
};
 
void DriveController::disableCB(const std_msgs::EmptyConstPtr msg)
{
  if (this->disable())
  {
    ROS_INFO_STREAM("Controller has been disabled. [" << name_ <<"]");
  }
  else
  {
    ROS_INFO_STREAM("Controller was already disabled. [" << name_ <<"]");
  }
};
 
void DriveController::bumperEventCB(const kobuki_msgs::BumperEventConstPtr msg)
{
  if (this->getState()) // check, if the controller is active
  {
    // Preparing LED message
    kobuki_msgs::LedPtr led_msg_ptr;
    led_msg_ptr.reset(new kobuki_msgs::Led());
 
    if (msg->state == kobuki_msgs::BumperEvent::PRESSED)
    {
      ROS_INFO_STREAM("Bumper pressed. Turning LED on. [" << name_ << "]");
      led_msg_ptr->value = kobuki_msgs::Led::GREEN;
      blink_publisher_.publish(led_msg_ptr);
    }
    else // kobuki_msgs::BumperEvent::RELEASED
    {
      ROS_INFO_STREAM("Bumper released. Turning LED off. [" << name_ << "]");
      led_msg_ptr->value = kobuki_msgs::Led::BLACK;
      blink_publisher_.publish(led_msg_ptr);
    }
  }
};
 
} // namespace kobuki
// %EndTag(FULLTEXT)%
#endif /* BUMP_BLINK_CONTROLLER_HPP_ */

package.xml:

<?xml version="1.0"?>
<package>
  <name>kobuki_autonome</name>
  <version>0.0.0</version>
  <description>The hva_autonome package</description>
 
  <!-- One maintainer tag required, multiple allowed, one person per tag -->
  <!-- Example:  -->
  <!-- <maintainer email="[email protected]">Jane Doe</maintainer> -->
  <maintainer email="[email protected]">mats</maintainer>
 
 
  <!-- One license tag required, multiple allowed, one license per tag -->
  <!-- Commonly used license strings: -->
  <!--   BSD, MIT, Boost Software License, GPLv2, GPLv3, LGPLv2.1, LGPLv3 -->
  <license>TODO</license>
 
  <buildtool_depend>catkin</buildtool_depend>
 
  <build_depend>roscpp</build_depend>
  <build_depend>nodelet</build_depend>
  <build_depend>pluginlib</build_depend>
  <build_depend>std_msgs</build_depend>
  <build_depend>kobuki_msgs</build_depend>
  <build_depend>yocs_controllers</build_depend>
 
  <run_depend>roscpp</run_depend>
  <run_depend>nodelet</run_depend>
  <run_depend>pluginlib</run_depend>
  <run_depend>std_msgs</run_depend>
  <run_depend>kobuki_msgs</run_depend>
  <run_depend>yocs_controllers</run_depend>
 
 
  <!-- The export tag contains other, unspecified, tags -->
  <export>
    <nodelet plugin="${prefix}/plugins/nodelet_plugins.xml" />
  </export>
</package>

Originally posted by Matszs on ROS Answers with karma: 16 on 2017-10-16

Post score: 0

$\endgroup$

2 Answers 2

0
$\begingroup$

Rosanswers logo

nodelet involves multiple files, so it's not straightforward. Sharing CMakeLists.txt, your code (especially the line you're exporting your class using pluginlib's mechanism if you're writing your nodelet in C++).

That said, your issue is likely FAQ, as I hit many other threads on google. I'd suggest checking the name of the lib file and the class name.


Originally posted by 130s with karma: 10937 on 2017-10-16

This answer was NOT ACCEPTED on the original site

Post score: 1


Original comments

Comment by Matszs on 2017-10-16:
Thank you for your reply, I have also seen this topics on Google and I have checked if the names are correct and they are.

$\endgroup$
0
$\begingroup$

Rosanswers logo

The problem is fixed. In the package.xml I removed the following lines:

<run_depend>pluginlib</run_depend>
<build_depend>pluginlib</build_depend>

And in the CMakeLists.txt remove the lines with 'pluginlib' in it.

And it worked...


Originally posted by Matszs with karma: 16 on 2017-10-17

This answer was ACCEPTED on the original site

Post score: 0


Original comments

Comment by 130s on 2017-10-17:
I'm not sure why that is a fix to your issue...After making the changes you mentioned, 1) have you re-installed dependencies? 2) have you rebuilt the workspace?

$\endgroup$

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.