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:
- Write my own, which looks like the 'random_walker' from git (https://github.com/yujinrobot/kobuki/tree/devel/kobuki_random_walker)
- Copied the random_walker source and change all the names
- And tried to create it from the tutorial.
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