123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328 |
- // This is an advanced implementation of the algorithm described in the
- // following paper:
- // C. Hertzberg, R. Wagner, U. Frese, and L. Schroder. Integratinggeneric sensor fusion algorithms with sound state representationsthrough encapsulation of manifolds.
- // CoRR, vol. abs/1107.1119, 2011.[Online]. Available: http://arxiv.org/abs/1107.1119
- /*
- * Copyright (c) 2019--2023, The University of Hong Kong
- * All rights reserved.
- *
- * Modifier: Dongjiao HE <hdj65822@connect.hku.hk>
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions
- * are met:
- *
- * * Redistributions of source code must retain the above copyright
- * notice, this list of conditions and the following disclaimer.
- * * Redistributions in binary form must reproduce the above
- * copyright notice, this list of conditions and the following
- * disclaimer in the documentation and/or other materials provided
- * with the distribution.
- * * Neither the name of the Universitaet Bremen nor the names of its
- * contributors may be used to endorse or promote products derived
- * from this software without specific prior written permission.
- *
- * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
- * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
- * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
- * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
- * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
- * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
- * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
- * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
- * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
- * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
- * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
- * POSSIBILITY OF SUCH DAMAGE.
- */
-
- /*
- * Copyright (c) 2008--2011, Universitaet Bremen
- * All rights reserved.
- *
- * Author: Christoph Hertzberg <chtz@informatik.uni-bremen.de>
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions
- * are met:
- *
- * * Redistributions of source code must retain the above copyright
- * notice, this list of conditions and the following disclaimer.
- * * Redistributions in binary form must reproduce the above
- * copyright notice, this list of conditions and the following
- * disclaimer in the documentation and/or other materials provided
- * with the distribution.
- * * Neither the name of the Universitaet Bremen nor the names of its
- * contributors may be used to endorse or promote products derived
- * from this software without specific prior written permission.
- *
- * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
- * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
- * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
- * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
- * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
- * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
- * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
- * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
- * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
- * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
- * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
- * POSSIBILITY OF SUCH DAMAGE.
- */
- /**
- * @file mtk/startIdx.hpp
- * @brief Tools to access sub-elements of compound manifolds.
- */
- #ifndef GET_START_INDEX_H_
- #define GET_START_INDEX_H_
- #include <Eigen/Core>
- #include "src/SubManifold.hpp"
- #include "src/vectview.hpp"
- namespace MTK {
- /**
- * \defgroup SubManifolds Accessing Submanifolds
- * For compound manifolds constructed using MTK_BUILD_MANIFOLD, member pointers
- * can be used to get sub-vectors or matrix-blocks of a corresponding big matrix.
- * E.g. for a type @a pose consisting of @a orient and @a trans the member pointers
- * @c &pose::orient and @c &pose::trans give all required information and are still
- * valid if the base type gets extended or the actual types of @a orient and @a trans
- * change (e.g. from 2D to 3D).
- *
- * @todo Maybe require manifolds to typedef MatrixType and VectorType, etc.
- */
- //@{
- /**
- * Determine the index of a sub-variable within a compound variable.
- */
- template<class Base, class T, int idx, int dim>
- int getStartIdx( MTK::SubManifold<T, idx, dim> Base::*)
- {
- return idx;
- }
- template<class Base, class T, int idx, int dim>
- int getStartIdx_( MTK::SubManifold<T, idx, dim> Base::*)
- {
- return dim;
- }
- /**
- * Determine the degrees of freedom of a sub-variable within a compound variable.
- */
- template<class Base, class T, int idx, int dim>
- int getDof( MTK::SubManifold<T, idx, dim> Base::*)
- {
- return T::DOF;
- }
- template<class Base, class T, int idx, int dim>
- int getDim( MTK::SubManifold<T, idx, dim> Base::*)
- {
- return T::DIM;
- }
- /**
- * set the diagonal elements of a covariance matrix corresponding to a sub-variable
- */
- template<class Base, class T, int idx, int dim>
- void setDiagonal(Eigen::Matrix<typename Base::scalar, Base::DOF, Base::DOF> &cov,
- MTK::SubManifold<T, idx, dim> Base::*, const typename Base::scalar &val)
- {
- cov.diagonal().template segment<T::DOF>(idx).setConstant(val);
- }
- template<class Base, class T, int idx, int dim>
- void setDiagonal_(Eigen::Matrix<typename Base::scalar, Base::DIM, Base::DIM> &cov,
- MTK::SubManifold<T, idx, dim> Base::*, const typename Base::scalar &val)
- {
- cov.diagonal().template segment<T::DIM>(dim).setConstant(val);
- }
- /**
- * Get the subblock of corresponding to two members, i.e.
- * \code
- * Eigen::Matrix<double, Pose::DOF, Pose::DOF> m;
- * MTK::subblock(m, &Pose::orient, &Pose::trans) = some_expression;
- * MTK::subblock(m, &Pose::trans, &Pose::orient) = some_expression.trans();
- * \endcode
- * lets you modify mixed covariance entries in a bigger covariance matrix.
- */
- template<class Base, class T1, int idx1, int dim1, class T2, int idx2, int dim2>
- typename MTK::internal::CovBlock<Base, T1, T2>::Type
- subblock(Eigen::Matrix<typename Base::scalar, Base::DOF, Base::DOF> &cov,
- MTK::SubManifold<T1, idx1, dim1> Base::*, MTK::SubManifold<T2, idx2, dim2> Base::*)
- {
- return cov.template block<T1::DOF, T2::DOF>(idx1, idx2);
- }
- template<class Base, class T1, int idx1, int dim1, class T2, int idx2, int dim2>
- typename MTK::internal::CovBlock_<Base, T1, T2>::Type
- subblock_(Eigen::Matrix<typename Base::scalar, Base::DIM, Base::DIM> &cov,
- MTK::SubManifold<T1, idx1, dim1> Base::*, MTK::SubManifold<T2, idx2, dim2> Base::*)
- {
- return cov.template block<T1::DIM, T2::DIM>(dim1, dim2);
- }
- template<typename Base1, typename Base2, typename T1, typename T2, int idx1, int idx2, int dim1, int dim2>
- typename MTK::internal::CrossCovBlock<Base1, Base2, T1, T2>::Type
- subblock(Eigen::Matrix<typename Base1::scalar, Base1::DOF, Base2::DOF> &cov, MTK::SubManifold<T1, idx1, dim1> Base1::*, MTK::SubManifold<T2, idx2, dim2> Base2::*)
- {
- return cov.template block<T1::DOF, T2::DOF>(idx1, idx2);
- }
- template<typename Base1, typename Base2, typename T1, typename T2, int idx1, int idx2, int dim1, int dim2>
- typename MTK::internal::CrossCovBlock_<Base1, Base2, T1, T2>::Type
- subblock_(Eigen::Matrix<typename Base1::scalar, Base1::DIM, Base2::DIM> &cov, MTK::SubManifold<T1, idx1, dim1> Base1::*, MTK::SubManifold<T2, idx2, dim2> Base2::*)
- {
- return cov.template block<T1::DIM, T2::DIM>(dim1, dim2);
- }
- /**
- * Get the subblock of corresponding to a member, i.e.
- * \code
- * Eigen::Matrix<double, Pose::DOF, Pose::DOF> m;
- * MTK::subblock(m, &Pose::orient) = some_expression;
- * \endcode
- * lets you modify covariance entries in a bigger covariance matrix.
- */
- template<class Base, class T, int idx, int dim>
- typename MTK::internal::CovBlock_<Base, T, T>::Type
- subblock_(Eigen::Matrix<typename Base::scalar, Base::DIM, Base::DIM> &cov,
- MTK::SubManifold<T, idx, dim> Base::*)
- {
- return cov.template block<T::DIM, T::DIM>(dim, dim);
- }
- template<class Base, class T, int idx, int dim>
- typename MTK::internal::CovBlock<Base, T, T>::Type
- subblock(Eigen::Matrix<typename Base::scalar, Base::DOF, Base::DOF> &cov,
- MTK::SubManifold<T, idx, dim> Base::*)
- {
- return cov.template block<T::DOF, T::DOF>(idx, idx);
- }
- template<typename Base>
- class get_cov {
- public:
- typedef Eigen::Matrix<typename Base::scalar, Base::DOF, Base::DOF> type;
- typedef const Eigen::Matrix<typename Base::scalar, Base::DOF, Base::DOF> const_type;
- };
- template<typename Base>
- class get_cov_ {
- public:
- typedef Eigen::Matrix<typename Base::scalar, Base::DIM, Base::DIM> type;
- typedef const Eigen::Matrix<typename Base::scalar, Base::DIM, Base::DIM> const_type;
- };
- template<typename Base1, typename Base2>
- class get_cross_cov {
- public:
- typedef Eigen::Matrix<typename Base1::scalar, Base1::DOF, Base2::DOF> type;
- typedef const type const_type;
- };
- template<typename Base1, typename Base2>
- class get_cross_cov_ {
- public:
- typedef Eigen::Matrix<typename Base1::scalar, Base1::DIM, Base2::DIM> type;
- typedef const type const_type;
- };
- template<class Base, class T, int idx, int dim>
- vectview<typename Base::scalar, T::DIM>
- subvector_impl_(vectview<typename Base::scalar, Base::DIM> vec, SubManifold<T, idx, dim> Base::*)
- {
- return vec.template segment<T::DIM>(dim);
- }
- template<class Base, class T, int idx, int dim>
- vectview<typename Base::scalar, T::DOF>
- subvector_impl(vectview<typename Base::scalar, Base::DOF> vec, SubManifold<T, idx, dim> Base::*)
- {
- return vec.template segment<T::DOF>(idx);
- }
- /**
- * Get the subvector corresponding to a sub-manifold from a bigger vector.
- */
- template<class Scalar, int BaseDIM, class Base, class T, int idx, int dim>
- vectview<Scalar, T::DIM>
- subvector_(vectview<Scalar, BaseDIM> vec, SubManifold<T, idx, dim> Base::* ptr)
- {
- return subvector_impl_(vec, ptr);
- }
- template<class Scalar, int BaseDOF, class Base, class T, int idx, int dim>
- vectview<Scalar, T::DOF>
- subvector(vectview<Scalar, BaseDOF> vec, SubManifold<T, idx, dim> Base::* ptr)
- {
- return subvector_impl(vec, ptr);
- }
- /**
- * @todo This should be covered already by subvector(vectview<typename Base::scalar,Base::DOF> vec,SubManifold<T,idx> Base::*)
- */
- template<class Scalar, int BaseDOF, class Base, class T, int idx, int dim>
- vectview<Scalar, T::DOF>
- subvector(Eigen::Matrix<Scalar, BaseDOF, 1>& vec, SubManifold<T, idx, dim> Base::* ptr)
- {
- return subvector_impl(vectview<Scalar, BaseDOF>(vec), ptr);
- }
-
- template<class Scalar, int BaseDIM, class Base, class T, int idx, int dim>
- vectview<Scalar, T::DIM>
- subvector_(Eigen::Matrix<Scalar, BaseDIM, 1>& vec, SubManifold<T, idx, dim> Base::* ptr)
- {
- return subvector_impl_(vectview<Scalar, BaseDIM>(vec), ptr);
- }
- template<class Scalar, int BaseDIM, class Base, class T, int idx, int dim>
- vectview<const Scalar, T::DIM>
- subvector_(const Eigen::Matrix<Scalar, BaseDIM, 1>& vec, SubManifold<T, idx, dim> Base::* ptr)
- {
- return subvector_impl_(vectview<const Scalar, BaseDIM>(vec), ptr);
- }
- template<class Scalar, int BaseDOF, class Base, class T, int idx, int dim>
- vectview<const Scalar, T::DOF>
- subvector(const Eigen::Matrix<Scalar, BaseDOF, 1>& vec, SubManifold<T, idx, dim> Base::* ptr)
- {
- return subvector_impl(vectview<const Scalar, BaseDOF>(vec), ptr);
- }
- /**
- * const version of subvector(vectview<typename Base::scalar,Base::DOF> vec,SubManifold<T,idx> Base::*)
- */
- template<class Base, class T, int idx, int dim>
- vectview<const typename Base::scalar, T::DOF>
- subvector_impl(const vectview<const typename Base::scalar, Base::DOF> cvec, SubManifold<T, idx, dim> Base::*)
- {
- return cvec.template segment<T::DOF>(idx);
- }
- template<class Base, class T, int idx, int dim>
- vectview<const typename Base::scalar, T::DIM>
- subvector_impl_(const vectview<const typename Base::scalar, Base::DIM> cvec, SubManifold<T, idx, dim> Base::*)
- {
- return cvec.template segment<T::DIM>(dim);
- }
- template<class Scalar, int BaseDOF, class Base, class T, int idx, int dim>
- vectview<const Scalar, T::DOF>
- subvector(const vectview<const Scalar, BaseDOF> cvec, SubManifold<T, idx, dim> Base::* ptr)
- {
- return subvector_impl(cvec, ptr);
- }
- } // namespace MTK
- #endif // GET_START_INDEX_H_
|