Custom rviz plugin MultiLibraryClassLoader crash when loading rosbag
Hello, I'm not really familiar with plugin building and loading configuration. I want to create an rviz Panel which loads grid_map from rosbag and user can update some of its data. I have modified a working example from rviz_plugin_tutorials. However when I try to use rosbag package, rviz crashes with message
terminate called after throwing an instance of 'pluginlib::CreateClassException'
what(): MultiLibraryClassLoader: Could not create object of class type rosbag::NoEncryptor as no factory exists for it. Make sure that the library exists and was explicitly loaded through MultiLibraryClassLoader::loadLibrary()
Aborted (core dumped)
I guess there are some problems with my CMakeLists.txt or package.xml, but I have no clue what should I add to load the rosbag library correctly. (I'm able to use rosbag in a ros node, this problem arises only when used in a plugin).
Thank you very much for your help
Here is (almost) minimal code to reproduce my problem:
package.xml
<package>
<name>bag_plugin</name>
<version>0.10.3</version>
<description>
Bag plugin.
</description>
<maintainer email="bag@plug.in">Bag plugin</maintainer>
<license>BSD</license>
<url>http://ros.org/wiki/bag_plugin</url>
<author>Bag plugin</author>
<buildtool_depend>catkin</buildtool_depend>
<build_depend>qtbase5-dev</build_depend>
<build_depend>rviz</build_depend>
<build_depend>rosbag</build_depend>
<build_depend>roscpp</build_depend>
<run_depend>libqt5-core</run_depend>
<run_depend>libqt5-gui</run_depend>
<run_depend>libqt5-widgets</run_depend>
<run_depend>rviz</run_depend>
<run_depend>rosbag</run_depend>
<run_depend>roscpp</run_depend>
<export>
<rosdoc config="${prefix}/rosdoc.yaml"/>
<rviz plugin="${prefix}/plugin_description.xml"/>
</export>
</package>
CMakeLists.txt
cmake_minimum_required(VERSION 2.8.3)
project(bag_plugin)
find_package(catkin REQUIRED COMPONENTS rviz
roscpp
rosbag
)
catkin_package(
LIBRARIES ${PROJECT_NAME}
CATKIN_DEPENDS rosbag
roscpp
rviz
DEPENDS rosbag
)
include_directories(${catkin_INCLUDE_DIRS})
link_directories(${catkin_LIBRARY_DIRS})
set(CMAKE_AUTOMOC ON)
if(rviz_QT_VERSION VERSION_LESS "5")
message(STATUS "Using Qt4 based on the rviz_QT_VERSION: ${rviz_QT_VERSION}")
find_package(Qt4 ${rviz_QT_VERSION} EXACT REQUIRED QtCore QtGui)
## pull in all required include dirs, define QT_LIBRARIES, etc.
include(${QT_USE_FILE})
else()
message(STATUS "Using Qt5 based on the rviz_QT_VERSION: ${rviz_QT_VERSION}")
find_package(Qt5 ${rviz_QT_VERSION} EXACT REQUIRED Core Widgets)
## make target_link_libraries(${QT_LIBRARIES}) pull in all required dependencies
set(QT_LIBRARIES Qt5::Widgets)
endif()
add_definitions(-DQT_NO_KEYWORDS)
set(SRC_FILES
src/bag_plugin.cpp
)
add_library(${PROJECT_NAME} ${SRC_FILES})
target_link_libraries(${PROJECT_NAME} ${QT_LIBRARIES} ${catkin_LIBRARIES})
## Install rules
install(TARGETS
${PROJECT_NAME}
ARCHIVE DESTINATION ${CATKIN_PACKAGE_LIB_DESTINATION}
LIBRARY DESTINATION ${CATKIN_PACKAGE_LIB_DESTINATION}
RUNTIME DESTINATION ${CATKIN_PACKAGE_BIN_DESTINATION}
)
install(FILES
plugin_description.xml
DESTINATION ${CATKIN_PACKAGE_SHARE_DESTINATION})
install(DIRECTORY media/
DESTINATION ${CATKIN_PACKAGE_SHARE_DESTINATION}/media)
install(DIRECTORY icons/
DESTINATION ${CATKIN_PACKAGE_SHARE_DESTINATION}/icons)
install(PROGRAMS scripts/send_test_msgs.py
DESTINATION ${CATKIN_PACKAGE_BIN_DESTINATION})
bag_plugin.h
#ifndef BAG_PLUGIN_H
#define BAG_PLUGIN_H
#ifndef Q_MOC_RUN
# include <ros/ros.h>
# include <rviz/panel.h>
#endif
#include <rosbag/bag.h>
#include <rosbag/encryptor.h>
namespace bag_plugin
{
class BagPlugin: public rviz::Panel
{
Q_OBJECT
public:
BagPlugin( QWidget* parent = 0 );
protected Q_SLOTS:
void loadBag();
protected:
ros::NodeHandle nh_;
};
} // end namespace bag_plugin
#endif
bag_plugin.cpp
#include "bag_plugin.h"
#include <QPushButton>
#include <QVBoxLayout>
namespace bag_plugin
{
BagPlugin::BagPlugin( QWidget* parent )
: rviz::Panel( parent )
{
auto load_button = new QPushButton( "Load" );
connect( load_button, SIGNAL( clicked() ), this, SLOT( loadBag() ));
QVBoxLayout* layout = new QVBoxLayout;
layout->addWidget( load_button );
setLayout( layout );
}
void BagPlugin::loadBag()
{
rosbag::Bag bag; // Here rviz crashes
ROS_INFO("open: %d", bag.isOpen() ? 1 : 0);
}
} // end namespace bag_plugin
#include <pluginlib/class_list_macros.h>
PLUGINLIB_EXPORT_CLASS(bag_plugin::BagPlugin,rviz::Panel )
Have you found a solution to your problem?
I found this bug report but dont understand how they fixed the issue... https://github.com/ros/ros_comm/issue...
Well that looks like you will have to clone (or download) the ros_comm package and build it from source (or wait for adding the update into apt). However I avoided the problem by restructuring my application - I have an RViz plugin which only visualizes data and processes user interaction and sends/receives messages to a standalone node which works with data in the bag. This way the rviz plugin does not use the crash causing rosbag package and additionaly you have a more elegant model-view-controller structure.
Sorry the update looked to be a while ago so I assumed it had hit apt by now. Also why I didn't understand how to fix the error :)
Thanks for letting me know how you got around the issue!