Load plugin where base class exists in another project
I'm having some trouble loading a plugin and decided to open an issue to see if it's even possible. I am creating package_B
where i'm creating a class that implements a plugin base class that exists in package_A
.
Also, somewhere in package_A
, they call loader->createInstance(plugin_type)
. When plugin_type equals the plugin i've created in package_B
, it fails saying the plugin doesn't exist. But when the plugin type is one of the plugins created/exported from package_A
, it works just fine. I feel like maybe pluginlib isn't built to do what i'm trying to make it do. Thoughts?
<?xml version="1.0"?>
<package format="2">
<name>test</name>
<version>0.2.0</version>
<description>The test package</description>
<maintainer email="me@domain.com">Jordan Lack</maintainer>
<license>TODO</license>
<buildtool_depend>catkin</buildtool_depend>
<build_depend>cmake_modules</build_depend>
<depend>eigen</depend>
<depend>hardware_interface</depend>
<depend>roscpp</depend>
<depend>pluginlib</depend>
<depend>tinyxml</depend>
<depend>boost</depend>
<depend>transmission_interface</depend>
<export>
<test plugin="${prefix}/plugins.xml" />
</export>
</package>
And here's my CMakeLists.txt
cmake_minimum_required(VERSION 2.8.3)
project(test)
find_package(catkin REQUIRED hmi_cmake hardware_interface roscpp cmake_modules pluginlib
transmission_interface)
find_package(TinyXML REQUIRED)
find_package(Boost REQUIRED)
find_package(Eigen3 REQUIRED)
# check c++11 / c++0x
include(CheckCXXCompilerFlag)
check_cxx_compiler_flag("-std=c++0x" COMPILER_SUPPORTS_CXX0X)
if (COMPILER_SUPPORTS_CXX0X)
set(CMAKE_CXX_FLAGS "-std=c++0x")
else ()
message(FATAL_ERROR "The compiler ${CMAKE_CXX_COMPILER} has no C++11 support. Please use a
different C++ compiler.")
endif ()
catkin_package(
INCLUDE_DIRS include
LIBRARIES ${PROJECT_NAME}
CATKIN_DEPENDS hardware_interface roscpp pluginlib transmission_interface
DEPENDS TinyXML Boost Eigen3
)
include_directories(include ${catkin_INCLUDE_DIRS} ${TinyXML_INCLUDE_DIRS} ${Boost_INCLUDE_DIRS}
${EIGEN3_INCLUDE_DIRS})
add_library(${PROJECT_NAME} src/sensor_parser.cpp src/transmission_interface_loader.cpp)
target_link_libraries(${PROJECT_NAME} ${catkin_LIBRARIES} ${TinyXML_LIBRARIES} ${Boost_LIBRARIES})
install(DIRECTORY include/${PROJECT_NAME}/
DESTINATION ${CATKIN_PACKAGE_INCLUDE_DESTINATION})
install(TARGETS ${PROJECT_NAME}
ARCHIVE DESTINATION ${CATKIN_PACKAGE_LIB_DESTINATION}
LIBRARY DESTINATION ${CATKIN_PACKAGE_LIB_DESTINATION}
RUNTIME DESTINATION ${CATKIN_PACKAGE_BIN_DESTINATION})
install(FILES plugins.xml
DESTINATION ${CATKIN_PACKAGE_SHARE_DESTINATION})
add_library(test_plugins test/test_plugins.cpp)
target_link_libraries(test_plugins ${catkin_LIBRARIES} ${PROJECT_NAME})
install(TARGETS test_plugins
ARCHIVE DESTINATION ${CATKIN_PACKAGE_LIB_DESTINATION}
LIBRARY DESTINATION ${CATKIN_PACKAGE_LIB_DESTINATION}
RUNTIME DESTINATION ${CATKIN_PACKAGE_BIN_DESTINATION})
And finally my plugins.xml
<library path="lib/libtest_plugins">
<class type="test_namespace::TestActuatorPlugin" base_class_type="test_namespace::Actuator">
<description>
An actuator plugin for unit testing
</description>
</class>
<class type="test_namespace::TestImuPlugin" base_class_type="test_namespace::Imu">
<description>
An imu plugin for unit testing
</description>
</class>
<class type="test_namespace::TestForceTorquePlugin" base_class_type="test_namespace::ForceTorque">
<description>
A force/torque plugin for unit testing
</description>
</class>
<!--This next plugin is the one that ros_control can't load-->
<class type="test_namespace::MyRequisiteProvider" base_class_type="transmission_interface::RequisiteProvider">
<description>
A force/torque plugin for unit testing
</description>
</class>
</library>
I can confirm if I build
ros_control
from source and put my plugin in ros controlsros_control_plugins.xml
it loads successfully. I feel like it has to be possible with my plugin in a different package. Isn't that how Gazebo loads other peoples Gazebo plugins? ohpackage_A
isros_control
If I understand the description of your setup correctly then this should be fully supported, but whether it'll be succesful depends on your
package.xml
andCMakeLists.txt
being correct. Could you edit your question and include both? Use the Preformatted Text (101010
) button.ok @gvdhoorn I have added the requested bits.
In order to be considered a plugin for something, your plugin needs a
run_depend
on that something. I can't really say whether that is the case here. See #q163476 for a related question.Since this is package.xml format 2, the
<depend>
tag should mean both<build_depend>
and<run_depend>
I believe. However your link raised a different question. In my package.xml, should my export line be<transmission_interface plugin="${prefix}/plugins.xml" />
?