I am trying to work through the simple plugin example (http://wiki.ros.org/pluginlib/Tutorials/Writing%20and%20Using%20a%20Simple%20Plugin) but cannot get it to build for ROS2.
Trying to use https://docs.ros.org/en/foxy/Guides/Ament-CMake-Documentation.html and the details in the tutorial, but I have limited CMake experience and cannot get it to build. Are there available examples that use ROS2?
Any help would be greatly appreciated.
EDIT
Been trying to piece together a few different resources and have got things to build, but now the library can't be found so I must be doing something wrong.
The plugin failed to load for some reason. Error: %sCould not find library corresponding to plugin
I've set up two packages, once containing the base class and one containing the plugins
Folder structure
src
-controller
-include
-Controller.h
-src
-ControlFramework.cpp
CMakeLists.txt
package.xml
-linear_controller
-include
-LinearController1.h
-LinearController2.h
-src
-LinearController1.cpp
-LinearController2.cpp
CMakeLists.txt
linear_controller_plugins.xml
package.xml
Base Class
Controller.h
#pragma once
namespace control_base
{
class Controller
{
public:
Controller() {};
virtual ~Controller() {};
virtual bool initialize(double p, double i, double d) = 0;
virtual double computeFeedback(double error) = 0;
};
}
ControlFramework.cpp
#include <iostream>
#include <pluginlib/class_loader.hpp>
#include <controller/Controller.h>
using namespace std;
int main(int argc, char** argv)
{
pluginlib::ClassLoader<control_base::Controller> poly_loader("linear_controller", "control_base::Controller");
try
{
std::shared_ptr<control_base::Controller> triangle = poly_loader.createSharedInstance("control_plugins::LinearController1");
triangle->initialize(10.0, 0.0, 0.0);
std::shared_ptr<control_base::Controller> square = poly_loader.createSharedInstance("control_plugins::LinearController2");
square->initialize(5.0, 0.0, 0.0);
cout << "Triangle area: %.2f" << triangle->computeFeedback(2.0);
cout << "Square area: %.2f" << square->computeFeedback(2.0);
}
catch(pluginlib::PluginlibException& ex)
{
cout << "The plugin failed to load for some reason. Error: %s" << ex.what();
}
return 0;
}
CMakeLists.txt
cmake_minimum_required(VERSION 3.5)
project(controller)
# Default to C++14
if(NOT CMAKE_CXX_STANDARD)
set(CMAKE_CXX_STANDARD 14)
endif()
if(CMAKE_COMPILER_IS_GNUCXX OR CMAKE_CXX_COMPILER_ID MATCHES "Clang")
add_compile_options(-Wall -Wextra -Wpedantic)
endif()
# find dependencies
find_package(ament_cmake REQUIRED)
find_package(pluginlib REQUIRED)
#Include directories
include_directories(
include
)
set(plugins_dependencies
pluginlib
)
add_executable(${PROJECT_NAME}
src/ControlFramework.cpp
)
ament_target_dependencies(${PROJECT_NAME} ${plugins_dependencies})
install(TARGETS ${PROJECT_NAME}
DESTINATION lib/${PROJECT_NAME}
)
install(DIRECTORY include/
DESTINATION include/
)
ament_package()
package.xml
<?xml version="1.0"?>
<?xml-model href="http://download.ros.org/schema/package_format3.xsd" schematypens="http://www.w3.org/2001/XMLSchema"?>
<package format="3">
<name>controller</name>
<version>0.0.0</version>
<description>TODO: Package description</description>
<maintainer email="[email protected]">angus</maintainer>
<license>TODO: License declaration</license>
<buildtool_depend>ament_cmake</buildtool_depend>
<depend>pluginlib</depend>
<test_depend>ament_lint_auto</test_depend>
<test_depend>ament_lint_common</test_depend>
<export>
<build_type>ament_cmake</build_type>
</export>
</package>
Plugin Package
LinearController1.h
#pragma once
#include <pluginlib/class_list_macros.hpp>
#include <controller/Controller.h> // Inheriting the base class
namespace control_plugins
{
class LinearController1 : public control_base::Controller {
public:
LinearController1() {}; // Constructor
// No destructor!
bool initialize(double p, double i, double d);
double computeFeedback(double error);
private:
double _p_gain{0};
double _i_gain{0};
double _d_gain{0};
};
}
LinearController1.cpp
#include <linear_controller/LinearController1.h>
namespace control_plugins
{
bool LinearController1::initialize(double p, double i, double d)
{
_p_gain = p;
_i_gain = i;
_d_gain = d;
return true;
}
double LinearController1::computeFeedback(double error)
{
return error*_p_gain;
}
}
PLUGINLIB_EXPORT_CLASS(control_plugins::LinearController1, control_base::Controller)
CMakeLists.txt
cmake_minimum_required(VERSION 3.5)
project(linear_controller)
# Default to C++14
if(NOT CMAKE_CXX_STANDARD)
set(CMAKE_CXX_STANDARD 14)
endif()
if(CMAKE_COMPILER_IS_GNUCXX OR CMAKE_CXX_COMPILER_ID MATCHES "Clang")
add_compile_options(-Wall -Wextra -Wpedantic)
endif()
#Find dependencies
find_package(ament_cmake REQUIRED)
find_package(pluginlib REQUIRED)
find_package(controller REQUIRED)
include_directories(
include
../controller/include
)
set(plugins_dependencies
pluginlib
controller
)
add_library(${PROJECT_NAME}
src/LinearController1.cpp
src/LinearController1.cpp
)
ament_target_dependencies(${PROJECT_NAME} ${plugins_dependencies})
install(TARGETS ${PROJECT_NAME}
ARCHIVE DESTINATION lib
LIBRARY DESTINATION lib
RUNTIME DESTINATION lib
)
install(DIRECTORY include/
DESTINATION include/
)
install(FILES linear_controller_plugins.xml
DESTINATION share
)
ament_export_include_directories(include)
ament_export_libraries(${PROJECT_NAME})
pluginlib_export_plugin_description_file(linear_controller linear_controller_plugins.xml)
ament_package()
package.xml
<?xml version="1.0"?>
<?xml-model href="http://download.ros.org/schema/package_format3.xsd" schematypens="http://www.w3.org/2001/XMLSchema"?>
<package format="3">
<name>linear_controller</name>
<version>0.0.0</version>
<description>TODO: Package description</description>
<maintainer email="[email protected]">angus</maintainer>
<license>TODO: License declaration</license>
<buildtool_depend>ament_cmake</buildtool_depend>
<depend>pluginlib</depend>
<depend>controller</depend>
<test_depend>ament_lint_auto</test_depend>
<test_depend>ament_lint_common</test_depend>
<export>
<build_type>ament_cmake</build_type>
<controller plugin="${prefix}/linear_controller_plugins.xml" />
</export>
</package>
linear_controller_plugins.xml
<library path="/liblinear_controller">
<class type="control_plugins::LinearController1" base_class_type="control_base::Controller">
<description>LinearController1 for control</description>
</class>
<class type="control_plugins::LinearController2" base_class_type="control_base::Controller">
<description>LinearController2 for control</description>
</class>
</library>
Originally posted by GusBus on ROS Answers with karma: 63 on 2021-06-11
Post score: 2