123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879880881882883884885886887888889890891892893894895896897898899900901902903904905906907908909910911912913914915916917918919920921922923924925926927928929930931932933934935936937938939940941942943944945946947948949950951952953954955956957958959960961962963964965966967968969970971972973974975976977978979980981982983984985986987988989990991992993994995996997998999100010011002100310041005100610071008100910101011101210131014101510161017101810191020102110221023102410251026102710281029103010311032103310341035103610371038103910401041104210431044104510461047104810491050105110521053105410551056105710581059106010611062106310641065106610671068106910701071107210731074107510761077107810791080108110821083108410851086108710881089109010911092109310941095109610971098109911001101110211031104110511061107110811091110111111121113111411151116111711181119112011211122112311241125112611271128112911301131113211331134113511361137113811391140114111421143114411451146114711481149115011511152115311541155115611571158115911601161116211631164116511661167116811691170117111721173117411751176117711781179118011811182118311841185118611871188118911901191119211931194119511961197119811991200120112021203120412051206120712081209121012111212121312141215121612171218121912201221122212231224122512261227122812291230123112321233123412351236123712381239124012411242124312441245124612471248124912501251125212531254125512561257125812591260126112621263126412651266126712681269127012711272127312741275127612771278127912801281128212831284128512861287128812891290129112921293129412951296129712981299130013011302130313041305130613071308130913101311131213131314131513161317131813191320132113221323132413251326132713281329133013311332133313341335133613371338133913401341134213431344134513461347134813491350135113521353135413551356135713581359136013611362136313641365136613671368136913701371137213731374137513761377137813791380138113821383138413851386138713881389139013911392139313941395139613971398139914001401140214031404140514061407140814091410141114121413141414151416141714181419142014211422142314241425142614271428142914301431143214331434143514361437143814391440144114421443144414451446144714481449145014511452145314541455145614571458145914601461146214631464146514661467146814691470147114721473147414751476147714781479148014811482148314841485148614871488148914901491149214931494149514961497149814991500150115021503150415051506150715081509151015111512151315141515151615171518151915201521152215231524152515261527152815291530153115321533153415351536153715381539154015411542154315441545154615471548154915501551155215531554155515561557155815591560156115621563156415651566156715681569157015711572157315741575157615771578157915801581158215831584158515861587158815891590159115921593159415951596159715981599160016011602160316041605160616071608160916101611161216131614161516161617161816191620162116221623162416251626162716281629163016311632163316341635163616371638163916401641164216431644164516461647164816491650165116521653165416551656165716581659166016611662166316641665166616671668166916701671167216731674167516761677167816791680168116821683168416851686168716881689169016911692169316941695169616971698169917001701170217031704170517061707170817091710171117121713171417151716171717181719172017211722172317241725172617271728172917301731173217331734173517361737173817391740174117421743174417451746174717481749175017511752175317541755175617571758175917601761176217631764176517661767176817691770177117721773177417751776177717781779178017811782178317841785178617871788178917901791179217931794179517961797179817991800180118021803180418051806180718081809181018111812181318141815181618171818181918201821182218231824182518261827182818291830183118321833183418351836183718381839184018411842184318441845184618471848184918501851185218531854185518561857185818591860186118621863186418651866186718681869187018711872187318741875187618771878187918801881188218831884188518861887188818891890189118921893189418951896189718981899190019011902190319041905190619071908190919101911191219131914191519161917191819191920192119221923192419251926192719281929193019311932193319341935193619371938193919401941194219431944194519461947194819491950195119521953195419551956195719581959196019611962196319641965196619671968196919701971197219731974197519761977 |
- /*
- * 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 ESEKFOM_EKF_HPP
- #define ESEKFOM_EKF_HPP
- #include <vector>
- #include <cstdlib>
- #include <boost/bind.hpp>
- #include <Eigen/Core>
- #include <Eigen/Geometry>
- #include <Eigen/Dense>
- #include <Eigen/Sparse>
- #include "../mtk/types/vect.hpp"
- #include "../mtk/types/SOn.hpp"
- #include "../mtk/types/S2.hpp"
- #include "../mtk/startIdx.hpp"
- #include "../mtk/build_manifold.hpp"
- #include "util.hpp"
- //#define USE_sparse
- namespace esekfom {
- using namespace Eigen;
- //used for iterated error state EKF update
- //for the aim to calculate measurement (z), estimate measurement (h), partial differention matrices (h_x, h_v) and the noise covariance (R) at the same time, by only one function.
- //applied for measurement as a manifold.
- template<typename S, typename M, int measurement_noise_dof = M::DOF>
- struct share_datastruct
- {
- bool valid;
- bool converge;
- M z;
- Eigen::Matrix<typename S::scalar, M::DOF, measurement_noise_dof> h_v;
- Eigen::Matrix<typename S::scalar, M::DOF, S::DOF> h_x;
- Eigen::Matrix<typename S::scalar, measurement_noise_dof, measurement_noise_dof> R;
- };
- //used for iterated error state EKF update
- //for the aim to calculate measurement (z), estimate measurement (h), partial differention matrices (h_x, h_v) and the noise covariance (R) at the same time, by only one function.
- //applied for measurement as an Eigen matrix whose dimension is changing
- template<typename T>
- struct dyn_share_datastruct
- {
- bool valid;
- bool converge;
- Eigen::Matrix<T, Eigen::Dynamic, 1> z;
- Eigen::Matrix<T, Eigen::Dynamic, 1> h; // estimate measurement (h) 残差
- Eigen::Matrix<T, Eigen::Dynamic, Eigen::Dynamic> h_v;
- Eigen::Matrix<T, Eigen::Dynamic, Eigen::Dynamic> h_x; // partial differention matrices
- Eigen::Matrix<T, Eigen::Dynamic, Eigen::Dynamic> R;
- };
- //used for iterated error state EKF update
- //for the aim to calculate measurement (z), estimate measurement (h), partial differention matrices (h_x, h_v) and the noise covariance (R) at the same time, by only one function.
- //applied for measurement as a dynamic manifold whose dimension or type is changing
- template<typename T>
- struct dyn_runtime_share_datastruct
- {
- bool valid;
- bool converge;
- //Z z;
- Eigen::Matrix<T, Eigen::Dynamic, Eigen::Dynamic> h_v;
- Eigen::Matrix<T, Eigen::Dynamic, Eigen::Dynamic> h_x;
- Eigen::Matrix<T, Eigen::Dynamic, Eigen::Dynamic> R;
- };
- //状态量,噪声,输入状态量
- template<typename state, int process_noise_dof, typename input = state, typename measurement=state, int measurement_noise_dof=0>
- class esekf{
- typedef esekf self;
- enum{
- n = state::DOF, m = state::DIM, l = measurement::DOF
- };
- public:
-
- typedef typename state::scalar scalar_type;
- typedef Matrix<scalar_type, n, n> cov;
- typedef Matrix<scalar_type, m, n> cov_;
- typedef SparseMatrix<scalar_type> spMt;
- typedef Matrix<scalar_type, n, 1> vectorized_state;
- typedef Matrix<scalar_type, m, 1> flatted_state;
- typedef flatted_state processModel(state &, const input &);
- typedef Eigen::Matrix<scalar_type, m, n> processMatrix1(state &, const input &);
- typedef Eigen::Matrix<scalar_type, m, process_noise_dof> processMatrix2(state &, const input &);
- typedef Eigen::Matrix<scalar_type, process_noise_dof, process_noise_dof> processnoisecovariance;
- typedef measurement measurementModel(state &, bool &);
- typedef measurement measurementModel_share(state &, share_datastruct<state, measurement, measurement_noise_dof> &);
- typedef Eigen::Matrix<scalar_type, Eigen::Dynamic, 1> measurementModel_dyn(state &, bool &);
- //typedef Eigen::Matrix<scalar_type, Eigen::Dynamic, 1> measurementModel_dyn_share(state &, dyn_share_datastruct<scalar_type> &);
- typedef void measurementModel_dyn_share(state &, dyn_share_datastruct<scalar_type> &);
- typedef Eigen::Matrix<scalar_type ,l, n> measurementMatrix1(state &, bool&);
- typedef Eigen::Matrix<scalar_type , Eigen::Dynamic, n> measurementMatrix1_dyn(state &, bool&);
- typedef Eigen::Matrix<scalar_type ,l, measurement_noise_dof> measurementMatrix2(state &, bool&);
- typedef Eigen::Matrix<scalar_type ,Eigen::Dynamic, Eigen::Dynamic> measurementMatrix2_dyn(state &, bool&);
- typedef Eigen::Matrix<scalar_type, measurement_noise_dof, measurement_noise_dof> measurementnoisecovariance;
- typedef Eigen::Matrix<scalar_type, Eigen::Dynamic, Eigen::Dynamic> measurementnoisecovariance_dyn;
- esekf(const state &x = state(),
- const cov &P = cov::Identity()): x_(x), P_(P){
- #ifdef USE_sparse
- SparseMatrix<scalar_type> ref(n, n);
- ref.setIdentity();
- l_ = ref;
- f_x_2 = ref;
- f_x_1 = ref;
- #endif
- };
- //receive system-specific models and their differentions.
- //for measurement as a manifold.
- void init(processModel f_in, processMatrix1 f_x_in, processMatrix2 f_w_in, measurementModel h_in, measurementMatrix1 h_x_in, measurementMatrix2 h_v_in, int maximum_iteration, scalar_type limit_vector[n])
- {
- f = f_in;
- f_x = f_x_in;
- f_w = f_w_in;
- h = h_in;
- h_x = h_x_in;
- h_v = h_v_in;
- maximum_iter = maximum_iteration;
- for(int i=0; i<n; i++)
- {
- limit[i] = limit_vector[i];
- }
- x_.build_S2_state();
- x_.build_SO3_state();
- x_.build_vect_state();
- }
- //receive system-specific models and their differentions.
- //for measurement as an Eigen matrix whose dimention is chaing.
- void init_dyn(processModel f_in, processMatrix1 f_x_in, processMatrix2 f_w_in, measurementModel_dyn h_in, measurementMatrix1_dyn h_x_in, measurementMatrix2_dyn h_v_in, int maximum_iteration, scalar_type limit_vector[n])
- {
- f = f_in;
- f_x = f_x_in;
- f_w = f_w_in;
- h_dyn = h_in;
- h_x_dyn = h_x_in;
- h_v_dyn = h_v_in;
- maximum_iter = maximum_iteration;
- for(int i=0; i<n; i++)
- {
- limit[i] = limit_vector[i];
- }
-
- x_.build_S2_state();
- x_.build_SO3_state();
- x_.build_vect_state();
- }
- //receive system-specific models and their differentions.
- //for measurement as a dynamic manifold whose dimension or type is changing.
- void init_dyn_runtime(processModel f_in, processMatrix1 f_x_in, processMatrix2 f_w_in, measurementMatrix1_dyn h_x_in, measurementMatrix2_dyn h_v_in, int maximum_iteration, scalar_type limit_vector[n])
- {
- f = f_in;
- f_x = f_x_in;
- f_w = f_w_in;
- h_x_dyn = h_x_in;
- h_v_dyn = h_v_in;
- maximum_iter = maximum_iteration;
- for(int i=0; i<n; i++)
- {
- limit[i] = limit_vector[i];
- }
- x_.build_S2_state();
- x_.build_SO3_state();
- x_.build_vect_state();
- }
- //receive system-specific models and their differentions
- //for measurement as a manifold.
- //calculate measurement (z), estimate measurement (h), partial differention matrices (h_x, h_v) and the noise covariance (R) at the same time, by only one function (h_share_in).
- void init_share(processModel f_in, processMatrix1 f_x_in, processMatrix2 f_w_in, measurementModel_share h_share_in, int maximum_iteration, scalar_type limit_vector[n])
- {
- f = f_in;
- f_x = f_x_in;
- f_w = f_w_in;
- h_share = h_share_in;
- maximum_iter = maximum_iteration;
- for(int i=0; i<n; i++)
- {
- limit[i] = limit_vector[i];
- }
- x_.build_S2_state();
- x_.build_SO3_state();
- x_.build_vect_state();
- }
- //receive system-specific models and their differentions
- //for measurement as an Eigen matrix whose dimension is changing.
- //calculate measurement (z), estimate measurement (h), partial differention matrices (h_x, h_v) and the noise covariance (R) at the same time, by only one function (h_dyn_share_in).
- void init_dyn_share(processModel f_in, processMatrix1 f_x_in, processMatrix2 f_w_in, measurementModel_dyn_share h_dyn_share_in, int maximum_iteration, scalar_type limit_vector[n])
- {
- f = f_in;
- f_x = f_x_in;
- f_w = f_w_in;
- h_dyn_share = h_dyn_share_in;
- maximum_iter = maximum_iteration;
- for(int i=0; i<n; i++)
- {
- limit[i] = limit_vector[i];
- }
- x_.build_S2_state();
- x_.build_SO3_state();
- x_.build_vect_state();
- }
- //receive system-specific models and their differentions
- //for measurement as a dynamic manifold whose dimension or type is changing.
- //calculate measurement (z), estimate measurement (h), partial differention matrices (h_x, h_v) and the noise covariance (R) at the same time, by only one function (h_dyn_share_in).
- //for any scenarios where it is needed
- void init_dyn_runtime_share(processModel f_in, processMatrix1 f_x_in, processMatrix2 f_w_in, int maximum_iteration, scalar_type limit_vector[n])
- {
- f = f_in;
- f_x = f_x_in;
- f_w = f_w_in;
- maximum_iter = maximum_iteration;
- for(int i=0; i<n; i++)
- {
- limit[i] = limit_vector[i];
- }
- x_.build_S2_state();
- x_.build_SO3_state();
- x_.build_vect_state();
- }
- // iterated error state EKF propogation
- void predict(double &dt, processnoisecovariance &Q, const input &i_in){
- flatted_state f_ = f(x_, i_in);
- cov_ f_x_ = f_x(x_, i_in);
- cov f_x_final;
- Matrix<scalar_type, m, process_noise_dof> f_w_ = f_w(x_, i_in);
- Matrix<scalar_type, n, process_noise_dof> f_w_final;
- state x_before = x_;
- x_.oplus(f_, dt);
- F_x1 = cov::Identity();
- for (std::vector<std::pair<std::pair<int, int>, int> >::iterator it = x_.vect_state.begin(); it != x_.vect_state.end(); it++) {
- int idx = (*it).first.first;
- int dim = (*it).first.second;
- int dof = (*it).second;
- for(int i = 0; i < n; i++){
- for(int j=0; j<dof; j++)
- {f_x_final(idx+j, i) = f_x_(dim+j, i);}
- }
- for(int i = 0; i < process_noise_dof; i++){
- for(int j=0; j<dof; j++)
- {f_w_final(idx+j, i) = f_w_(dim+j, i);}
- }
- }
- Matrix<scalar_type, 3, 3> res_temp_SO3;
- MTK::vect<3, scalar_type> seg_SO3;
- for (std::vector<std::pair<int, int> >::iterator it = x_.SO3_state.begin(); it != x_.SO3_state.end(); it++) {
- int idx = (*it).first;
- int dim = (*it).second;
- for(int i = 0; i < 3; i++){
- seg_SO3(i) = -1 * f_(dim + i) * dt;
- }
- MTK::SO3<scalar_type> res;
- res.w() = MTK::exp<scalar_type, 3>(res.vec(), seg_SO3, scalar_type(1/2));
- #ifdef USE_sparse
- res_temp_SO3 = res.toRotationMatrix();
- for(int i = 0; i < 3; i++){
- for(int j = 0; j < 3; j++){
- f_x_1.coeffRef(idx + i, idx + j) = res_temp_SO3(i, j);
- }
- }
- #else
- F_x1.template block<3, 3>(idx, idx) = res.toRotationMatrix();
- #endif
- res_temp_SO3 = MTK::A_matrix(seg_SO3);
- for(int i = 0; i < n; i++){
- f_x_final. template block<3, 1>(idx, i) = res_temp_SO3 * (f_x_. template block<3, 1>(dim, i));
- }
- for(int i = 0; i < process_noise_dof; i++){
- f_w_final. template block<3, 1>(idx, i) = res_temp_SO3 * (f_w_. template block<3, 1>(dim, i));
- }
- }
-
-
- Matrix<scalar_type, 2, 3> res_temp_S2;
- Matrix<scalar_type, 2, 2> res_temp_S2_;
- MTK::vect<3, scalar_type> seg_S2;
- for (std::vector<std::pair<int, int> >::iterator it = x_.S2_state.begin(); it != x_.S2_state.end(); it++) {
- int idx = (*it).first;
- int dim = (*it).second;
- for(int i = 0; i < 3; i++){
- seg_S2(i) = f_(dim + i) * dt;
- }
- MTK::vect<2, scalar_type> vec = MTK::vect<2, scalar_type>::Zero();
- MTK::SO3<scalar_type> res;
- res.w() = MTK::exp<scalar_type, 3>(res.vec(), seg_S2, scalar_type(1/2));
- Eigen::Matrix<scalar_type, 2, 3> Nx;
- Eigen::Matrix<scalar_type, 3, 2> Mx;
- x_.S2_Nx_yy(Nx, idx);
- x_before.S2_Mx(Mx, vec, idx);
- #ifdef USE_sparse
- res_temp_S2_ = Nx * res.toRotationMatrix() * Mx;
- for(int i = 0; i < 2; i++){
- for(int j = 0; j < 2; j++){
- f_x_1.coeffRef(idx + i, idx + j) = res_temp_S2_(i, j);
- }
- }
- #else
- F_x1.template block<2, 2>(idx, idx) = Nx * res.toRotationMatrix() * Mx;
- #endif
- Eigen::Matrix<scalar_type, 3, 3> x_before_hat;
- x_before.S2_hat(x_before_hat, idx);
- res_temp_S2 = -Nx * res.toRotationMatrix() * x_before_hat*MTK::A_matrix(seg_S2).transpose();
-
- for(int i = 0; i < n; i++){
- f_x_final. template block<2, 1>(idx, i) = res_temp_S2 * (f_x_. template block<3, 1>(dim, i));
-
- }
- for(int i = 0; i < process_noise_dof; i++){
- f_w_final. template block<2, 1>(idx, i) = res_temp_S2 * (f_w_. template block<3, 1>(dim, i));
- }
- }
-
- #ifdef USE_sparse
- f_x_1.makeCompressed();
- spMt f_x2 = f_x_final.sparseView();
- spMt f_w1 = f_w_final.sparseView();
- spMt xp = f_x_1 + f_x2 * dt;
- P_ = xp * P_ * xp.transpose() + (f_w1 * dt) * Q * (f_w1 * dt).transpose();
- #else
- F_x1 += f_x_final * dt;
- P_ = (F_x1) * P_ * (F_x1).transpose() + (dt * f_w_final) * Q * (dt * f_w_final).transpose();//更新协方差矩阵
- #endif
- }
- //iterated error state EKF update for measurement as a manifold.
- void update_iterated(measurement& z, measurementnoisecovariance &R) {
-
- if(!(is_same<typename measurement::scalar, scalar_type>())){
- std::cerr << "the scalar type of measurment must be the same as the state" << std::endl;
- std::exit(100);
- }
- int t = 0;
- bool converg = true;
- bool valid = true;
- state x_propagated = x_;
- cov P_propagated = P_;
-
- for(int i=-1; i<maximum_iter; i++)
- {
- vectorized_state dx, dx_new;
- x_.boxminus(dx, x_propagated);
- dx_new = dx;
- #ifdef USE_sparse
- spMt h_x_ = h_x(x_, valid).sparseView();
- spMt h_v_ = h_v(x_, valid).sparseView();
- spMt R_ = R.sparseView();
- #else
- Matrix<scalar_type, l, n> h_x_ = h_x(x_, valid);
- Matrix<scalar_type, l, Eigen::Dynamic> h_v_ = h_v(x_, valid);
- #endif
- if(! valid)
- {
- continue;
- }
- P_ = P_propagated;
-
- Matrix<scalar_type, 3, 3> res_temp_SO3;
- MTK::vect<3, scalar_type> seg_SO3;
- for (std::vector<std::pair<int, int> >::iterator it = x_.SO3_state.begin(); it != x_.SO3_state.end(); it++) {
- int idx = (*it).first;
- int dim = (*it).second;
- for(int i = 0; i < 3; i++){
- seg_SO3(i) = dx(idx+i);
- }
- res_temp_SO3 = A_matrix(seg_SO3).transpose();
- dx_new.template block<3, 1>(idx, 0) = res_temp_SO3 * dx.template block<3, 1>(idx, 0);
- for(int i = 0; i < n; i++){
- P_. template block<3, 1>(idx, i) = res_temp_SO3 * (P_. template block<3, 1>(idx, i));
- }
- for(int i = 0; i < n; i++){
- P_. template block<1, 3>(i, idx) =(P_. template block<1, 3>(i, idx)) * res_temp_SO3.transpose();
- }
- }
-
-
- Matrix<scalar_type, 2, 2> res_temp_S2;
- MTK::vect<2, scalar_type> seg_S2;
- for (std::vector<std::pair<int, int> >::iterator it = x_.S2_state.begin(); it != x_.S2_state.end(); it++) {
- int idx = (*it).first;
- int dim = (*it).second;
- for(int i = 0; i < 2; i++){
- seg_S2(i) = dx(idx + i);
- }
-
- Eigen::Matrix<scalar_type, 2, 3> Nx;
- Eigen::Matrix<scalar_type, 3, 2> Mx;
- x_.S2_Nx_yy(Nx, idx);
- x_propagated.S2_Mx(Mx, seg_S2, idx);
- res_temp_S2 = Nx * Mx;
- dx_new.template block<2, 1>(idx, 0) = res_temp_S2 * dx.template block<2, 1>(idx, 0);
- for(int i = 0; i < n; i++){
- P_. template block<2, 1>(idx, i) = res_temp_S2 * (P_. template block<2, 1>(idx, i));
- }
- for(int i = 0; i < n; i++){
- P_. template block<1, 2>(i, idx) = (P_. template block<1, 2>(i, idx)) * res_temp_S2.transpose();
- }
- }
- Matrix<scalar_type, n, l> K_;
- if(n > l)
- {
- #ifdef USE_sparse
- Matrix<scalar_type, l, l> K_temp = h_x_ * P_ * h_x_.transpose();
- spMt R_temp = h_v_ * R_ * h_v_.transpose();
- K_temp += R_temp;
- K_ = P_ * h_x_.transpose() * K_temp.inverse();
- #else
- K_= P_ * h_x_.transpose() * (h_x_ * P_ * h_x_.transpose() + h_v_ * R * h_v_.transpose()).inverse();
- #endif
- }
- else
- {
- #ifdef USE_sparse
- measurementnoisecovariance b = measurementnoisecovariance::Identity();
- Eigen::SparseQR<Eigen::SparseMatrix<scalar_type>, Eigen::COLAMDOrdering<int>> solver;
- solver.compute(R_);
- measurementnoisecovariance R_in_temp = solver.solve(b);
- spMt R_in = R_in_temp.sparseView();
- spMt K_temp = h_x_.transpose() * R_in * h_x_;
- cov P_temp = P_.inverse();
- P_temp += K_temp;
- K_ = P_temp.inverse() * h_x_.transpose() * R_in;
- #else
- measurementnoisecovariance R_in = (h_v_*R*h_v_.transpose()).inverse();
- K_ = (h_x_.transpose() * R_in * h_x_ + P_.inverse()).inverse() * h_x_.transpose() * R_in;
- #endif
- }
- Matrix<scalar_type, l, 1> innovation;
- z.boxminus(innovation, h(x_, valid));
- cov K_x = K_ * h_x_;
- Matrix<scalar_type, n, 1> dx_ = K_ * innovation + (K_x - Matrix<scalar_type, n, n>::Identity()) * dx_new;
- state x_before = x_;
- x_.boxplus(dx_);
- converg = true;
- for(int i = 0; i < n ; i++)
- {
- if(std::fabs(dx_[i]) > limit[i])
- {
- converg = false;
- break;
- }
- }
- if(converg) t++;
-
- if(t > 1 || i == maximum_iter - 1)
- {
- L_ = P_;
-
- Matrix<scalar_type, 3, 3> res_temp_SO3;
- MTK::vect<3, scalar_type> seg_SO3;
- for(typename std::vector<std::pair<int, int> >::iterator it = x_.SO3_state.begin(); it != x_.SO3_state.end(); it++) {
- int idx = (*it).first;
- for(int i = 0; i < 3; i++){
- seg_SO3(i) = dx_(i + idx);
- }
- res_temp_SO3 = A_matrix(seg_SO3).transpose();
- for(int i = 0; i < n; i++){
- L_. template block<3, 1>(idx, i) = res_temp_SO3 * (P_. template block<3, 1>(idx, i));
- }
- if(n > l)
- {
- for(int i = 0; i < l; i++){
- K_. template block<3, 1>(idx, i) = res_temp_SO3 * (K_. template block<3, 1>(idx, i));
- }
- }
- else
- {
- for(int i = 0; i < n; i++){
- K_x. template block<3, 1>(idx, i) = res_temp_SO3 * (K_x. template block<3, 1>(idx, i));
- }
- }
- for(int i = 0; i < n; i++){
- L_. template block<1, 3>(i, idx) = (L_. template block<1, 3>(i, idx)) * res_temp_SO3.transpose();
- P_. template block<1, 3>(i, idx) = (P_. template block<1, 3>(i, idx)) * res_temp_SO3.transpose();
- }
- }
- Matrix<scalar_type, 2, 2> res_temp_S2;
- MTK::vect<2, scalar_type> seg_S2;
- for(typename std::vector<std::pair<int, int> >::iterator it = x_.S2_state.begin(); it != x_.S2_state.end(); it++) {
- int idx = (*it).first;
-
- for(int i = 0; i < 2; i++){
- seg_S2(i) = dx_(i + idx);
- }
-
- Eigen::Matrix<scalar_type, 2, 3> Nx;
- Eigen::Matrix<scalar_type, 3, 2> Mx;
- x_.S2_Nx_yy(Nx, idx);
- x_propagated.S2_Mx(Mx, seg_S2, idx);
- res_temp_S2 = Nx * Mx;
-
- for(int i = 0; i < n; i++){
- L_. template block<2, 1>(idx, i) = res_temp_S2 * (P_. template block<2, 1>(idx, i));
- }
- if(n > l)
- {
- for(int i = 0; i < l; i++){
- K_. template block<2, 1>(idx, i) = res_temp_S2 * (K_. template block<2, 1>(idx, i));
- }
- }
- else
- {
- for(int i = 0; i < n; i++){
- K_x. template block<2, 1>(idx, i) = res_temp_S2 * (K_x. template block<2, 1>(idx, i));
- }
- }
- for(int i = 0; i < n; i++){
- L_. template block<1, 2>(i, idx) = (L_. template block<1, 2>(i, idx)) * res_temp_S2.transpose();
- P_. template block<1, 2>(i, idx) = (P_. template block<1, 2>(i, idx)) * res_temp_S2.transpose();
- }
- }
- if(n > l)
- {
- P_ = L_ - K_ * h_x_ * P_;
- }
- else
- {
- P_ = L_ - K_x * P_;
- }
- return;
- }
- }
- }
- //iterated error state EKF update for measurement as a manifold.
- //calculate measurement (z), estimate measurement (h), partial differention matrices (h_x, h_v) and the noise covariance (R) at the same time, by only one function.
- void update_iterated_share() {
-
- if(!(is_same<typename measurement::scalar, scalar_type>())){
- std::cerr << "the scalar type of measurment must be the same as the state" << std::endl;
- std::exit(100);
- }
- int t = 0;
- share_datastruct<state, measurement, measurement_noise_dof> _share;
- _share.valid = true;
- _share.converge = true;
- state x_propagated = x_;
- cov P_propagated = P_;
-
- for(int i=-1; i<maximum_iter; i++)
- {
- vectorized_state dx, dx_new;
- x_.boxminus(dx, x_propagated);
- dx_new = dx;
- measurement h = h_share(x_, _share);
- measurement z = _share.z;
- measurementnoisecovariance R = _share.R;
- #ifdef USE_sparse
- spMt h_x_ = _share.h_x.sparseView();
- spMt h_v_ = _share.h_v.sparseView();
- spMt R_ = _share.R.sparseView();
- #else
- Matrix<scalar_type, l, n> h_x_ = _share.h_x;
- Matrix<scalar_type, l, Eigen::Dynamic> h_v_ = _share.h_v;
- #endif
- if(! _share.valid)
- {
- continue;
- }
- P_ = P_propagated;
-
- Matrix<scalar_type, 3, 3> res_temp_SO3;
- MTK::vect<3, scalar_type> seg_SO3;
- for (std::vector<std::pair<int, int> >::iterator it = x_.SO3_state.begin(); it != x_.SO3_state.end(); it++) {
- int idx = (*it).first;
- int dim = (*it).second;
- for(int i = 0; i < 3; i++){
- seg_SO3(i) = dx(idx+i);
- }
- res_temp_SO3 = A_matrix(seg_SO3).transpose();
- dx_new.template block<3, 1>(idx, 0) = res_temp_SO3 * dx.template block<3, 1>(idx, 0);
- for(int i = 0; i < n; i++){
- P_. template block<3, 1>(idx, i) = res_temp_SO3 * (P_. template block<3, 1>(idx, i));
- }
- for(int i = 0; i < n; i++){
- P_. template block<1, 3>(i, idx) =(P_. template block<1, 3>(i, idx)) * res_temp_SO3.transpose();
- }
- }
-
-
- Matrix<scalar_type, 2, 2> res_temp_S2;
- MTK::vect<2, scalar_type> seg_S2;
- for (std::vector<std::pair<int, int> >::iterator it = x_.S2_state.begin(); it != x_.S2_state.end(); it++) {
- int idx = (*it).first;
- int dim = (*it).second;
- for(int i = 0; i < 2; i++){
- seg_S2(i) = dx(idx + i);
- }
-
- Eigen::Matrix<scalar_type, 2, 3> Nx;
- Eigen::Matrix<scalar_type, 3, 2> Mx;
- x_.S2_Nx_yy(Nx, idx);
- x_propagated.S2_Mx(Mx, seg_S2, idx);
- res_temp_S2 = Nx * Mx;
- dx_new.template block<2, 1>(idx, 0) = res_temp_S2 * dx.template block<2, 1>(idx, 0);
- for(int i = 0; i < n; i++){
- P_. template block<2, 1>(idx, i) = res_temp_S2 * (P_. template block<2, 1>(idx, i));
- }
- for(int i = 0; i < n; i++){
- P_. template block<1, 2>(i, idx) = (P_. template block<1, 2>(i, idx)) * res_temp_S2.transpose();
- }
- }
- Matrix<scalar_type, n, l> K_;
- if(n > l)
- {
- #ifdef USE_sparse
- Matrix<scalar_type, l, l> K_temp = h_x_ * P_ * h_x_.transpose();
- spMt R_temp = h_v_ * R_ * h_v_.transpose();
- K_temp += R_temp;
- K_ = P_ * h_x_.transpose() * K_temp.inverse();
- #else
- K_= P_ * h_x_.transpose() * (h_x_ * P_ * h_x_.transpose() + h_v_ * R * h_v_.transpose()).inverse();
- #endif
- }
- else
- {
- #ifdef USE_sparse
- measurementnoisecovariance b = measurementnoisecovariance::Identity();
- Eigen::SparseQR<Eigen::SparseMatrix<scalar_type>, Eigen::COLAMDOrdering<int>> solver;
- solver.compute(R_);
- measurementnoisecovariance R_in_temp = solver.solve(b);
- spMt R_in = R_in_temp.sparseView();
- spMt K_temp = h_x_.transpose() * R_in * h_x_;
- cov P_temp = P_.inverse();
- P_temp += K_temp;
- K_ = P_temp.inverse() * h_x_.transpose() * R_in;
- #else
- measurementnoisecovariance R_in = (h_v_*R*h_v_.transpose()).inverse();
- K_ = (h_x_.transpose() * R_in * h_x_ + P_.inverse()).inverse() * h_x_.transpose() * R_in;
- #endif
- }
- Matrix<scalar_type, l, 1> innovation;
- z.boxminus(innovation, h);
- cov K_x = K_ * h_x_;
- Matrix<scalar_type, n, 1> dx_ = K_ * innovation + (K_x - Matrix<scalar_type, n, n>::Identity()) * dx_new;
- state x_before = x_;
- x_.boxplus(dx_);
- _share.converge = true;
- for(int i = 0; i < n ; i++)
- {
- if(std::fabs(dx_[i]) > limit[i])
- {
- _share.converge = false;
- break;
- }
- }
- if(_share.converge) t++;
-
- if(t > 1 || i == maximum_iter - 1)
- {
- L_ = P_;
-
- Matrix<scalar_type, 3, 3> res_temp_SO3;
- MTK::vect<3, scalar_type> seg_SO3;
- for(typename std::vector<std::pair<int, int> >::iterator it = x_.SO3_state.begin(); it != x_.SO3_state.end(); it++) {
- int idx = (*it).first;
- for(int i = 0; i < 3; i++){
- seg_SO3(i) = dx_(i + idx);
- }
- res_temp_SO3 = A_matrix(seg_SO3).transpose();
- for(int i = 0; i < n; i++){
- L_. template block<3, 1>(idx, i) = res_temp_SO3 * (P_. template block<3, 1>(idx, i));
- }
- if(n > l)
- {
- for(int i = 0; i < l; i++){
- K_. template block<3, 1>(idx, i) = res_temp_SO3 * (K_. template block<3, 1>(idx, i));
- }
- }
- else
- {
- for(int i = 0; i < n; i++){
- K_x. template block<3, 1>(idx, i) = res_temp_SO3 * (K_x. template block<3, 1>(idx, i));
- }
- }
- for(int i = 0; i < n; i++){
- L_. template block<1, 3>(i, idx) = (L_. template block<1, 3>(i, idx)) * res_temp_SO3.transpose();
- P_. template block<1, 3>(i, idx) = (P_. template block<1, 3>(i, idx)) * res_temp_SO3.transpose();
- }
- }
- Matrix<scalar_type, 2, 2> res_temp_S2;
- MTK::vect<2, scalar_type> seg_S2;
- for(typename std::vector<std::pair<int, int> >::iterator it = x_.S2_state.begin(); it != x_.S2_state.end(); it++) {
- int idx = (*it).first;
-
- for(int i = 0; i < 2; i++){
- seg_S2(i) = dx_(i + idx);
- }
-
- Eigen::Matrix<scalar_type, 2, 3> Nx;
- Eigen::Matrix<scalar_type, 3, 2> Mx;
- x_.S2_Nx_yy(Nx, idx);
- x_propagated.S2_Mx(Mx, seg_S2, idx);
- res_temp_S2 = Nx * Mx;
-
- for(int i = 0; i < n; i++){
- L_. template block<2, 1>(idx, i) = res_temp_S2 * (P_. template block<2, 1>(idx, i));
- }
- if(n > l)
- {
- for(int i = 0; i < l; i++){
- K_. template block<2, 1>(idx, i) = res_temp_S2 * (K_. template block<2, 1>(idx, i));
- }
- }
- else
- {
- for(int i = 0; i < n; i++){
- K_x. template block<2, 1>(idx, i) = res_temp_S2 * (K_x. template block<2, 1>(idx, i));
- }
- }
- for(int i = 0; i < n; i++){
- L_. template block<1, 2>(i, idx) = (L_. template block<1, 2>(i, idx)) * res_temp_S2.transpose();
- P_. template block<1, 2>(i, idx) = (P_. template block<1, 2>(i, idx)) * res_temp_S2.transpose();
- }
- }
- if(n > l)
- {
- P_ = L_ - K_ * h_x_ * P_;
- }
- else
- {
- P_ = L_ - K_x * P_;
- }
- return;
- }
- }
- }
- //iterated error state EKF update for measurement as an Eigen matrix whose dimension is changing.
- void update_iterated_dyn(Eigen::Matrix<scalar_type, Eigen::Dynamic, 1> z, measurementnoisecovariance_dyn R) {
-
- int t = 0;
- bool valid = true;
- bool converg = true;
- state x_propagated = x_;
- cov P_propagated = P_;
- int dof_Measurement;
- int dof_Measurement_noise = R.rows();
- for(int i=-1; i<maximum_iter; i++)
- {
- valid = true;
- #ifdef USE_sparse
- spMt h_x_ = h_x_dyn(x_, valid).sparseView();
- spMt h_v_ = h_v_dyn(x_, valid).sparseView();
- spMt R_ = R.sparseView();
- #else
- Matrix<scalar_type, Eigen::Dynamic, n> h_x_ = h_x_dyn(x_, valid);
- Matrix<scalar_type, Eigen::Dynamic, Eigen::Dynamic> h_v_ = h_v_dyn(x_, valid);
- #endif
- Matrix<scalar_type, Eigen::Dynamic, 1> h_ = h_dyn(x_, valid);
- dof_Measurement = h_.rows();
- vectorized_state dx, dx_new;
- x_.boxminus(dx, x_propagated);
- dx_new = dx;
- if(! valid)
- {
- continue;
- }
- P_ = P_propagated;
- Matrix<scalar_type, 3, 3> res_temp_SO3;
- MTK::vect<3, scalar_type> seg_SO3;
- for (std::vector<std::pair<int, int> >::iterator it = x_.SO3_state.begin(); it != x_.SO3_state.end(); it++) {
- int idx = (*it).first;
- int dim = (*it).second;
- for(int i = 0; i < 3; i++){
- seg_SO3(i) = dx(idx+i);
- }
- res_temp_SO3 = MTK::A_matrix(seg_SO3).transpose();
- dx_new.template block<3, 1>(idx, 0) = res_temp_SO3 * dx_new.template block<3, 1>(idx, 0);
- for(int i = 0; i < n; i++){
- P_. template block<3, 1>(idx, i) = res_temp_SO3 * (P_. template block<3, 1>(idx, i));
- }
- for(int i = 0; i < n; i++){
- P_. template block<1, 3>(i, idx) =(P_. template block<1, 3>(i, idx)) * res_temp_SO3.transpose();
- }
- }
-
- Matrix<scalar_type, 2, 2> res_temp_S2;
- MTK::vect<2, scalar_type> seg_S2;
- for (std::vector<std::pair<int, int> >::iterator it = x_.S2_state.begin(); it != x_.S2_state.end(); it++) {
- int idx = (*it).first;
- int dim = (*it).second;
- for(int i = 0; i < 2; i++){
- seg_S2(i) = dx(idx + i);
- }
- Eigen::Matrix<scalar_type, 2, 3> Nx;
- Eigen::Matrix<scalar_type, 3, 2> Mx;
- x_.S2_Nx_yy(Nx, idx);
- x_propagated.S2_Mx(Mx, seg_S2, idx);
- res_temp_S2 = Nx * Mx;
- dx_new.template block<2, 1>(idx, 0) = res_temp_S2 * dx_new.template block<2, 1>(idx, 0);
- for(int i = 0; i < n; i++){
- P_. template block<2, 1>(idx, i) = res_temp_S2 * (P_. template block<2, 1>(idx, i));
- }
- for(int i = 0; i < n; i++){
- P_. template block<1, 2>(i, idx) = (P_. template block<1, 2>(i, idx)) * res_temp_S2.transpose();
- }
- }
- Matrix<scalar_type, Eigen::Dynamic, Eigen::Dynamic> K_;
- if(n > dof_Measurement)
- {
- #ifdef USE_sparse
- Matrix<scalar_type, Eigen::Dynamic, Eigen::Dynamic> K_temp = h_x_ * P_ * h_x_.transpose();
- spMt R_temp = h_v_ * R_ * h_v_.transpose();
- K_temp += R_temp;
- K_ = P_ * h_x_.transpose() * K_temp.inverse();
- #else
- K_= P_ * h_x_.transpose() * (h_x_ * P_ * h_x_.transpose() + h_v_ * R * h_v_.transpose()).inverse();
- #endif
- }
- else
- {
- #ifdef USE_sparse
- Eigen::Matrix<scalar_type, Eigen::Dynamic, Eigen::Dynamic> b = Eigen::Matrix<scalar_type, Eigen::Dynamic, Eigen::Dynamic>::Identity(dof_Measurement_noise, dof_Measurement_noise);
- Eigen::SparseQR<Eigen::SparseMatrix<scalar_type>, Eigen::COLAMDOrdering<int>> solver;
- solver.compute(R_);
- Eigen::Matrix<scalar_type, Eigen::Dynamic, Eigen::Dynamic> R_in_temp = solver.solve(b);
- spMt R_in = R_in_temp.sparseView();
- spMt K_temp = h_x_.transpose() * R_in * h_x_;
- cov P_temp = P_.inverse();
- P_temp += K_temp;
- K_ = P_temp.inverse() * h_x_.transpose() * R_in;
- #else
- Eigen::Matrix<scalar_type, Eigen::Dynamic, Eigen::Dynamic> R_in = (h_v_*R*h_v_.transpose()).inverse();
- K_ = (h_x_.transpose() * R_in * h_x_ + P_.inverse()).inverse() * h_x_.transpose() * R_in;
- #endif
- }
- cov K_x = K_ * h_x_;
- Matrix<scalar_type, n, 1> dx_ = K_ * (z - h_) + (K_x - Matrix<scalar_type, n, n>::Identity()) * dx_new;
- state x_before = x_;
- x_.boxplus(dx_);
- converg = true;
- for(int i = 0; i < n ; i++)
- {
- if(std::fabs(dx_[i]) > limit[i])
- {
- converg = false;
- break;
- }
- }
- if(converg) t++;
- if(t > 1 || i == maximum_iter - 1)
- {
- L_ = P_;
- std::cout << "iteration time:" << t << "," << i << std::endl;
-
- Matrix<scalar_type, 3, 3> res_temp_SO3;
- MTK::vect<3, scalar_type> seg_SO3;
- for(typename std::vector<std::pair<int, int> >::iterator it = x_.SO3_state.begin(); it != x_.SO3_state.end(); it++) {
- int idx = (*it).first;
- for(int i = 0; i < 3; i++){
- seg_SO3(i) = dx_(i + idx);
- }
- res_temp_SO3 = MTK::A_matrix(seg_SO3).transpose();
- for(int i = 0; i < n; i++){
- L_. template block<3, 1>(idx, i) = res_temp_SO3 * (P_. template block<3, 1>(idx, i));
- }
- if(n > dof_Measurement)
- {
- for(int i = 0; i < dof_Measurement; i++){
- K_. template block<3, 1>(idx, i) = res_temp_SO3 * (K_. template block<3, 1>(idx, i));
- }
- }
- else
- {
- for(int i = 0; i < n; i++){
- K_x. template block<3, 1>(idx, i) = res_temp_SO3 * (K_x. template block<3, 1>(idx, i));
- }
- }
- for(int i = 0; i < n; i++){
- L_. template block<1, 3>(i, idx) = (L_. template block<1, 3>(i, idx)) * res_temp_SO3.transpose();
- P_. template block<1, 3>(i, idx) = (P_. template block<1, 3>(i, idx)) * res_temp_SO3.transpose();
- }
- }
- Matrix<scalar_type, 2, 2> res_temp_S2;
- MTK::vect<2, scalar_type> seg_S2;
- for(typename std::vector<std::pair<int, int> >::iterator it = x_.S2_state.begin(); it != x_.S2_state.end(); it++) {
- int idx = (*it).first;
-
- for(int i = 0; i < 2; i++){
- seg_S2(i) = dx_(i + idx);
- }
-
- Eigen::Matrix<scalar_type, 2, 3> Nx;
- Eigen::Matrix<scalar_type, 3, 2> Mx;
- x_.S2_Nx_yy(Nx, idx);
- x_propagated.S2_Mx(Mx, seg_S2, idx);
- res_temp_S2 = Nx * Mx;
-
- for(int i = 0; i < n; i++){
- L_. template block<2, 1>(idx, i) = res_temp_S2 * (P_. template block<2, 1>(idx, i));
- }
- if(n > dof_Measurement)
- {
- for(int i = 0; i < dof_Measurement; i++){
- K_. template block<2, 1>(idx, i) = res_temp_S2 * (K_. template block<2, 1>(idx, i));
- }
- }
- else
- {
- for(int i = 0; i < n; i++){
- K_x. template block<2, 1>(idx, i) = res_temp_S2 * (K_x. template block<2, 1>(idx, i));
- }
- }
- for(int i = 0; i < n; i++){
- L_. template block<1, 2>(i, idx) = (L_. template block<1, 2>(i, idx)) * res_temp_S2.transpose();
- P_. template block<1, 2>(i, idx) = (P_. template block<1, 2>(i, idx)) * res_temp_S2.transpose();
- }
- }
- if(n > dof_Measurement)
- {
- P_ = L_ - K_*h_x_*P_;
- }
- else
- {
- P_ = L_ - K_x * P_;
- }
- return;
- }
- }
- }
- //iterated error state EKF update for measurement as an Eigen matrix whose dimension is changing.
- //calculate measurement (z), estimate measurement (h), partial differention matrices (h_x, h_v) and the noise covariance (R) at the same time, by only one function.
- void update_iterated_dyn_share() {
-
- int t = 0;
- dyn_share_datastruct<scalar_type> dyn_share;
- dyn_share.valid = true;
- dyn_share.converge = true;
- state x_propagated = x_;
- cov P_propagated = P_;
- int dof_Measurement;
- int dof_Measurement_noise;
- for(int i=-1; i<maximum_iter; i++)
- {
- dyn_share.valid = true;
- h_dyn_share (x_, dyn_share);
- //Matrix<scalar_type, Eigen::Dynamic, 1> h = h_dyn_share (x_, dyn_share);
- Matrix<scalar_type, Eigen::Dynamic, 1> z = dyn_share.z;
- Matrix<scalar_type, Eigen::Dynamic, 1> h = dyn_share.h;
- #ifdef USE_sparse
- spMt h_x = dyn_share.h_x.sparseView();
- spMt h_v = dyn_share.h_v.sparseView();
- spMt R_ = dyn_share.R.sparseView();
- #else
- Matrix<scalar_type, Eigen::Dynamic, Eigen::Dynamic> R = dyn_share.R;
- Matrix<scalar_type, Eigen::Dynamic, Eigen::Dynamic> h_x = dyn_share.h_x;
- Matrix<scalar_type, Eigen::Dynamic, Eigen::Dynamic> h_v = dyn_share.h_v;
- #endif
- dof_Measurement = h_x.rows();
- dof_Measurement_noise = dyn_share.R.rows();
- vectorized_state dx, dx_new;
- x_.boxminus(dx, x_propagated);
- dx_new = dx;
- if(! (dyn_share.valid))
- {
- continue;
- }
- P_ = P_propagated;
- Matrix<scalar_type, 3, 3> res_temp_SO3;
- MTK::vect<3, scalar_type> seg_SO3;
- for (std::vector<std::pair<int, int> >::iterator it = x_.SO3_state.begin(); it != x_.SO3_state.end(); it++) {
- int idx = (*it).first;
- int dim = (*it).second;
- for(int i = 0; i < 3; i++){
- seg_SO3(i) = dx(idx+i);
- }
- res_temp_SO3 = MTK::A_matrix(seg_SO3).transpose();
- dx_new.template block<3, 1>(idx, 0) = res_temp_SO3 * dx_new.template block<3, 1>(idx, 0);
- for(int i = 0; i < n; i++){
- P_. template block<3, 1>(idx, i) = res_temp_SO3 * (P_. template block<3, 1>(idx, i));
- }
- for(int i = 0; i < n; i++){
- P_. template block<1, 3>(i, idx) =(P_. template block<1, 3>(i, idx)) * res_temp_SO3.transpose();
- }
- }
-
- Matrix<scalar_type, 2, 2> res_temp_S2;
- MTK::vect<2, scalar_type> seg_S2;
- for (std::vector<std::pair<int, int> >::iterator it = x_.S2_state.begin(); it != x_.S2_state.end(); it++) {
- int idx = (*it).first;
- int dim = (*it).second;
- for(int i = 0; i < 2; i++){
- seg_S2(i) = dx(idx + i);
- }
- Eigen::Matrix<scalar_type, 2, 3> Nx;
- Eigen::Matrix<scalar_type, 3, 2> Mx;
- x_.S2_Nx_yy(Nx, idx);
- x_propagated.S2_Mx(Mx, seg_S2, idx);
- res_temp_S2 = Nx * Mx;
- dx_new.template block<2, 1>(idx, 0) = res_temp_S2 * dx_new.template block<2, 1>(idx, 0);
- for(int i = 0; i < n; i++){
- P_. template block<2, 1>(idx, i) = res_temp_S2 * (P_. template block<2, 1>(idx, i));
- }
- for(int i = 0; i < n; i++){
- P_. template block<1, 2>(i, idx) = (P_. template block<1, 2>(i, idx)) * res_temp_S2.transpose();
- }
- }
- Matrix<scalar_type, Eigen::Dynamic, Eigen::Dynamic> K_;
- if(n > dof_Measurement)
- {
- #ifdef USE_sparse
- Matrix<scalar_type, Eigen::Dynamic, Eigen::Dynamic> K_temp = h_x * P_ * h_x.transpose();
- spMt R_temp = h_v * R_ * h_v.transpose();
- K_temp += R_temp;
- K_ = P_ * h_x.transpose() * K_temp.inverse();
- #else
- K_= P_ * h_x.transpose() * (h_x * P_ * h_x.transpose() + h_v * R * h_v.transpose()).inverse();
- #endif
- }
- else
- {
- #ifdef USE_sparse
- Eigen::Matrix<scalar_type, Eigen::Dynamic, Eigen::Dynamic> b = Eigen::Matrix<scalar_type, Eigen::Dynamic, Eigen::Dynamic>::Identity(dof_Measurement_noise, dof_Measurement_noise);
- Eigen::SparseQR<Eigen::SparseMatrix<scalar_type>, Eigen::COLAMDOrdering<int>> solver;
- solver.compute(R_);
- Eigen::Matrix<scalar_type, Eigen::Dynamic, Eigen::Dynamic> R_in_temp = solver.solve(b);
- spMt R_in = R_in_temp.sparseView();
- spMt K_temp = h_x.transpose() * R_in * h_x;
- cov P_temp = P_.inverse();
- P_temp += K_temp;
- K_ = P_temp.inverse() * h_x.transpose() * R_in;
- #else
- Eigen::Matrix<scalar_type, Eigen::Dynamic, Eigen::Dynamic> R_in = (h_v*R*h_v.transpose()).inverse();
- K_ = (h_x.transpose() * R_in * h_x + P_.inverse()).inverse() * h_x.transpose() * R_in;
- #endif
- }
- cov K_x = K_ * h_x;
- Matrix<scalar_type, n, 1> dx_ = K_ * (z - h) + (K_x - Matrix<scalar_type, n, n>::Identity()) * dx_new;
- state x_before = x_;
- x_.boxplus(dx_);
- dyn_share.converge = true;
- for(int i = 0; i < n ; i++)
- {
- if(std::fabs(dx_[i]) > limit[i])
- {
- dyn_share.converge = false;
- break;
- }
- }
- if(dyn_share.converge) t++;
- if(t > 1 || i == maximum_iter - 1)
- {
- L_ = P_;
- std::cout << "iteration time:" << t << "," << i << std::endl;
-
- Matrix<scalar_type, 3, 3> res_temp_SO3;
- MTK::vect<3, scalar_type> seg_SO3;
- for(typename std::vector<std::pair<int, int> >::iterator it = x_.SO3_state.begin(); it != x_.SO3_state.end(); it++) {
- int idx = (*it).first;
- for(int i = 0; i < 3; i++){
- seg_SO3(i) = dx_(i + idx);
- }
- res_temp_SO3 = MTK::A_matrix(seg_SO3).transpose();
- for(int i = 0; i < int(n); i++){
- L_. template block<3, 1>(idx, i) = res_temp_SO3 * (P_. template block<3, 1>(idx, i));
- }
- if(n > dof_Measurement)
- {
- for(int i = 0; i < dof_Measurement; i++){
- K_. template block<3, 1>(idx, i) = res_temp_SO3 * (K_. template block<3, 1>(idx, i));
- }
- }
- else
- {
- for(int i = 0; i < n; i++){
- K_x. template block<3, 1>(idx, i) = res_temp_SO3 * (K_x. template block<3, 1>(idx, i));
- }
- }
- for(int i = 0; i < n; i++){
- L_. template block<1, 3>(i, idx) = (L_. template block<1, 3>(i, idx)) * res_temp_SO3.transpose();
- P_. template block<1, 3>(i, idx) = (P_. template block<1, 3>(i, idx)) * res_temp_SO3.transpose();
- }
- }
- Matrix<scalar_type, 2, 2> res_temp_S2;
- MTK::vect<2, scalar_type> seg_S2;
- for(typename std::vector<std::pair<int, int> >::iterator it = x_.S2_state.begin(); it != x_.S2_state.end(); it++) {
- int idx = (*it).first;
-
- for(int i = 0; i < 2; i++){
- seg_S2(i) = dx_(i + idx);
- }
-
- Eigen::Matrix<scalar_type, 2, 3> Nx;
- Eigen::Matrix<scalar_type, 3, 2> Mx;
- x_.S2_Nx_yy(Nx, idx);
- x_propagated.S2_Mx(Mx, seg_S2, idx);
- res_temp_S2 = Nx * Mx;
-
- for(int i = 0; i < n; i++){
- L_. template block<2, 1>(idx, i) = res_temp_S2 * (P_. template block<2, 1>(idx, i));
- }
- if(n > dof_Measurement)
- {
- for(int i = 0; i < dof_Measurement; i++){
- K_. template block<2, 1>(idx, i) = res_temp_S2 * (K_. template block<2, 1>(idx, i));
- }
- }
- else
- {
- for(int i = 0; i < n; i++){
- K_x. template block<2, 1>(idx, i) = res_temp_S2 * (K_x. template block<2, 1>(idx, i));
- }
- }
- for(int i = 0; i < n; i++){
- L_. template block<1, 2>(i, idx) = (L_. template block<1, 2>(i, idx)) * res_temp_S2.transpose();
- P_. template block<1, 2>(i, idx) = (P_. template block<1, 2>(i, idx)) * res_temp_S2.transpose();
- }
- }
- if(n > dof_Measurement)
- {
- P_ = L_ - K_*h_x*P_;
- }
- else
- {
- P_ = L_ - K_x * P_;
- }
- return;
- }
- }
- }
- //iterated error state EKF update for measurement as a dynamic manifold, whose dimension or type is changing.
- //the measurement and the measurement model are received in a dynamic manner.
- template<typename measurement_runtime, typename measurementModel_runtime>
- void update_iterated_dyn_runtime(measurement_runtime z, measurementnoisecovariance_dyn R, measurementModel_runtime h_runtime) {
-
- int t = 0;
- bool valid = true;
- bool converg = true;
- state x_propagated = x_;
- cov P_propagated = P_;
- int dof_Measurement;
- int dof_Measurement_noise;
- for(int i=-1; i<maximum_iter; i++)
- {
- valid = true;
- #ifdef USE_sparse
- spMt h_x_ = h_x_dyn(x_, valid).sparseView();
- spMt h_v_ = h_v_dyn(x_, valid).sparseView();
- spMt R_ = R.sparseView();
- #else
- Matrix<scalar_type, Eigen::Dynamic, n> h_x_ = h_x_dyn(x_, valid);
- Matrix<scalar_type, Eigen::Dynamic, Eigen::Dynamic> h_v_ = h_v_dyn(x_, valid);
- #endif
- measurement_runtime h_ = h_runtime(x_, valid);
- dof_Measurement = measurement_runtime::DOF;
- dof_Measurement_noise = R.rows();
- vectorized_state dx, dx_new;
- x_.boxminus(dx, x_propagated);
- dx_new = dx;
- if(! valid)
- {
- continue;
- }
- P_ = P_propagated;
- Matrix<scalar_type, 3, 3> res_temp_SO3;
- MTK::vect<3, scalar_type> seg_SO3;
- for (std::vector<std::pair<int, int> >::iterator it = x_.SO3_state.begin(); it != x_.SO3_state.end(); it++) {
- int idx = (*it).first;
- int dim = (*it).second;
- for(int i = 0; i < 3; i++){
- seg_SO3(i) = dx(idx+i);
- }
- res_temp_SO3 = MTK::A_matrix(seg_SO3).transpose();
- dx_new.template block<3, 1>(idx, 0) = res_temp_SO3 * dx_new.template block<3, 1>(idx, 0);
- for(int i = 0; i < n; i++){
- P_. template block<3, 1>(idx, i) = res_temp_SO3 * (P_. template block<3, 1>(idx, i));
- }
- for(int i = 0; i < n; i++){
- P_. template block<1, 3>(i, idx) =(P_. template block<1, 3>(i, idx)) * res_temp_SO3.transpose();
- }
- }
-
- Matrix<scalar_type, 2, 2> res_temp_S2;
- MTK::vect<2, scalar_type> seg_S2;
- for (std::vector<std::pair<int, int> >::iterator it = x_.S2_state.begin(); it != x_.S2_state.end(); it++) {
- int idx = (*it).first;
- int dim = (*it).second;
- for(int i = 0; i < 2; i++){
- seg_S2(i) = dx(idx + i);
- }
- Eigen::Matrix<scalar_type, 2, 3> Nx;
- Eigen::Matrix<scalar_type, 3, 2> Mx;
- x_.S2_Nx_yy(Nx, idx);
- x_propagated.S2_Mx(Mx, seg_S2, idx);
- res_temp_S2 = Nx * Mx;
- dx_new.template block<2, 1>(idx, 0) = res_temp_S2 * dx_new.template block<2, 1>(idx, 0);
- for(int i = 0; i < n; i++){
- P_. template block<2, 1>(idx, i) = res_temp_S2 * (P_. template block<2, 1>(idx, i));
- }
- for(int i = 0; i < n; i++){
- P_. template block<1, 2>(i, idx) = (P_. template block<1, 2>(i, idx)) * res_temp_S2.transpose();
- }
- }
- Matrix<scalar_type, Eigen::Dynamic, Eigen::Dynamic> K_;
- if(n > dof_Measurement)
- {
- #ifdef USE_sparse
- Matrix<scalar_type, Eigen::Dynamic, Eigen::Dynamic> K_temp = h_x_ * P_ * h_x_.transpose();
- spMt R_temp = h_v_ * R_ * h_v_.transpose();
- K_temp += R_temp;
- K_ = P_ * h_x_.transpose() * K_temp.inverse();
- #else
- K_= P_ * h_x_.transpose() * (h_x_ * P_ * h_x_.transpose() + h_v_ * R * h_v_.transpose()).inverse();
- #endif
- }
- else
- {
- #ifdef USE_sparse
- Eigen::Matrix<scalar_type, Eigen::Dynamic, Eigen::Dynamic> b = Eigen::Matrix<scalar_type, Eigen::Dynamic, Eigen::Dynamic>::Identity(dof_Measurement_noise, dof_Measurement_noise);
- Eigen::SparseQR<Eigen::SparseMatrix<scalar_type>, Eigen::COLAMDOrdering<int>> solver;
- solver.compute(R_);
- Eigen::Matrix<scalar_type, Eigen::Dynamic, Eigen::Dynamic> R_in_temp = solver.solve(b);
- spMt R_in = R_in_temp.sparseView();
- spMt K_temp = h_x_.transpose() * R_in * h_x_;
- cov P_temp = P_.inverse();
- P_temp += K_temp;
- K_ = P_temp.inverse() * h_x_.transpose() * R_in;
- #else
- Eigen::Matrix<scalar_type, Eigen::Dynamic, Eigen::Dynamic> R_in = (h_v_*R*h_v_.transpose()).inverse();
- K_ = (h_x_.transpose() * R_in * h_x_ + P_.inverse()).inverse() * h_x_.transpose() * R_in;
- #endif
- }
- cov K_x = K_ * h_x_;
- Eigen::Matrix<scalar_type, measurement_runtime::DOF, 1> innovation;
- z.boxminus(innovation, h_);
- Matrix<scalar_type, n, 1> dx_ = K_ * innovation + (K_x - Matrix<scalar_type, n, n>::Identity()) * dx_new;
- state x_before = x_;
- x_.boxplus(dx_);
- converg = true;
- for(int i = 0; i < n ; i++)
- {
- if(std::fabs(dx_[i]) > limit[i])
- {
- converg = false;
- break;
- }
- }
- if(converg) t++;
- if(t > 1 || i == maximum_iter - 1)
- {
- L_ = P_;
- std::cout << "iteration time:" << t << "," << i << std::endl;
-
- Matrix<scalar_type, 3, 3> res_temp_SO3;
- MTK::vect<3, scalar_type> seg_SO3;
- for(typename std::vector<std::pair<int, int> >::iterator it = x_.SO3_state.begin(); it != x_.SO3_state.end(); it++) {
- int idx = (*it).first;
- for(int i = 0; i < 3; i++){
- seg_SO3(i) = dx_(i + idx);
- }
- res_temp_SO3 = MTK::A_matrix(seg_SO3).transpose();
- for(int i = 0; i < n; i++){
- L_. template block<3, 1>(idx, i) = res_temp_SO3 * (P_. template block<3, 1>(idx, i));
- }
- if(n > dof_Measurement)
- {
- for(int i = 0; i < dof_Measurement; i++){
- K_. template block<3, 1>(idx, i) = res_temp_SO3 * (K_. template block<3, 1>(idx, i));
- }
- }
- else
- {
- for(int i = 0; i < n; i++){
- K_x. template block<3, 1>(idx, i) = res_temp_SO3 * (K_x. template block<3, 1>(idx, i));
- }
- }
- for(int i = 0; i < n; i++){
- L_. template block<1, 3>(i, idx) = (L_. template block<1, 3>(i, idx)) * res_temp_SO3.transpose();
- P_. template block<1, 3>(i, idx) = (P_. template block<1, 3>(i, idx)) * res_temp_SO3.transpose();
- }
- }
- Matrix<scalar_type, 2, 2> res_temp_S2;
- MTK::vect<2, scalar_type> seg_S2;
- for(typename std::vector<std::pair<int, int> >::iterator it = x_.S2_state.begin(); it != x_.S2_state.end(); it++) {
- int idx = (*it).first;
-
- for(int i = 0; i < 2; i++){
- seg_S2(i) = dx_(i + idx);
- }
-
- Eigen::Matrix<scalar_type, 2, 3> Nx;
- Eigen::Matrix<scalar_type, 3, 2> Mx;
- x_.S2_Nx_yy(Nx, idx);
- x_propagated.S2_Mx(Mx, seg_S2, idx);
- res_temp_S2 = Nx * Mx;
-
- for(int i = 0; i < n; i++){
- L_. template block<2, 1>(idx, i) = res_temp_S2 * (P_. template block<2, 1>(idx, i));
- }
- if(n > dof_Measurement)
- {
- for(int i = 0; i < dof_Measurement; i++){
- K_. template block<2, 1>(idx, i) = res_temp_S2 * (K_. template block<2, 1>(idx, i));
- }
- }
- else
- {
- for(int i = 0; i < n; i++){
- K_x. template block<2, 1>(idx, i) = res_temp_S2 * (K_x. template block<2, 1>(idx, i));
- }
- }
- for(int i = 0; i < n; i++){
- L_. template block<1, 2>(i, idx) = (L_. template block<1, 2>(i, idx)) * res_temp_S2.transpose();
- P_. template block<1, 2>(i, idx) = (P_. template block<1, 2>(i, idx)) * res_temp_S2.transpose();
- }
- }
- if(n > dof_Measurement)
- {
- P_ = L_ - K_*h_x_*P_;
- }
- else
- {
- P_ = L_ - K_x * P_;
- }
- return;
- }
- }
- }
- //iterated error state EKF update for measurement as a dynamic manifold, whose dimension or type is changing.
- //the measurement and the measurement model are received in a dynamic manner.
- //calculate measurement (z), estimate measurement (h), partial differention matrices (h_x, h_v) and the noise covariance (R) at the same time, by only one function.
- template<typename measurement_runtime, typename measurementModel_dyn_runtime_share>
- void update_iterated_dyn_runtime_share(measurement_runtime z, measurementModel_dyn_runtime_share h) {
-
- int t = 0;
- dyn_runtime_share_datastruct<scalar_type> dyn_share;
- dyn_share.valid = true;
- dyn_share.converge = true;
- state x_propagated = x_;
- cov P_propagated = P_;
- int dof_Measurement;
- int dof_Measurement_noise;
- for(int i=-1; i<maximum_iter; i++)
- {
- dyn_share.valid = true;
- measurement_runtime h_ = h(x_, dyn_share);
- //measurement_runtime z = dyn_share.z;
- #ifdef USE_sparse
- spMt h_x = dyn_share.h_x.sparseView();
- spMt h_v = dyn_share.h_v.sparseView();
- spMt R_ = dyn_share.R.sparseView();
- #else
- Matrix<scalar_type, Eigen::Dynamic, Eigen::Dynamic> R = dyn_share.R;
- Matrix<scalar_type, Eigen::Dynamic, Eigen::Dynamic> h_x = dyn_share.h_x;
- Matrix<scalar_type, Eigen::Dynamic, Eigen::Dynamic> h_v = dyn_share.h_v;
- #endif
- dof_Measurement = measurement_runtime::DOF;
- dof_Measurement_noise = dyn_share.R.rows();
- vectorized_state dx, dx_new;
- x_.boxminus(dx, x_propagated);
- dx_new = dx;
- if(! (dyn_share.valid))
- {
- continue;
- }
- P_ = P_propagated;
- Matrix<scalar_type, 3, 3> res_temp_SO3;
- MTK::vect<3, scalar_type> seg_SO3;
- for (std::vector<std::pair<int, int> >::iterator it = x_.SO3_state.begin(); it != x_.SO3_state.end(); it++) {
- int idx = (*it).first;
- int dim = (*it).second;
- for(int i = 0; i < 3; i++){
- seg_SO3(i) = dx(idx+i);
- }
- res_temp_SO3 = MTK::A_matrix(seg_SO3).transpose();
- dx_new.template block<3, 1>(idx, 0) = res_temp_SO3 * dx_new.template block<3, 1>(idx, 0);
- for(int i = 0; i < n; i++){
- P_. template block<3, 1>(idx, i) = res_temp_SO3 * (P_. template block<3, 1>(idx, i));
- }
- for(int i = 0; i < n; i++){
- P_. template block<1, 3>(i, idx) =(P_. template block<1, 3>(i, idx)) * res_temp_SO3.transpose();
- }
- }
-
- Matrix<scalar_type, 2, 2> res_temp_S2;
- MTK::vect<2, scalar_type> seg_S2;
- for (std::vector<std::pair<int, int> >::iterator it = x_.S2_state.begin(); it != x_.S2_state.end(); it++) {
- int idx = (*it).first;
- int dim = (*it).second;
- for(int i = 0; i < 2; i++){
- seg_S2(i) = dx(idx + i);
- }
- Eigen::Matrix<scalar_type, 2, 3> Nx;
- Eigen::Matrix<scalar_type, 3, 2> Mx;
- x_.S2_Nx_yy(Nx, idx);
- x_propagated.S2_Mx(Mx, seg_S2, idx);
- res_temp_S2 = Nx * Mx;
- dx_new.template block<2, 1>(idx, 0) = res_temp_S2 * dx_new.template block<2, 1>(idx, 0);
- for(int i = 0; i < n; i++){
- P_. template block<2, 1>(idx, i) = res_temp_S2 * (P_. template block<2, 1>(idx, i));
- }
- for(int i = 0; i < n; i++){
- P_. template block<1, 2>(i, idx) = (P_. template block<1, 2>(i, idx)) * res_temp_S2.transpose();
- }
- }
- Matrix<scalar_type, Eigen::Dynamic, Eigen::Dynamic> K_;
- if(n > dof_Measurement)
- {
- #ifdef USE_sparse
- Matrix<scalar_type, Eigen::Dynamic, Eigen::Dynamic> K_temp = h_x * P_ * h_x.transpose();
- spMt R_temp = h_v * R_ * h_v.transpose();
- K_temp += R_temp;
- K_ = P_ * h_x.transpose() * K_temp.inverse();
- #else
- K_= P_ * h_x.transpose() * (h_x * P_ * h_x.transpose() + h_v * R * h_v.transpose()).inverse();
- #endif
- }
- else
- {
- #ifdef USE_sparse
- Eigen::Matrix<scalar_type, Eigen::Dynamic, Eigen::Dynamic> b = Eigen::Matrix<scalar_type, Eigen::Dynamic, Eigen::Dynamic>::Identity(dof_Measurement_noise, dof_Measurement_noise);
- Eigen::SparseQR<Eigen::SparseMatrix<scalar_type>, Eigen::COLAMDOrdering<int>> solver;
- solver.compute(R_);
- Eigen::Matrix<scalar_type, Eigen::Dynamic, Eigen::Dynamic> R_in_temp = solver.solve(b);
- spMt R_in =R_in_temp.sparseView();
- spMt K_temp = h_x.transpose() * R_in * h_x;
- cov P_temp = P_.inverse();
- P_temp += K_temp;
- K_ = P_temp.inverse() * h_x.transpose() * R_in;
- #else
- Eigen::Matrix<scalar_type, Eigen::Dynamic, Eigen::Dynamic> R_in = (h_v*R*h_v.transpose()).inverse();
- K_ = (h_x.transpose() * R_in * h_x + P_.inverse()).inverse() * h_x.transpose() * R_in;
- #endif
- }
- cov K_x = K_ * h_x;
- Eigen::Matrix<scalar_type, measurement_runtime::DOF, 1> innovation;
- z.boxminus(innovation, h_);
- Matrix<scalar_type, n, 1> dx_ = K_ * innovation + (K_x - Matrix<scalar_type, n, n>::Identity()) * dx_new;
- state x_before = x_;
- x_.boxplus(dx_);
- dyn_share.converge = true;
- for(int i = 0; i < n ; i++)
- {
- if(std::fabs(dx_[i]) > limit[i])
- {
- dyn_share.converge = false;
- break;
- }
- }
- if(dyn_share.converge) t++;
- if(t > 1 || i == maximum_iter - 1)
- {
- L_ = P_;
- std::cout << "iteration time:" << t << "," << i << std::endl;
-
- Matrix<scalar_type, 3, 3> res_temp_SO3;
- MTK::vect<3, scalar_type> seg_SO3;
- for(typename std::vector<std::pair<int, int> >::iterator it = x_.SO3_state.begin(); it != x_.SO3_state.end(); it++) {
- int idx = (*it).first;
- for(int i = 0; i < 3; i++){
- seg_SO3(i) = dx_(i + idx);
- }
- res_temp_SO3 = MTK::A_matrix(seg_SO3).transpose();
- for(int i = 0; i < int(n); i++){
- L_. template block<3, 1>(idx, i) = res_temp_SO3 * (P_. template block<3, 1>(idx, i));
- }
- if(n > dof_Measurement)
- {
- for(int i = 0; i < dof_Measurement; i++){
- K_. template block<3, 1>(idx, i) = res_temp_SO3 * (K_. template block<3, 1>(idx, i));
- }
- }
- else
- {
- for(int i = 0; i < n; i++){
- K_x. template block<3, 1>(idx, i) = res_temp_SO3 * (K_x. template block<3, 1>(idx, i));
- }
- }
- for(int i = 0; i < n; i++){
- L_. template block<1, 3>(i, idx) = (L_. template block<1, 3>(i, idx)) * res_temp_SO3.transpose();
- P_. template block<1, 3>(i, idx) = (P_. template block<1, 3>(i, idx)) * res_temp_SO3.transpose();
- }
- }
- Matrix<scalar_type, 2, 2> res_temp_S2;
- MTK::vect<2, scalar_type> seg_S2;
- for(typename std::vector<std::pair<int, int> >::iterator it = x_.S2_state.begin(); it != x_.S2_state.end(); it++) {
- int idx = (*it).first;
-
- for(int i = 0; i < 2; i++){
- seg_S2(i) = dx_(i + idx);
- }
-
- Eigen::Matrix<scalar_type, 2, 3> Nx;
- Eigen::Matrix<scalar_type, 3, 2> Mx;
- x_.S2_Nx_yy(Nx, idx);
- x_propagated.S2_Mx(Mx, seg_S2, idx);
- res_temp_S2 = Nx * Mx;
-
- for(int i = 0; i < n; i++){
- L_. template block<2, 1>(idx, i) = res_temp_S2 * (P_. template block<2, 1>(idx, i));
- }
- if(n > dof_Measurement)
- {
- for(int i = 0; i < dof_Measurement; i++){
- K_. template block<2, 1>(idx, i) = res_temp_S2 * (K_. template block<2, 1>(idx, i));
- }
- }
- else
- {
- for(int i = 0; i < n; i++){
- K_x. template block<2, 1>(idx, i) = res_temp_S2 * (K_x. template block<2, 1>(idx, i));
- }
- }
- for(int i = 0; i < n; i++){
- L_. template block<1, 2>(i, idx) = (L_. template block<1, 2>(i, idx)) * res_temp_S2.transpose();
- P_. template block<1, 2>(i, idx) = (P_. template block<1, 2>(i, idx)) * res_temp_S2.transpose();
- }
- }
- if(n > dof_Measurement)
- {
- P_ = L_ - K_*h_x * P_;
- }
- else
- {
- P_ = L_ - K_x * P_;
- }
- return;
- }
- }
- }
-
- //iterated error state EKF update modified for one specific system.
- bool update_iterated_dyn_share_modified(double R, double &solve_time) {
-
- dyn_share_datastruct<scalar_type> dyn_share;
- dyn_share.valid = true;
- dyn_share.converge = true;
- int t = 0;
- //获取上一次的状态和协方差矩阵
- state x_propagated = x_;
- cov P_propagated = P_;
- int dof_Measurement;
-
- Matrix<scalar_type, n, 1> K_h;
- Matrix<scalar_type, n, n> K_x;
-
- vectorized_state dx_new = vectorized_state::Zero();
- for(int i=-1; i<maximum_iter; i++)
- {
- dyn_share.valid = true;
- h_dyn_share(x_, dyn_share); //计算残差与雅可比
- if(! dyn_share.valid)
- {
- continue;
- }
- //Matrix<scalar_type, Eigen::Dynamic, 1> h = h_dyn_share(x_, dyn_share);
- #ifdef USE_sparse
- spMt h_x_ = dyn_share.h_x.sparseView();
- #else
- Eigen::Matrix<scalar_type, Eigen::Dynamic, 12> h_x_ = dyn_share.h_x; // partial differention matrices
- #endif
- double solve_start = omp_get_wtime();
- dof_Measurement = h_x_.rows(); // 观测方程个数m
- vectorized_state dx;
- x_.boxminus(dx, x_propagated); //获取误差dx
- dx_new = dx;
-
-
- // 迭代过程不更新协方差矩阵,迭代后更新
- P_ = P_propagated;
- //更新协方差矩阵的传播,更新dx_new
- Matrix<scalar_type, 3, 3> res_temp_SO3;
- MTK::vect<3, scalar_type> seg_SO3;
- for (std::vector<std::pair<int, int> >::iterator it = x_.SO3_state.begin(); it != x_.SO3_state.end(); it++) {
- int idx = (*it).first;
- int dim = (*it).second;
- for(int i = 0; i < 3; i++){
- seg_SO3(i) = dx(idx+i);
- }
- res_temp_SO3 = MTK::A_matrix(seg_SO3).transpose();
- dx_new.template block<3, 1>(idx, 0) = res_temp_SO3 * dx_new.template block<3, 1>(idx, 0);
- for(int i = 0; i < n; i++){
- P_. template block<3, 1>(idx, i) = res_temp_SO3 * (P_. template block<3, 1>(idx, i));
- }
- for(int i = 0; i < n; i++){
- P_. template block<1, 3>(i, idx) =(P_. template block<1, 3>(i, idx)) * res_temp_SO3.transpose();
- }
- }
- Matrix<scalar_type, 2, 2> res_temp_S2;
- MTK::vect<2, scalar_type> seg_S2;
- for (std::vector<std::pair<int, int> >::iterator it = x_.S2_state.begin(); it != x_.S2_state.end(); it++) {
- int idx = (*it).first;
- int dim = (*it).second;
- for(int i = 0; i < 2; i++){
- seg_S2(i) = dx(idx + i);
- }
- Eigen::Matrix<scalar_type, 2, 3> Nx;
- Eigen::Matrix<scalar_type, 3, 2> Mx;
- x_.S2_Nx_yy(Nx, idx);
- x_propagated.S2_Mx(Mx, seg_S2, idx);
- res_temp_S2 = Nx * Mx;
- dx_new.template block<2, 1>(idx, 0) = res_temp_S2 * dx_new.template block<2, 1>(idx, 0);
- for(int i = 0; i < n; i++){
- P_. template block<2, 1>(idx, i) = res_temp_S2 * (P_. template block<2, 1>(idx, i));
- }
- for(int i = 0; i < n; i++){
- P_. template block<1, 2>(i, idx) = (P_. template block<1, 2>(i, idx)) * res_temp_S2.transpose();
- }
- }
- // 如果状态量维度大于观测方程 n > m,不满秩
- if(n > dof_Measurement)
- {
- //#ifdef USE_sparse
- //Matrix<scalar_type, Eigen::Dynamic, Eigen::Dynamic> K_temp = h_x * P_ * h_x.transpose();
- //spMt R_temp = h_v * R_ * h_v.transpose();
- //K_temp += R_temp;
- Eigen::Matrix<scalar_type, Eigen::Dynamic, Eigen::Dynamic> h_x_cur = Eigen::Matrix<scalar_type, Eigen::Dynamic, Eigen::Dynamic>::Zero(dof_Measurement, n);
- h_x_cur.topLeftCorner(dof_Measurement, 12) = h_x_;
- /*
- h_x_cur.col(0) = h_x_.col(0);
- h_x_cur.col(1) = h_x_.col(1);
- h_x_cur.col(2) = h_x_.col(2);
- h_x_cur.col(3) = h_x_.col(3);
- h_x_cur.col(4) = h_x_.col(4);
- h_x_cur.col(5) = h_x_.col(5);
- h_x_cur.col(6) = h_x_.col(6);
- h_x_cur.col(7) = h_x_.col(7);
- h_x_cur.col(8) = h_x_.col(8);
- h_x_cur.col(9) = h_x_.col(9);
- h_x_cur.col(10) = h_x_.col(10);
- h_x_cur.col(11) = h_x_.col(11);
- */
- // 重新计算增益矩阵K
- Matrix<scalar_type, Eigen::Dynamic, Eigen::Dynamic> K_ = P_ * h_x_cur.transpose() * (h_x_cur * P_ * h_x_cur.transpose()/R + Eigen::Matrix<double, Dynamic, Dynamic>::Identity(dof_Measurement, dof_Measurement)).inverse()/R;
- K_h = K_ * dyn_share.h; // K × h
- K_x = K_ * h_x_cur; // K * H
- //#else
- // K_= P_ * h_x.transpose() * (h_x * P_ * h_x.transpose() + h_v * R * h_v.transpose()).inverse();
- //#endif
- }
- else
- {
- #ifdef USE_sparse
- //Eigen::Matrix<scalar_type, n, n> b = Eigen::Matrix<scalar_type, n, n>::Identity();
- //Eigen::SparseQR<Eigen::SparseMatrix<scalar_type>, Eigen::COLAMDOrdering<int>> solver;
- spMt A = h_x_.transpose() * h_x_;
- cov P_temp = (P_/R).inverse();
- P_temp. template block<12, 12>(0, 0) += A;
- P_temp = P_temp.inverse();
- /*
- Eigen::Matrix<scalar_type, Eigen::Dynamic, Eigen::Dynamic> h_x_cur = Eigen::Matrix<scalar_type, Eigen::Dynamic, Eigen::Dynamic>::Zero(dof_Measurement, n);
- h_x_cur.col(0) = h_x_.col(0);
- h_x_cur.col(1) = h_x_.col(1);
- h_x_cur.col(2) = h_x_.col(2);
- h_x_cur.col(3) = h_x_.col(3);
- h_x_cur.col(4) = h_x_.col(4);
- h_x_cur.col(5) = h_x_.col(5);
- h_x_cur.col(6) = h_x_.col(6);
- h_x_cur.col(7) = h_x_.col(7);
- h_x_cur.col(8) = h_x_.col(8);
- h_x_cur.col(9) = h_x_.col(9);
- h_x_cur.col(10) = h_x_.col(10);
- h_x_cur.col(11) = h_x_.col(11);
- */
- K_ = P_temp. template block<n, 12>(0, 0) * h_x_.transpose();
- K_x = cov::Zero();
- K_x. template block<n, 12>(0, 0) = P_inv. template block<n, 12>(0, 0) * HTH;
- /*
- solver.compute(R_);
- Eigen::Matrix<scalar_type, Eigen::Dynamic, Eigen::Dynamic> R_in_temp = solver.solve(b);
- spMt R_in =R_in_temp.sparseView();
- spMt K_temp = h_x.transpose() * R_in * h_x;
- cov P_temp = P_.inverse();
- P_temp += K_temp;
- K_ = P_temp.inverse() * h_x.transpose() * R_in;
- */
- #else
- cov P_temp = (P_/R).inverse(); //P^-1
- //Eigen::Matrix<scalar_type, 12, Eigen::Dynamic> h_T = h_x_.transpose();
- Eigen::Matrix<scalar_type, 12, 12> HTH = h_x_.transpose() * h_x_;
- P_temp. template block<12, 12>(0, 0) += HTH;
- /*
- Eigen::Matrix<scalar_type, Eigen::Dynamic, Eigen::Dynamic> h_x_cur = Eigen::Matrix<scalar_type, Eigen::Dynamic, Eigen::Dynamic>::Zero(dof_Measurement, n);
- //std::cout << "line 1767" << std::endl;
- h_x_cur.col(0) = h_x_.col(0);
- h_x_cur.col(1) = h_x_.col(1);
- h_x_cur.col(2) = h_x_.col(2);
- h_x_cur.col(3) = h_x_.col(3);
- h_x_cur.col(4) = h_x_.col(4);
- h_x_cur.col(5) = h_x_.col(5);
- h_x_cur.col(6) = h_x_.col(6);
- h_x_cur.col(7) = h_x_.col(7);
- h_x_cur.col(8) = h_x_.col(8);
- h_x_cur.col(9) = h_x_.col(9);
- h_x_cur.col(10) = h_x_.col(10);
- h_x_cur.col(11) = h_x_.col(11);
- */
- cov P_inv = P_temp.inverse(); // (H_T_H + P^-1)^-1
- //std::cout << "line 1781" << std::endl;
- K_h = P_inv. template block<n, 12>(0, 0) * h_x_.transpose() * dyn_share.h; // (H_T_H + P^-1)^-1 * H^T * h(残差) = K * h
- //std::cout << "line 1780" << std::endl;
- //cov HTH_cur = cov::Zero();
- //HTH_cur. template block<12, 12>(0, 0) = HTH;
- K_x.setZero(); // = cov::Zero();
- K_x. template block<n, 12>(0, 0) = P_inv. template block<n, 12>(0, 0) * HTH; //(H_T_H + P^-1)^-1 * H_T_H = KH
- //K_= (h_x_.transpose() * h_x_ + (P_/R).inverse()).inverse()*h_x_.transpose();
- #endif
- }
- //K_x = K_ * h_x_;
- Matrix<scalar_type, n, 1> dx_ = K_h + (K_x - Matrix<scalar_type, n, n>::Identity()) * dx_new; //误差增量后验 K*h + (K*H - I) dx
- state x_before = x_;
- x_.boxplus(dx_); //根据计算得到的误差增量后验,更新状态量
- dyn_share.converge = true;
- for(int i = 0; i < n ; i++)
- {
- if(std::fabs(dx_[i]) > limit[i])
- {
- dyn_share.converge = false;
- break;
- }
- }
- if(dyn_share.converge) t++;
-
- if(!t && i == maximum_iter - 2)
- {
- dyn_share.converge = true;
- }
- // 最后一次迭代更新协方差矩阵
- if(t > 1 || i == maximum_iter - 1)
- {
- L_ = P_;
- //std::cout << "iteration time" << t << "," << i << std::endl;
- Matrix<scalar_type, 3, 3> res_temp_SO3;
- MTK::vect<3, scalar_type> seg_SO3;
- for(typename std::vector<std::pair<int, int> >::iterator it = x_.SO3_state.begin(); it != x_.SO3_state.end(); it++) {
- int idx = (*it).first;
- for(int i = 0; i < 3; i++){
- seg_SO3(i) = dx_(i + idx);
- }
- res_temp_SO3 = MTK::A_matrix(seg_SO3).transpose();
- for(int i = 0; i < n; i++){
- L_. template block<3, 1>(idx, i) = res_temp_SO3 * (P_. template block<3, 1>(idx, i));
- }
- // if(n > dof_Measurement)
- // {
- // for(int i = 0; i < dof_Measurement; i++){
- // K_.template block<3, 1>(idx, i) = res_temp_SO3 * (K_. template block<3, 1>(idx, i));
- // }
- // }
- // else
- // {
- for(int i = 0; i < 12; i++){
- K_x. template block<3, 1>(idx, i) = res_temp_SO3 * (K_x. template block<3, 1>(idx, i));
- }
- //}
- for(int i = 0; i < n; i++){
- L_. template block<1, 3>(i, idx) = (L_. template block<1, 3>(i, idx)) * res_temp_SO3.transpose();
- P_. template block<1, 3>(i, idx) = (P_. template block<1, 3>(i, idx)) * res_temp_SO3.transpose();
- }
- }
- Matrix<scalar_type, 2, 2> res_temp_S2;
- MTK::vect<2, scalar_type> seg_S2;
- for(typename std::vector<std::pair<int, int> >::iterator it = x_.S2_state.begin(); it != x_.S2_state.end(); it++) {
- int idx = (*it).first;
- for(int i = 0; i < 2; i++){
- seg_S2(i) = dx_(i + idx);
- }
- Eigen::Matrix<scalar_type, 2, 3> Nx;
- Eigen::Matrix<scalar_type, 3, 2> Mx;
- x_.S2_Nx_yy(Nx, idx);
- x_propagated.S2_Mx(Mx, seg_S2, idx);
- res_temp_S2 = Nx * Mx;
- for(int i = 0; i < n; i++){
- L_. template block<2, 1>(idx, i) = res_temp_S2 * (P_. template block<2, 1>(idx, i));
- }
- // if(n > dof_Measurement)
- // {
- // for(int i = 0; i < dof_Measurement; i++){
- // K_. template block<2, 1>(idx, i) = res_temp_S2 * (K_. template block<2, 1>(idx, i));
- // }
- // }
- // else
- // {
- for(int i = 0; i < 12; i++){
- K_x. template block<2, 1>(idx, i) = res_temp_S2 * (K_x. template block<2, 1>(idx, i));
- }
- //}
- for(int i = 0; i < n; i++){
- L_. template block<1, 2>(i, idx) = (L_. template block<1, 2>(i, idx)) * res_temp_S2.transpose();
- P_. template block<1, 2>(i, idx) = (P_. template block<1, 2>(i, idx)) * res_temp_S2.transpose();
- }
- }
- P_ = L_ - K_x.template block<n, 12>(0, 0) * P_.template block<12, n>(0, 0);
- solve_time += omp_get_wtime() - solve_start;
- return dyn_share.converge;
- }
- solve_time += omp_get_wtime() - solve_start;
- }
- return dyn_share.converge;
- }
- void change_x(state &input_state)
- {
- x_ = input_state;
- if((!x_.vect_state.size())&&(!x_.SO3_state.size())&&(!x_.S2_state.size()))
- {
- x_.build_S2_state();
- x_.build_SO3_state();
- x_.build_vect_state();
- }
- }
- void change_P(cov &input_cov)
- {
- P_ = input_cov;
- }
- const state& get_x() const {
- return x_;
- }
- const cov& get_P() const {
- return P_;
- }
- private:
- state x_;
- measurement m_;
- cov P_;
- spMt l_;
- spMt f_x_1;
- spMt f_x_2;
- cov F_x1 = cov::Identity();
- cov F_x2 = cov::Identity();
- cov L_ = cov::Identity();
- processModel *f;
- processMatrix1 *f_x;
- processMatrix2 *f_w;
- measurementModel *h;
- measurementMatrix1 *h_x;
- measurementMatrix2 *h_v;
- measurementModel_dyn *h_dyn;
- measurementMatrix1_dyn *h_x_dyn;
- measurementMatrix2_dyn *h_v_dyn;
- measurementModel_share *h_share;
- measurementModel_dyn_share *h_dyn_share;
- int maximum_iter = 0;
- scalar_type limit[n];
-
- template <typename T>
- T check_safe_update( T _temp_vec )
- {
- T temp_vec = _temp_vec;
- if ( std::isnan( temp_vec(0, 0) ) )
- {
- temp_vec.setZero();
- return temp_vec;
- }
- double angular_dis = temp_vec.block( 0, 0, 3, 1 ).norm() * 57.3;
- double pos_dis = temp_vec.block( 3, 0, 3, 1 ).norm();
- if ( angular_dis >= 20 || pos_dis > 1 )
- {
- printf( "Angular dis = %.2f, pos dis = %.2f\r\n", angular_dis, pos_dis );
- temp_vec.setZero();
- }
- return temp_vec;
- }
- public:
- EIGEN_MAKE_ALIGNED_OPERATOR_NEW
- };
- } // namespace esekfom
- #endif // ESEKFOM_EKF_HPP
|