Custom rviz plugin MultiLibraryClassLoader crash when loading rosbag

asked 2019-01-31 07:31:18 -0500

afrixs gravatar image

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 )
edit retag flag offensive close merge delete

Comments

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...

Marq gravatar image Marq  ( 2019-05-27 12:15:55 -0500 )edit

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.

afrixs gravatar image afrixs  ( 2019-05-28 04:00:35 -0500 )edit

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!

Marq gravatar image Marq  ( 2019-05-28 21:30:11 -0500 )edit