With the latest version of Nvidia Jetpack the conflicts between cv_bridge, image_geometry and opencv4tegra seems to have been solved… but a few issues still remain since ROS searches for OpenCV v2.4.8, but opencv4tegra is based on OpenCV v2.4.12.
Despite this mismatch of version cv_bridge and image_geometry packages work correctly, but if we try to compile a new node that uses OpenCV (for example the zed-ros-wrapper for Stereolabs ZED camera) the linker will fail trying to link “libopencv-videostab2.4.8.so”.
On the official Nvidia developer forum, the user “kgregson” posted a solution to this problem and after a few tests I must confirm that the solution is good and it works as expected.
What we must “say” to cv_bridge and image_geometry is to not search for OpenCV in the default ARM path “/usr/lib/arm-linux-gnueabihf”, but in “/usr/lib” (I do not know why Nvidia chose this path) and that the current version of OpenCV is 2.4.12 and not 2.4.8… finally we must remove the references to the module OpenCL because Nvidia does not provide it.
Files to be modified
- /opt/ros/<ros-version>/lib/pkgconfig/cv_bridge.pc
- /opt/ros/<ros-version>/lib/pkgconfig/image_geometry.pc
- /opt/ros/<ros-version>/share/cv_bridge/cmake/cv_bridgeConfig.cmake
- /opt/ros/<ros-version>/share/image_geometry/cmake/image_geometryConfig.cmake
You can backup and modify each file using the following commands (example for ROS Indigo):
$ sudo cp /opt/ros/indigo/lib/pkgconfig/cv_bridge.pc /opt/ros/indigo/lib/pkgconfig/cv_bridge.pc-bak sudo cp /opt/ros/indigo/lib/pkgconfig/image_geometry.pc /opt/ros/indigo/lib/pkgconfig/image_geometry.pc-bak sudo cp /opt/ros/indigo/share/cv_bridge/cmake/cv_bridgeConfig.cmake /opt/ros/indigo/share/cv_bridge/cmake/cv_bridgeConfig.cmake-bak sudo cp /opt/ros/indigo/share/image_geometry/cmake/image_geometryConfig.cmake /opt/ros/indigo/share/image_geometry/cmake/image_geometryConfig.cmake-bak sudo gedit /opt/ros/indigo/lib/pkgconfig/cv_bridge.pc & sudo gedit /opt/ros/indigo/lib/pkgconfig/image_geometry.pc & sudo gedit /opt/ros/indigo/share/cv_bridge/cmake/cv_bridgeConfig.cmake & sudo gedit /opt/ros/indigo/share/image_geometry/cmake/image_geometryConfig.cmake &
Modifications for each file
- remove each instance “/usr/lib/arm-linux-gnueabihf/libopencv_ocl.so.2.4.8;“
- replace each instance of “/usr/lib/arm-linux-gnueabihf/” with “/usr/lib“
- replace each instance of “2.4.8” with “2.4.12” (or the current version of OpenCV in opencv4tegra package)
Finally you can compile your OpenCV based node without any error.
Modified files
Following the final configuration that each modified file should reflect:
prefix=/opt/ros/indigo Name: cv_bridge Description: Description of cv_bridge Version: 1.11.6 Cflags: -I/opt/ros/indigo/include -I/usr/include/opencv -I/usr/include Libs: -L/opt/ros/indigo/lib -lcv_bridge -l:/usr/lib/libopencv_videostab.so.2.4.12 -l:/usr/lib/libopencv_video.so.2.4.12 -l:/usr/lib/libopencv_superres.so.2.4.12 -l:/usr/lib/libopencv_stitching.so.2.4.12 -l:/usr/lib/libopencv_photo.so.2.4.12 -l:/usr/lib/libopencv_objdetect.so.2.4.12 -l:/usr/lib/libopencv_ml.so.2.4.12 -l:/usr/lib/libopencv_legacy.so.2.4.12 -l:/usr/lib/libopencv_imgproc.so.2.4.12 -l:/usr/lib/libopencv_highgui.so.2.4.12 -l:/usr/lib/libopencv_gpu.so.2.4.12 -l:/usr/lib/libopencv_flann.so.2.4.12 -l:/usr/lib/libopencv_features2d.so.2.4.12 -l:/usr/lib/libopencv_core.so.2.4.12 -l:/usr/lib/libopencv_contrib.so.2.4.12 -l:/usr/lib/libopencv_calib3d.so.2.4.12 Requires: rosconsole sensor_msgs
prefix=/opt/ros/indigo Name: image_geometry Description: Description of image_geometry Version: 1.11.6 Cflags: -I/opt/ros/indigo/include -I/usr/include/opencv -I/usr/include Libs: -L/opt/ros/indigo/lib -limage_geometry -l:/usr/lib/libopencv_videostab.so.2.4.12 -l:/usr/lib/libopencv_video.so.2.4.12 -l:/usr/lib/libopencv_superres.so.2.4.12 -l:/usr/lib/libopencv_stitching.so.2.4.12 -l:/usr/lib/libopencv_photo.so.2.4.12 -l:/usr/lib/libopencv_objdetect.so.2.4.12 -l:/usr/lib/libopencv_ml.so.2.4.12 -l:/usr/lib/libopencv_legacy.so.2.4.12 -l:/usr/lib/libopencv_imgproc.so.2.4.12 -l:/usr/lib/libopencv_highgui.so.2.4.12 -l:/usr/lib/libopencv_gpu.so.2.4.12 -l:/usr/lib/libopencv_flann.so.2.4.12 -l:/usr/lib/libopencv_features2d.so.2.4.12 -l:/usr/lib/libopencv_core.so.2.4.12 -l:/usr/lib/libopencv_contrib.so.2.4.12 -l:/usr/lib/libopencv_calib3d.so.2.4.12 Requires: sensor_msgs
# generated from catkin/cmake/template/pkgConfig.cmake.in # append elements to a list and remove existing duplicates from the list # copied from catkin/cmake/list_append_deduplicate.cmake to keep pkgConfig # self contained macro(_list_append_deduplicate listname) if(NOT "${ARGN}" STREQUAL "") if(${listname}) list(REMOVE_ITEM ${listname} ${ARGN}) endif() list(APPEND ${listname} ${ARGN}) endif() endmacro() # append elements to a list if they are not already in the list # copied from catkin/cmake/list_append_unique.cmake to keep pkgConfig # self contained macro(_list_append_unique listname) foreach(_item ${ARGN}) list(FIND ${listname} ${_item} _index) if(_index EQUAL -1) list(APPEND ${listname} ${_item}) endif() endforeach() endmacro() # pack a list of libraries with optional build configuration keywords # copied from catkin/cmake/catkin_libraries.cmake to keep pkgConfig # self contained macro(_pack_libraries_with_build_configuration VAR) set(${VAR} "") set(_argn ${ARGN}) list(LENGTH _argn _count) set(_index 0) while(${_index} LESS ${_count}) list(GET _argn ${_index} lib) if("${lib}" MATCHES "^debug|optimized|general$") math(EXPR _index "${_index} + 1") if(${_index} EQUAL ${_count}) message(FATAL_ERROR "_pack_libraries_with_build_configuration() the list of libraries '${ARGN}' ends with '${lib}' which is a build configuration keyword and must be followed by a library") endif() list(GET _argn ${_index} library) list(APPEND ${VAR} "${lib}${CATKIN_BUILD_CONFIGURATION_KEYWORD_SEPARATOR}${library}") else() list(APPEND ${VAR} "${lib}") endif() math(EXPR _index "${_index} + 1") endwhile() endmacro() # unpack a list of libraries with optional build configuration keyword prefixes # copied from catkin/cmake/catkin_libraries.cmake to keep pkgConfig # self contained macro(_unpack_libraries_with_build_configuration VAR) set(${VAR} "") foreach(lib ${ARGN}) string(REGEX REPLACE "^(debug|optimized|general)${CATKIN_BUILD_CONFIGURATION_KEYWORD_SEPARATOR}(.+)$" "\\1;\\2" lib "${lib}") list(APPEND ${VAR} "${lib}") endforeach() endmacro() if(cv_bridge_CONFIG_INCLUDED) return() endif() set(cv_bridge_CONFIG_INCLUDED TRUE) # set variables for source/devel/install prefixes if("FALSE" STREQUAL "TRUE") set(cv_bridge_SOURCE_PREFIX /tmp/buildd/ros-indigo-cv-bridge-1.11.6-0trusty-20141201-2058) set(cv_bridge_DEVEL_PREFIX /tmp/buildd/ros-indigo-cv-bridge-1.11.6-0trusty-20141201-2058/obj-arm-linux-gnueabihf/devel) set(cv_bridge_INSTALL_PREFIX "") set(cv_bridge_PREFIX ${cv_bridge_DEVEL_PREFIX}) else() set(cv_bridge_SOURCE_PREFIX "") set(cv_bridge_DEVEL_PREFIX "") set(cv_bridge_INSTALL_PREFIX /opt/ros/indigo) set(cv_bridge_PREFIX ${cv_bridge_INSTALL_PREFIX}) endif() # warn when using a deprecated package if(NOT "" STREQUAL "") set(_msg "WARNING: package 'cv_bridge' is deprecated") # append custom deprecation text if available if(NOT "" STREQUAL "TRUE") set(_msg "${_msg} ()") endif() message("${_msg}") endif() # flag project as catkin-based to distinguish if a find_package()-ed project is a catkin project set(cv_bridge_FOUND_CATKIN_PROJECT TRUE) if(NOT "include;/usr/include/opencv;/usr/include" STREQUAL "") set(cv_bridge_INCLUDE_DIRS "") set(_include_dirs "include;/usr/include/opencv;/usr/include") foreach(idir ${_include_dirs}) if(IS_ABSOLUTE ${idir} AND IS_DIRECTORY ${idir}) set(include ${idir}) elseif("${idir}" STREQUAL "include") get_filename_component(include "${cv_bridge_DIR}/../../../include" ABSOLUTE) if(NOT IS_DIRECTORY ${include}) message(FATAL_ERROR "Project 'cv_bridge' specifies '${idir}' as an include dir, which is not found. It does not exist in '${include}'. Ask the maintainer 'Vincent Rabaud <vincent.rabaud@gmail.com>' to fix it.") endif() else() message(FATAL_ERROR "Project 'cv_bridge' specifies '${idir}' as an include dir, which is not found. It does neither exist as an absolute directory nor in '/opt/ros/indigo/${idir}'. Ask the maintainer 'Vincent Rabaud <vincent.rabaud@gmail.com>' to fix it.") endif() _list_append_unique(cv_bridge_INCLUDE_DIRS ${include}) endforeach() endif() set(libraries "cv_bridge;/usr/lib/libopencv_videostab.so.2.4.12;/usr/lib/libopencv_video.so.2.4.12;/usr/lib/libopencv_superres.so.2.4.12;/usr/lib/libopencv_stitching.so.2.4.12;/usr/lib/libopencv_photo.so.2.4.12;/usr/lib/libopencv_objdetect.so.2.4.12;/usr/lib/libopencv_ml.so.2.4.12;/usr/lib/libopencv_legacy.so.2.4.12;/usr/lib/libopencv_imgproc.so.2.4.12;/usr/lib/libopencv_highgui.so.2.4.12;/usr/lib/libopencv_gpu.so.2.4.12;/usr/lib/libopencv_flann.so.2.4.12;/usr/lib/libopencv_features2d.so.2.4.12;/usr/lib/libopencv_core.so.2.4.12;/usr/lib/libopencv_contrib.so.2.4.12;/usr/lib/libopencv_calib3d.so.2.4.12") foreach(library ${libraries}) # keep build configuration keywords, target names and absolute libraries as-is if("${library}" MATCHES "^debug|optimized|general$") list(APPEND cv_bridge_LIBRARIES ${library}) elseif(TARGET ${library}) list(APPEND cv_bridge_LIBRARIES ${library}) elseif(IS_ABSOLUTE ${library}) list(APPEND cv_bridge_LIBRARIES ${library}) else() set(lib_path "") set(lib "${library}-NOTFOUND") # since the path where the library is found is returned we have to iterate over the paths manually foreach(path /opt/ros/indigo/lib;/opt/ros/indigo/lib) find_library(lib ${library} PATHS ${path} NO_DEFAULT_PATH NO_CMAKE_FIND_ROOT_PATH) if(lib) set(lib_path ${path}) break() endif() endforeach() if(lib) _list_append_unique(cv_bridge_LIBRARY_DIRS ${lib_path}) list(APPEND cv_bridge_LIBRARIES ${lib}) else() # as a fall back for non-catkin libraries try to search globally find_library(lib ${library}) if(NOT lib) message(FATAL_ERROR "Project '${PROJECT_NAME}' tried to find library '${library}'. The library is neither a target nor built/installed properly. Did you compile project 'cv_bridge'? Did you find_package() it before the subdirectory containing its code is included?") endif() list(APPEND cv_bridge_LIBRARIES ${lib}) endif() endif() endforeach() set(cv_bridge_EXPORTED_TARGETS "") # create dummy targets for exported code generation targets to make life of users easier foreach(t ${cv_bridge_EXPORTED_TARGETS}) if(NOT TARGET ${t}) add_custom_target(${t}) endif() endforeach() set(depends "rosconsole;sensor_msgs") foreach(depend ${depends}) string(REPLACE " " ";" depend_list ${depend}) # the package name of the dependency must be kept in a unique variable so that it is not overwritten in recursive calls list(GET depend_list 0 cv_bridge_dep) list(LENGTH depend_list count) if(${count} EQUAL 1) # simple dependencies must only be find_package()-ed once if(NOT ${cv_bridge_dep}_FOUND) find_package(${cv_bridge_dep} REQUIRED) endif() else() # dependencies with components must be find_package()-ed again list(REMOVE_AT depend_list 0) find_package(${cv_bridge_dep} REQUIRED ${depend_list}) endif() _list_append_unique(cv_bridge_INCLUDE_DIRS ${${cv_bridge_dep}_INCLUDE_DIRS}) # merge build configuration keywords with library names to correctly deduplicate _pack_libraries_with_build_configuration(cv_bridge_LIBRARIES ${cv_bridge_LIBRARIES}) _pack_libraries_with_build_configuration(_libraries ${${cv_bridge_dep}_LIBRARIES}) _list_append_deduplicate(cv_bridge_LIBRARIES ${_libraries}) # undo build configuration keyword merging after deduplication _unpack_libraries_with_build_configuration(cv_bridge_LIBRARIES ${cv_bridge_LIBRARIES}) _list_append_unique(cv_bridge_LIBRARY_DIRS ${${cv_bridge_dep}_LIBRARY_DIRS}) list(APPEND cv_bridge_EXPORTED_TARGETS ${${cv_bridge_dep}_EXPORTED_TARGETS}) endforeach() set(pkg_cfg_extras "") foreach(extra ${pkg_cfg_extras}) if(NOT IS_ABSOLUTE ${extra}) set(extra ${cv_bridge_DIR}/${extra}) endif() include(${extra}) endforeach()
# generated from catkin/cmake/template/pkgConfig.cmake.in # append elements to a list and remove existing duplicates from the list # copied from catkin/cmake/list_append_deduplicate.cmake to keep pkgConfig # self contained macro(_list_append_deduplicate listname) if(NOT "${ARGN}" STREQUAL "") if(${listname}) list(REMOVE_ITEM ${listname} ${ARGN}) endif() list(APPEND ${listname} ${ARGN}) endif() endmacro() # append elements to a list if they are not already in the list # copied from catkin/cmake/list_append_unique.cmake to keep pkgConfig # self contained macro(_list_append_unique listname) foreach(_item ${ARGN}) list(FIND ${listname} ${_item} _index) if(_index EQUAL -1) list(APPEND ${listname} ${_item}) endif() endforeach() endmacro() # pack a list of libraries with optional build configuration keywords # copied from catkin/cmake/catkin_libraries.cmake to keep pkgConfig # self contained macro(_pack_libraries_with_build_configuration VAR) set(${VAR} "") set(_argn ${ARGN}) list(LENGTH _argn _count) set(_index 0) while(${_index} LESS ${_count}) list(GET _argn ${_index} lib) if("${lib}" MATCHES "^debug|optimized|general$") math(EXPR _index "${_index} + 1") if(${_index} EQUAL ${_count}) message(FATAL_ERROR "_pack_libraries_with_build_configuration() the list of libraries '${ARGN}' ends with '${lib}' which is a build configuration keyword and must be followed by a library") endif() list(GET _argn ${_index} library) list(APPEND ${VAR} "${lib}${CATKIN_BUILD_CONFIGURATION_KEYWORD_SEPARATOR}${library}") else() list(APPEND ${VAR} "${lib}") endif() math(EXPR _index "${_index} + 1") endwhile() endmacro() # unpack a list of libraries with optional build configuration keyword prefixes # copied from catkin/cmake/catkin_libraries.cmake to keep pkgConfig # self contained macro(_unpack_libraries_with_build_configuration VAR) set(${VAR} "") foreach(lib ${ARGN}) string(REGEX REPLACE "^(debug|optimized|general)${CATKIN_BUILD_CONFIGURATION_KEYWORD_SEPARATOR}(.+)$" "\\1;\\2" lib "${lib}") list(APPEND ${VAR} "${lib}") endforeach() endmacro() if(image_geometry_CONFIG_INCLUDED) return() endif() set(image_geometry_CONFIG_INCLUDED TRUE) # set variables for source/devel/install prefixes if("FALSE" STREQUAL "TRUE") set(image_geometry_SOURCE_PREFIX /tmp/buildd/ros-indigo-image-geometry-1.11.6-0trusty-20141201-2057) set(image_geometry_DEVEL_PREFIX /tmp/buildd/ros-indigo-image-geometry-1.11.6-0trusty-20141201-2057/obj-arm-linux-gnueabihf/devel) set(image_geometry_INSTALL_PREFIX "") set(image_geometry_PREFIX ${image_geometry_DEVEL_PREFIX}) else() set(image_geometry_SOURCE_PREFIX "") set(image_geometry_DEVEL_PREFIX "") set(image_geometry_INSTALL_PREFIX /opt/ros/indigo) set(image_geometry_PREFIX ${image_geometry_INSTALL_PREFIX}) endif() # warn when using a deprecated package if(NOT "" STREQUAL "") set(_msg "WARNING: package 'image_geometry' is deprecated") # append custom deprecation text if available if(NOT "" STREQUAL "TRUE") set(_msg "${_msg} ()") endif() message("${_msg}") endif() # flag project as catkin-based to distinguish if a find_package()-ed project is a catkin project set(image_geometry_FOUND_CATKIN_PROJECT TRUE) if(NOT "include;/usr/include/opencv;/usr/include" STREQUAL "") set(image_geometry_INCLUDE_DIRS "") set(_include_dirs "include;/usr/include/opencv;/usr/include") foreach(idir ${_include_dirs}) if(IS_ABSOLUTE ${idir} AND IS_DIRECTORY ${idir}) set(include ${idir}) elseif("${idir}" STREQUAL "include") get_filename_component(include "${image_geometry_DIR}/../../../include" ABSOLUTE) if(NOT IS_DIRECTORY ${include}) message(FATAL_ERROR "Project 'image_geometry' specifies '${idir}' as an include dir, which is not found. It does not exist in '${include}'. Ask the maintainer 'Vincent Rabaud <vincent.rabaud@gmail.com>' to fix it.") endif() else() message(FATAL_ERROR "Project 'image_geometry' specifies '${idir}' as an include dir, which is not found. It does neither exist as an absolute directory nor in '/opt/ros/indigo/${idir}'. Ask the maintainer 'Vincent Rabaud <vincent.rabaud@gmail.com>' to fix it.") endif() _list_append_unique(image_geometry_INCLUDE_DIRS ${include}) endforeach() endif() set(libraries "image_geometry;/usr/lib/libopencv_videostab.so.2.4.12;/usr/lib/libopencv_video.so.2.4.12;/usr/lib/libopencv_superres.so.2.4.12;/usr/lib/libopencv_stitching.so.2.4.12;/usr/lib/libopencv_photo.so.2.4.12;/usr/lib/libopencv_objdetect.so.2.4.12;/usr/lib/libopencv_ml.so.2.4.12;/usr/lib/libopencv_legacy.so.2.4.12;/usr/lib/libopencv_imgproc.so.2.4.12;/usr/lib/libopencv_highgui.so.2.4.12;/usr/lib/libopencv_gpu.so.2.4.12;/usr/lib/libopencv_flann.so.2.4.12;/usr/lib/libopencv_features2d.so.2.4.12;/usr/lib/libopencv_core.so.2.4.12;/usr/lib/libopencv_contrib.so.2.4.12;/usr/lib/libopencv_calib3d.so.2.4.12") foreach(library ${libraries}) # keep build configuration keywords, target names and absolute libraries as-is if("${library}" MATCHES "^debug|optimized|general$") list(APPEND image_geometry_LIBRARIES ${library}) elseif(TARGET ${library}) list(APPEND image_geometry_LIBRARIES ${library}) elseif(IS_ABSOLUTE ${library}) list(APPEND image_geometry_LIBRARIES ${library}) else() set(lib_path "") set(lib "${library}-NOTFOUND") # since the path where the library is found is returned we have to iterate over the paths manually foreach(path /opt/ros/indigo/lib;/opt/ros/indigo/lib) find_library(lib ${library} PATHS ${path} NO_DEFAULT_PATH NO_CMAKE_FIND_ROOT_PATH) if(lib) set(lib_path ${path}) break() endif() endforeach() if(lib) _list_append_unique(image_geometry_LIBRARY_DIRS ${lib_path}) list(APPEND image_geometry_LIBRARIES ${lib}) else() # as a fall back for non-catkin libraries try to search globally find_library(lib ${library}) if(NOT lib) message(FATAL_ERROR "Project '${PROJECT_NAME}' tried to find library '${library}'. The library is neither a target nor built/installed properly. Did you compile project 'image_geometry'? Did you find_package() it before the subdirectory containing its code is included?") endif() list(APPEND image_geometry_LIBRARIES ${lib}) endif() endif() endforeach() set(image_geometry_EXPORTED_TARGETS "") # create dummy targets for exported code generation targets to make life of users easier foreach(t ${image_geometry_EXPORTED_TARGETS}) if(NOT TARGET ${t}) add_custom_target(${t}) endif() endforeach() set(depends "sensor_msgs") foreach(depend ${depends}) string(REPLACE " " ";" depend_list ${depend}) # the package name of the dependency must be kept in a unique variable so that it is not overwritten in recursive calls list(GET depend_list 0 image_geometry_dep) list(LENGTH depend_list count) if(${count} EQUAL 1) # simple dependencies must only be find_package()-ed once if(NOT ${image_geometry_dep}_FOUND) find_package(${image_geometry_dep} REQUIRED) endif() else() # dependencies with components must be find_package()-ed again list(REMOVE_AT depend_list 0) find_package(${image_geometry_dep} REQUIRED ${depend_list}) endif() _list_append_unique(image_geometry_INCLUDE_DIRS ${${image_geometry_dep}_INCLUDE_DIRS}) # merge build configuration keywords with library names to correctly deduplicate _pack_libraries_with_build_configuration(image_geometry_LIBRARIES ${image_geometry_LIBRARIES}) _pack_libraries_with_build_configuration(_libraries ${${image_geometry_dep}_LIBRARIES}) _list_append_deduplicate(image_geometry_LIBRARIES ${_libraries}) # undo build configuration keyword merging after deduplication _unpack_libraries_with_build_configuration(image_geometry_LIBRARIES ${image_geometry_LIBRARIES}) _list_append_unique(image_geometry_LIBRARY_DIRS ${${image_geometry_dep}_LIBRARY_DIRS}) list(APPEND image_geometry_EXPORTED_TARGETS ${${image_geometry_dep}_EXPORTED_TARGETS}) endforeach() set(pkg_cfg_extras "") foreach(extra ${pkg_cfg_extras}) if(NOT IS_ABSOLUTE ${extra}) set(extra ${image_geometry_DIR}/${extra}) endif() include(${extra}) endforeach()