mirror of
https://github.com/HViktorTsoi/FAST_LIO_LOCALIZATION.git
synced 2023-05-28 12:51:38 +08:00
fast_lio2 released!
This commit is contained in:
2005
include/IKFoM_toolkit/esekfom/esekfom.hpp
Executable file
2005
include/IKFoM_toolkit/esekfom/esekfom.hpp
Executable file
File diff suppressed because it is too large
Load Diff
82
include/IKFoM_toolkit/esekfom/util.hpp
Executable file
82
include/IKFoM_toolkit/esekfom/util.hpp
Executable file
@@ -0,0 +1,82 @@
|
||||
/*
|
||||
* Copyright (c) 2019--2023, The University of Hong Kong
|
||||
* All rights reserved.
|
||||
*
|
||||
* Author: 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.
|
||||
*/
|
||||
|
||||
#ifndef __MEKFOM_UTIL_HPP__
|
||||
#define __MEKFOM_UTIL_HPP__
|
||||
|
||||
#include <Eigen/Core>
|
||||
#include "../mtk/src/mtkmath.hpp"
|
||||
namespace esekfom {
|
||||
|
||||
template <typename T1, typename T2>
|
||||
class is_same {
|
||||
public:
|
||||
operator bool() {
|
||||
return false;
|
||||
}
|
||||
};
|
||||
template<typename T1>
|
||||
class is_same<T1, T1> {
|
||||
public:
|
||||
operator bool() {
|
||||
return true;
|
||||
}
|
||||
};
|
||||
|
||||
template <typename T>
|
||||
class is_double {
|
||||
public:
|
||||
operator bool() {
|
||||
return false;
|
||||
}
|
||||
};
|
||||
|
||||
template<>
|
||||
class is_double<double> {
|
||||
public:
|
||||
operator bool() {
|
||||
return true;
|
||||
}
|
||||
};
|
||||
|
||||
template<typename T>
|
||||
static T
|
||||
id(const T &x)
|
||||
{
|
||||
return x;
|
||||
}
|
||||
|
||||
} // namespace esekfom
|
||||
|
||||
#endif // __MEKFOM_UTIL_HPP__
|
||||
229
include/IKFoM_toolkit/mtk/build_manifold.hpp
Executable file
229
include/IKFoM_toolkit/mtk/build_manifold.hpp
Executable file
@@ -0,0 +1,229 @@
|
||||
// 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/build_manifold.hpp
|
||||
* @brief Macro to automatically construct compound manifolds.
|
||||
*
|
||||
*/
|
||||
#ifndef MTK_AUTOCONSTRUCT_HPP_
|
||||
#define MTK_AUTOCONSTRUCT_HPP_
|
||||
|
||||
#include <vector>
|
||||
|
||||
#include <boost/preprocessor/seq.hpp>
|
||||
#include <boost/preprocessor/cat.hpp>
|
||||
#include <Eigen/Core>
|
||||
|
||||
#include "src/SubManifold.hpp"
|
||||
#include "startIdx.hpp"
|
||||
|
||||
#ifndef PARSED_BY_DOXYGEN
|
||||
//////// internals //////
|
||||
|
||||
#define MTK_APPLY_MACRO_ON_TUPLE(r, macro, tuple) macro tuple
|
||||
|
||||
#define MTK_TRANSFORM_COMMA(macro, entries) BOOST_PP_SEQ_ENUM(BOOST_PP_SEQ_TRANSFORM_S(1, MTK_APPLY_MACRO_ON_TUPLE, macro, entries))
|
||||
|
||||
#define MTK_TRANSFORM(macro, entries) BOOST_PP_SEQ_FOR_EACH_R(1, MTK_APPLY_MACRO_ON_TUPLE, macro, entries)
|
||||
|
||||
#define MTK_CONSTRUCTOR_ARG( type, id) const type& id = type()
|
||||
#define MTK_CONSTRUCTOR_COPY( type, id) id(id)
|
||||
#define MTK_BOXPLUS( type, id) id.boxplus(MTK::subvector(__vec, &self::id), __scale);
|
||||
#define MTK_OPLUS( type, id) id.oplus(MTK::subvector_(__vec, &self::id), __scale);
|
||||
#define MTK_BOXMINUS( type, id) id.boxminus(MTK::subvector(__res, &self::id), __oth.id);
|
||||
#define MTK_S2_hat( type, id) if(id.IDX == idx){id.S2_hat(res);}
|
||||
#define MTK_S2_Nx_yy( type, id) if(id.IDX == idx){id.S2_Nx_yy(res);}
|
||||
#define MTK_S2_Mx( type, id) if(id.IDX == idx){id.S2_Mx(res, dx);}
|
||||
#define MTK_OSTREAM( type, id) << __var.id << " "
|
||||
#define MTK_ISTREAM( type, id) >> __var.id
|
||||
#define MTK_S2_state( type, id) if(id.TYP == 1){S2_state.push_back(std::make_pair(id.IDX, id.DIM));}
|
||||
#define MTK_SO3_state( type, id) if(id.TYP == 2){(SO3_state).push_back(std::make_pair(id.IDX, id.DIM));}
|
||||
#define MTK_vect_state( type, id) if(id.TYP == 0){(vect_state).push_back(std::make_pair(std::make_pair(id.IDX, id.DIM), type::DOF));}
|
||||
|
||||
#define MTK_SUBVARLIST(seq, S2state, SO3state) \
|
||||
BOOST_PP_FOR_1( \
|
||||
( \
|
||||
BOOST_PP_SEQ_SIZE(seq), \
|
||||
BOOST_PP_SEQ_HEAD(seq), \
|
||||
BOOST_PP_SEQ_TAIL(seq) (~), \
|
||||
0,\
|
||||
0,\
|
||||
S2state,\
|
||||
SO3state ),\
|
||||
MTK_ENTRIES_TEST, MTK_ENTRIES_NEXT, MTK_ENTRIES_OUTPUT)
|
||||
|
||||
#define MTK_PUT_TYPE(type, id, dof, dim, S2state, SO3state) \
|
||||
MTK::SubManifold<type, dof, dim> id;
|
||||
#define MTK_PUT_TYPE_AND_ENUM(type, id, dof, dim, S2state, SO3state) \
|
||||
MTK_PUT_TYPE(type, id, dof, dim, S2state, SO3state) \
|
||||
enum {DOF = type::DOF + dof}; \
|
||||
enum {DIM = type::DIM+dim}; \
|
||||
typedef type::scalar scalar;
|
||||
|
||||
#define MTK_ENTRIES_OUTPUT(r, state) MTK_ENTRIES_OUTPUT_I state
|
||||
#define MTK_ENTRIES_OUTPUT_I(s, head, seq, dof, dim, S2state, SO3state) \
|
||||
MTK_APPLY_MACRO_ON_TUPLE(~, \
|
||||
BOOST_PP_IF(BOOST_PP_DEC(s), MTK_PUT_TYPE, MTK_PUT_TYPE_AND_ENUM), \
|
||||
( BOOST_PP_TUPLE_REM_2 head, dof, dim, S2state, SO3state))
|
||||
|
||||
#define MTK_ENTRIES_TEST(r, state) MTK_TUPLE_ELEM_4_0 state
|
||||
|
||||
//! this used to be BOOST_PP_TUPLE_ELEM_4_0:
|
||||
#define MTK_TUPLE_ELEM_4_0(a,b,c,d,e,f, g) a
|
||||
|
||||
#define MTK_ENTRIES_NEXT(r, state) MTK_ENTRIES_NEXT_I state
|
||||
#define MTK_ENTRIES_NEXT_I(len, head, seq, dof, dim, S2state, SO3state) ( \
|
||||
BOOST_PP_DEC(len), \
|
||||
BOOST_PP_SEQ_HEAD(seq), \
|
||||
BOOST_PP_SEQ_TAIL(seq), \
|
||||
dof + BOOST_PP_TUPLE_ELEM_2_0 head::DOF,\
|
||||
dim + BOOST_PP_TUPLE_ELEM_2_0 head::DIM,\
|
||||
S2state,\
|
||||
SO3state)
|
||||
|
||||
#endif /* not PARSED_BY_DOXYGEN */
|
||||
|
||||
|
||||
/**
|
||||
* Construct a manifold.
|
||||
* @param name is the class-name of the manifold,
|
||||
* @param entries is the list of sub manifolds
|
||||
*
|
||||
* Entries must be given in a list like this:
|
||||
* @code
|
||||
* typedef MTK::trafo<MTK::SO3<double> > Pose;
|
||||
* typedef MTK::vect<double, 3> Vec3;
|
||||
* MTK_BUILD_MANIFOLD(imu_state,
|
||||
* ((Pose, pose))
|
||||
* ((Vec3, vel))
|
||||
* ((Vec3, acc_bias))
|
||||
* )
|
||||
* @endcode
|
||||
* Whitespace is optional, but the double parentheses are necessary.
|
||||
* Construction is done entirely in preprocessor.
|
||||
* After construction @a name is also a manifold. Its members can be
|
||||
* accessed by names given in @a entries.
|
||||
*
|
||||
* @note Variable types are not allowed to have commas, thus types like
|
||||
* @c vect<double, 3> need to be typedef'ed ahead.
|
||||
*/
|
||||
#define MTK_BUILD_MANIFOLD(name, entries) \
|
||||
struct name { \
|
||||
typedef name self; \
|
||||
std::vector<std::pair<int, int> > S2_state;\
|
||||
std::vector<std::pair<int, int> > SO3_state;\
|
||||
std::vector<std::pair<std::pair<int, int>, int> > vect_state;\
|
||||
MTK_SUBVARLIST(entries, S2_state, SO3_state) \
|
||||
name ( \
|
||||
MTK_TRANSFORM_COMMA(MTK_CONSTRUCTOR_ARG, entries) \
|
||||
) : \
|
||||
MTK_TRANSFORM_COMMA(MTK_CONSTRUCTOR_COPY, entries) {}\
|
||||
int getDOF() const { return DOF; } \
|
||||
void boxplus(const MTK::vectview<const scalar, DOF> & __vec, scalar __scale = 1 ) { \
|
||||
MTK_TRANSFORM(MTK_BOXPLUS, entries)\
|
||||
} \
|
||||
void oplus(const MTK::vectview<const scalar, DIM> & __vec, scalar __scale = 1 ) { \
|
||||
MTK_TRANSFORM(MTK_OPLUS, entries)\
|
||||
} \
|
||||
void boxminus(MTK::vectview<scalar,DOF> __res, const name& __oth) const { \
|
||||
MTK_TRANSFORM(MTK_BOXMINUS, entries)\
|
||||
} \
|
||||
friend std::ostream& operator<<(std::ostream& __os, const name& __var){ \
|
||||
return __os MTK_TRANSFORM(MTK_OSTREAM, entries); \
|
||||
} \
|
||||
void build_S2_state(){\
|
||||
MTK_TRANSFORM(MTK_S2_state, entries)\
|
||||
}\
|
||||
void build_vect_state(){\
|
||||
MTK_TRANSFORM(MTK_vect_state, entries)\
|
||||
}\
|
||||
void build_SO3_state(){\
|
||||
MTK_TRANSFORM(MTK_SO3_state, entries)\
|
||||
}\
|
||||
void S2_hat(Eigen::Matrix<scalar, 3, 3> &res, int idx) {\
|
||||
MTK_TRANSFORM(MTK_S2_hat, entries)\
|
||||
}\
|
||||
void S2_Nx_yy(Eigen::Matrix<scalar, 2, 3> &res, int idx) {\
|
||||
MTK_TRANSFORM(MTK_S2_Nx_yy, entries)\
|
||||
}\
|
||||
void S2_Mx(Eigen::Matrix<scalar, 3, 2> &res, Eigen::Matrix<scalar, 2, 1> dx, int idx) {\
|
||||
MTK_TRANSFORM(MTK_S2_Mx, entries)\
|
||||
}\
|
||||
friend std::istream& operator>>(std::istream& __is, name& __var){ \
|
||||
return __is MTK_TRANSFORM(MTK_ISTREAM, entries); \
|
||||
} \
|
||||
};
|
||||
|
||||
|
||||
|
||||
#endif /*MTK_AUTOCONSTRUCT_HPP_*/
|
||||
123
include/IKFoM_toolkit/mtk/src/SubManifold.hpp
Executable file
123
include/IKFoM_toolkit/mtk/src/SubManifold.hpp
Executable file
@@ -0,0 +1,123 @@
|
||||
// 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/src/SubManifold.hpp
|
||||
* @brief Defines the SubManifold class
|
||||
*/
|
||||
|
||||
|
||||
#ifndef SUBMANIFOLD_HPP_
|
||||
#define SUBMANIFOLD_HPP_
|
||||
|
||||
|
||||
#include "vectview.hpp"
|
||||
|
||||
|
||||
namespace MTK {
|
||||
|
||||
/**
|
||||
* @ingroup SubManifolds
|
||||
* Helper class for compound manifolds.
|
||||
* This class wraps a manifold T and provides an enum IDX refering to the
|
||||
* index of the SubManifold within the compound manifold.
|
||||
*
|
||||
* Memberpointers to a submanifold can be used for @ref SubManifolds "functions accessing submanifolds".
|
||||
*
|
||||
* @tparam T The manifold type of the sub-type
|
||||
* @tparam idx The index of the sub-type within the compound manifold
|
||||
*/
|
||||
template<class T, int idx, int dim>
|
||||
struct SubManifold : public T
|
||||
{
|
||||
enum {IDX = idx, DIM = dim /*!< index of the sub-type within the compound manifold */ };
|
||||
//! manifold type
|
||||
typedef T type;
|
||||
|
||||
//! Construct from derived type
|
||||
template<class X>
|
||||
explicit
|
||||
SubManifold(const X& t) : T(t) {};
|
||||
|
||||
//! Construct from internal type
|
||||
//explicit
|
||||
SubManifold(const T& t) : T(t) {};
|
||||
|
||||
//! inherit assignment operator
|
||||
using T::operator=;
|
||||
|
||||
};
|
||||
|
||||
} // namespace MTK
|
||||
|
||||
|
||||
#endif /* SUBMANIFOLD_HPP_ */
|
||||
294
include/IKFoM_toolkit/mtk/src/mtkmath.hpp
Executable file
294
include/IKFoM_toolkit/mtk/src/mtkmath.hpp
Executable file
@@ -0,0 +1,294 @@
|
||||
// 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/src/mtkmath.hpp
|
||||
* @brief several math utility functions.
|
||||
*/
|
||||
|
||||
#ifndef MTKMATH_H_
|
||||
#define MTKMATH_H_
|
||||
|
||||
#include <cmath>
|
||||
|
||||
#include <boost/math/tools/precision.hpp>
|
||||
|
||||
#include "../types/vect.hpp"
|
||||
|
||||
#ifndef M_PI
|
||||
#define M_PI 3.1415926535897932384626433832795
|
||||
#endif
|
||||
|
||||
|
||||
namespace MTK {
|
||||
|
||||
namespace internal {
|
||||
|
||||
template<class Manifold>
|
||||
struct traits {
|
||||
typedef typename Manifold::scalar scalar;
|
||||
enum {DOF = Manifold::DOF};
|
||||
typedef vect<DOF, scalar> vectorized_type;
|
||||
typedef Eigen::Matrix<scalar, DOF, DOF> matrix_type;
|
||||
};
|
||||
|
||||
template<>
|
||||
struct traits<float> : traits<Scalar<float> > {};
|
||||
template<>
|
||||
struct traits<double> : traits<Scalar<double> > {};
|
||||
|
||||
} // namespace internal
|
||||
|
||||
/**
|
||||
* \defgroup MTKMath Mathematical helper functions
|
||||
*/
|
||||
//@{
|
||||
|
||||
//! constant @f$ \pi @f$
|
||||
const double pi = M_PI;
|
||||
|
||||
template<class scalar> inline scalar tolerance();
|
||||
|
||||
template<> inline float tolerance<float >() { return 1e-5f; }
|
||||
template<> inline double tolerance<double>() { return 1e-11; }
|
||||
|
||||
|
||||
/**
|
||||
* normalize @a x to @f$[-bound, bound] @f$.
|
||||
*
|
||||
* result for @f$ x = bound + 2\cdot n\cdot bound @f$ is arbitrary @f$\pm bound @f$.
|
||||
*/
|
||||
template<class scalar>
|
||||
inline scalar normalize(scalar x, scalar bound){ //not used
|
||||
if(std::fabs(x) <= bound) return x;
|
||||
int r = (int)(x *(scalar(1.0)/ bound));
|
||||
return x - ((r + (r>>31) + 1) & ~1)*bound;
|
||||
}
|
||||
|
||||
/**
|
||||
* Calculate cosine and sinc of sqrt(x2).
|
||||
* @param x2 the squared angle must be non-negative
|
||||
* @return a pair containing cos and sinc of sqrt(x2)
|
||||
*/
|
||||
template<class scalar>
|
||||
std::pair<scalar, scalar> cos_sinc_sqrt(const scalar &x2){
|
||||
using std::sqrt;
|
||||
using std::cos;
|
||||
using std::sin;
|
||||
static scalar const taylor_0_bound = boost::math::tools::epsilon<scalar>();
|
||||
static scalar const taylor_2_bound = sqrt(taylor_0_bound);
|
||||
static scalar const taylor_n_bound = sqrt(taylor_2_bound);
|
||||
|
||||
assert(x2>=0 && "argument must be non-negative");
|
||||
|
||||
// FIXME check if bigger bounds are possible
|
||||
if(x2>=taylor_n_bound) {
|
||||
// slow fall-back solution
|
||||
scalar x = sqrt(x2);
|
||||
return std::make_pair(cos(x), sin(x)/x); // x is greater than 0.
|
||||
}
|
||||
|
||||
// FIXME Replace by Horner-Scheme (4 instead of 5 FLOP/term, numerically more stable, theoretically cos and sinc can be calculated in parallel using SSE2 mulpd/addpd)
|
||||
// TODO Find optimal coefficients using Remez algorithm
|
||||
static scalar const inv[] = {1/3., 1/4., 1/5., 1/6., 1/7., 1/8., 1/9.};
|
||||
scalar cosi = 1., sinc=1;
|
||||
scalar term = -1/2. * x2;
|
||||
for(int i=0; i<3; ++i) {
|
||||
cosi += term;
|
||||
term *= inv[2*i];
|
||||
sinc += term;
|
||||
term *= -inv[2*i+1] * x2;
|
||||
}
|
||||
|
||||
return std::make_pair(cosi, sinc);
|
||||
|
||||
}
|
||||
|
||||
template<typename Base>
|
||||
Eigen::Matrix<typename Base::scalar, 3, 3> hat(const Base& v) {
|
||||
Eigen::Matrix<typename Base::scalar, 3, 3> res;
|
||||
res << 0, -v[2], v[1],
|
||||
v[2], 0, -v[0],
|
||||
-v[1], v[0], 0;
|
||||
return res;
|
||||
}
|
||||
|
||||
template<typename Base>
|
||||
Eigen::Matrix<typename Base::scalar, 3, 3> A_inv_trans(const Base& v){
|
||||
Eigen::Matrix<typename Base::scalar, 3, 3> res;
|
||||
if(v.norm() > MTK::tolerance<typename Base::scalar>())
|
||||
{
|
||||
res = Eigen::Matrix<typename Base::scalar, 3, 3>::Identity() + 0.5 * hat<Base>(v) + (1 - v.norm() * std::cos(v.norm() / 2) / 2 / std::sin(v.norm() / 2)) * hat(v) * hat(v) / v.squaredNorm();
|
||||
|
||||
}
|
||||
else
|
||||
{
|
||||
res = Eigen::Matrix<typename Base::scalar, 3, 3>::Identity();
|
||||
}
|
||||
|
||||
return res;
|
||||
}
|
||||
|
||||
template<typename Base>
|
||||
Eigen::Matrix<typename Base::scalar, 3, 3> A_inv(const Base& v){
|
||||
Eigen::Matrix<typename Base::scalar, 3, 3> res;
|
||||
if(v.norm() > MTK::tolerance<typename Base::scalar>())
|
||||
{
|
||||
res = Eigen::Matrix<typename Base::scalar, 3, 3>::Identity() - 0.5 * hat<Base>(v) + (1 - v.norm() * std::cos(v.norm() / 2) / 2 / std::sin(v.norm() / 2)) * hat(v) * hat(v) / v.squaredNorm();
|
||||
|
||||
}
|
||||
else
|
||||
{
|
||||
res = Eigen::Matrix<typename Base::scalar, 3, 3>::Identity();
|
||||
}
|
||||
|
||||
return res;
|
||||
}
|
||||
|
||||
template<typename scalar>
|
||||
Eigen::Matrix<scalar, 2, 3> S2_w_expw_( Eigen::Matrix<scalar, 2, 1> v, scalar length)
|
||||
{
|
||||
Eigen::Matrix<scalar, 2, 3> res;
|
||||
scalar norm = std::sqrt(v[0]*v[0] + v[1]*v[1]);
|
||||
if(norm < MTK::tolerance<scalar>()){
|
||||
res = Eigen::Matrix<scalar, 2, 3>::Zero();
|
||||
res(0, 1) = 1;
|
||||
res(1, 2) = 1;
|
||||
res /= length;
|
||||
}
|
||||
else{
|
||||
res << -v[0]*(1/norm-1/std::tan(norm))/std::sin(norm), norm/std::sin(norm), 0,
|
||||
-v[1]*(1/norm-1/std::tan(norm))/std::sin(norm), 0, norm/std::sin(norm);
|
||||
res /= length;
|
||||
}
|
||||
}
|
||||
|
||||
template<typename Base>
|
||||
Eigen::Matrix<typename Base::scalar, 3, 3> A_matrix(const Base & v){
|
||||
Eigen::Matrix<typename Base::scalar, 3, 3> res;
|
||||
double squaredNorm = v[0] * v[0] + v[1] * v[1] + v[2] * v[2];
|
||||
double norm = std::sqrt(squaredNorm);
|
||||
if(norm < MTK::tolerance<typename Base::scalar>()){
|
||||
res = Eigen::Matrix<typename Base::scalar, 3, 3>::Identity();
|
||||
}
|
||||
else{
|
||||
res = Eigen::Matrix<typename Base::scalar, 3, 3>::Identity() + (1 - std::cos(norm)) / squaredNorm * hat(v) + (1 - std::sin(norm) / norm) / squaredNorm * hat(v) * hat(v);
|
||||
}
|
||||
return res;
|
||||
}
|
||||
|
||||
template<class scalar, int n>
|
||||
scalar exp(vectview<scalar, n> result, vectview<const scalar, n> vec, const scalar& scale = 1) {
|
||||
scalar norm2 = vec.squaredNorm();
|
||||
std::pair<scalar, scalar> cos_sinc = cos_sinc_sqrt(scale*scale * norm2);
|
||||
scalar mult = cos_sinc.second * scale;
|
||||
result = mult * vec;
|
||||
return cos_sinc.first;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Inverse function to @c exp.
|
||||
*
|
||||
* @param result @c vectview to the result
|
||||
* @param w scalar part of input
|
||||
* @param vec vector part of input
|
||||
* @param scale scale result by this value
|
||||
* @param plus_minus_periodicity if true values @f$[w, vec]@f$ and @f$[-w, -vec]@f$ give the same result
|
||||
*/
|
||||
template<class scalar, int n>
|
||||
void log(vectview<scalar, n> result,
|
||||
const scalar &w, const vectview<const scalar, n> vec,
|
||||
const scalar &scale, bool plus_minus_periodicity)
|
||||
{
|
||||
// FIXME implement optimized case for vec.squaredNorm() <= tolerance() * (w*w) via Rational Remez approximation ~> only one division
|
||||
scalar nv = vec.norm();
|
||||
if(nv < tolerance<scalar>()) {
|
||||
if(!plus_minus_periodicity && w < 0) {
|
||||
// find the maximal entry:
|
||||
int i;
|
||||
nv = vec.cwiseAbs().maxCoeff(&i);
|
||||
result = scale * std::atan2(nv, w) * vect<n, scalar>::Unit(i);
|
||||
return;
|
||||
}
|
||||
nv = tolerance<scalar>();
|
||||
}
|
||||
scalar s = scale / nv * (plus_minus_periodicity ? std::atan(nv / w) : std::atan2(nv, w) );
|
||||
|
||||
result = s * vec;
|
||||
}
|
||||
|
||||
|
||||
} // namespace MTK
|
||||
|
||||
|
||||
#endif /* MTKMATH_H_ */
|
||||
168
include/IKFoM_toolkit/mtk/src/vectview.hpp
Executable file
168
include/IKFoM_toolkit/mtk/src/vectview.hpp
Executable file
@@ -0,0 +1,168 @@
|
||||
|
||||
/*
|
||||
* 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/src/vectview.hpp
|
||||
* @brief Wrapper class around a pointer used as interface for plain vectors.
|
||||
*/
|
||||
|
||||
#ifndef VECTVIEW_HPP_
|
||||
#define VECTVIEW_HPP_
|
||||
|
||||
#include <Eigen/Core>
|
||||
|
||||
namespace MTK {
|
||||
|
||||
/**
|
||||
* A view to a vector.
|
||||
* Essentially, @c vectview is only a pointer to @c scalar but can be used directly in @c Eigen expressions.
|
||||
* The dimension of the vector is given as template parameter and type-checked when used in expressions.
|
||||
* Data has to be modifiable.
|
||||
*
|
||||
* @tparam scalar Scalar type of the vector.
|
||||
* @tparam dim Dimension of the vector.
|
||||
*
|
||||
* @todo @c vectview can be replaced by simple inheritance of @c Eigen::Map, as soon as they get const-correct
|
||||
*/
|
||||
namespace internal {
|
||||
template<class Base, class T1, class T2>
|
||||
struct CovBlock {
|
||||
typedef typename Eigen::Block<Eigen::Matrix<typename Base::scalar, Base::DOF, Base::DOF>, T1::DOF, T2::DOF> Type;
|
||||
typedef typename Eigen::Block<const Eigen::Matrix<typename Base::scalar, Base::DOF, Base::DOF>, T1::DOF, T2::DOF> ConstType;
|
||||
};
|
||||
|
||||
template<class Base, class T1, class T2>
|
||||
struct CovBlock_ {
|
||||
typedef typename Eigen::Block<Eigen::Matrix<typename Base::scalar, Base::DIM, Base::DIM>, T1::DIM, T2::DIM> Type;
|
||||
typedef typename Eigen::Block<const Eigen::Matrix<typename Base::scalar, Base::DIM, Base::DIM>, T1::DIM, T2::DIM> ConstType;
|
||||
};
|
||||
|
||||
template<typename Base1, typename Base2, typename T1, typename T2>
|
||||
struct CrossCovBlock {
|
||||
typedef typename Eigen::Block<Eigen::Matrix<typename Base1::scalar, Base1::DOF, Base2::DOF>, T1::DOF, T2::DOF> Type;
|
||||
typedef typename Eigen::Block<const Eigen::Matrix<typename Base1::scalar, Base1::DOF, Base2::DOF>, T1::DOF, T2::DOF> ConstType;
|
||||
};
|
||||
|
||||
template<typename Base1, typename Base2, typename T1, typename T2>
|
||||
struct CrossCovBlock_ {
|
||||
typedef typename Eigen::Block<Eigen::Matrix<typename Base1::scalar, Base1::DIM, Base2::DIM>, T1::DIM, T2::DIM> Type;
|
||||
typedef typename Eigen::Block<const Eigen::Matrix<typename Base1::scalar, Base1::DIM, Base2::DIM>, T1::DIM, T2::DIM> ConstType;
|
||||
};
|
||||
|
||||
template<class scalar, int dim>
|
||||
struct VectviewBase {
|
||||
typedef Eigen::Matrix<scalar, dim, 1> matrix_type;
|
||||
typedef typename matrix_type::MapType Type;
|
||||
typedef typename matrix_type::ConstMapType ConstType;
|
||||
};
|
||||
|
||||
template<class T>
|
||||
struct UnalignedType {
|
||||
typedef T type;
|
||||
};
|
||||
}
|
||||
|
||||
template<class scalar, int dim>
|
||||
class vectview : public internal::VectviewBase<scalar, dim>::Type {
|
||||
typedef internal::VectviewBase<scalar, dim> VectviewBase;
|
||||
public:
|
||||
//! plain matrix type
|
||||
typedef typename VectviewBase::matrix_type matrix_type;
|
||||
//! base type
|
||||
typedef typename VectviewBase::Type base;
|
||||
//! construct from pointer
|
||||
explicit
|
||||
vectview(scalar* data, int dim_=dim) : base(data, dim_) {}
|
||||
//! construct from plain matrix
|
||||
vectview(matrix_type& m) : base(m.data(), m.size()) {}
|
||||
//! construct from another @c vectview
|
||||
vectview(const vectview &v) : base(v) {}
|
||||
//! construct from Eigen::Block:
|
||||
template<class Base>
|
||||
vectview(Eigen::VectorBlock<Base, dim> block) : base(&block.coeffRef(0), block.size()) {}
|
||||
template<class Base, bool PacketAccess>
|
||||
vectview(Eigen::Block<Base, dim, 1, PacketAccess> block) : base(&block.coeffRef(0), block.size()) {}
|
||||
|
||||
//! inherit assignment operator
|
||||
using base::operator=;
|
||||
//! data pointer
|
||||
scalar* data() {return const_cast<scalar*>(base::data());}
|
||||
};
|
||||
|
||||
/**
|
||||
* @c const version of @c vectview.
|
||||
* Compared to @c Eigen::Map this implementation is const correct, i.e.,
|
||||
* data will not be modifiable using this view.
|
||||
*
|
||||
* @tparam scalar Scalar type of the vector.
|
||||
* @tparam dim Dimension of the vector.
|
||||
*
|
||||
* @sa vectview
|
||||
*/
|
||||
template<class scalar, int dim>
|
||||
class vectview<const scalar, dim> : public internal::VectviewBase<scalar, dim>::ConstType {
|
||||
typedef internal::VectviewBase<scalar, dim> VectviewBase;
|
||||
public:
|
||||
//! plain matrix type
|
||||
typedef typename VectviewBase::matrix_type matrix_type;
|
||||
//! base type
|
||||
typedef typename VectviewBase::ConstType base;
|
||||
//! construct from const pointer
|
||||
explicit
|
||||
vectview(const scalar* data, int dim_ = dim) : base(data, dim_) {}
|
||||
//! construct from column vector
|
||||
template<int options>
|
||||
vectview(const Eigen::Matrix<scalar, dim, 1, options>& m) : base(m.data()) {}
|
||||
//! construct from row vector
|
||||
template<int options, int phony>
|
||||
vectview(const Eigen::Matrix<scalar, 1, dim, options, phony>& m) : base(m.data()) {}
|
||||
//! construct from another @c vectview
|
||||
vectview(vectview<scalar, dim> x) : base(x.data()) {}
|
||||
//! construct from base
|
||||
vectview(const base &x) : base(x) {}
|
||||
/**
|
||||
* Construct from Block
|
||||
* @todo adapt this, when Block gets const-correct
|
||||
*/
|
||||
template<class Base>
|
||||
vectview(Eigen::VectorBlock<Base, dim> block) : base(&block.coeffRef(0)) {}
|
||||
template<class Base, bool PacketAccess>
|
||||
vectview(Eigen::Block<Base, dim, 1, PacketAccess> block) : base(&block.coeffRef(0)) {}
|
||||
|
||||
};
|
||||
|
||||
|
||||
} // namespace MTK
|
||||
|
||||
#endif /* VECTVIEW_HPP_ */
|
||||
328
include/IKFoM_toolkit/mtk/startIdx.hpp
Executable file
328
include/IKFoM_toolkit/mtk/startIdx.hpp
Executable file
@@ -0,0 +1,328 @@
|
||||
// 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_
|
||||
316
include/IKFoM_toolkit/mtk/types/S2.hpp
Executable file
316
include/IKFoM_toolkit/mtk/types/S2.hpp
Executable file
@@ -0,0 +1,316 @@
|
||||
// This is a NEW 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/types/S2.hpp
|
||||
* @brief Unit vectors on the sphere, or directions in 3D.
|
||||
*/
|
||||
#ifndef S2_H_
|
||||
#define S2_H_
|
||||
|
||||
|
||||
#include "vect.hpp"
|
||||
|
||||
#include "SOn.hpp"
|
||||
#include "../src/mtkmath.hpp"
|
||||
|
||||
|
||||
|
||||
|
||||
namespace MTK {
|
||||
|
||||
/**
|
||||
* Manifold representation of @f$ S^2 @f$.
|
||||
* Used for unit vectors on the sphere or directions in 3D.
|
||||
*
|
||||
* @todo add conversions from/to polar angles?
|
||||
*/
|
||||
template<class _scalar = double, int den = 1, int num = 1, int S2_typ = 3>
|
||||
struct S2 {
|
||||
|
||||
typedef _scalar scalar;
|
||||
typedef vect<3, scalar> vect_type;
|
||||
typedef SO3<scalar> SO3_type;
|
||||
typedef typename vect_type::base vec3;
|
||||
scalar length = scalar(den)/scalar(num);
|
||||
enum {DOF=2, TYP = 1, DIM = 3};
|
||||
|
||||
//private:
|
||||
/**
|
||||
* Unit vector on the sphere, or vector pointing in a direction
|
||||
*/
|
||||
vect_type vec;
|
||||
|
||||
public:
|
||||
S2() {
|
||||
if(S2_typ == 3) vec=length * vec3(0, 0, std::sqrt(1));
|
||||
if(S2_typ == 2) vec=length * vec3(0, std::sqrt(1), 0);
|
||||
if(S2_typ == 1) vec=length * vec3(std::sqrt(1), 0, 0);
|
||||
}
|
||||
S2(const scalar &x, const scalar &y, const scalar &z) : vec(vec3(x, y, z)) {
|
||||
vec.normalize();
|
||||
vec = vec * length;
|
||||
}
|
||||
|
||||
S2(const vect_type &_vec) : vec(_vec) {
|
||||
vec.normalize();
|
||||
vec = vec * length;
|
||||
}
|
||||
|
||||
void oplus(MTK::vectview<const scalar, 3> delta, scalar scale = 1)
|
||||
{
|
||||
SO3_type res;
|
||||
res.w() = MTK::exp<scalar, 3>(res.vec(), delta, scalar(scale/2));
|
||||
vec = res.toRotationMatrix() * vec;
|
||||
}
|
||||
|
||||
void boxplus(MTK::vectview<const scalar, 2> delta, scalar scale=1) {
|
||||
Eigen::Matrix<scalar, 3, 2> Bx;
|
||||
S2_Bx(Bx);
|
||||
vect_type Bu = Bx*delta;SO3_type res;
|
||||
res.w() = MTK::exp<scalar, 3>(res.vec(), Bu, scalar(scale/2));
|
||||
vec = res.toRotationMatrix() * vec;
|
||||
}
|
||||
|
||||
void boxminus(MTK::vectview<scalar, 2> res, const S2<scalar, den, num, S2_typ>& other) const {
|
||||
scalar v_sin = (MTK::hat(vec)*other.vec).norm();
|
||||
scalar v_cos = vec.transpose() * other.vec;
|
||||
scalar theta = std::atan2(v_sin, v_cos);
|
||||
if(v_sin < MTK::tolerance<scalar>())
|
||||
{
|
||||
if(std::fabs(theta) > MTK::tolerance<scalar>() )
|
||||
{
|
||||
res[0] = 3.1415926;
|
||||
res[1] = 0;
|
||||
}
|
||||
else{
|
||||
res[0] = 0;
|
||||
res[1] = 0;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
S2<scalar, den, num, S2_typ> other_copy = other;
|
||||
Eigen::Matrix<scalar, 3, 2>Bx;
|
||||
other_copy.S2_Bx(Bx);
|
||||
res = theta/v_sin * Bx.transpose() * MTK::hat(other.vec)*vec;
|
||||
}
|
||||
}
|
||||
|
||||
void S2_hat(Eigen::Matrix<scalar, 3, 3> &res)
|
||||
{
|
||||
Eigen::Matrix<scalar, 3, 3> skew_vec;
|
||||
skew_vec << scalar(0), -vec[2], vec[1],
|
||||
vec[2], scalar(0), -vec[0],
|
||||
-vec[1], vec[0], scalar(0);
|
||||
res = skew_vec;
|
||||
}
|
||||
|
||||
|
||||
void S2_Bx(Eigen::Matrix<scalar, 3, 2> &res)
|
||||
{
|
||||
if(S2_typ == 3)
|
||||
{
|
||||
if(vec[2] + length > tolerance<scalar>())
|
||||
{
|
||||
|
||||
res << length - vec[0]*vec[0]/(length+vec[2]), -vec[0]*vec[1]/(length+vec[2]),
|
||||
-vec[0]*vec[1]/(length+vec[2]), length-vec[1]*vec[1]/(length+vec[2]),
|
||||
-vec[0], -vec[1];
|
||||
res /= length;
|
||||
}
|
||||
else
|
||||
{
|
||||
res = Eigen::Matrix<scalar, 3, 2>::Zero();
|
||||
res(1, 1) = -1;
|
||||
res(2, 0) = 1;
|
||||
}
|
||||
}
|
||||
else if(S2_typ == 2)
|
||||
{
|
||||
if(vec[1] + length > tolerance<scalar>())
|
||||
{
|
||||
|
||||
res << length - vec[0]*vec[0]/(length+vec[1]), -vec[0]*vec[2]/(length+vec[1]),
|
||||
-vec[0], -vec[2],
|
||||
-vec[0]*vec[2]/(length+vec[1]), length-vec[2]*vec[2]/(length+vec[1]);
|
||||
res /= length;
|
||||
}
|
||||
else
|
||||
{
|
||||
res = Eigen::Matrix<scalar, 3, 2>::Zero();
|
||||
res(1, 1) = -1;
|
||||
res(2, 0) = 1;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
if(vec[0] + length > tolerance<scalar>())
|
||||
{
|
||||
|
||||
res << -vec[1], -vec[2],
|
||||
length - vec[1]*vec[1]/(length+vec[0]), -vec[2]*vec[1]/(length+vec[0]),
|
||||
-vec[2]*vec[1]/(length+vec[0]), length-vec[2]*vec[2]/(length+vec[0]);
|
||||
res /= length;
|
||||
}
|
||||
else
|
||||
{
|
||||
res = Eigen::Matrix<scalar, 3, 2>::Zero();
|
||||
res(1, 1) = -1;
|
||||
res(2, 0) = 1;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void S2_Nx(Eigen::Matrix<scalar, 2, 3> &res, S2<scalar, den, num, S2_typ>& subtrahend)
|
||||
{
|
||||
if((vec+subtrahend.vec).norm() > tolerance<scalar>())
|
||||
{
|
||||
Eigen::Matrix<scalar, 3, 2> Bx;
|
||||
S2_Bx(Bx);
|
||||
if((vec-subtrahend.vec).norm() > tolerance<scalar>())
|
||||
{
|
||||
scalar v_sin = (MTK::hat(vec)*subtrahend.vec).norm();
|
||||
scalar v_cos = vec.transpose() * subtrahend.vec;
|
||||
|
||||
res = Bx.transpose() * (std::atan2(v_sin, v_cos)/v_sin*MTK::hat(vec)+MTK::hat(vec)*subtrahend.vec*((-v_cos/v_sin/v_sin/length/length/length/length+std::atan2(v_sin, v_cos)/v_sin/v_sin/v_sin)*subtrahend.vec.transpose()*MTK::hat(vec)*MTK::hat(vec)-vec.transpose()/length/length/length/length));
|
||||
}
|
||||
else
|
||||
{
|
||||
res = 1/length/length*Bx.transpose()*MTK::hat(vec);
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
std::cerr << "No N(x, y) for x=-y" << std::endl;
|
||||
std::exit(100);
|
||||
}
|
||||
}
|
||||
|
||||
void S2_Nx_yy(Eigen::Matrix<scalar, 2, 3> &res)
|
||||
{
|
||||
Eigen::Matrix<scalar, 3, 2> Bx;
|
||||
S2_Bx(Bx);
|
||||
res = 1/length/length*Bx.transpose()*MTK::hat(vec);
|
||||
}
|
||||
|
||||
void S2_Mx(Eigen::Matrix<scalar, 3, 2> &res, MTK::vectview<const scalar, 2> delta)
|
||||
{
|
||||
Eigen::Matrix<scalar, 3, 2> Bx;
|
||||
S2_Bx(Bx);
|
||||
if(delta.norm() < tolerance<scalar>())
|
||||
{
|
||||
res = -MTK::hat(vec)*Bx;
|
||||
}
|
||||
else{
|
||||
vect_type Bu = Bx*delta;
|
||||
SO3_type exp_delta;
|
||||
exp_delta.w() = MTK::exp<scalar, 3>(exp_delta.vec(), Bu, scalar(1/2));
|
||||
res = -exp_delta.toRotationMatrix()*MTK::hat(vec)*MTK::A_matrix(Bu).transpose()*Bx;
|
||||
}
|
||||
}
|
||||
|
||||
operator const vect_type&() const{
|
||||
return vec;
|
||||
}
|
||||
|
||||
const vect_type& get_vect() const {
|
||||
return vec;
|
||||
}
|
||||
|
||||
friend S2<scalar, den, num, S2_typ> operator*(const SO3<scalar>& rot, const S2<scalar, den, num, S2_typ>& dir)
|
||||
{
|
||||
S2<scalar, den, num, S2_typ> ret;
|
||||
ret.vec = rot * dir.vec;
|
||||
return ret;
|
||||
}
|
||||
|
||||
scalar operator[](int idx) const {return vec[idx]; }
|
||||
|
||||
friend std::ostream& operator<<(std::ostream &os, const S2<scalar, den, num, S2_typ>& vec){
|
||||
return os << vec.vec.transpose() << " ";
|
||||
}
|
||||
friend std::istream& operator>>(std::istream &is, S2<scalar, den, num, S2_typ>& vec){
|
||||
for(int i=0; i<3; ++i)
|
||||
is >> vec.vec[i];
|
||||
vec.vec.normalize();
|
||||
vec.vec = vec.vec * vec.length;
|
||||
return is;
|
||||
|
||||
}
|
||||
};
|
||||
|
||||
|
||||
} // namespace MTK
|
||||
|
||||
|
||||
#endif /*S2_H_*/
|
||||
317
include/IKFoM_toolkit/mtk/types/SOn.hpp
Executable file
317
include/IKFoM_toolkit/mtk/types/SOn.hpp
Executable file
@@ -0,0 +1,317 @@
|
||||
// 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/types/SOn.hpp
|
||||
* @brief Standard Orthogonal Groups i.e.\ rotatation groups.
|
||||
*/
|
||||
#ifndef SON_H_
|
||||
#define SON_H_
|
||||
|
||||
#include <Eigen/Geometry>
|
||||
|
||||
#include "vect.hpp"
|
||||
#include "../src/mtkmath.hpp"
|
||||
|
||||
|
||||
namespace MTK {
|
||||
|
||||
|
||||
/**
|
||||
* Two-dimensional orientations represented as scalar.
|
||||
* There is no guarantee that the representing scalar is within any interval,
|
||||
* but the result of boxminus will always have magnitude @f$\le\pi @f$.
|
||||
*/
|
||||
template<class _scalar = double, int Options = Eigen::AutoAlign>
|
||||
struct SO2 : public Eigen::Rotation2D<_scalar> {
|
||||
enum {DOF = 1, DIM = 2, TYP = 3};
|
||||
|
||||
typedef _scalar scalar;
|
||||
typedef Eigen::Rotation2D<scalar> base;
|
||||
typedef vect<DIM, scalar, Options> vect_type;
|
||||
|
||||
//! Construct from angle
|
||||
SO2(const scalar& angle = 0) : base(angle) { }
|
||||
|
||||
//! Construct from Eigen::Rotation2D
|
||||
SO2(const base& src) : base(src) {}
|
||||
|
||||
/**
|
||||
* Construct from 2D vector.
|
||||
* Resulting orientation will rotate the first unit vector to point to vec.
|
||||
*/
|
||||
SO2(const vect_type &vec) : base(atan2(vec[1], vec[0])) {};
|
||||
|
||||
|
||||
//! Calculate @c this->inverse() * @c r
|
||||
SO2 operator%(const base &r) const {
|
||||
return base::inverse() * r;
|
||||
}
|
||||
|
||||
//! Calculate @c this->inverse() * @c r
|
||||
template<class Derived>
|
||||
vect_type operator%(const Eigen::MatrixBase<Derived> &vec) const {
|
||||
return base::inverse() * vec;
|
||||
}
|
||||
|
||||
//! Calculate @c *this * @c r.inverse()
|
||||
SO2 operator/(const SO2 &r) const {
|
||||
return *this * r.inverse();
|
||||
}
|
||||
|
||||
//! Gets the angle as scalar.
|
||||
operator scalar() const {
|
||||
return base::angle();
|
||||
}
|
||||
void S2_hat(Eigen::Matrix<scalar, 3, 3> &res)
|
||||
{
|
||||
res = Eigen::Matrix<scalar, 3, 3>::Zero();
|
||||
}
|
||||
//! @name Manifold requirements
|
||||
void S2_Nx_yy(Eigen::Matrix<scalar, 2, 3> &res)
|
||||
{
|
||||
std::cerr << "wrong idx for S2" << std::endl;
|
||||
std::exit(100);
|
||||
res = Eigen::Matrix<scalar, 2, 3>::Zero();
|
||||
}
|
||||
|
||||
void S2_Mx(Eigen::Matrix<scalar, 3, 2> &res, MTK::vectview<const scalar, 2> delta)
|
||||
{
|
||||
std::cerr << "wrong idx for S2" << std::endl;
|
||||
std::exit(100);
|
||||
res = Eigen::Matrix<scalar, 3, 2>::Zero();
|
||||
}
|
||||
|
||||
void oplus(MTK::vectview<const scalar, DOF> vec, scalar scale = 1) {
|
||||
base::angle() += scale * vec[0];
|
||||
}
|
||||
|
||||
void boxplus(MTK::vectview<const scalar, DOF> vec, scalar scale = 1) {
|
||||
base::angle() += scale * vec[0];
|
||||
}
|
||||
void boxminus(MTK::vectview<scalar, DOF> res, const SO2<scalar>& other) const {
|
||||
res[0] = MTK::normalize(base::angle() - other.angle(), scalar(MTK::pi));
|
||||
}
|
||||
|
||||
friend std::istream& operator>>(std::istream &is, SO2<scalar>& ang){
|
||||
return is >> ang.angle();
|
||||
}
|
||||
|
||||
};
|
||||
|
||||
|
||||
/**
|
||||
* Three-dimensional orientations represented as Quaternion.
|
||||
* It is assumed that the internal Quaternion always stays normalized,
|
||||
* should this not be the case, call inherited member function @c normalize().
|
||||
*/
|
||||
template<class _scalar = double, int Options = Eigen::AutoAlign>
|
||||
struct SO3 : public Eigen::Quaternion<_scalar, Options> {
|
||||
enum {DOF = 3, DIM = 3, TYP = 2};
|
||||
typedef _scalar scalar;
|
||||
typedef Eigen::Quaternion<scalar, Options> base;
|
||||
typedef Eigen::Quaternion<scalar> Quaternion;
|
||||
typedef vect<DIM, scalar, Options> vect_type;
|
||||
|
||||
//! Calculate @c this->inverse() * @c r
|
||||
template<class OtherDerived> EIGEN_STRONG_INLINE
|
||||
Quaternion operator%(const Eigen::QuaternionBase<OtherDerived> &r) const {
|
||||
return base::conjugate() * r;
|
||||
}
|
||||
|
||||
//! Calculate @c this->inverse() * @c r
|
||||
template<class Derived>
|
||||
vect_type operator%(const Eigen::MatrixBase<Derived> &vec) const {
|
||||
return base::conjugate() * vec;
|
||||
}
|
||||
|
||||
//! Calculate @c this * @c r.conjugate()
|
||||
template<class OtherDerived> EIGEN_STRONG_INLINE
|
||||
Quaternion operator/(const Eigen::QuaternionBase<OtherDerived> &r) const {
|
||||
return *this * r.conjugate();
|
||||
}
|
||||
|
||||
/**
|
||||
* Construct from real part and three imaginary parts.
|
||||
* Quaternion is normalized after construction.
|
||||
*/
|
||||
SO3(const scalar& w, const scalar& x, const scalar& y, const scalar& z) : base(w, x, y, z) {
|
||||
base::normalize();
|
||||
}
|
||||
|
||||
/**
|
||||
* Construct from Eigen::Quaternion.
|
||||
* @note Non-normalized input may result result in spurious behavior.
|
||||
*/
|
||||
SO3(const base& src = base::Identity()) : base(src) {}
|
||||
|
||||
/**
|
||||
* Construct from rotation matrix.
|
||||
* @note Invalid rotation matrices may lead to spurious behavior.
|
||||
*/
|
||||
template<class Derived>
|
||||
SO3(const Eigen::MatrixBase<Derived>& matrix) : base(matrix) {}
|
||||
|
||||
/**
|
||||
* Construct from arbitrary rotation type.
|
||||
* @note Invalid rotation matrices may lead to spurious behavior.
|
||||
*/
|
||||
template<class Derived>
|
||||
SO3(const Eigen::RotationBase<Derived, 3>& rotation) : base(rotation.derived()) {}
|
||||
|
||||
//! @name Manifold requirements
|
||||
|
||||
void boxplus(MTK::vectview<const scalar, DOF> vec, scalar scale=1) {
|
||||
SO3 delta = exp(vec, scale);
|
||||
*this = *this * delta;
|
||||
}
|
||||
void boxminus(MTK::vectview<scalar, DOF> res, const SO3<scalar>& other) const {
|
||||
res = SO3::log(other.conjugate() * *this);
|
||||
}
|
||||
//}
|
||||
|
||||
void oplus(MTK::vectview<const scalar, DOF> vec, scalar scale=1) {
|
||||
SO3 delta = exp(vec, scale);
|
||||
*this = *this * delta;
|
||||
}
|
||||
|
||||
void S2_hat(Eigen::Matrix<scalar, 3, 3> &res)
|
||||
{
|
||||
res = Eigen::Matrix<scalar, 3, 3>::Zero();
|
||||
}
|
||||
void S2_Nx_yy(Eigen::Matrix<scalar, 2, 3> &res)
|
||||
{
|
||||
std::cerr << "wrong idx for S2" << std::endl;
|
||||
std::exit(100);
|
||||
res = Eigen::Matrix<scalar, 2, 3>::Zero();
|
||||
}
|
||||
|
||||
void S2_Mx(Eigen::Matrix<scalar, 3, 2> &res, MTK::vectview<const scalar, 2> delta)
|
||||
{
|
||||
std::cerr << "wrong idx for S2" << std::endl;
|
||||
std::exit(100);
|
||||
res = Eigen::Matrix<scalar, 3, 2>::Zero();
|
||||
}
|
||||
|
||||
friend std::ostream& operator<<(std::ostream &os, const SO3<scalar, Options>& q){
|
||||
return os << q.coeffs().transpose() << " ";
|
||||
}
|
||||
|
||||
friend std::istream& operator>>(std::istream &is, SO3<scalar, Options>& q){
|
||||
vect<4,scalar> coeffs;
|
||||
is >> coeffs;
|
||||
q.coeffs() = coeffs.normalized();
|
||||
return is;
|
||||
}
|
||||
|
||||
//! @name Helper functions
|
||||
//{
|
||||
/**
|
||||
* Calculate the exponential map. In matrix terms this would correspond
|
||||
* to the Rodrigues formula.
|
||||
*/
|
||||
// FIXME vectview<> can't be constructed from every MatrixBase<>, use const Vector3x& as workaround
|
||||
// static SO3 exp(MTK::vectview<const scalar, 3> dvec, scalar scale = 1){
|
||||
static SO3 exp(const Eigen::Matrix<scalar, 3, 1>& dvec, scalar scale = 1){
|
||||
SO3 res;
|
||||
res.w() = MTK::exp<scalar, 3>(res.vec(), dvec, scalar(scale/2));
|
||||
return res;
|
||||
}
|
||||
/**
|
||||
* Calculate the inverse of @c exp.
|
||||
* Only guarantees that <code>exp(log(x)) == x </code>
|
||||
*/
|
||||
static typename base::Vector3 log(const SO3 &orient){
|
||||
typename base::Vector3 res;
|
||||
MTK::log<scalar, 3>(res, orient.w(), orient.vec(), scalar(2), true);
|
||||
return res;
|
||||
}
|
||||
};
|
||||
|
||||
namespace internal {
|
||||
template<class Scalar, int Options>
|
||||
struct UnalignedType<SO2<Scalar, Options > >{
|
||||
typedef SO2<Scalar, Options | Eigen::DontAlign> type;
|
||||
};
|
||||
|
||||
template<class Scalar, int Options>
|
||||
struct UnalignedType<SO3<Scalar, Options > >{
|
||||
typedef SO3<Scalar, Options | Eigen::DontAlign> type;
|
||||
};
|
||||
|
||||
} // namespace internal
|
||||
|
||||
|
||||
} // namespace MTK
|
||||
|
||||
#endif /*SON_H_*/
|
||||
|
||||
461
include/IKFoM_toolkit/mtk/types/vect.hpp
Executable file
461
include/IKFoM_toolkit/mtk/types/vect.hpp
Executable file
@@ -0,0 +1,461 @@
|
||||
// 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/types/vect.hpp
|
||||
* @brief Basic vectors interpreted as manifolds.
|
||||
*
|
||||
* This file also implements a simple wrapper for matrices, for arbitrary scalars
|
||||
* and for positive scalars.
|
||||
*/
|
||||
#ifndef VECT_H_
|
||||
#define VECT_H_
|
||||
|
||||
#include <iosfwd>
|
||||
#include <iostream>
|
||||
#include <vector>
|
||||
|
||||
#include "../src/vectview.hpp"
|
||||
|
||||
namespace MTK {
|
||||
|
||||
static const Eigen::IOFormat IO_no_spaces(Eigen::StreamPrecision, Eigen::DontAlignCols, ",", ",", "", "", "[", "]");
|
||||
|
||||
|
||||
/**
|
||||
* A simple vector class.
|
||||
* Implementation is basically a wrapper around Eigen::Matrix with manifold
|
||||
* requirements added.
|
||||
*/
|
||||
template<int D = 3, class _scalar = double, int _Options=Eigen::AutoAlign>
|
||||
struct vect : public Eigen::Matrix<_scalar, D, 1, _Options> {
|
||||
typedef Eigen::Matrix<_scalar, D, 1, _Options> base;
|
||||
enum {DOF = D, DIM = D, TYP = 0};
|
||||
typedef _scalar scalar;
|
||||
|
||||
//using base::operator=;
|
||||
|
||||
/** Standard constructor. Sets all values to zero. */
|
||||
vect(const base &src = base::Zero()) : base(src) {}
|
||||
|
||||
/** Constructor copying the value of the expression \a other */
|
||||
template<typename OtherDerived>
|
||||
EIGEN_STRONG_INLINE vect(const Eigen::DenseBase<OtherDerived>& other) : base(other) {}
|
||||
|
||||
/** Construct from memory. */
|
||||
vect(const scalar* src, int size = DOF) : base(base::Map(src, size)) { }
|
||||
|
||||
void boxplus(MTK::vectview<const scalar, D> vec, scalar scale=1) {
|
||||
*this += scale * vec;
|
||||
}
|
||||
void boxminus(MTK::vectview<scalar, D> res, const vect<D, scalar>& other) const {
|
||||
res = *this - other;
|
||||
}
|
||||
|
||||
void oplus(MTK::vectview<const scalar, D> vec, scalar scale=1) {
|
||||
*this += scale * vec;
|
||||
}
|
||||
|
||||
void S2_hat(Eigen::Matrix<scalar, 3, 3> &res)
|
||||
{
|
||||
res = Eigen::Matrix<scalar, 3, 3>::Zero();
|
||||
}
|
||||
|
||||
void S2_Nx_yy(Eigen::Matrix<scalar, 2, 3> &res)
|
||||
{
|
||||
std::cerr << "wrong idx for S2" << std::endl;
|
||||
std::exit(100);
|
||||
res = Eigen::Matrix<scalar, 2, 3>::Zero();
|
||||
}
|
||||
|
||||
void S2_Mx(Eigen::Matrix<scalar, 3, 2> &res, MTK::vectview<const scalar, 2> delta)
|
||||
{
|
||||
std::cerr << "wrong idx for S2" << std::endl;
|
||||
std::exit(100);
|
||||
res = Eigen::Matrix<scalar, 3, 2>::Zero();
|
||||
}
|
||||
|
||||
friend std::ostream& operator<<(std::ostream &os, const vect<D, scalar, _Options>& v){
|
||||
// Eigen sometimes messes with the streams flags, so output manually:
|
||||
for(int i=0; i<DOF; ++i)
|
||||
os << v(i) << " ";
|
||||
return os;
|
||||
}
|
||||
friend std::istream& operator>>(std::istream &is, vect<D, scalar, _Options>& v){
|
||||
char term=0;
|
||||
is >> std::ws; // skip whitespace
|
||||
switch(is.peek()) {
|
||||
case '(': term=')'; is.ignore(1); break;
|
||||
case '[': term=']'; is.ignore(1); break;
|
||||
case '{': term='}'; is.ignore(1); break;
|
||||
default: break;
|
||||
}
|
||||
if(D==Eigen::Dynamic) {
|
||||
assert(term !=0 && "Dynamic vectors must be embraced");
|
||||
std::vector<scalar> temp;
|
||||
while(is.good() && is.peek() != term) {
|
||||
scalar x;
|
||||
is >> x;
|
||||
temp.push_back(x);
|
||||
if(is.peek()==',') is.ignore(1);
|
||||
}
|
||||
v = vect::Map(temp.data(), temp.size());
|
||||
} else
|
||||
for(int i=0; i<v.size(); ++i){
|
||||
is >> v[i];
|
||||
if(is.peek()==',') { // ignore commas between values
|
||||
is.ignore(1);
|
||||
}
|
||||
}
|
||||
if(term!=0) {
|
||||
char x;
|
||||
is >> x;
|
||||
if(x!=term) {
|
||||
is.setstate(is.badbit);
|
||||
// assert(x==term && "start and end bracket do not match!");
|
||||
}
|
||||
}
|
||||
return is;
|
||||
}
|
||||
|
||||
template<int dim>
|
||||
vectview<scalar, dim> tail(){
|
||||
BOOST_STATIC_ASSERT(0< dim && dim <= DOF);
|
||||
return base::template tail<dim>();
|
||||
}
|
||||
template<int dim>
|
||||
vectview<const scalar, dim> tail() const{
|
||||
BOOST_STATIC_ASSERT(0< dim && dim <= DOF);
|
||||
return base::template tail<dim>();
|
||||
}
|
||||
template<int dim>
|
||||
vectview<scalar, dim> head(){
|
||||
BOOST_STATIC_ASSERT(0< dim && dim <= DOF);
|
||||
return base::template head<dim>();
|
||||
}
|
||||
template<int dim>
|
||||
vectview<const scalar, dim> head() const{
|
||||
BOOST_STATIC_ASSERT(0< dim && dim <= DOF);
|
||||
return base::template head<dim>();
|
||||
}
|
||||
};
|
||||
|
||||
|
||||
/**
|
||||
* A simple matrix class.
|
||||
* Implementation is basically a wrapper around Eigen::Matrix with manifold
|
||||
* requirements added, i.e., matrix is viewed as a plain vector for that.
|
||||
*/
|
||||
template<int M, int N, class _scalar = double, int _Options = Eigen::Matrix<_scalar, M, N>::Options>
|
||||
struct matrix : public Eigen::Matrix<_scalar, M, N, _Options> {
|
||||
typedef Eigen::Matrix<_scalar, M, N, _Options> base;
|
||||
enum {DOF = M * N, TYP = 4, DIM=0};
|
||||
typedef _scalar scalar;
|
||||
|
||||
using base::operator=;
|
||||
|
||||
/** Standard constructor. Sets all values to zero. */
|
||||
matrix() {
|
||||
base::setZero();
|
||||
}
|
||||
|
||||
/** Constructor copying the value of the expression \a other */
|
||||
template<typename OtherDerived>
|
||||
EIGEN_STRONG_INLINE matrix(const Eigen::MatrixBase<OtherDerived>& other) : base(other) {}
|
||||
|
||||
/** Construct from memory. */
|
||||
matrix(const scalar* src) : base(src) { }
|
||||
|
||||
void boxplus(MTK::vectview<const scalar, DOF> vec, scalar scale = 1) {
|
||||
*this += scale * base::Map(vec.data());
|
||||
}
|
||||
void boxminus(MTK::vectview<scalar, DOF> res, const matrix& other) const {
|
||||
base::Map(res.data()) = *this - other;
|
||||
}
|
||||
|
||||
void S2_hat(Eigen::Matrix<scalar, 3, 3> &res)
|
||||
{
|
||||
res = Eigen::Matrix<scalar, 3, 3>::Zero();
|
||||
}
|
||||
|
||||
void oplus(MTK::vectview<const scalar, DOF> vec, scalar scale = 1) {
|
||||
*this += scale * base::Map(vec.data());
|
||||
}
|
||||
|
||||
void S2_Nx_yy(Eigen::Matrix<scalar, 2, 3> &res)
|
||||
{
|
||||
std::cerr << "wrong idx for S2" << std::endl;
|
||||
std::exit(100);
|
||||
res = Eigen::Matrix<scalar, 2, 3>::Zero();
|
||||
}
|
||||
|
||||
void S2_Mx(Eigen::Matrix<scalar, 3, 2> &res, MTK::vectview<const scalar, 2> delta)
|
||||
{
|
||||
std::cerr << "wrong idx for S2" << std::endl;
|
||||
std::exit(100);
|
||||
res = Eigen::Matrix<scalar, 3, 2>::Zero();
|
||||
}
|
||||
|
||||
friend std::ostream& operator<<(std::ostream &os, const matrix<M, N, scalar, _Options>& mat){
|
||||
for(int i=0; i<DOF; ++i){
|
||||
os << mat.data()[i] << " ";
|
||||
}
|
||||
return os;
|
||||
}
|
||||
friend std::istream& operator>>(std::istream &is, matrix<M, N, scalar, _Options>& mat){
|
||||
for(int i=0; i<DOF; ++i){
|
||||
is >> mat.data()[i];
|
||||
}
|
||||
return is;
|
||||
}
|
||||
};// @todo What if M / N = Eigen::Dynamic?
|
||||
|
||||
|
||||
|
||||
/**
|
||||
* A simple scalar type.
|
||||
*/
|
||||
template<class _scalar = double>
|
||||
struct Scalar {
|
||||
enum {DOF = 1, TYP = 5, DIM=0};
|
||||
typedef _scalar scalar;
|
||||
|
||||
scalar value;
|
||||
|
||||
Scalar(const scalar& value = scalar(0)) : value(value) {}
|
||||
operator const scalar&() const { return value; }
|
||||
operator scalar&() { return value; }
|
||||
Scalar& operator=(const scalar& val) { value = val; return *this; }
|
||||
|
||||
void S2_hat(Eigen::Matrix<scalar, 3, 3> &res)
|
||||
{
|
||||
res = Eigen::Matrix<scalar, 3, 3>::Zero();
|
||||
}
|
||||
|
||||
void S2_Nx_yy(Eigen::Matrix<scalar, 2, 3> &res)
|
||||
{
|
||||
std::cerr << "wrong idx for S2" << std::endl;
|
||||
std::exit(100);
|
||||
res = Eigen::Matrix<scalar, 2, 3>::Zero();
|
||||
}
|
||||
|
||||
void S2_Mx(Eigen::Matrix<scalar, 3, 2> &res, MTK::vectview<const scalar, 2> delta)
|
||||
{
|
||||
std::cerr << "wrong idx for S2" << std::endl;
|
||||
std::exit(100);
|
||||
res = Eigen::Matrix<scalar, 3, 2>::Zero();
|
||||
}
|
||||
|
||||
void oplus(MTK::vectview<const scalar, DOF> vec, scalar scale=1) {
|
||||
value += scale * vec[0];
|
||||
}
|
||||
|
||||
void boxplus(MTK::vectview<const scalar, DOF> vec, scalar scale=1) {
|
||||
value += scale * vec[0];
|
||||
}
|
||||
void boxminus(MTK::vectview<scalar, DOF> res, const Scalar& other) const {
|
||||
res[0] = *this - other;
|
||||
}
|
||||
};
|
||||
|
||||
/**
|
||||
* Positive scalars.
|
||||
* Boxplus is implemented using multiplication by @f$x\boxplus\delta = x\cdot\exp(\delta) @f$.
|
||||
*/
|
||||
template<class _scalar = double>
|
||||
struct PositiveScalar {
|
||||
enum {DOF = 1, TYP = 6, DIM=0};
|
||||
typedef _scalar scalar;
|
||||
|
||||
scalar value;
|
||||
|
||||
PositiveScalar(const scalar& value = scalar(1)) : value(value) {
|
||||
assert(value > scalar(0));
|
||||
}
|
||||
operator const scalar&() const { return value; }
|
||||
PositiveScalar& operator=(const scalar& val) { assert(val>0); value = val; return *this; }
|
||||
|
||||
void boxplus(MTK::vectview<const scalar, DOF> vec, scalar scale = 1) {
|
||||
value *= std::exp(scale * vec[0]);
|
||||
}
|
||||
void boxminus(MTK::vectview<scalar, DOF> res, const PositiveScalar& other) const {
|
||||
res[0] = std::log(*this / other);
|
||||
}
|
||||
|
||||
void oplus(MTK::vectview<const scalar, DOF> vec, scalar scale = 1) {
|
||||
value *= std::exp(scale * vec[0]);
|
||||
}
|
||||
|
||||
void S2_hat(Eigen::Matrix<scalar, 3, 3> &res)
|
||||
{
|
||||
res = Eigen::Matrix<scalar, 3, 3>::Zero();
|
||||
}
|
||||
|
||||
void S2_Nx_yy(Eigen::Matrix<scalar, 2, 3> &res)
|
||||
{
|
||||
std::cerr << "wrong idx for S2" << std::endl;
|
||||
std::exit(100);
|
||||
res = Eigen::Matrix<scalar, 2, 3>::Zero();
|
||||
}
|
||||
|
||||
void S2_Mx(Eigen::Matrix<scalar, 3, 2> &res, MTK::vectview<const scalar, 2> delta)
|
||||
{
|
||||
std::cerr << "wrong idx for S2" << std::endl;
|
||||
std::exit(100);
|
||||
res = Eigen::Matrix<scalar, 3, 2>::Zero();
|
||||
}
|
||||
|
||||
|
||||
friend std::istream& operator>>(std::istream &is, PositiveScalar<scalar>& s){
|
||||
is >> s.value;
|
||||
assert(s.value > 0);
|
||||
return is;
|
||||
}
|
||||
};
|
||||
|
||||
template<class _scalar = double>
|
||||
struct Complex : public std::complex<_scalar>{
|
||||
enum {DOF = 2, TYP = 7, DIM=0};
|
||||
typedef _scalar scalar;
|
||||
|
||||
typedef std::complex<scalar> Base;
|
||||
|
||||
Complex(const Base& value) : Base(value) {}
|
||||
Complex(const scalar& re = 0.0, const scalar& im = 0.0) : Base(re, im) {}
|
||||
Complex(const MTK::vectview<const scalar, 2> &in) : Base(in[0], in[1]) {}
|
||||
template<class Derived>
|
||||
Complex(const Eigen::DenseBase<Derived> &in) : Base(in[0], in[1]) {}
|
||||
|
||||
void boxplus(MTK::vectview<const scalar, DOF> vec, scalar scale = 1) {
|
||||
Base::real() += scale * vec[0];
|
||||
Base::imag() += scale * vec[1];
|
||||
};
|
||||
void boxminus(MTK::vectview<scalar, DOF> res, const Complex& other) const {
|
||||
Complex diff = *this - other;
|
||||
res << diff.real(), diff.imag();
|
||||
}
|
||||
|
||||
void S2_hat(Eigen::Matrix<scalar, 3, 3> &res)
|
||||
{
|
||||
res = Eigen::Matrix<scalar, 3, 3>::Zero();
|
||||
}
|
||||
|
||||
void oplus(MTK::vectview<const scalar, DOF> vec, scalar scale = 1) {
|
||||
Base::real() += scale * vec[0];
|
||||
Base::imag() += scale * vec[1];
|
||||
};
|
||||
|
||||
void S2_Nx_yy(Eigen::Matrix<scalar, 2, 3> &res)
|
||||
{
|
||||
std::cerr << "wrong idx for S2" << std::endl;
|
||||
std::exit(100);
|
||||
res = Eigen::Matrix<scalar, 2, 3>::Zero();
|
||||
}
|
||||
|
||||
void S2_Mx(Eigen::Matrix<scalar, 3, 2> &res, MTK::vectview<const scalar, 2> delta)
|
||||
{
|
||||
std::cerr << "wrong idx for S2" << std::endl;
|
||||
std::exit(100);
|
||||
res = Eigen::Matrix<scalar, 3, 2>::Zero();
|
||||
}
|
||||
|
||||
scalar squaredNorm() const {
|
||||
return std::pow(Base::real(),2) + std::pow(Base::imag(),2);
|
||||
}
|
||||
|
||||
const scalar& operator()(int i) const {
|
||||
assert(0<=i && i<2 && "Index out of range");
|
||||
return i==0 ? Base::real() : Base::imag();
|
||||
}
|
||||
scalar& operator()(int i){
|
||||
assert(0<=i && i<2 && "Index out of range");
|
||||
return i==0 ? Base::real() : Base::imag();
|
||||
}
|
||||
};
|
||||
|
||||
|
||||
namespace internal {
|
||||
|
||||
template<int dim, class Scalar, int Options>
|
||||
struct UnalignedType<vect<dim, Scalar, Options > >{
|
||||
typedef vect<dim, Scalar, Options | Eigen::DontAlign> type;
|
||||
};
|
||||
|
||||
} // namespace internal
|
||||
|
||||
|
||||
} // namespace MTK
|
||||
|
||||
|
||||
|
||||
|
||||
#endif /*VECT_H_*/
|
||||
113
include/IKFoM_toolkit/mtk/types/wrapped_cv_mat.hpp
Executable file
113
include/IKFoM_toolkit/mtk/types/wrapped_cv_mat.hpp
Executable file
@@ -0,0 +1,113 @@
|
||||
/*
|
||||
* Copyright (c) 2010--2011, Universitaet Bremen and DFKI GmbH
|
||||
* All rights reserved.
|
||||
*
|
||||
* Author: Rene Wagner <rene.wagner@dfki.de>
|
||||
* 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 DFKI GmbH
|
||||
* 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.
|
||||
*/
|
||||
|
||||
#ifndef WRAPPED_CV_MAT_HPP_
|
||||
#define WRAPPED_CV_MAT_HPP_
|
||||
|
||||
#include <Eigen/Core>
|
||||
#include <opencv/cv.h>
|
||||
|
||||
namespace MTK {
|
||||
|
||||
template<class f_type>
|
||||
struct cv_f_type;
|
||||
|
||||
template<>
|
||||
struct cv_f_type<double>
|
||||
{
|
||||
enum {value = CV_64F};
|
||||
};
|
||||
|
||||
template<>
|
||||
struct cv_f_type<float>
|
||||
{
|
||||
enum {value = CV_32F};
|
||||
};
|
||||
|
||||
/**
|
||||
* cv_mat wraps a CvMat around an Eigen Matrix
|
||||
*/
|
||||
template<int rows, int cols, class f_type = double>
|
||||
class cv_mat : public matrix<rows, cols, f_type, cols==1 ? Eigen::ColMajor : Eigen::RowMajor>
|
||||
{
|
||||
typedef matrix<rows, cols, f_type, cols==1 ? Eigen::ColMajor : Eigen::RowMajor> base_type;
|
||||
enum {type_ = cv_f_type<f_type>::value};
|
||||
CvMat cv_mat_;
|
||||
|
||||
public:
|
||||
cv_mat()
|
||||
{
|
||||
cv_mat_ = cvMat(rows, cols, type_, base_type::data());
|
||||
}
|
||||
|
||||
cv_mat(const cv_mat& oth) : base_type(oth)
|
||||
{
|
||||
cv_mat_ = cvMat(rows, cols, type_, base_type::data());
|
||||
}
|
||||
|
||||
template<class Derived>
|
||||
cv_mat(const Eigen::MatrixBase<Derived> &value) : base_type(value)
|
||||
{
|
||||
cv_mat_ = cvMat(rows, cols, type_, base_type::data());
|
||||
}
|
||||
|
||||
template<class Derived>
|
||||
cv_mat& operator=(const Eigen::MatrixBase<Derived> &value)
|
||||
{
|
||||
base_type::operator=(value);
|
||||
return *this;
|
||||
}
|
||||
|
||||
cv_mat& operator=(const cv_mat& value)
|
||||
{
|
||||
base_type::operator=(value);
|
||||
return *this;
|
||||
}
|
||||
|
||||
// FIXME: Maybe overloading operator& is not a good idea ...
|
||||
CvMat* operator&()
|
||||
{
|
||||
return &cv_mat_;
|
||||
}
|
||||
const CvMat* operator&() const
|
||||
{
|
||||
return &cv_mat_;
|
||||
}
|
||||
};
|
||||
|
||||
} // namespace MTK
|
||||
|
||||
#endif /* WRAPPED_CV_MAT_HPP_ */
|
||||
@@ -5,66 +5,76 @@
|
||||
#include <Eigen/Eigen>
|
||||
#include <pcl/point_types.h>
|
||||
#include <pcl/point_cloud.h>
|
||||
#include <fast_lio/States.h>
|
||||
#include <fast_lio/Pose6D.h>
|
||||
#include <sensor_msgs/Imu.h>
|
||||
#include <nav_msgs/Odometry.h>
|
||||
#include <tf/transform_broadcaster.h>
|
||||
#include <eigen_conversions/eigen_msg.h>
|
||||
|
||||
using namespace std;
|
||||
using namespace Eigen;
|
||||
|
||||
// #define DEBUG_PRINT
|
||||
// #define USE_ikdtree
|
||||
#define USE_IKFOM
|
||||
|
||||
#define PI_M (3.14159265358)
|
||||
#define G_m_s2 (9.8099) // Gravaty const in GuangDong/China
|
||||
#define DIM_OF_STATES (18) // Dimension of states (Let Dim(SO(3)) = 3)
|
||||
#define DIM_OF_PROC_N (12) // Dimension of process noise (Let Dim(SO(3)) = 3)
|
||||
#define G_m_s2 (9.81) // Gravaty const in GuangDong/China
|
||||
#define DIM_STATE (18) // Dimension of states (Let Dim(SO(3)) = 3)
|
||||
#define DIM_PROC_N (12) // Dimension of process noise (Let Dim(SO(3)) = 3)
|
||||
#define CUBE_LEN (6.0)
|
||||
#define LIDAR_SP_LEN (2)
|
||||
#define INIT_COV (0.0001)
|
||||
#define INIT_COV (1)
|
||||
#define NUM_MATCH_POINTS (5)
|
||||
#define MAX_MEAS_DIM (10000)
|
||||
|
||||
#define VEC_FROM_ARRAY(v) v[0],v[1],v[2]
|
||||
#define MAT_FROM_ARRAY(v) v[0],v[1],v[2],v[3],v[4],v[5],v[6],v[7],v[8]
|
||||
#define CONSTRAIN(v,min,max) ((v>min)?((v<max)?v:max):min)
|
||||
#define ARRAY_FROM_EIGEN(mat) mat.data(), mat.data() + mat.rows() * mat.cols()
|
||||
#define STD_VEC_FROM_EIGEN(mat) std::vector<decltype(mat)::Scalar> (mat.data(), mat.data() + mat.rows() * mat.cols())
|
||||
|
||||
|
||||
#define DEBUG_FILE_DIR(name) (std::string(std::string(ROOT_DIR) + "Log/"+ name))
|
||||
#define STD_VEC_FROM_EIGEN(mat) vector<decltype(mat)::Scalar> (mat.data(), mat.data() + mat.rows() * mat.cols())
|
||||
#define DEBUG_FILE_DIR(name) (string(string(ROOT_DIR) + "Log/"+ name))
|
||||
|
||||
typedef fast_lio::Pose6D Pose6D;
|
||||
typedef pcl::PointXYZINormal PointType;
|
||||
typedef pcl::PointCloud<PointType> PointCloudXYZI;
|
||||
typedef vector<PointType, Eigen::aligned_allocator<PointType>> PointVector;
|
||||
typedef Vector3d V3D;
|
||||
typedef Matrix3d M3D;
|
||||
typedef Vector3f V3F;
|
||||
typedef Matrix3f M3F;
|
||||
|
||||
Eigen::Matrix3d Eye3d(Eigen::Matrix3d::Identity());
|
||||
Eigen::Matrix3f Eye3f(Eigen::Matrix3f::Identity());
|
||||
Eigen::Vector3d Zero3d(0, 0, 0);
|
||||
Eigen::Vector3f Zero3f(0, 0, 0);
|
||||
// Eigen::Vector3d Lidar_offset_to_IMU(0.05512, 0.02226, 0.0297); // Horizon
|
||||
Eigen::Vector3d Lidar_offset_to_IMU(0.04165, 0.02326, -0.0284); // Avia
|
||||
#define MD(a,b) Matrix<double, (a), (b)>
|
||||
#define VD(a) Matrix<double, (a), 1>
|
||||
#define MF(a,b) Matrix<float, (a), (b)>
|
||||
#define VF(a) Matrix<float, (a), 1>
|
||||
|
||||
M3D Eye3d(M3D::Identity());
|
||||
M3F Eye3f(M3F::Identity());
|
||||
V3D Zero3d(0, 0, 0);
|
||||
V3F Zero3f(0, 0, 0);
|
||||
|
||||
struct MeasureGroup // Lidar data and imu dates for the curent process
|
||||
{
|
||||
MeasureGroup()
|
||||
{
|
||||
lidar_beg_time = 0.0;
|
||||
this->lidar.reset(new PointCloudXYZI());
|
||||
};
|
||||
double lidar_beg_time;
|
||||
PointCloudXYZI::Ptr lidar;
|
||||
std::deque<sensor_msgs::Imu::ConstPtr> imu;
|
||||
deque<sensor_msgs::Imu::ConstPtr> imu;
|
||||
};
|
||||
|
||||
struct StatesGroup
|
||||
{
|
||||
StatesGroup() {
|
||||
this->rot_end = Eigen::Matrix3d::Identity();
|
||||
this->rot_end = M3D::Identity();
|
||||
this->pos_end = Zero3d;
|
||||
this->vel_end = Zero3d;
|
||||
this->bias_g = Zero3d;
|
||||
this->bias_a = Zero3d;
|
||||
this->gravity = Zero3d;
|
||||
this->cov = Eigen::Matrix<double,DIM_OF_STATES,DIM_OF_STATES>::Identity() * INIT_COV;
|
||||
this->cov = MD(DIM_STATE,DIM_STATE)::Identity() * INIT_COV;
|
||||
this->cov.block<9,9>(9,9) = MD(9,9)::Identity() * 0.00001;
|
||||
};
|
||||
|
||||
StatesGroup(const StatesGroup& b) {
|
||||
@@ -89,8 +99,7 @@ struct StatesGroup
|
||||
return *this;
|
||||
};
|
||||
|
||||
|
||||
StatesGroup operator+(const Eigen::Matrix<double, DIM_OF_STATES, 1> &state_add)
|
||||
StatesGroup operator+(const Matrix<double, DIM_STATE, 1> &state_add)
|
||||
{
|
||||
StatesGroup a;
|
||||
a.rot_end = this->rot_end * Exp(state_add(0,0), state_add(1,0), state_add(2,0));
|
||||
@@ -103,7 +112,7 @@ struct StatesGroup
|
||||
return a;
|
||||
};
|
||||
|
||||
StatesGroup& operator+=(const Eigen::Matrix<double, DIM_OF_STATES, 1> &state_add)
|
||||
StatesGroup& operator+=(const Matrix<double, DIM_STATE, 1> &state_add)
|
||||
{
|
||||
this->rot_end = this->rot_end * Exp(state_add(0,0), state_add(1,0), state_add(2,0));
|
||||
this->pos_end += state_add.block<3,1>(3,0);
|
||||
@@ -114,10 +123,10 @@ struct StatesGroup
|
||||
return *this;
|
||||
};
|
||||
|
||||
Eigen::Matrix<double, DIM_OF_STATES, 1> operator-(const StatesGroup& b)
|
||||
Matrix<double, DIM_STATE, 1> operator-(const StatesGroup& b)
|
||||
{
|
||||
Eigen::Matrix<double, DIM_OF_STATES, 1> a;
|
||||
Eigen::Matrix3d rotd(b.rot_end.transpose() * this->rot_end);
|
||||
Matrix<double, DIM_STATE, 1> a;
|
||||
M3D rotd(b.rot_end.transpose() * this->rot_end);
|
||||
a.block<3,1>(0,0) = Log(rotd);
|
||||
a.block<3,1>(3,0) = this->pos_end - b.pos_end;
|
||||
a.block<3,1>(6,0) = this->vel_end - b.vel_end;
|
||||
@@ -127,13 +136,20 @@ struct StatesGroup
|
||||
return a;
|
||||
};
|
||||
|
||||
Eigen::Matrix3d rot_end; // the estimated attitude (rotation matrix) at the end lidar point
|
||||
Eigen::Vector3d pos_end; // the estimated position at the end lidar point (world frame)
|
||||
Eigen::Vector3d vel_end; // the estimated velocity at the end lidar point (world frame)
|
||||
Eigen::Vector3d bias_g; // gyroscope bias
|
||||
Eigen::Vector3d bias_a; // accelerator bias
|
||||
Eigen::Vector3d gravity; // the estimated gravity acceleration
|
||||
Eigen::Matrix<double, DIM_OF_STATES, DIM_OF_STATES> cov; // states covariance
|
||||
void resetpose()
|
||||
{
|
||||
this->rot_end = M3D::Identity();
|
||||
this->pos_end = Zero3d;
|
||||
this->vel_end = Zero3d;
|
||||
}
|
||||
|
||||
M3D rot_end; // the estimated attitude (rotation matrix) at the end lidar point
|
||||
V3D pos_end; // the estimated position at the end lidar point (world frame)
|
||||
V3D vel_end; // the estimated velocity at the end lidar point (world frame)
|
||||
V3D bias_g; // gyroscope bias
|
||||
V3D bias_a; // accelerator bias
|
||||
V3D gravity; // the estimated gravity acceleration
|
||||
Matrix<double, DIM_STATE, DIM_STATE> cov; // states covariance
|
||||
};
|
||||
|
||||
template<typename T>
|
||||
@@ -149,8 +165,8 @@ T deg2rad(T degrees)
|
||||
}
|
||||
|
||||
template<typename T>
|
||||
auto set_pose6d(const double t, const Eigen::Matrix<T, 3, 1> &a, const Eigen::Matrix<T, 3, 1> &g, \
|
||||
const Eigen::Matrix<T, 3, 1> &v, const Eigen::Matrix<T, 3, 1> &p, const Eigen::Matrix<T, 3, 3> &R)
|
||||
auto set_pose6d(const double t, const Matrix<T, 3, 1> &a, const Matrix<T, 3, 1> &g, \
|
||||
const Matrix<T, 3, 1> &v, const Matrix<T, 3, 1> &p, const Matrix<T, 3, 3> &R)
|
||||
{
|
||||
Pose6D rot_kp;
|
||||
rot_kp.offset_time = t;
|
||||
@@ -162,10 +178,81 @@ auto set_pose6d(const double t, const Eigen::Matrix<T, 3, 1> &a, const Eigen::Ma
|
||||
rot_kp.pos[i] = p(i);
|
||||
for (int j = 0; j < 3; j++) rot_kp.rot[i*3+j] = R(i,j);
|
||||
}
|
||||
// Eigen::Map<Eigen::Matrix3d>(rot_kp.rot, 3,3) = R;
|
||||
return std::move(rot_kp);
|
||||
return move(rot_kp);
|
||||
}
|
||||
|
||||
/* comment
|
||||
plane equation: Ax + By + Cz + D = 0
|
||||
convert to: A/D*x + B/D*y + C/D*z = -1
|
||||
solve: A0*x0 = b0
|
||||
where A0_i = [x_i, y_i, z_i], x0 = [A/D, B/D, C/D]^T, b0 = [-1, ..., -1]^T
|
||||
normvec: normalized x0
|
||||
*/
|
||||
template<typename T>
|
||||
bool esti_normvector(Matrix<T, 3, 1> &normvec, const PointVector &point, const T &threshold, const int &point_num)
|
||||
{
|
||||
MatrixXf A(point_num, 3);
|
||||
MatrixXf b(point_num, 1);
|
||||
b.setOnes();
|
||||
b *= -1.0f;
|
||||
|
||||
for (int j = 0; j < point_num; j++)
|
||||
{
|
||||
A(j,0) = point[j].x;
|
||||
A(j,1) = point[j].y;
|
||||
A(j,2) = point[j].z;
|
||||
}
|
||||
normvec = A.colPivHouseholderQr().solve(b);
|
||||
|
||||
for (int j = 0; j < point_num; j++)
|
||||
{
|
||||
if (fabs(normvec(0) * point[j].x + normvec(1) * point[j].y + normvec(2) * point[j].z + 1.0f) > threshold)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
#endif
|
||||
normvec.normalize();
|
||||
return true;
|
||||
}
|
||||
|
||||
float calc_dist(PointType p1, PointType p2){
|
||||
float d = (p1.x - p2.x) * (p1.x - p2.x) + (p1.y - p2.y) * (p1.y - p2.y) + (p1.z - p2.z) * (p1.z - p2.z);
|
||||
return d;
|
||||
}
|
||||
|
||||
template<typename T>
|
||||
bool esti_plane(Matrix<T, 4, 1> &pca_result, const PointVector &point, const T &threshold)
|
||||
{
|
||||
Matrix<T, NUM_MATCH_POINTS, 3> A;
|
||||
Matrix<T, NUM_MATCH_POINTS, 1> b;
|
||||
A.setZero();
|
||||
b.setOnes();
|
||||
b *= -1.0f;
|
||||
|
||||
for (int j = 0; j < NUM_MATCH_POINTS; j++)
|
||||
{
|
||||
A(j,0) = point[j].x;
|
||||
A(j,1) = point[j].y;
|
||||
A(j,2) = point[j].z;
|
||||
}
|
||||
|
||||
Matrix<T, 3, 1> normvec = A.colPivHouseholderQr().solve(b);
|
||||
|
||||
T n = normvec.norm();
|
||||
pca_result(0) = normvec(0) / n;
|
||||
pca_result(1) = normvec(1) / n;
|
||||
pca_result(2) = normvec(2) / n;
|
||||
pca_result(3) = 1.0 / n;
|
||||
|
||||
for (int j = 0; j < NUM_MATCH_POINTS; j++)
|
||||
{
|
||||
if (fabs(pca_result(0) * point[j].x + pca_result(1) * point[j].y + pca_result(2) * point[j].z + pca_result(3)) > threshold)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
#endif
|
||||
1
include/ikd-Tree
Submodule
1
include/ikd-Tree
Submodule
Submodule include/ikd-Tree added at 3d115a4137
@@ -3,11 +3,17 @@
|
||||
|
||||
#include <math.h>
|
||||
#include <Eigen/Core>
|
||||
#include <opencv2/core.hpp>
|
||||
// #include <common_lib.h>
|
||||
|
||||
#define SKEW_SYM_MATRX(v) 0.0,-v[2],v[1],v[2],0.0,-v[0],-v[1],v[0],0.0
|
||||
|
||||
template<typename T>
|
||||
Eigen::Matrix<T, 3, 3> skew_sym_mat(const Eigen::Matrix<T, 3, 1> &v)
|
||||
{
|
||||
Eigen::Matrix<T, 3, 3> skew_sym_mat;
|
||||
skew_sym_mat<<0.0,-v[2],v[1],v[2],0.0,-v[0],-v[1],v[0],0.0;
|
||||
return skew_sym_mat;
|
||||
}
|
||||
|
||||
template<typename T>
|
||||
Eigen::Matrix<T, 3, 3> Exp(const Eigen::Matrix<T, 3, 1> &&ang)
|
||||
{
|
||||
|
||||
126
include/use-ikfom.hpp
Normal file
126
include/use-ikfom.hpp
Normal file
@@ -0,0 +1,126 @@
|
||||
#ifndef USE_IKFOM_H
|
||||
#define USE_IKFOM_H
|
||||
|
||||
#include <IKFoM_toolkit/esekfom/esekfom.hpp>
|
||||
|
||||
typedef MTK::vect<3, double> vect3;
|
||||
typedef MTK::SO3<double> SO3;
|
||||
typedef MTK::S2<double, 98090, 10000, 1> S2;
|
||||
typedef MTK::vect<1, double> vect1;
|
||||
typedef MTK::vect<2, double> vect2;
|
||||
|
||||
MTK_BUILD_MANIFOLD(state_ikfom,
|
||||
((vect3, pos))
|
||||
((SO3, rot))
|
||||
((SO3, offset_R_L_I))
|
||||
((vect3, offset_T_L_I))
|
||||
((vect3, vel))
|
||||
((vect3, bg))
|
||||
((vect3, ba))
|
||||
((S2, grav))
|
||||
);
|
||||
|
||||
MTK_BUILD_MANIFOLD(input_ikfom,
|
||||
((vect3, acc))
|
||||
((vect3, gyro))
|
||||
);
|
||||
|
||||
MTK_BUILD_MANIFOLD(process_noise_ikfom,
|
||||
((vect3, ng))
|
||||
((vect3, na))
|
||||
((vect3, nbg))
|
||||
((vect3, nba))
|
||||
);
|
||||
|
||||
MTK::get_cov<process_noise_ikfom>::type process_noise_cov()
|
||||
{
|
||||
MTK::get_cov<process_noise_ikfom>::type cov = MTK::get_cov<process_noise_ikfom>::type::Zero();
|
||||
MTK::setDiagonal<process_noise_ikfom, vect3, 0>(cov, &process_noise_ikfom::ng, 0.0001);// 0.03
|
||||
MTK::setDiagonal<process_noise_ikfom, vect3, 3>(cov, &process_noise_ikfom::na, 0.0001); // *dt 0.01 0.01 * dt * dt 0.05
|
||||
MTK::setDiagonal<process_noise_ikfom, vect3, 6>(cov, &process_noise_ikfom::nbg, 0.00001); // *dt 0.00001 0.00001 * dt *dt 0.3 //0.001 0.0001 0.01
|
||||
MTK::setDiagonal<process_noise_ikfom, vect3, 9>(cov, &process_noise_ikfom::nba, 0.00001); //0.001 0.05 0.0001/out 0.01
|
||||
return cov;
|
||||
}
|
||||
|
||||
//double L_offset_to_I[3] = {0.04165, 0.02326, -0.0284}; // Avia
|
||||
//vect3 Lidar_offset_to_IMU(L_offset_to_I, 3);
|
||||
Eigen::Matrix<double, 24, 1> get_f(state_ikfom &s, const input_ikfom &in)
|
||||
{
|
||||
Eigen::Matrix<double, 24, 1> res = Eigen::Matrix<double, 24, 1>::Zero();
|
||||
vect3 omega;
|
||||
in.gyro.boxminus(omega, s.bg);
|
||||
vect3 a_inertial = s.rot * (in.acc-s.ba);
|
||||
for(int i = 0; i < 3; i++ ){
|
||||
res(i) = s.vel[i];
|
||||
res(i + 3) = omega[i];
|
||||
res(i + 12) = a_inertial[i] + s.grav[i];
|
||||
}
|
||||
return res;
|
||||
}
|
||||
|
||||
Eigen::Matrix<double, 24, 23> df_dx(state_ikfom &s, const input_ikfom &in)
|
||||
{
|
||||
Eigen::Matrix<double, 24, 23> cov = Eigen::Matrix<double, 24, 23>::Zero();
|
||||
cov.template block<3, 3>(0, 12) = Eigen::Matrix3d::Identity();
|
||||
vect3 acc_;
|
||||
in.acc.boxminus(acc_, s.ba);
|
||||
vect3 omega;
|
||||
in.gyro.boxminus(omega, s.bg);
|
||||
cov.template block<3, 3>(12, 3) = -s.rot.toRotationMatrix()*MTK::hat(acc_);
|
||||
cov.template block<3, 3>(12, 18) = -s.rot.toRotationMatrix();
|
||||
Eigen::Matrix<state_ikfom::scalar, 2, 1> vec = Eigen::Matrix<state_ikfom::scalar, 2, 1>::Zero();
|
||||
Eigen::Matrix<state_ikfom::scalar, 3, 2> grav_matrix;
|
||||
s.S2_Mx(grav_matrix, vec, 21);
|
||||
cov.template block<3, 2>(12, 21) = grav_matrix;
|
||||
cov.template block<3, 3>(3, 15) = -Eigen::Matrix3d::Identity();
|
||||
return cov;
|
||||
}
|
||||
|
||||
|
||||
Eigen::Matrix<double, 24, 12> df_dw(state_ikfom &s, const input_ikfom &in)
|
||||
{
|
||||
Eigen::Matrix<double, 24, 12> cov = Eigen::Matrix<double, 24, 12>::Zero();
|
||||
cov.template block<3, 3>(12, 3) = -s.rot.toRotationMatrix();
|
||||
cov.template block<3, 3>(3, 0) = -Eigen::Matrix3d::Identity();
|
||||
cov.template block<3, 3>(15, 6) = Eigen::Matrix3d::Identity();
|
||||
cov.template block<3, 3>(18, 9) = Eigen::Matrix3d::Identity();
|
||||
return cov;
|
||||
}
|
||||
|
||||
vect3 SO3ToEuler(const SO3 &orient)
|
||||
{
|
||||
Eigen::Matrix<double, 3, 1> _ang;
|
||||
Eigen::Vector4d q_data = orient.coeffs().transpose();
|
||||
//scalar w=orient.coeffs[3], x=orient.coeffs[0], y=orient.coeffs[1], z=orient.coeffs[2];
|
||||
double sqw = q_data[3]*q_data[3];
|
||||
double sqx = q_data[0]*q_data[0];
|
||||
double sqy = q_data[1]*q_data[1];
|
||||
double sqz = q_data[2]*q_data[2];
|
||||
double unit = sqx + sqy + sqz + sqw; // if normalized is one, otherwise is correction factor
|
||||
double test = q_data[3]*q_data[1] - q_data[2]*q_data[0];
|
||||
|
||||
if (test > 0.49999*unit) { // singularity at north pole
|
||||
|
||||
_ang << 2 * std::atan2(q_data[0], q_data[3]), M_PI/2, 0;
|
||||
double temp[3] = {_ang[0] * 57.3, _ang[1] * 57.3, _ang[2] * 57.3};
|
||||
vect3 euler_ang(temp, 3);
|
||||
return euler_ang;
|
||||
}
|
||||
if (test < -0.49999*unit) { // singularity at south pole
|
||||
_ang << -2 * std::atan2(q_data[0], q_data[3]), -M_PI/2, 0;
|
||||
double temp[3] = {_ang[0] * 57.3, _ang[1] * 57.3, _ang[2] * 57.3};
|
||||
vect3 euler_ang(temp, 3);
|
||||
return euler_ang;
|
||||
}
|
||||
|
||||
_ang <<
|
||||
std::atan2(2*q_data[0]*q_data[3]+2*q_data[1]*q_data[2] , -sqx - sqy + sqz + sqw),
|
||||
std::asin (2*test/unit),
|
||||
std::atan2(2*q_data[2]*q_data[3]+2*q_data[1]*q_data[0] , sqx - sqy - sqz + sqw);
|
||||
double temp[3] = {_ang[0] * 57.3, _ang[1] * 57.3, _ang[2] * 57.3};
|
||||
vect3 euler_ang(temp, 3);
|
||||
// euler_ang[0] = roll, euler_ang[1] = pitch, euler_ang[2] = yaw
|
||||
return euler_ang;
|
||||
}
|
||||
|
||||
#endif
|
||||
Reference in New Issue
Block a user