stonier/sophus

Not finding Sophus in Eloquent

Closed this issue · 5 comments

I have installed with sudo apt install ros-eloquent-sophus.
Does not work with dashing either.

I am getting this compiler error:

/home/martin/ros2_ws/src/acrobat_packages/acrobat_common/include/acrobat_common/geometry/lie_groups.hpp:4:10: fatal error: 'sophus/se3.hpp' file not found
#include <sophus/se3.hpp>
         ^~~~~~~~~~~~~~~~

In my package.xml

  <build_depend>Sophus</build_depend>

In my CMakeLists.txt

# find dependencies
find_package(ament_cmake REQUIRED)
find_package(Sophus REQUIRED)

add_library(${PROJECT_NAME} src/maffs.cpp)
target_include_directories(${PROJECT_NAME}
  PUBLIC
  "$<BUILD_INTERFACE:${CMAKE_CURRENT_SOURCE_DIR}/include>"
  "$<INSTALL_INTERFACE:include>"
)

ament_target_dependencies(${PROJECT_NAME} Sophus)

There is a problem with ament_target_dependencies - it can't handle modern CMake3 style imported targets. See ament/ament_cmake#178 and ament/ament_cmake#183.

You'll have to do this CMake style, which is actually little pain because the problems ament_target_dependencies is trying to solve by aggregating many variables together is also solved by CMake3 imported targets.

You'll need to link it in with target_link_libraries, e.g.

target_link_libraries(
  ${PROJECT_NAME}
  PUBLIC
    Sophus::Sophus
)

An actual example here: https://github.com/stonier/ecl_core/blob/c2a2326c55acc948dad2c9b3ff60181ebd54724d/ecl_linear_algebra/src/lib/CMakeLists.txt#L20-L28

Sorry for the late response.

I tried this, but it doesn't work. I am also having trouble including tf2_geometry_msgs. However, I was able to compile ecl_core so I'm not sure what is different. I will post everything which will maybe expose the problem.

The error:

In file included from /home/martin/ros2_ws/src/acrobat_packages/acrobat_common/include/acrobat_common/lie_groups/lie_group_conversions.hpp:3:0,
                 from /home/martin/ros2_ws/src/acrobat_packages/acrobat_common/tests/lie_group_conversions_test.cpp:3:
/home/martin/ros2_ws/src/acrobat_packages/acrobat_common/include/acrobat_common/lie_groups/lie_groups.hpp:3:10: fatal error: sophus/se3.hpp: No such file or directory
 #include <sophus/se3.hpp>
          ^~~~~~~~~~~~~~~~
compilation terminated.

CMakeLists.txt:

cmake_minimum_required(VERSION 3.5)
project(acrobat_common)

# Default to C99
if(NOT CMAKE_C_STANDARD)
  set(CMAKE_C_STANDARD 99)
endif()

# Default to C++17
if(NOT CMAKE_CXX_STANDARD)
  set(CMAKE_CXX_STANDARD 17)
endif()

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

# find dependencies
find_package(ament_cmake REQUIRED)
find_package(Sophus REQUIRED)
find_package(tf2_geometry_msgs REQUIRED)

include_directories(include)

add_library(${PROJECT_NAME} SHARED 

  # Lie groups
  src/lie_groups/lie_groups.cpp
  src/lie_groups/lie_group_conversions.cpp

)

target_include_directories(
  ${PROJECT_NAME}
  INTERFACE
    $<BUILD_INTERFACE:${PROJECT_SOURCE_DIR}/include>
    $<INSTALL_INTERFACE:include>
)

target_link_libraries(
  ${PROJECT_NAME}
  PUBLIC
    Sophus::Sophus
)

ament_export_interfaces(export_${PROJECT_NAME} HAS_LIBRARY_TARGET)
ament_export_libraries(${PROJECT_NAME})
ament_export_include_directories(include)

if(BUILD_TESTING)
  find_package(ament_lint_auto REQUIRED)
  find_package(ament_cmake_gtest REQUIRED)

  ament_lint_auto_find_test_dependencies()
  # the following line skips the linter which checks for copyrights
  # uncomment the line when a copyright and license is not present in all source files
  #set(ament_cmake_copyright_FOUND TRUE)
  # the following line skips cpplint (only works in a git repo)
  # uncomment the line when this package is not in a git repo
  #set(ament_cmake_cpplint_FOUND TRUE)
  ament_add_gtest(${PROJECT_NAME}_lie_group_conversions_test tests/lie_group_conversions_test.cpp)

endif()

install(
  DIRECTORY include/
  DESTINATION include
)

install(
  TARGETS ${PROJECT_NAME}
  EXPORT export_${PROJECT_NAME}
  LIBRARY DESTINATION lib
  ARCHIVE DESTINATION lib
  RUNTIME DESTINATION bin
  INCLUDES DESTINATION include
)

ament_package()

lie_groups.hpp:

#pragma once

#include <sophus/se3.hpp>
#include <sophus/sim3.hpp>
#include <sophus/so3.hpp>

#include <acrobat_common/math/math_defines.hpp>

namespace acrobat::lie_groups {

using Scalar = math::Scalar;

using Vector3    = Eigen::Matrix<Scalar, 3, 1>;
using Quaternion = Eigen::Quaternion<Scalar>;

using SO3  = Sophus::SO3<Scalar>;
using SE3  = Sophus::SE3<Scalar>;
using SIM3 = Sophus::Sim3<Scalar>;

} // namespace acrobat::lie_groups

package.xml (I'm still not sure if this matters other than building packages in order)

<?xml version="1.0"?>
<?xml-model href="http://download.ros.org/schema/package_format3.xsd" schematypens="http://www.w3.org/2001/XMLSchema"?>
<package format="3">
  <name>acrobat_common</name>
  <version>0.0.0</version>
  <description>TODO: Package description</description>
  <maintainer email="mdeegan@umich.edu">martin</maintainer>
  <license>TODO: License declaration</license>

  <depend>sophus</depend>
  <build_depend>tf2_geometry_msgs</build_depend>
  <exec_depend>tf2_geometry_msgs</exec_depend>

  <buildtool_depend>ament_cmake</buildtool_depend>

  <test_depend>ament_lint_auto</test_depend>
  <test_depend>ament_lint_common</test_depend>
  <test_depend>ament_cmake_gtest</test_depend>

  <export>
    <build_type>ament_cmake</build_type>
  </export>
</package>

I figured it out while writing that. I had an extra include_directories(include).

I think I will abandon ament_cmake and just use cmake because ament_target_dependencies doesn't seem to work with target_link_libraries.

Huh. I wouldn't have guessed that would have caused it to make Sophus go awol.

You should still be able to use ament_cmake with ament_target_dependencies. I have a colleague who brings all the old style cmake ros dependencies to a target via ament_target_dependencies and then brings the modern cmake / cmake-ros dependencies via target_link_libraries and it works fine.

Yup you are right, you can use both. However, ament_target_dependencies uses target_link_libraries without a PUBLIC, PRIVATE, or INTERFACE keyword which means you can't link with a keyword either. Slightly annoying, but not a big deal...

Just for documentations sake here is my final CMakeLists.txt:

# find system dependencies
find_package(ament_cmake REQUIRED)
find_package(Sophus REQUIRED)
find_package(tf2_geometry_msgs REQUIRED)

# find project dependencies
find_package(project_settings REQUIRED)

add_library(
  acrobat_common SHARED
  # Lie groups
  src/lie_groups/lie_group_conversions.cpp src/lie_groups/lie_groups.cpp)

target_include_directories(acrobat_common PUBLIC "$<BUILD_INTERFACE:${CMAKE_CURRENT_SOURCE_DIR}/include>"
                                                 "$<INSTALL_INTERFACE:include>")

ament_target_dependencies(acrobat_common "project_settings" "tf2_geometry_msgs")
target_link_libraries(acrobat_common Sophus::Sophus)

ament_export_include_directories(include)
ament_export_libraries(acrobat_common)
ament_export_dependencies(Sophus tf2_geometry_msgs)
ament_export_interfaces(export_acrobat_common HAS_LIBRARY_TARGET)

install(DIRECTORY include/ DESTINATION include)

install(
  TARGETS acrobat_common
  EXPORT export_acrobat_common
  RUNTIME DESTINATION bin
  LIBRARY DESTINATION lib
  ARCHIVE DESTINATION lib
  INCLUDES
  DESTINATION include)

if(BUILD_TESTING)
  add_subdirectory(test)
endif()

ament_package()