robotology / idyntree

Multibody Dynamics Library designed for Free Floating Robots
BSD 3-Clause "New" or "Revised" License
175 stars 67 forks source link

Unable to use matrix view with Eigen::Ref and Eigen::Map #797

Closed GiulioRomualdi closed 3 years ago

GiulioRomualdi commented 3 years ago

If I try to compile the these lines

     iDynTree::MatrixDynSize a;
     m_kinDyn->getFrameFreeFloatingJacobian(m_frameIndex,
                                            iDynTree::toEigen(a));

the following error is thrown by the compiler

/home/gromualdi/robot-code/robotology-superbuild/build/install/include/iDynTree/KinDynComputations.h:697:10: note:   no known conversion for argument 2 from ‘Eigen::Map<Eigen::Matrix<double, -1, -1, 1> >’ to ‘iDynTree::MatrixView<double>’

Something similar happens if I do

     m_kinDyn->getFrameFreeFloatingJacobian(m_frameIndex,
                                            this->subA(m_robotAccelerationVariable));

where the function subA is

Eigen::Ref<Eigen::MatrixXd> subA(const VariablesHandler::VariableDescription& description)
{
    return m_A.block(0, description.offset, 6, description.size);
}

This is the error

bool iDynTree::KinDynComputations::getFrameFreeFloatingJacobian(iDynTree::FrameIndex, iDynTree::MatrixView<double>)
     bool getFrameFreeFloatingJacobian(const FrameIndex frameIndex,
          ^~~~~~~~~~~~~~~~~~~~~~~~~~~~
/home/gromualdi/robot-code/robotology-superbuild/build/install/include/iDynTree/KinDynComputations.h:697:10: note:   no known conversion for argument 2 from ‘Eigen::Ref<Eigen::Matrix<double, -1, -1> >’ to ‘iDynTree::MatrixView<double>’

Actually supporting the eigen::map is not really important since matrixview can be seen as a map, so we can wrap directly a non-idyntree object using the matrixview. On the other hand, adding the support to eigen::ref it would be really nice since it may happen that the input of a function is an Eigen::Ref object. I think that the problem can be split into these subtasks:

  1. understand why the eigen::ref doesn't work out of the box.
  2. implement a SubMatrixView. This can be used to extract a block from a MatrixView (this is actually what I need)

cc @traversaro and @S-Dafarra

GiulioRomualdi commented 3 years ago

In order to replicate the error, try to instantiate a MatrixVew from an eigenRef, i.e.

     iDynTree::MatrixView a(eigenRef);
/home/gromualdi/robot-code/bipedal-locomotion-framework/src/TSID/src/SE3Task.cpp:88:36: error: class template argument deduction failed:
     iDynTree::MatrixView a(eigenRef);
                                    ^
/home/gromualdi/robot-code/bipedal-locomotion-framework/src/TSID/src/SE3Task.cpp:88:36: error: no matching function for call to ‘MatrixView(Eigen::Ref<Eigen::Matrix<double, -1, -1> >&)’
In file included from /home/gromualdi/robot-code/robotology-superbuild/build/install/include/iDynTree/Core/MatrixDynSize.h:17:0,
                 from /home/gromualdi/robot-code/robotology-superbuild/build/install/include/iDynTree/KinDynComputations.h:18,
                 from /home/gromualdi/robot-code/bipedal-locomotion-framework/src/TSID/include/BipedalLocomotion/TSID/OptimalControlElement.h:15,
                 from /home/gromualdi/robot-code/bipedal-locomotion-framework/src/TSID/include/BipedalLocomotion/TSID/SE3Task.h:11,
                 from /home/gromualdi/robot-code/bipedal-locomotion-framework/src/TSID/src/SE3Task.cpp:8:
/home/gromualdi/robot-code/robotology-superbuild/build/install/include/iDynTree/Core/MatrixView.h:169:9: note: candidate: template<class ElementType> MatrixView(iDynTree::MatrixView<ElementType>::pointer, iDynTree::MatrixView<ElementType>::index_type, iDynTree::MatrixView<ElementType>::index_type, const iDynTree::MatrixStorageOrdering&)-> iDynTree::MatrixView<ElementType>
         MatrixView(pointer in_data,
         ^~~~~~~~~~
/home/gromualdi/robot-code/robotology-superbuild/build/install/include/iDynTree/Core/MatrixView.h:169:9: note:   template argument deduction/substitution failed:
/home/gromualdi/robot-code/bipedal-locomotion-framework/src/TSID/src/SE3Task.cpp:88:36: note:   mismatched types ‘iDynTree::MatrixView<ElementType>::element_type*’ and ‘Eigen::Ref<Eigen::Matrix<double, -1, -1> >’
     iDynTree::MatrixView a(eigenRef);
                                    ^
In file included from /home/gromualdi/robot-code/robotology-superbuild/build/install/include/iDynTree/Core/MatrixDynSize.h:17:0,
                 from /home/gromualdi/robot-code/robotology-superbuild/build/install/include/iDynTree/KinDynComputations.h:18,
                 from /home/gromualdi/robot-code/bipedal-locomotion-framework/src/TSID/include/BipedalLocomotion/TSID/OptimalControlElement.h:15,
                 from /home/gromualdi/robot-code/bipedal-locomotion-framework/src/TSID/include/BipedalLocomotion/TSID/SE3Task.h:11,
                 from /home/gromualdi/robot-code/bipedal-locomotion-framework/src/TSID/src/SE3Task.cpp:8:
/home/gromualdi/robot-code/robotology-superbuild/build/install/include/iDynTree/Core/MatrixView.h:162:9: note: candidate: template<class ElementType, class Container, typename std::enable_if<((std::is_convertible<decltype (declval<Container>().data()), ElementType*>::value && (! iDynTree::MatrixViewInternal::has_IsRowMajor<Container, void>::value)) && (! std::is_same<Container, iDynTree::MatrixView<ElementType> >::value)), int>::type <anonymous> > MatrixView(Container&, const iDynTree::MatrixStorageOrdering&)-> iDynTree::MatrixView<ElementType>
         MatrixView(Container& matrix, const MatrixStorageOrdering& order = MatrixStorageOrdering::RowMajor)
         ^~~~~~~~~~
/home/gromualdi/robot-code/robotology-superbuild/build/install/include/iDynTree/Core/MatrixView.h:162:9: note:   template argument deduction/substitution failed:
/home/gromualdi/robot-code/bipedal-locomotion-framework/src/TSID/src/SE3Task.cpp:88:36: note:   couldn't deduce template parameter ‘ElementType’
     iDynTree::MatrixView a(eigenRef);
                                    ^
In file included from /home/gromualdi/robot-code/robotology-superbuild/build/install/include/iDynTree/Core/MatrixDynSize.h:17:0,
                 from /home/gromualdi/robot-code/robotology-superbuild/build/install/include/iDynTree/KinDynComputations.h:18,
                 from /home/gromualdi/robot-code/bipedal-locomotion-framework/src/TSID/include/BipedalLocomotion/TSID/OptimalControlElement.h:15,
                 from /home/gromualdi/robot-code/bipedal-locomotion-framework/src/TSID/include/BipedalLocomotion/TSID/SE3Task.h:11,
                 from /home/gromualdi/robot-code/bipedal-locomotion-framework/src/TSID/src/SE3Task.cpp:8:
/home/gromualdi/robot-code/robotology-superbuild/build/install/include/iDynTree/Core/MatrixView.h:147:9: note: candidate: template<class ElementType, class Container, typename std::enable_if<((std::is_convertible<decltype (declval<Container>().data()), ElementType*>::value && iDynTree::MatrixViewInternal::has_IsRowMajor<Container, void>::value) && (! std::is_same<Container, iDynTree::MatrixView<ElementType> >::value)), int>::type <anonymous> > MatrixView(Container&)-> iDynTree::MatrixView<ElementType>
         MatrixView(Container& matrix)
         ^~~~~~~~~~
/home/gromualdi/robot-code/robotology-superbuild/build/install/include/iDynTree/Core/MatrixView.h:147:9: note:   template argument deduction/substitution failed:
/home/gromualdi/robot-code/bipedal-locomotion-framework/src/TSID/src/SE3Task.cpp:88:36: note:   couldn't deduce template parameter ‘ElementType’
     iDynTree::MatrixView a(eigenRef);
                                    ^
In file included from /home/gromualdi/robot-code/robotology-superbuild/build/install/include/iDynTree/Core/MatrixDynSize.h:17:0,
                 from /home/gromualdi/robot-code/robotology-superbuild/build/install/include/iDynTree/KinDynComputations.h:18,
                 from /home/gromualdi/robot-code/bipedal-locomotion-framework/src/TSID/include/BipedalLocomotion/TSID/OptimalControlElement.h:15,
                 from /home/gromualdi/robot-code/bipedal-locomotion-framework/src/TSID/include/BipedalLocomotion/TSID/SE3Task.h:11,
                 from /home/gromualdi/robot-code/bipedal-locomotion-framework/src/TSID/src/SE3Task.cpp:8:
/home/gromualdi/robot-code/robotology-superbuild/build/install/include/iDynTree/Core/MatrixView.h:136:9: note: candidate: template<class ElementType, class Container, typename std::enable_if<(((std::is_const<_Tp>::value && std::is_convertible<decltype (declval<Container>().data()), ElementType*>::value) && (! iDynTree::MatrixViewInternal::has_IsRowMajor<Container, void>::value)) && (! std::is_same<Container, iDynTree::MatrixView<ElementType> >::value)), int>::type <anonymous> > MatrixView(const Container&, const iDynTree::MatrixStorageOrdering&)-> iDynTree::MatrixView<ElementType>
         MatrixView(const Container& matrix, const MatrixStorageOrdering& order = MatrixStorageOrdering::RowMajor)
         ^~~~~~~~~~
/home/gromualdi/robot-code/robotology-superbuild/build/install/include/iDynTree/Core/MatrixView.h:136:9: note:   template argument deduction/substitution failed:
/home/gromualdi/robot-code/bipedal-locomotion-framework/src/TSID/src/SE3Task.cpp:88:36: note:   couldn't deduce template parameter ‘ElementType’
     iDynTree::MatrixView a(eigenRef);
                                    ^
In file included from /home/gromualdi/robot-code/robotology-superbuild/build/install/include/iDynTree/Core/MatrixDynSize.h:17:0,
                 from /home/gromualdi/robot-code/robotology-superbuild/build/install/include/iDynTree/KinDynComputations.h:18,
                 from /home/gromualdi/robot-code/bipedal-locomotion-framework/src/TSID/include/BipedalLocomotion/TSID/OptimalControlElement.h:15,
                 from /home/gromualdi/robot-code/bipedal-locomotion-framework/src/TSID/include/BipedalLocomotion/TSID/SE3Task.h:11,
                 from /home/gromualdi/robot-code/bipedal-locomotion-framework/src/TSID/src/SE3Task.cpp:8:
/home/gromualdi/robot-code/robotology-superbuild/build/install/include/iDynTree/Core/MatrixView.h:119:9: note: candidate: template<class ElementType, class Container, typename std::enable_if<(((std::is_const<_Tp>::value && std::is_convertible<decltype (declval<Container>().data()), ElementType*>::value) && iDynTree::MatrixViewInternal::has_IsRowMajor<Container, void>::value) && (! std::is_same<Container, iDynTree::MatrixView<ElementType> >::value)), int>::type <anonymous> > MatrixView(const Container&)-> iDynTree::MatrixView<ElementType>
         MatrixView(const Container& matrix)
         ^~~~~~~~~~
/home/gromualdi/robot-code/robotology-superbuild/build/install/include/iDynTree/Core/MatrixView.h:119:9: note:   template argument deduction/substitution failed:
/home/gromualdi/robot-code/bipedal-locomotion-framework/src/TSID/src/SE3Task.cpp:88:36: note:   couldn't deduce template parameter ‘ElementType’
     iDynTree::MatrixView a(eigenRef);
                                    ^
In file included from /home/gromualdi/robot-code/robotology-superbuild/build/install/include/iDynTree/Core/MatrixDynSize.h:17:0,
                 from /home/gromualdi/robot-code/robotology-superbuild/build/install/include/iDynTree/KinDynComputations.h:18,
                 from /home/gromualdi/robot-code/bipedal-locomotion-framework/src/TSID/include/BipedalLocomotion/TSID/OptimalControlElement.h:15,
                 from /home/gromualdi/robot-code/bipedal-locomotion-framework/src/TSID/include/BipedalLocomotion/TSID/SE3Task.h:11,
                 from /home/gromualdi/robot-code/bipedal-locomotion-framework/src/TSID/src/SE3Task.cpp:8:
/home/gromualdi/robot-code/robotology-superbuild/build/install/include/iDynTree/Core/MatrixView.h:106:28: note: candidate: template<class ElementType, class OtherElementType, class> MatrixView(const iDynTree::MatrixView<OtherElementType>&)-> iDynTree::MatrixView<ElementType>
         IDYNTREE_CONSTEXPR MatrixView(const MatrixView<OtherElementType>& other)
                            ^~~~~~~~~~
/home/gromualdi/robot-code/robotology-superbuild/build/install/include/iDynTree/Core/MatrixView.h:106:28: note:   template argument deduction/substitution failed:
/home/gromualdi/robot-code/bipedal-locomotion-framework/src/TSID/src/SE3Task.cpp:88:36: note:   ‘Eigen::Ref<Eigen::Matrix<double, -1, -1> >’ is not derived from ‘const iDynTree::MatrixView<OtherElementType>’
     iDynTree::MatrixView a(eigenRef);
                                    ^
In file included from /home/gromualdi/robot-code/robotology-superbuild/build/install/include/iDynTree/Core/MatrixDynSize.h:17:0,
                 from /home/gromualdi/robot-code/robotology-superbuild/build/install/include/iDynTree/KinDynComputations.h:18,
                 from /home/gromualdi/robot-code/bipedal-locomotion-framework/src/TSID/include/BipedalLocomotion/TSID/OptimalControlElement.h:15,
                 from /home/gromualdi/robot-code/bipedal-locomotion-framework/src/TSID/include/BipedalLocomotion/TSID/SE3Task.h:11,
                 from /home/gromualdi/robot-code/bipedal-locomotion-framework/src/TSID/src/SE3Task.cpp:8:
/home/gromualdi/robot-code/robotology-superbuild/build/install/include/iDynTree/Core/MatrixView.h:96:9: note: candidate: template<class ElementType> MatrixView(const iDynTree::MatrixView<ElementType>&)-> iDynTree::MatrixView<ElementType>
         MatrixView(const MatrixView& other)
         ^~~~~~~~~~
/home/gromualdi/robot-code/robotology-superbuild/build/install/include/iDynTree/Core/MatrixView.h:96:9: note:   template argument deduction/substitution failed:
/home/gromualdi/robot-code/bipedal-locomotion-framework/src/TSID/src/SE3Task.cpp:88:36: note:   ‘Eigen::Ref<Eigen::Matrix<double, -1, -1> >’ is not derived from ‘const iDynTree::MatrixView<ElementType>’
     iDynTree::MatrixView a(eigenRef);
                                    ^
In file included from /home/gromualdi/robot-code/robotology-superbuild/build/install/include/iDynTree/Core/MatrixDynSize.h:17:0,
                 from /home/gromualdi/robot-code/robotology-superbuild/build/install/include/iDynTree/KinDynComputations.h:18,
                 from /home/gromualdi/robot-code/bipedal-locomotion-framework/src/TSID/include/BipedalLocomotion/TSID/OptimalControlElement.h:15,
                 from /home/gromualdi/robot-code/bipedal-locomotion-framework/src/TSID/include/BipedalLocomotion/TSID/SE3Task.h:11,
                 from /home/gromualdi/robot-code/bipedal-locomotion-framework/src/TSID/src/SE3Task.cpp:8:
/home/gromualdi/robot-code/robotology-superbuild/build/install/include/iDynTree/Core/MatrixView.h:93:9: note: candidate: template<class ElementType> MatrixView()-> iDynTree::MatrixView<ElementType>
         MatrixView()
         ^~~~~~~~~~
/home/gromualdi/robot-code/robotology-superbuild/build/install/include/iDynTree/Core/MatrixView.h:93:9: note:   template argument deduction/substitution failed:
/home/gromualdi/robot-code/bipedal-locomotion-framework/src/TSID/src/SE3Task.cpp:88:36: note:   candidate expects 0 arguments, 1 provided
     iDynTree::MatrixView a(eigenRef);
                                    ^
In file included from /home/gromualdi/robot-code/robotology-superbuild/build/install/include/iDynTree/Core/MatrixDynSize.h:17:0,
                 from /home/gromualdi/robot-code/robotology-superbuild/build/install/include/iDynTree/KinDynComputations.h:18,
                 from /home/gromualdi/robot-code/bipedal-locomotion-framework/src/TSID/include/BipedalLocomotion/TSID/OptimalControlElement.h:15,
                 from /home/gromualdi/robot-code/bipedal-locomotion-framework/src/TSID/include/BipedalLocomotion/TSID/SE3Task.h:11,
                 from /home/gromualdi/robot-code/bipedal-locomotion-framework/src/TSID/src/SE3Task.cpp:8:
/home/gromualdi/robot-code/robotology-superbuild/build/install/include/iDynTree/Core/MatrixView.h:64:40: note: candidate: template<class ElementType> MatrixView(iDynTree::MatrixView<ElementType>)-> iDynTree::MatrixView<ElementType>
     template <class ElementType> class MatrixView
                                        ^~~~~~~~~~
/home/gromualdi/robot-code/robotology-superbuild/build/install/include/iDynTree/Core/MatrixView.h:64:40: note:   template argument deduction/substitution failed:
/home/gromualdi/robot-code/bipedal-locomotion-framework/src/TSID/src/SE3Task.cpp:88:36: note:   ‘Eigen::Ref<Eigen::Matrix<double, -1, -1> >’ is not derived from ‘iDynTree::MatrixView<ElementType>’
     iDynTree::MatrixView a(eigenRef);
                                    ^
src/TSID/CMakeFiles/TSID.dir/build.make:94: recipe for target 'src/TSID/CMakeFiles/TSID.dir/src/SE3Task.cpp.o' failed
make[2]: *** [src/TSID/CMakeFiles/TSID.dir/src/SE3Task.cpp.o] Error 1
CMakeFiles/Makefile2:2706: recipe for target 'src/TSID/CMakeFiles/TSID.dir/all' failed
make[1]: *** [src/TSID/CMakeFiles/TSID.dir/all] Error 2
Makefile:159: recipe for target 'all' failed
make: *** [all] Error 2
traversaro commented 3 years ago

understand why the eigen::ref doesn't work out of the box.

Note that iDynTree::MatrixView is meant to represent Matrices that are arranged continuously in memory, either in ColMajor or RowMajor order, so any kind of such conversion is only possible for Ref that are continuous in memory, while Eigen::Ref is a more general kind of wrapper, see the docs ( https://eigen.tuxfamily.org/dox/classEigen_1_1Ref.html ) and the source code ( https://gitlab.com/libeigen/eigen/-/blob/master/Eigen/src/Core/Ref.h ) :

Likewise, a Ref can reference any column-major dense matrix expression of float whose column's elements are contiguously stored with the possibility to have a constant space in-between each column, i.e. the inner stride must be equal to 1, but the outer stride (or leading dimension) can be greater than the number of rows.

However, for Ref that are continuous in memory, indeed this should be possible. Have you tried to define explicitly the MatrixView constructor that uses Eigen::Ref, just to try?

implement a SubMatrixView. This can be used to extract a block from a MatrixView (this is actually what I need)

What would be the return value of SubMatrixView ? As we don't support to specify inner or outer strides in MatrixView, in general we can't express blocks of an existing Matrix using MatrixView as it is.

GiulioRomualdi commented 3 years ago

What do you think about handling inner/outer strides into MatrixView?

traversaro commented 3 years ago

What do you think about handling inner/outer strides into MatrixView?

To me (given that I never worked extensively with strides) seems to be a bit complex w.r.t. to the advantages that it provides, but if someone wants to work on it I would be happy to have it in iDynTree.

S-Dafarra commented 3 years ago

Sorry to jump in just now. I am a bit skeptical about having a Ref as input, since you cannot guarantee if the memory is contiguous. Maybe it is possible with Map though.

Back in time, I thought a little bit about it and I think it may be possible to get a submatrix from a MatrixView, but as you said it is possible only if you can specify the inner and outer stride too.

Assuming that we are not mixing RowMajor and ColMajor, you can get a sub-block of the matrix by simply offsetting the raw pointer to the position of the top left element of the block, change the row and cols to the dimension of the block and keep the same inner and outer stride. In fact, the distance in memory between rows and columns does not change, you are only changing the boundaries.

GiulioRomualdi commented 3 years ago

Hi @S-Dafarra the main limitation of what we implemented is that this kind of code cannot compile

void foo(Eigen::Ref<Eigen::MatrixXd> m)
{
    kinDyn.getFreeFloatingMassMatrix(m);
    return;
} 

while the following works

void foo(Eigen::MatrixXd& m)
{
    kinDyn.getFreeFloatingMassMatrix(m);
    return;
} 
S-Dafarra commented 3 years ago

Hi @S-Dafarra the main limitation of what we implemented is that this kind of code cannot compile

void foo(Eigen::Ref<Eigen::MatrixXd> m)
{
    kinDyn.getFreeFloatingMassMatrix(m);
    return;
} 

while the following works

void foo(Eigen::MatrixXd& m)
{
    kinDyn.getFreeFloatingMassMatrix(m);
    return;
} 

I understand. Does Ref provide a data method returning a double*. Also, from the errors above, it seems that is not able to deduce the ElementType, as it is it cannot understand what is the type of the object.

GiulioRomualdi commented 3 years ago

Today I had the opportunity to understand deeper the problem.

First of all the problem that I underlined in https://github.com/robotology/idyntree/issues/797#issuecomment-750630820

iDynTree::MatrixView a(eigenRef);

it is simply a template deduction problem (as @S-Dafarra suggested in https://github.com/robotology/idyntree/issues/797#issuecomment-754675295). indeed iDynTree::MatrixView<double> a(eigenRef) compiles without any problem.

For instance this snippet

#include <iostream>
#include <Eigen/Dense>
#include <iDynTree/Core/MatrixView.h>

void foo(iDynTree::MatrixView<double> view) {
  std::cout << "Size: " << view.rows() << " x " << view.cols() << std::endl;
  std::cout << "view(0,0): " << view(0, 0) << std::endl;
  view(0, 0) = 2;
  std::cout << "view(0,0): " << view(0, 0) << std::endl;
}

int main() {
  Eigen::MatrixXd m(10, 10);
  Eigen::MatrixXd n(10, 10);
  m.setZero();
  n.setIdentity();
  Eigen::Ref<Eigen::MatrixXd> ref(m);

  std::cout << "Eigen::Ref" << std::endl;
  foo(ref);

  std::cout << std::endl;
  std::cout << "Eigen::MatrixXd" << std::endl;
  foo(n);

  return 0;
}

gives

Eigen::Ref
Size: 10 x 10
view(0,0): 0
view(0,0): 2

Eigen::MatrixXd
Size: 10 x 10
view(0,0): 1
view(0,0): 2

On the other hand as @traversaro and @S-Dafarra explained the Eigen::Ref is able to handle also a non-contiguous area of memory. (A block of a dense matrix is represented by a non-contiguous memory). Fortunately, if you try to pass matrix sublock to foo the following error is thrown by the compiler (gcc 10)

/home/gromualdi/robot-code/test_eigen/span_eigen.cpp: In function ‘int main()’:
/home/gromualdi/robot-code/test_eigen/span_eigen.cpp:32:14: error: could not convert ‘((Eigen::DenseBase<Eigen::Matrix<double, -1, -1> >*)(& n))->Eigen::DenseBase<Eigen::Matrix<double, -1, -1> >::block(1, 1, 1, 1)’ from ‘Eigen::DenseBase<Eigen::Matrix<double, -1, -1> >::BlockXpr’ {aka ‘Eigen::Block<Eigen::Matrix<double, -1, -1>, -1, -1, false>’} to ‘iDynTree::MatrixView<double>’
   32 |   foo(n.block(1,1,1,1));
      |       ~~~~~~~^~~~~~~~~
      |              |
      |              Eigen::DenseBase<Eigen::Matrix<double, -1, -1> >::BlockXpr {aka Eigen::Block<Eigen::Matrix<double, -1, -1>, -1, -1, false>}

This problem does not subsist if foo takes as input an iDynTree::MatrixView<const double>. Indeed in this case foo(n.block(1,1,1,1)); compiles without any issue. This happens because a temporary object is created at runtime.

traversaro commented 3 years ago

This was partically fixed by https://github.com/robotology/idyntree/pull/800, right @GiulioRomualdi ? Could you specify what is missing to close the issue, or eventually open an issue just for that?

GiulioRomualdi commented 3 years ago

Hi @traversaro, #800 implements the possibility to retrieve a sub-block of a matrix view. The nice thing is that we can use Eigen::Map of a sub-block of matrix view. Everything works fine

For instance, this now works without problems:

void foo(Eigen::Ref<double> m)
{
     m.setIdentity();
}

Eigen::MatixXd m(20,30);
iDynTree::MatrixView view(m);

foo(iDynTree::toEigen(view.block(0,0,10,10)));
GiulioRomualdi commented 3 years ago

In my opinion, we can close the issue