ANYbotics / signal_logger

BSD 3-Clause "New" or "Revised" License
3 stars 7 forks source link

Signal logger does not compile with Eigen 3.4.0 log elements #3

Closed simonkerscher closed 3 years ago

simonkerscher commented 3 years ago

I have added the following lines to reproduce this issue:

git diff
diff --git a/signal_logger_example/include/signal_logger_example/SignalLoggerExample.hpp b/signal_logger_example/include/signal_logger_example/SignalLoggerExample.hpp
index da04d4b..fa30680 100644
--- a/signal_logger_example/include/signal_logger_example/SignalLoggerExample.hpp
+++ b/signal_logger_example/include/signal_logger_example/SignalLoggerExample.hpp
@@ -32,6 +32,8 @@
 #include <signal.h>
 #include <stdlib.h>

+#include <Eigen/Core>
+
 namespace signal_logger_example {

 class SignalLoggerExample: public any_node::Node
@@ -62,6 +64,7 @@ class SignalLoggerExample: public any_node::Node
     std::pair<std::string, double> pair_;
     std::map<std::string, int> map_;
     std::unordered_map<int, double> umap_;
+    Eigen::Matrix<double, 25, 1> eigen_;

 };

diff --git a/signal_logger_example/src/SignalLoggerExample.cpp b/signal_logger_example/src/SignalLoggerExample.cpp
index a32329c..20ba3e3 100644
--- a/signal_logger_example/src/SignalLoggerExample.cpp
+++ b/signal_logger_example/src/SignalLoggerExample.cpp
@@ -62,6 +62,7 @@ bool SignalLoggerExample::init()
   signal_logger::add(pair_, "pair", "nsSTL");
   signal_logger::add(map_, "map", "nsSTL");
   signal_logger::add(umap_, "unorderedMap", "nsSTL");
+  signal_logger::add(eigen_, "eigen", "nsSTL");

   // Call update logger, this loads the variables from the siloOptions.collectScriptFileName_ file.
   signal_logger::logger->updateLogger();

When building signal_logger_example with Eigen 3.3.7, there is no issue. When building signal_logger_example with Eigen 3.4.0, we get the following error message:

rrors     << signal_logger_example:make /home/catkin_ws/logs/signal_logger_example/build.make.000.log
In file included from /home/catkin_ws/src/signal_logger/signal_logger_ros/include/signal_logger_ros/SignalLoggerRos.hpp:13,
                 from /home/catkin_ws/src/signal_logger/signal_logger/include/signal_logger/signal_logger.hpp:17,
                 from /home/catkin_ws/src/signal_logger/signal_logger_example/include/signal_logger_example/SignalLoggerExample.hpp:13,
                 from /home/catkin_ws/src/signal_logger/signal_logger_example/src/SignalLoggerExample.cpp:8:
/home/catkin_ws/src/signal_logger/signal_logger_ros/include/signal_logger_ros/LogElementRos.hpp: In instantiation of ‘class signal_logger_ros::LogElementRos<Eigen::Matrix<double, 25, 1> >’:
/home/catkin_ws/src/signal_logger/signal_logger_ros/include/signal_logger_ros/SignalLoggerRos.hpp:68:44:   required from ‘void signal_logger_ros::SignalLoggerRos::add(const ValueType_*, const string&, const string&, const string&, std::size_t, signal_logger::LogElementAction, std::size_t, signal_logger::BufferType) [with ValueType_ = Eigen::Matrix<double, 25, 1>; std::string = std::__cxx11::basic_string<char>; std::size_t = long unsigned int]’
/home/catkin_ws/src/signal_logger/signal_logger/include/signal_logger/signal_logger.hpp:72:9:   required from ‘void signal_logger::add(const ValueType_&, const string&, const string&, const string&, std::size_t, signal_logger::LogElementAction, std::size_t, signal_logger::BufferType) [with ValueType_ = Eigen::Matrix<double, 25, 1>; std::string = std::__cxx11::basic_string<char>; std::size_t = long unsigned int]’
/home/catkin_ws/src/signal_logger/signal_logger_example/src/SignalLoggerExample.cpp:65:46:   required from here
/home/catkin_ws/src/signal_logger/signal_logger_ros/include/signal_logger_ros/LogElementRos.hpp:31:9: error: ambiguous template instantiation for ‘struct signal_logger_ros::traits::slr_msg_traits<Eigen::Matrix<double, 25, 1>, void>’
   31 |   using MsgType = typename traits::slr_msg_traits<ValueType_>::msgtype;
      |         ^~~~~~~
In file included from /home/catkin_ws/src/signal_logger/signal_logger_ros/include/signal_logger_ros/LogElementRos.hpp:12,
                 from /home/catkin_ws/src/signal_logger/signal_logger_ros/include/signal_logger_ros/SignalLoggerRos.hpp:13,
                 from /home/catkin_ws/src/signal_logger/signal_logger/include/signal_logger/signal_logger.hpp:17,
                 from /home/catkin_ws/src/signal_logger/signal_logger_example/include/signal_logger_example/SignalLoggerExample.hpp:13,
                 from /home/catkin_ws/src/signal_logger/signal_logger_example/src/SignalLoggerExample.cpp:8:
/home/catkin_ws/src/signal_logger/signal_logger_ros/include/signal_logger_ros/signal_logger_ros_traits.hpp:178:8: note: candidates are: ‘template<class ValueType_> struct signal_logger_ros::traits::slr_msg_traits<ValueType_, typename std::enable_if<(signal_logger::traits::is_container<T>::value && std::is_same<double, typename std::remove_cv<typename std::remove_reference<decltype (* std::begin(declval<T&>()))>::type>::type>::value)>::type> [with ValueType_ = Eigen::Matrix<double, 25, 1>]’
  178 | struct slr_msg_traits<ValueType_, typename std::enable_if<is_container<ValueType_>::value &&
      |        ^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
  179 |     std::is_same<double, element_type_t<ValueType_>>::value>::type> {
      |     ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
/home/catkin_ws/src/signal_logger/signal_logger_ros/include/signal_logger_ros/signal_logger_ros_traits.hpp:258:8: note:                 ‘template<class ValueType_> struct signal_logger_ros::traits::slr_msg_traits<ValueType_, typename std::enable_if<signal_logger::traits::is_eigen_matrix_of_scalar_excluding_vector3<ValueType_, double>::value>::type> [with ValueType_ = Eigen::Matrix<double, 25, 1>]’
  258 | struct slr_msg_traits<
      |        ^~~~~~~~~~~~~~~
  259 |     ValueType_, typename std::enable_if<is_eigen_matrix_of_scalar_excluding_vector3<ValueType_, double>::value>::type> {
      |     ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
In file included from /home/catkin_ws/src/signal_logger/signal_logger_ros/include/signal_logger_ros/SignalLoggerRos.hpp:13,
                 from /home/catkin_ws/src/signal_logger/signal_logger/include/signal_logger/signal_logger.hpp:17,
                 from /home/catkin_ws/src/signal_logger/signal_logger_example/include/signal_logger_example/SignalLoggerExample.hpp:13,
                 from /home/catkin_ws/src/signal_logger/signal_logger_example/src/SignalLoggerExample.cpp:8:
/home/catkin_ws/src/signal_logger/signal_logger_ros/include/signal_logger_ros/LogElementRos.hpp:31:9: error: invalid use of incomplete type ‘struct signal_logger_ros::traits::slr_msg_traits<Eigen::Matrix<double, 25, 1>, void>’
   31 |   using MsgType = typename traits::slr_msg_traits<ValueType_>::msgtype;
      |         ^~~~~~~
In file included from /home/catkin_ws/src/signal_logger/signal_logger_ros/include/signal_logger_ros/LogElementRos.hpp:12,
                 from /home/catkin_ws/src/signal_logger/signal_logger_ros/include/signal_logger_ros/SignalLoggerRos.hpp:13,
                 from /home/catkin_ws/src/signal_logger/signal_logger/include/signal_logger/signal_logger.hpp:17,
                 from /home/catkin_ws/src/signal_logger/signal_logger_example/include/signal_logger_example/SignalLoggerExample.hpp:13,
                 from /home/catkin_ws/src/signal_logger/signal_logger_example/src/SignalLoggerExample.cpp:8:
/home/catkin_ws/src/signal_logger/signal_logger_ros/include/signal_logger_ros/signal_logger_ros_traits.hpp:65:8: note: declaration of ‘struct signal_logger_ros::traits::slr_msg_traits<Eigen::Matrix<double, 25, 1>, void>’
   65 | struct slr_msg_traits;
      |        ^~~~~~~~~~~~~~
In file included from /home/catkin_ws/src/signal_logger/signal_logger_ros/include/signal_logger_ros/SignalLoggerRos.hpp:13,
                 from /home/catkin_ws/src/signal_logger/signal_logger/include/signal_logger/signal_logger.hpp:17,
                 from /home/catkin_ws/src/signal_logger/signal_logger_example/include/signal_logger_example/SignalLoggerExample.hpp:13,
                 from /home/catkin_ws/src/signal_logger/signal_logger_example/src/SignalLoggerExample.cpp:8:
/home/catkin_ws/src/signal_logger/signal_logger_ros/include/signal_logger_ros/LogElementRos.hpp:32:9: error: invalid use of incomplete type ‘struct signal_logger_ros::traits::slr_msg_traits<Eigen::Matrix<double, 25, 1>, void>’
   32 |   using MsgTypePtr = boost::shared_ptr<MsgType>;
      |         ^~~~~~~~~~
In file included from /home/catkin_ws/src/signal_logger/signal_logger_ros/include/signal_logger_ros/LogElementRos.hpp:12,
                 from /home/catkin_ws/src/signal_logger/signal_logger_ros/include/signal_logger_ros/SignalLoggerRos.hpp:13,
                 from /home/catkin_ws/src/signal_logger/signal_logger/include/signal_logger/signal_logger.hpp:17,
                 from /home/catkin_ws/src/signal_logger/signal_logger_example/include/signal_logger_example/SignalLoggerExample.hpp:13,
                 from /home/catkin_ws/src/signal_logger/signal_logger_example/src/SignalLoggerExample.cpp:8:
/home/catkin_ws/src/signal_logger/signal_logger_ros/include/signal_logger_ros/signal_logger_ros_traits.hpp:65:8: note: declaration of ‘struct signal_logger_ros::traits::slr_msg_traits<Eigen::Matrix<double, 25, 1>, void>’
   65 | struct slr_msg_traits;
      |        ^~~~~~~~~~~~~~
In file included from /home/catkin_ws/src/signal_logger/signal_logger_std/include/signal_logger_std/SignalLoggerStd.hpp:13,
                 from /home/catkin_ws/src/signal_logger/signal_logger_ros/include/signal_logger_ros/SignalLoggerRos.hpp:12,
                 from /home/catkin_ws/src/signal_logger/signal_logger/include/signal_logger/signal_logger.hpp:17,
                 from /home/catkin_ws/src/signal_logger/signal_logger_example/include/signal_logger_example/SignalLoggerExample.hpp:13,
                 from /home/catkin_ws/src/signal_logger/signal_logger_example/src/SignalLoggerExample.cpp:8:
/home/catkin_ws/src/signal_logger/signal_logger_std/include/signal_logger_std/LogElementStd.hpp: In instantiation of ‘void signal_logger_std::LogElementStd<ValueType_>::saveDataToLogFile(const TimeElement&, unsigned int, signal_logger::LogFileType) [with ValueType_ = Eigen::Matrix<double, 25, 1>; signal_logger::TimeElement = signal_logger::LogElementBase<std::pair<long int, long int> >]’:
/home/catkin_ws/src/signal_logger/signal_logger_std/include/signal_logger_std/LogElementStd.hpp:58:8:   required from here
/home/catkin_ws/src/signal_logger/signal_logger_std/include/signal_logger_std/LogElementStd.hpp:79:94: error: ambiguous template instantiation for ‘struct signal_logger_std::traits::sls_traits<Eigen::Matrix<double, 25, 1>, Eigen::Matrix<double, 25, 1>, void>’
   79 |       signal_logger_std::traits::sls_traits<ValueType_, ValueType_>::writeLogElementToStreams(
      |       ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~^
   80 |           textStream_, binaryStream_, type, this->bufferCopy_, this->optionsCopy_.getName(), this->optionsCopy_.getDivider(), startDiff, endDiff);
      |           ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
In file included from /home/catkin_ws/src/signal_logger/signal_logger_std/include/signal_logger_std/LogElementStd.hpp:12,
                 from /home/catkin_ws/src/signal_logger/signal_logger_std/include/signal_logger_std/SignalLoggerStd.hpp:13,
                 from /home/catkin_ws/src/signal_logger/signal_logger_ros/include/signal_logger_ros/SignalLoggerRos.hpp:12,
                 from /home/catkin_ws/src/signal_logger/signal_logger/include/signal_logger/signal_logger.hpp:17,
                 from /home/catkin_ws/src/signal_logger/signal_logger_example/include/signal_logger_example/SignalLoggerExample.hpp:13,
                 from /home/catkin_ws/src/signal_logger/signal_logger_example/src/SignalLoggerExample.cpp:8:
/home/catkin_ws/src/signal_logger/signal_logger_std/include/signal_logger_std/signal_logger_std_traits.hpp:266:8: note: candidates are: ‘template<class ValueType_, class ContainerType_> struct signal_logger_std::traits::sls_traits<ValueType_, ContainerType_, typename std::enable_if<(signal_logger::traits::is_container<T>::value && (std::is_arithmetic<typename std::remove_cv<typename std::remove_reference<decltype (* std::begin(declval<T&>()))>::type>::type>::value || signal_logger::traits::is_pair<typename std::remove_cv<typename std::remove_reference<decltype (* std::begin(declval<T&>()))>::type>::type>::value))>::type> [with ValueType_ = Eigen::Matrix<double, 25, 1>; ContainerType_ = Eigen::Matrix<double, 25, 1>]’
  266 | struct sls_traits<ValueType_, ContainerType_, typename std::enable_if<is_container<ValueType_>::value &&
      |        ^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
  267 | (std::is_arithmetic<element_type_t<ValueType_>>::value || is_pair<element_type_t<ValueType_>>::value) >::type>
      | ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
/home/catkin_ws/src/signal_logger/signal_logger_std/include/signal_logger_std/signal_logger_std_traits.hpp:377:8: note:                 ‘template<class ValueType_, class ContainerType_> struct signal_logger_std::traits::sls_traits<ValueType_, ContainerType_, typename std::enable_if<signal_logger::traits::is_eigen_matrix_excluding_vector3<ValueType_>::value>::type> [with ValueType_ = Eigen::Matrix<double, 25, 1>; ContainerType_ = Eigen::Matrix<double, 25, 1>]’
  377 | struct sls_traits<ValueType_, ContainerType_, typename std::enable_if< is_eigen_matrix_excluding_vector3<ValueType_>::value >::type>
      |        ^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
In file included from /home/catkin_ws/src/signal_logger/signal_logger_std/include/signal_logger_std/SignalLoggerStd.hpp:13,
                 from /home/catkin_ws/src/signal_logger/signal_logger_ros/include/signal_logger_ros/SignalLoggerRos.hpp:12,
                 from /home/catkin_ws/src/signal_logger/signal_logger/include/signal_logger/signal_logger.hpp:17,
                 from /home/catkin_ws/src/signal_logger/signal_logger_example/include/signal_logger_example/SignalLoggerExample.hpp:13,
                 from /home/catkin_ws/src/signal_logger/signal_logger_example/src/SignalLoggerExample.cpp:8:
/home/catkin_ws/src/signal_logger/signal_logger_std/include/signal_logger_std/LogElementStd.hpp:79:94: error: incomplete type ‘signal_logger_std::traits::sls_traits<Eigen::Matrix<double, 25, 1>, Eigen::Matrix<double, 25, 1>, void>’ used in nested name specifier
   79 |       signal_logger_std::traits::sls_traits<ValueType_, ValueType_>::writeLogElementToStreams(
      |       ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~^
   80 |           textStream_, binaryStream_, type, this->bufferCopy_, this->optionsCopy_.getName(), this->optionsCopy_.getDivider(), startDiff, endDiff);
      |           ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
make[2]: *** [CMakeFiles/signal_logger_example.dir/build.make:63: CMakeFiles/signal_logger_example.dir/src/SignalLoggerExample.cpp.o] Error 1
make[1]: *** [CMakeFiles/Makefile2:221: CMakeFiles/signal_logger_example.dir/all] Error 2
make: *** [Makefile:141: all] Error 2
cd /home/catkin_ws/build/signal_logger_example; catkin build --get-env signal_logger_example | catkin env -si  /usr/bin/make --jobserver-auth=3,4; cd -

The compiler is gcc 9.3.0 on Ubuntu 20.04 with ROS Noetic installed, accessed through catkin build

remod commented 3 years ago

Hi @simonkerscher !

Thanks for creating this issue.

I am afraid we are currently only supporting the default version on 20.04, which is 3.3.7. If you have an idea how to fix it, it would be great if you could create a PR!

Tagging the maintainers @pleemann and @hogabrie so they know that there might be a breaking change soon.

hogabrie commented 3 years ago

Signal logger uses traits to identify the types.

With Eigen 3.3.* the matrix types only match: is_eigen_matrix_of_scalar_excluding_vector3

With Eigen 3.4.* the matrix types match: is_eigen_matrix_of_scalar_excluding_vector3 is_container

The reason is that Eigen 3.4.* adds a begin() and end() operators (https://gitlab.com/libeigen/eigen/-/blob/3.4/Eigen/src/Core/DenseBase.h#L647) that are used to identify whether something is a container.

You could try to update the is_container trait: https://github.com/ANYbotics/signal_logger/blob/d121faab4c9d02b09a3a573e6e70a289b230dac2/signal_logger_core/include/signal_logger_core/signal_logger_traits.hpp#L107

with:

template <typename T>
struct is_container
{
  static const bool value = has_const_iterator<T>::value && !std::is_same<std::string, typename std::remove_cv<T>::type>::value &&
          !std::is_base_of<Eigen::EigenBase<T>, T> && has_begin_end<T>::beg_value && has_begin_end<T>::end_value;
};

As @remod points out, we do not support eigen 3.4, so I can not really help you more than that :)

simonkerscher commented 3 years ago

Gabriel's suggestion works after the inclusion of ::value, leading to

template <typename T>
struct is_container
{
  static const bool value = has_const_iterator<T>::value && !std::is_same<std::string, typename std::remove_cv<T>::type>::value &&
          !std::is_base_of<Eigen::EigenBase<T>, T>::value && has_begin_end<T>::beg_value && has_begin_end<T>::end_value;
};

I have made a PR for this change on our leggedrobotics fork, see https://github.com/ANYbotics/signal_logger/compare/master...leggedrobotics:fix/eigen3.4.0