00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024
00025
00026
00027
00028
00029
00030
00031
00032
00033
00034
00035
00036
00037
00038 #ifndef IMU_FILTER_IMU_STATE_H_
00039 #define IMU_FILTER_IMU_STATE_H_
00040
00041 #include <iostream>
00042
00043 #include <Eigen/Core>
00044 #include <Eigen/Geometry>
00045
00046 #include <imu_filter/quaternion_helper.h>
00047 #include <imu_filter/utils.h>
00048
00049 #define EARTH_GRAVITY ( 9.80665 )
00050
00051
00052 namespace imu_filter
00053 {
00054
00058 class ImuState
00059 {
00060 public:
00061 static const size_t Dimension = 19;
00062 typedef Eigen::Matrix<double, Dimension, 1> StateVector;
00063 typedef Eigen::Matrix<double, Dimension, Dimension> CovarianceMatrix;
00065 ImuState() :
00066 orientation_( Eigen::Quaterniond::Identity() ),
00067 position_( Eigen::Vector3d::Zero() ),
00068 velocity_( Eigen::Vector3d::Zero() ),
00069 gyroBias_( Eigen::Vector3d::Zero() ),
00070 accBias_( Eigen::Vector3d::Zero() ),
00071 gravity_( 0, 0, -EARTH_GRAVITY ),
00072 covariance_( CovarianceMatrix::Zero() ),
00073 gyroBiasRange_( Eigen::Vector3d( 0.01, 0.01, 0.01 ) ),
00074 accBiasRange_( Eigen::Vector3d( 0.3, 0.3, 0.3 ) ),
00075 body2ImuR_( Eigen::Quaterniond::Identity() ),
00076 body2ImuT_( Eigen::Vector3d::Zero() ),
00077 estimate_gravity_( true ),
00078 estimate_gyro_bias_( true ),
00079 estimate_acc_bias_( true ),
00080 world2ImuPose_( Eigen::Affine3d::Identity() )
00081 {
00082 }
00083
00084 ImuState( const ImuState & other ) :
00085 orientation_( other.orientation_ ),
00086 position_( other.position_ ),
00087 velocity_( other.velocity_ ),
00088 gyroBias_( other.gyroBias_ ),
00089 accBias_( other.accBias_ ),
00090 gravity_( other.gravity_ ),
00091 covariance_( other.covariance_ ),
00092 gyroBiasRange_( other.gyroBiasRange_ ),
00093 accBiasRange_( other.accBiasRange_ ),
00094 body2ImuR_( other.body2ImuR_ ),
00095 body2ImuT_( other.body2ImuT_ )
00096 {
00097 }
00098
00099 ImuState & operator=( const ImuState & other )
00100 {
00101 orientation_ = other.orientation_;
00102 position_ = other.position_;
00103 velocity_ = other.velocity_;
00104 gyroBias_ = other.gyroBias_;
00105 accBias_ = other.accBias_;
00106 gravity_ = other.gravity_;
00107 covariance_ = other.covariance_;
00108 gyroBiasRange_ = other.gyroBiasRange_;
00109 accBiasRange_ = other.accBiasRange_;
00110 body2ImuR_ = other.body2ImuR_;
00111 body2ImuT_ = other.body2ImuT_;
00112 return *this;
00113 }
00114
00119 void update( const StateVector & updateVector )
00120 {
00121 orientation_.x() += updateVector[ 0 ];
00122 orientation_.y() += updateVector[ 1 ];
00123 orientation_.z() += updateVector[ 2 ];
00124 orientation_.w() += updateVector[ 3 ];
00125
00126 orientation_.normalize();
00127
00128 position_ += updateVector.block<3, 1>( 4, 0 );
00129 velocity_ += updateVector.block<3, 1>( 7, 0 );
00130
00131 if( estimate_gyro_bias_ )
00132 gyroBias_ += updateVector.block<3, 1>( 10, 0 );
00133
00134 if( estimate_acc_bias_ )
00135 accBias_ += updateVector.block<3, 1>( 13, 0 );
00136
00137 if( estimate_gravity_ )
00138 gravity_ += updateVector.block<3, 1>( 16, 0 );
00139
00140
00141 gyroBias_[ 0 ] = utils::clamp( gyroBias_[ 0 ], -gyroBiasRange_[ 0 ], gyroBiasRange_[ 0 ] );
00142 gyroBias_[ 1 ] = utils::clamp( gyroBias_[ 1 ], -gyroBiasRange_[ 1 ], gyroBiasRange_[ 1 ] );
00143 gyroBias_[ 2 ] = utils::clamp( gyroBias_[ 2 ], -gyroBiasRange_[ 2 ], gyroBiasRange_[ 2 ] );
00144
00145 accBias_[ 0 ] = utils::clamp( accBias_[ 0 ], -accBiasRange_[ 0 ], accBiasRange_[ 0 ] );
00146 accBias_[ 1 ] = utils::clamp( accBias_[ 1 ], -accBiasRange_[ 1 ], accBiasRange_[ 1 ] );
00147 accBias_[ 2 ] = utils::clamp( accBias_[ 2 ], -accBiasRange_[ 2 ], accBiasRange_[ 2 ] );
00148 }
00149
00154 void setParameter( const StateVector & vector )
00155 {
00156 orientation_.x() = vector[ 0 ];
00157 orientation_.y() = vector[ 1 ];
00158 orientation_.z() = vector[ 2 ];
00159 orientation_.w() = vector[ 3 ];
00160 position_[ 0 ] = vector[ 4 ];
00161 position_[ 1 ] = vector[ 5 ];
00162 position_[ 2 ] = vector[ 6 ];
00163 velocity_[ 0 ] = vector[ 7 ];
00164 velocity_[ 1 ] = vector[ 8 ];
00165 velocity_[ 2 ] = vector[ 9 ];
00166 gyroBias_[ 0 ] = vector[ 10 ];
00167 gyroBias_[ 1 ] = vector[ 11 ];
00168 gyroBias_[ 2 ] = vector[ 12 ];
00169 accBias_[ 0 ] = vector[ 13 ];
00170 accBias_[ 1 ] = vector[ 14 ];
00171 accBias_[ 2 ] = vector[ 15 ];
00172 gravity_[ 0 ] = vector[ 16 ];
00173 gravity_[ 1 ] = vector[ 17 ];
00174 gravity_[ 2 ] = vector[ 18 ];
00175 }
00176
00180 const Eigen::Quaterniond & orientation() const { return orientation_; }
00181
00185 Eigen::Quaterniond & orientation() { return orientation_; }
00186
00190 void setOrientation( const Eigen::Quaterniond & newOrientation )
00191 {
00192 orientation_ = newOrientation;
00193 }
00194
00198 const Eigen::Vector3d & position() const { return position_; }
00199
00203 Eigen::Vector3d & position() { return position_; }
00204
00208 void setPosition( const Eigen::Vector3d & newPosition ) { position_ = newPosition; }
00209
00213 const Eigen::Vector3d & velocity() const { return velocity_; }
00214
00218 Eigen::Vector3d & velocity() { return velocity_; }
00219
00223 void setVelocity( const Eigen::Vector3d & newVelocity ) { velocity_ = newVelocity; }
00224
00228 const Eigen::Vector3d & gyroBias() const { return gyroBias_; }
00229
00233 Eigen::Vector3d & gyroBias() { return gyroBias_; }
00234
00238 void setGyroBias( const Eigen::Vector3d & newGyroBias ) { gyroBias_ = newGyroBias; }
00239
00243 const Eigen::Vector3d & accBias() const { return accBias_; }
00244
00248 Eigen::Vector3d & accBias() { return accBias_; }
00249
00253 void setAccBias( const Eigen::Vector3d & newAccBias ) { accBias_ = newAccBias; }
00254
00258 const Eigen::Vector3d & gravity() const { return gravity_; }
00259
00263 Eigen::Vector3d & gravity() { return gravity_; }
00264
00268 void setGravity( const Eigen::Vector3d & newGravity ) { gravity_ = newGravity; }
00269
00273 const CovarianceMatrix & covariance() const { return covariance_; }
00274
00278 CovarianceMatrix & covariance() { return covariance_; }
00279
00283 const Eigen::Quaterniond & body2ImuRotation() const { return body2ImuR_; }
00284
00288 void setBody2ImuRotation( const Eigen::Quaterniond & rot ) { body2ImuR_ = rot; }
00289
00293 const Eigen::Vector3d & body2ImuTranslation() const { return body2ImuT_; }
00294
00298 void setBody2ImuTranslation( const Eigen::Vector3d & trans ) { body2ImuT_ = trans; }
00299
00303 void setEstimateGravity( bool v ) { estimate_gravity_ = v; }
00304
00308 void setEstimateGyroBias( bool v ) { estimate_gyro_bias_ = v; }
00309
00313 void setEstimateAccBias( bool v ) { estimate_acc_bias_ = v; }
00314
00320 void setGyroBiasRange( double rx, double ry, double rz )
00321 {
00322 gyroBiasRange_[ 0 ] = rx;
00323 gyroBiasRange_[ 1 ] = ry;
00324 gyroBiasRange_[ 2 ] = rz;
00325 }
00326
00332 void setAccBiasRange( double rx, double ry, double rz )
00333 {
00334 accBiasRange_[ 0 ] = rx;
00335 accBiasRange_[ 1 ] = ry;
00336 accBiasRange_[ 2 ] = rz;
00337 }
00338
00343 void toVector( StateVector & vec ) const
00344 {
00345 vec[ 0 ] = orientation_.x();
00346 vec[ 1 ] = orientation_.y();
00347 vec[ 2 ] = orientation_.z();
00348 vec[ 3 ] = orientation_.w();
00349
00350 vec[ 4 ] = position_.x();
00351 vec[ 5 ] = position_.y();
00352 vec[ 6 ] = position_.z();
00353
00354 vec[ 7 ] = velocity_.x();
00355 vec[ 8 ] = velocity_.y();
00356 vec[ 9 ] = velocity_.z();
00357
00358 vec[ 10 ] = gyroBias_.x();
00359 vec[ 11 ] = gyroBias_.y();
00360 vec[ 12 ] = gyroBias_.z();
00361
00362 vec[ 13 ] = accBias_.x();
00363 vec[ 14 ] = accBias_.y();
00364 vec[ 15 ] = accBias_.z();
00365
00366 vec[ 16 ] = gravity_.x();
00367 vec[ 17 ] = gravity_.y();
00368 vec[ 18 ] = gravity_.z();
00369 }
00370
00374 void fixCovariance()
00375 {
00376
00377 if( !estimate_gyro_bias_ ){
00378 covariance_.block<3, 3>( 10, 10 ).setZero();
00379 }
00380
00381
00382 if( !estimate_acc_bias_ ){
00383 covariance_.block<3, 3>( 13, 13 ).setZero();
00384 }
00385
00386
00387 if( !estimate_gravity_ ){
00388 covariance_.block<3, 3>( 16, 16 ).setZero();
00389 }
00390 }
00391
00395 const Eigen::Affine3d & world2Imu()
00396 {
00397 world2ImuPose_.linear() = orientation_.toRotationMatrix();
00398 world2ImuPose_.translation() = position_;
00399 return world2ImuPose_;
00400 }
00401
00402 private:
00403
00404 Eigen::Quaterniond orientation_;
00405
00406
00407 Eigen::Vector3d position_;
00408
00409
00410 Eigen::Vector3d velocity_;
00411
00412
00413 Eigen::Vector3d gyroBias_;
00414
00415
00416 Eigen::Vector3d accBias_;
00417
00418
00419 Eigen::Vector3d gravity_;
00420
00421
00422 CovarianceMatrix covariance_;
00423
00424
00425 Eigen::Vector3d gyroBiasRange_;
00426 Eigen::Vector3d accBiasRange_;
00427
00428
00429 Eigen::Quaterniond body2ImuR_;
00430 Eigen::Vector3d body2ImuT_;
00431
00432 bool estimate_gravity_;
00433 bool estimate_gyro_bias_;
00434 bool estimate_acc_bias_;
00435
00436 Eigen::Affine3d world2ImuPose_;
00437 };
00438
00439 inline std::ostream & operator<<( std::ostream & os, const ImuState & state )
00440 {
00441 os << "ImuState:\n"
00442 << "\torientation: ["
00443 << state.orientation().w() << ", "
00444 << state.orientation().x() << ", "
00445 << state.orientation().y() << ", "
00446 << state.orientation().z() << " ]\n"
00447 << "\tposition: ["
00448 << state.position().x() << ", "
00449 << state.position().y() << ", "
00450 << state.position().z() << " ]\n"
00451 << "\tvelocity: ["
00452 << state.velocity().x() << ", "
00453 << state.velocity().y() << ", "
00454 << state.velocity().z() << " ]\n"
00455 << "\tgyroBias: ["
00456 << state.gyroBias().x() << ", "
00457 << state.gyroBias().y() << ", "
00458 << state.gyroBias().z() << " ]\n"
00459 << "\taccBias: ["
00460 << state.accBias().x() << ", "
00461 << state.accBias().y() << ", "
00462 << state.accBias().z() << " ]\n"
00463 << "\tgravity: ["
00464 << state.gravity().x() << ", "
00465 << state.gravity().y() << ", "
00466 << state.gravity().z() << " ] (Norm: " << state.gravity().norm() << " )\n" << std::endl;
00467 return os;
00468 }
00469
00470 }
00471 #endif