7 #include "hrpsys/util/Hrpsys.h" 11 typedef Eigen::Matrix<double, 7, 1>
Vector7;
18 Q(Eigen::Matrix3d::Identity() * 0.001),
19 R(Eigen::Matrix3d::Identity() * 0.03),
20 g_vec(Eigen::Vector3d(0.0, 0.0, 9.80665)),
21 z_k(Eigen::Vector3d(0.0, 0.0, 9.80665)),
22 min_mag_thre_acc(0.005), max_mag_thre_acc(0.05),
23 min_mag_thre_gyro(0.0075), max_mag_thre_gyro(0.035)
25 x << 1, 0, 0, 0, 0, 0, 0;
30 void calcOmega(Eigen::Matrix4d& omega,
const Eigen::Vector3d& w)
const {
33 0, -w[0], -w[1], -w[2],
40 const Eigen::Vector4d& q,
41 const Eigen::Vector3d& gyro,
42 const Eigen::Vector3d& drift)
const {
44 Eigen::Vector4d q_a_priori;
45 Eigen::Vector3d gyro_compensated = gyro - drift;
46 Eigen::Matrix4d omega;
47 calcOmega(omega, gyro_compensated);
48 q_a_priori = q + dt / 2 * omega * q;
49 _x_a_priori.head<4>() = q_a_priori.normalized();
50 _x_a_priori.tail<3>() = drift;
54 const Eigen::Vector4d& q,
55 const Eigen::Vector3d& gyro,
56 const Eigen::Vector3d& drift)
const {
57 F = hrp::Matrix77::Identity();
58 Eigen::Vector3d gyro_compensated = gyro - drift;
59 Eigen::Matrix4d omega;
60 calcOmega(omega, gyro_compensated);
61 F.block<4, 4>(0, 0) += dt / 2 * omega;
62 F.block<4, 3>(0, 4) <<
63 + q[1], + q[2], + q[3],
64 - q[0], + q[3], - q[2],
65 - q[3], - q[0], + q[1],
66 + q[2], - q[1], - q[0];
67 F.block<4, 3>(0, 4) *= dt / 2;
72 const Eigen::Vector4d& q)
const {
74 Eigen::Matrix<double, 4, 3> V_upper;
76 - q[1], - q[2], - q[3],
77 + q[0], - q[3], + q[2],
78 + q[3], + q[0], - q[1],
79 - q[2], + q[1], + q[0];
82 VQVt.block<4, 4>(0, 0) = V_upper * Q * V_upper.transpose();
83 _P_a_priori = F * P * F.transpose() + VQVt;
86 Eigen::Vector3d
calcAcc(
const Eigen::Vector4d& q)
const {
87 Eigen::Quaternion<double> q_tmp(q[0], q[1], q[2], q[3]);
88 Eigen::Vector3d acc = q_tmp.conjugate()._transformVector(g_vec);
92 void calcH(Eigen::Matrix<double, 3, 7>& H,
const Eigen::Vector4d& q)
const {
93 double w = q[0],
x = q[1],
y = q[2],
z = q[3];
95 -
y, +
z, -w, +
x, 0, 0, 0,
96 +
x, +w, +
z, +
y, 0, 0, 0,
97 +w, -
x, -
y, +
z, 0, 0, 0;
102 const Eigen::Vector4d& q)
const {
104 Eigen::Vector3d
y = acc_measured - calcAcc(q);
110 Eigen::Vector4d q =
x.head<4>();
111 Eigen::Vector3d drift =
x.tail<3>();
113 calcF(F, q, u, drift);
115 calcPredictedState(x_tmp, q, u, drift);
118 calcPredictedCovariance(P_tmp, F, q);
122 void correction(
const Eigen::Vector3d&
z,
const Eigen::Matrix3d& fuzzyR) {
123 Eigen::Vector4d q_a_priori = x_a_priori.head<4>();
124 Eigen::Matrix<double, 3, 7> H;
126 Eigen::Vector3d
y = calcMeasurementResidual(z, q_a_priori);
127 calcH(H, q_a_priori);
128 Eigen::Matrix3d S = H * P_a_priori * H.transpose() + fuzzyR;
129 Eigen::Matrix<double, 7, 3> K = P_a_priori * H.transpose() * S.inverse();
131 x.head<4>() = x_tmp.head<4>().normalized();
132 x.tail<3>() = x_tmp.tail<3>();
133 P = (hrp::Matrix77::Identity() - K * H) * P_a_priori;
137 std::cerr <<
"x" << std::endl <<
x << std::endl;
138 std::cerr <<
"x_a_priori" << std::endl << x_a_priori << std::endl;
139 std::cerr <<
"P" << std::endl << P << std::endl << std::endl;
140 std::cerr <<
"P_a_priori" << std::endl << P_a_priori << std::endl << std::endl;
148 double alpha =
std::min(std::fabs(acc.norm() - g_vec.norm()) / g_vec.norm(), 0.1);
149 double beta =
std::min(gyro.norm(), 0.05);
150 double large_mu_acc =
std::max(
std::min((alpha - min_mag_thre_acc) / (max_mag_thre_acc - min_mag_thre_acc), 1.0), 0.0);
151 double large_mu_gyro =
std::max(
std::min((beta - min_mag_thre_gyro) / (max_mag_thre_gyro - min_mag_thre_gyro), 1.0), 0.0);
152 double w1, w2, w3, w4;
153 w1 = (1.0 - large_mu_acc) * (1.0 - large_mu_gyro);
154 w2 = (1.0 - large_mu_acc) * large_mu_gyro;
155 w3 = large_mu_acc * (1.0 - large_mu_gyro);
156 w4 = large_mu_acc * large_mu_gyro;
157 double z = (w1 * 0.0 + w2 * (3.5 * alpha + 8.0 * beta + 0.5) + w3 * (3.5 * alpha + 8.0 * beta + 0.5) + w4 * 1.0) / (w1 + w2 + w3 + w4);
159 fuzzyR =
R + k1 * z * z * Eigen::Matrix3d::Identity();
164 Eigen::Matrix3d fuzzyR;
165 calcRWithFuzzyRule(fuzzyR, acc, gyro);
167 correction(acc, fuzzyR);
169 Eigen::Quaternion<double> q(
x[0],
x[1],
x[2],
x[3]);
173 void setdt (
const double _dt) { dt = _dt;};
175 Eigen::Quaternion<double> tmp_q;
176 tmp_q.setFromTwoVectors(z_k, g_vec);
177 x << tmp_q.w(), tmp_q.x(), tmp_q.y(), tmp_q.z(), 0, 0, 0;
182 Eigen::Matrix3d Q,
R;
183 Eigen::Vector3d g_vec,
z_k;
void setdt(const double _dt)
hrp::Vector7 getx() const
Eigen::Matrix< double, 7, 7 > Matrix77
void main_one(hrp::Vector3 &rpy, hrp::Vector3 &rpyRaw, const hrp::Vector3 &acc, const hrp::Vector3 &gyro)
void correction(const Eigen::Vector3d &z, const Eigen::Matrix3d &fuzzyR)
Eigen::Vector3d calcAcc(const Eigen::Vector4d &q) const
void calcPredictedCovariance(hrp::Matrix77 &_P_a_priori, const hrp::Matrix77 &F, const Eigen::Vector4d &q) const
Eigen::Matrix< double, 7, 1 > Vector7
void resetKalmanFilterState()
void calcH(Eigen::Matrix< double, 3, 7 > &H, const Eigen::Vector4d &q) const
void prediction(const Eigen::Vector3d &u)
void calcPredictedState(hrp::Vector7 &_x_a_priori, const Eigen::Vector4d &q, const Eigen::Vector3d &gyro, const Eigen::Vector3d &drift) const
HRP_UTIL_EXPORT Vector3 rpyFromRot(const Matrix33 &m)
void calcOmega(Eigen::Matrix4d &omega, const Eigen::Vector3d &w) const
void calcF(hrp::Matrix77 &F, const Eigen::Vector4d &q, const Eigen::Vector3d &gyro, const Eigen::Vector3d &drift) const
void calcRWithFuzzyRule(Eigen::Matrix3d &fuzzyR, const hrp::Vector3 &acc, const hrp::Vector3 &gyro) const
Eigen::Vector3d calcMeasurementResidual(const Eigen::Vector3d &acc_measured, const Eigen::Vector4d &q) const