Ask Your Question
3

Porting rviz plugin to rviz2 (cmake trouble)

asked 2019-02-03 06:56:33 -0500

coenig gravatar image

updated 2019-02-04 10:28:41 -0500

I am trying to port a working rviz1 display plugin (ROS Kinetik) to rviz2 (ROS2 Crystal). I got pretty far, but now I am stuck at creating a shared ".so" library with cmake to be used by rviz2. I end up with either a static ".a" library or errors (which I assume are related to MOC file processing) during compilation. (I am not exactly a cmake wizard, so it may well be easy to solve.)

My pretty simplistic test workspace looks something like this:

src
└── traffic_sign_delegation_manager
    ├── icons [...]
    ├── images [...]
    ├── msg [...]
    ├── ui
    │   ├── traffic_sign_delegation_manager_panel.ui
    │   ├── traffic_sign_delegation_manager.qrc
    │   └── traffic_sign_list_item.ui
    ├── CMakeLists.txt
    ├── package.xml
    ├── plugin_description.xml
    ├── adv_interaction_groupbox.cpp
    ├── adv_interaction_groupbox.h
    ├── draw_area.cpp
    ├── draw_area.h
    ├── traffic_sign_delegation_manager_display.cpp
    ├── traffic_sign_delegation_manager_display.h
    ├── traffic_sign_delegation_manager_panel.cpp
    ├── traffic_sign_delegation_manager_panel.h
    └── ...

I converted my old catkin CMakeLists.txt to the below one, by looking at the migration guide and the available plugins for rviz2. It does compile (via colcon build), but it creates a static .a library - and rviz2 wants a .so library. These are the things I tried to fix it:

  • If I add the SHARED keyword to the add_library command like this: add_library(delegator_lib SHARED ...), I get this strange error: /usr/bin/ld: cannot find -lXAW_LIBRARY-NOTFOUND. Interestingly, in the catkin version, the SHARED keyword was not necessary to get a .so library. My feeling is that this is still the way to go... But why doesn't it work?
  • If I omit AUTO_MOC and do it the old-fashioned way (by uncommenting the qt5_wrap_cpp macros below), I end up with fatal error: ui_traffic_sign_delegation_manager_panel.h: No such file or directory (and the same for ui_traffic_sign_list_item.h).
  • If I activate both AUTO_MOC and the old macro, I get a multiple_instances error for the four MOC files - which makes sense...

At this point, I have no idea what else to try. I'd be very grateful for ANY suggestions!

(I'm on Ubuntu xenial 16.04.)

CMakeLists.txt:

project(traffic_sign_delegation_manager)

set(CMAKE_CXX_STANDARD 17)

if(NOT WIN32)
  add_definitions(-fPIC)
endif()

if(CMAKE_COMPILER_IS_GNUCXX OR CMAKE_CXX_COMPILER_ID MATCHES "Clang")
  add_compile_options(-Wall -Wextra -Wpedantic -Wno-deprecated-declarations)
endif()

set(CMAKE_INCLUDE_CURRENT_DIR ON)
set(CMAKE_AUTOMOC ON)

find_package(ament_cmake REQUIRED)
find_package(rclcpp REQUIRED)
find_package(rviz_common REQUIRED)
find_package(std_msgs REQUIRED)
find_package(rosidl_default_generators REQUIRED)
find_package(rosidl_generator_cpp)
find_package(pluginlib REQUIRED)

find_package(Qt5Core REQUIRED)
find_package(Qt5Gui REQUIRED)
find_package(Qt5OpenGL REQUIRED)
find_package(Qt5 REQUIRED COMPONENTS Widgets)

set(msg_files
  "msg/TrafficSignList.msg"
  "msg/TrafficSign.msg"
  "msg/TrafficSignSetList.msg"
  "msg/TrafficSignSet.msg"
  "msg/TrafficSignSetStatus.msg"
  "msg/TrafficSignsManaged.msg"
  "msg/AccLever2.msg"
  "msg/VehicleOdometry.msg"
)

rosidl_generate_interfaces(${PROJECT_NAME}
  ${msg_files}
  DEPENDENCIES std_msgs
)

link_directories(${ament_cmake_LIBRARY_DIRS})

add_definitions(-DQT_NO_KEYWORDS)

qt5_wrap_ui(QT_UI_FILES ui/traffic_sign_delegation_manager_panel.ui)
qt5_wrap_ui(QT_UI_FILES ui/traffic_sign_list_item.ui)

#qt5_wrap_cpp(MOC_FILES
#  traffic_sign_delegation_manager_panel.h
#  traffic_sign_delegation_manager_display.h
#  adv_interaction_groupbox.h
#  draw_area.h
#)

qt5_add_resources(QT_QRC_FILES ui/traffic_sign_delegation_manager.qrc)

set_property(SOURCE traffic_sign_delegation_manager_panel.h PROPERTY SKIP_AUTOMOC ON)
set_property(SOURCE draw_area.h PROPERTY SKIP_AUTOMOC ON)
set_property(SOURCE adv_interaction_groupbox.h PROPERTY SKIP_AUTOMOC ON)
set_property(SOURCE traffic_sign_delegation_manager_display.h PROPERTY SKIP_AUTOMOC ON)

add_library(delegator_lib      # SHARED
  vec2d.cpp
  vec2d.h
  traffic_sign_delegation_manager_panel.cpp
  traffic_sign_delegation_manager_panel.h
  draw_area.cpp
  draw_area.h
  traffic_sign_delegation_manager_display.cpp
  traffic_sign_delegation_manager_display.h
  adv_interaction_groupbox.cpp
  adv_interaction_groupbox.h
  ui/traffic_sign_list_item.ui
  ui/traffic_sign_delegation_manager_panel.ui
  ${QT_UI_FILES}
  ${MOC_FILES}
)

rosidl_target_interfaces(delegator_lib ${PROJECT_NAME} "rosidl_typesupport_cpp")

target_include_directories ...
(more)
edit retag flag offensive close merge delete

1 Answer

Sort by » oldest newest most voted
0

answered 2019-02-05 06:43:35 -0500

coenig gravatar image

Turns out it was just a missing library.

sudo apt-get install libxaw7-dev

did the trick. After that the compilation with the SHARED keyword worked.

(Noteworthy is the cyrptic error message, though. The following means, apparently, that the xaw library is missing: /usr/bin/ld: cannot find -lXAW_LIBRARY-NOTFOUND.)

edit flag offensive delete link more

Comments

If CMake does not throw an error (when configuring) when this library is missing then your CMake file is missing some checks. Make sure deps are installed before trying to compile anything. That way when the library is missing an error is thrown when configuring saying "libxaw7-dev" is missing.

VictorLamoine gravatar imageVictorLamoine ( 2019-02-05 09:43:44 -0500 )edit

Ah! And how do I do that? Why hasn't my cmake been able to detect that?

coenig gravatar imagecoenig ( 2019-02-07 04:10:49 -0500 )edit

From most preferred option to least: find_package(), the package must provide a .cmake file in order to be found. Second option is FindPkgConfig, if the package provides

VictorLamoine gravatar imageVictorLamoine ( 2019-02-07 04:16:50 -0500 )edit

a .pc file. Which is the case of libxaw7-dev (check with pkg-query -L libxaw7-dev | grep .pc). Last option is using find_program() or find_library().

VictorLamoine gravatar imageVictorLamoine ( 2019-02-07 04:18:23 -0500 )edit

I have just realized you do not link to libxaw in your CMakeLists.txt, so the problem is upstream, some package is not checking for libxaw to be installed. So the CMake check should be done in the package that links to libxaw

VictorLamoine gravatar imageVictorLamoine ( 2019-02-07 04:21:53 -0500 )edit

RViz for ROS2 does depend on libxaw , see https://github.com/ros2/rviz/blob/ros...

VictorLamoine gravatar imageVictorLamoine ( 2019-02-07 04:23:22 -0500 )edit

Your Answer

Please start posting anonymously - your entry will be published after you log in or create a new account.

Add Answer

Question Tools

2 followers

Stats

Asked: 2019-02-03 06:56:33 -0500

Seen: 167 times

Last updated: Feb 05