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 #include <hector_pose_estimation/system/imu_model.h>
00030 #include <hector_pose_estimation/filter/set_filter.h>
00031
00032 namespace hector_pose_estimation {
00033
00034 template class System_<GyroModel>;
00035 template class System_<AccelerometerModel>;
00036
00037 GyroModel::GyroModel()
00038 {
00039 rate_stddev_ = 1.0 * M_PI/180.0;
00040 rate_drift_ = 1.0e-1 * M_PI/180.0;
00041 parameters().add("stddev", rate_stddev_);
00042 parameters().add("drift", rate_drift_);
00043 }
00044
00045 GyroModel::~GyroModel()
00046 {}
00047
00048 bool GyroModel::init(PoseEstimation& estimator, State& state)
00049 {
00050 drift_ = state.addSubState<3>(this, "gyro");
00051 return drift_;
00052 }
00053
00054 void GyroModel::getSystemNoise(NoiseVariance& Q, const State& state, bool init)
00055 {
00056 if (init) {
00057 Q(BIAS_GYRO_X,BIAS_GYRO_X) = Q(BIAS_GYRO_Y,BIAS_GYRO_Y) = Q(BIAS_GYRO_Z,BIAS_GYRO_Z) = pow(rate_drift_, 2);
00058 }
00059 }
00060
00061 void GyroModel::getStateJacobian(SystemMatrix& A1, CrossSystemMatrix& A01, const State& state, bool)
00062 {
00063 if (state.getRateIndex() >= 0) return;
00064
00065 State::ConstOrientationType q(state.getOrientation());
00066 State::ConstVelocityType v(state.getVelocity());
00067
00068 if (state.getOrientationIndex() >= 0) {
00069 A01(State::QUATERNION_W, BIAS_GYRO_X) = -0.5*q.x();
00070 A01(State::QUATERNION_W, BIAS_GYRO_Y) = -0.5*q.y();
00071 A01(State::QUATERNION_W, BIAS_GYRO_Z) = -0.5*q.z();
00072
00073 A01(State::QUATERNION_X, BIAS_GYRO_X) = 0.5*q.w();
00074 A01(State::QUATERNION_X, BIAS_GYRO_Y) = -0.5*q.z();
00075 A01(State::QUATERNION_X, BIAS_GYRO_Z) = 0.5*q.y();
00076
00077 A01(State::QUATERNION_Y, BIAS_GYRO_X) = 0.5*q.z();
00078 A01(State::QUATERNION_Y, BIAS_GYRO_Y) = 0.5*q.w();
00079 A01(State::QUATERNION_Y, BIAS_GYRO_Z) = -0.5*q.x();
00080
00081 A01(State::QUATERNION_Z, BIAS_GYRO_X) = -0.5*q.y();
00082 A01(State::QUATERNION_Z, BIAS_GYRO_Y) = 0.5*q.x();
00083 A01(State::QUATERNION_Z, BIAS_GYRO_Z) = 0.5*q.w();
00084 }
00085
00086 #ifdef VELOCITY_IN_BODY_FRAME
00087 if (state.getVelocityIndex() >= 0 && state.getSystemStatus() & STATE_VELOCITY_XY) {
00088 A01(State::VELOCITY_X, BIAS_GYRO_X) = 0.0;
00089 A01(State::VELOCITY_X, BIAS_GYRO_Y) = -v.z();
00090 A01(State::VELOCITY_X, BIAS_GYRO_Z) = v.y();
00091
00092 A01(State::VELOCITY_Y, BIAS_GYRO_X) = v.z();
00093 A01(State::VELOCITY_Y, BIAS_GYRO_Y) = 0.0;
00094 A01(State::VELOCITY_Y, BIAS_GYRO_Z) = -v.x();
00095 }
00096
00097 if (state.getVelocityIndex() >= 0 && state.getSystemStatus() & STATE_VELOCITY_Z) {
00098 A01(State::VELOCITY_Z, BIAS_GYRO_X) = -v.y();
00099 A01(State::VELOCITY_Z, BIAS_GYRO_Y) = v.x();
00100 A01(State::VELOCITY_Z, BIAS_GYRO_Z) = 0.0;
00101 }
00102
00103 #endif
00104 }
00105
00106 AccelerometerModel::AccelerometerModel()
00107 {
00108 acceleration_stddev_ = 1.0e-2;
00109 acceleration_drift_ = 1.0e-3;
00110 parameters().add("stddev", acceleration_stddev_);
00111 parameters().add("drift", acceleration_drift_);
00112 }
00113
00114 AccelerometerModel::~AccelerometerModel()
00115 {}
00116
00117 bool AccelerometerModel::init(PoseEstimation& estimator, State& state)
00118 {
00119 drift_ = state.addSubState<3>(this, "accelerometer");
00120 return drift_;
00121 }
00122
00123 void AccelerometerModel::getSystemNoise(NoiseVariance& Q, const State& state, bool init)
00124 {
00125 if (init) {
00126 Q(BIAS_ACCEL_X,BIAS_ACCEL_X) = Q(BIAS_ACCEL_Y,BIAS_ACCEL_Y) = pow(acceleration_drift_, 2);
00127 Q(BIAS_ACCEL_Z,BIAS_ACCEL_Z) = pow(acceleration_drift_, 2);
00128 }
00129 }
00130
00131 void AccelerometerModel::getStateJacobian(SystemMatrix& A1, CrossSystemMatrix& A01, const State& state, bool)
00132 {
00133 if (state.getAccelerationIndex() >= 0) return;
00134
00135 A01 = 0;
00136
00137 #ifdef VELOCITY_IN_BODY_FRAME
00138 if (state.getVelocityIndex() >= 0) {
00139 if (state.getSystemStatus() & STATE_VELOCITY_XY) {
00140 A01.block(State::VELOCITY_X, BIAS_ACCEL_X, 2, 2).setIdentity();
00141 }
00142
00143 if (state.getSystemStatus() & STATE_VELOCITY_Z) {
00144 A01.block(State::VELOCITY_Z, BIAS_ACCEL_Z, 1, 1).setIdentity();
00145 }
00146 }
00147
00148 #else
00149 State::ConstOrientationType q(state.getOrientation());
00150 if (state.getVelocityIndex() >= 0) {
00151 if (state.getSystemStatus() & STATE_VELOCITY_XY) {
00152 A01(State::VELOCITY_X, BIAS_ACCEL_X) = (q.w()*q.w()+q.x()*q.x()-q.y()*q.y()-q.z()*q.z());
00153 A01(State::VELOCITY_X, BIAS_ACCEL_Y) = (2.0*q.x()*q.y()-2.0*q.w()*q.z());
00154 A01(State::VELOCITY_X, BIAS_ACCEL_Z) = (2.0*q.x()*q.z()+2.0*q.w()*q.y());
00155
00156 A01(State::VELOCITY_Y, BIAS_ACCEL_X) = (2.0*q.x()*q.y()+2.0*q.w()*q.z());
00157 A01(State::VELOCITY_Y, BIAS_ACCEL_Y) = (q.w()*q.w()-q.x()*q.x()+q.y()*q.y()-q.z()*q.z());
00158 A01(State::VELOCITY_Y, BIAS_ACCEL_Z) = (2.0*q.y()*q.z()-2.0*q.w()*q.x());
00159 }
00160
00161 if (state.getSystemStatus() & STATE_VELOCITY_Z) {
00162 A01(State::VELOCITY_Z, BIAS_ACCEL_X) = ( 2.0*q.x()*q.z()-2.0*q.w()*q.y());
00163 A01(State::VELOCITY_Z, BIAS_ACCEL_Y) = ( 2.0*q.y()*q.z()+2.0*q.w()*q.x());
00164 A01(State::VELOCITY_Z, BIAS_ACCEL_Z) = (q.w()*q.w()-q.x()*q.x()-q.y()*q.y()+q.z()*q.z());
00165 }
00166 }
00167 #endif
00168
00169 }
00170
00171 }