RPYKalmanFilter.h
Go to the documentation of this file.
1 #ifndef RPYKALMANFILTER_H
2 #define RPYKALMANFILTER_H
3 
4 #include <hrpUtil/EigenTypes.h>
5 #include <hrpUtil/Eigen3d.h>
6 #include "hrpsys/util/Hrpsys.h"
7 namespace hrp{
8  typedef Eigen::Vector2d Vector2;
9  typedef Eigen::Matrix2d Matrix22;
10 }
11 #include <iostream>
12 
13 class KFilter {
14 public:
15  KFilter() {
16  F(0,0) = 1; F(0,1) =-0.005;
17  F(1,0) = 0; F(1,1) = 1;
18 
19  P(0,0) = 0; P(0,1) = 0;
20  P(1,0) = 0; P(1,1) = 0;
21 
22  Q(0,0) = 0.001 * 0.005; Q(0,1) = 0.000 * 0.005;
23  Q(1,0) = 0.000 * 0.005; Q(1,1) = 0.003 * 0.005;
24 
25  R = 0.03;
26 
27  B(0) = 0.005; B(1) = 0;
28 
29  H(0,0) = 1; H(0,1) = 0;
30 
31  x(0) = 0; x(1) = 0;
32  z = 0;
33 
34  I = hrp::dmatrix::Identity(2,2);
35  }
36  void setF(const double _f0, const double _f1, const double _f2, const double _f3) { F << _f0, _f1, _f2, _f3; };
37  void setP(const double _p0, const double _p1, const double _p2, const double _p3) { P << _p0, _p1, _p2, _p3; };
38  void setQ(const double _q0, const double _q1, const double _q2, const double _q3) { Q << _q0, _q1, _q2, _q3; };
39  void setR(const double _R) { R = _R; }
40  void setB(const double _b0, const double _b1) { B << _b0, _b1; };
41  const hrp::Vector2 &getx() { return x; }
42  void update(const double u, const double _z) {
43  // Predicted (a priori) state estimate
44  x = F * x + B * u;
45  // Predicted (a priori) estimate covariance
46  P = F * P * F.transpose() + Q;
47  //
48  // Innovation or measurement residual
49  z = _z;
50  double y = z - H * x;
51  // Innovation (or residual) covariance
52  double S = H * P * H.transpose() + R;
53  // Optimal Kalman gain
54  K = P * H.transpose() / S;
55  // Updated (a posteriori) state estimate
56  x = x + K * y;
57  // Updated (a posteriori) estimate covariance
58  P = (I - K * H) * P;
59  }
61  x << z ,0;
62  };
63 private:
64  hrp::Matrix22 P, Q, I, F;
65  Eigen::Matrix<double, 1, 2> H;
68  double R, z;
69 };
70 
72 public:
73  RPYKalmanFilter() : m_sensorR(hrp::Matrix33::Identity()) {};
74  void main_one (hrp::Vector3& rpy, hrp::Vector3& rpyRaw, hrp::Vector3& baseRpyCurrent, const hrp::Vector3& acc, const hrp::Vector3& gyro, const double& sl_y, const hrp::Matrix33& BtoS)
75  {
76  //
77  // G = [ cosb, sinb sina, sinb cosa,
78  // 0, cosa, -sina,
79  // -sinb, cosb sina, cosb cosa]
80  // s = [sx, sy, sz]t ( accelerometer )
81  // g = [ 0 0 -g]t
82  // s = G g = [g sinb, -g cosb sina, -g cosb cosa]t
83  // hrp::RateGyroSensor* sensor = m_robot->sensor<hrp::RateGyroSensor>("gyrometer");
84  double g = sqrt(acc(0) * acc(0) + acc(1) * acc(1) + acc(2) * acc(2));
85  // atan2(y, x) = atan(y/x)
86  double a, b;
87  b = atan2( - acc(0) / g, sqrt( acc(1)/g * acc(1)/g + acc(2)/g * acc(2)/g ) );
88  a = atan2( ( acc(1)/g ), ( acc(2)/g ) );
89  rpyRaw = hrp::Vector3(a,b,sl_y);
90  // #if 0
91  // // complementary filter
92  // m_rpy.data.r = 0.98 *(m_rpy.data.r+m_rate.data.avx*m_dt) + 0.02*m_rpyRaw.data.r;
93  // m_rpy.data.p = 0.98 *(m_rpy.data.p+m_rate.data.avy*m_dt) + 0.02*m_rpyRaw.data.p;
94  // m_rpy.data.y = 0.98 *(m_rpy.data.y+m_rate.data.avz*m_dt) + 0.02*m_rpyRaw.data.y;
95  // #endif
96  // kalman filter
97  // x[0] = m_rpyRaw.data.r; // angle (from m/sec Acceleration3D, unstable, no drift )
98  // x[1] = m_rate.data.avx; // rate ( rad/sec, AngularVelocity, gyro, stable/drift )
99  // use kalman filter with imaginary data
100  hrp::Vector3 gyro2 = gyro;
101 #if 1
102  double roll = r_filter.getx()[0];
103  double pitch = p_filter.getx()[0];
104  double yaw = y_filter.getx()[0];
105  hrp::Matrix33 tmpMat;
106  tmpMat << 1.0, sin(roll)*sin(pitch)/cos(pitch), cos(roll)*sin(pitch)/cos(pitch),
107  0, cos(roll), -sin(roll),
108  0, sin(roll)/cos(pitch), cos(roll)/cos(pitch);
109  gyro2 = tmpMat * gyro;
110 #endif
111  r_filter.update(gyro2(0), rpyRaw(0));
112  p_filter.update(gyro2(1), rpyRaw(1));
113  y_filter.update(gyro2(2), rpyRaw(2));
114 
115  hrp::Matrix33 imaginaryRotationMatrix = hrp::rotFromRpy(r_filter.getx()[0], p_filter.getx()[0], y_filter.getx()[0]); // the imaginary frame relative to a world reference frame
116  hrp::Matrix33 realRotationMatrix = imaginaryRotationMatrix * m_sensorR; // the imu frame relative to a world reference frame
117  hrp::Vector3 euler = hrp::rpyFromRot(realRotationMatrix);
118  rpy(0) = euler(0);
119  rpy(1) = euler(1);
120  rpy(2) = euler(2);
121  hrp::Matrix33 WtoB = realRotationMatrix * BtoS.transpose(); // the body frame relative to a world reference frame
122  hrp::Vector3 euler2 = hrp::rpyFromRot(WtoB);
123  baseRpyCurrent(0) = euler2(0);
124  baseRpyCurrent(1) = euler2(1);
125  baseRpyCurrent(2) = euler2(2);
126  };
127  void setParam (const double _dt, const double _Q_angle, const double _Q_rate, const double _R_angle, const std::string print_str = "")
128  {
129  Q_angle = _Q_angle;
130  Q_rate = _Q_rate;
131  R_angle = _R_angle;
132  r_filter.setF(1, -_dt, 0, 1);
133  r_filter.setP(0, 0, 0, 0);
134  r_filter.setQ(Q_angle*_dt, 0, 0, Q_rate*_dt);
135  r_filter.setR(R_angle);
136  r_filter.setB(_dt, 0);
137 
138  p_filter.setF(1, -_dt, 0, 1);
139  p_filter.setP(0, 0, 0, 0);
140  p_filter.setQ(Q_angle*_dt, 0, 0, Q_rate*_dt);
141  p_filter.setR(R_angle);
142  p_filter.setB(_dt, 0);
143 
144  y_filter.setF(1, -_dt, 0, 1);
145  y_filter.setP(0, 0, 0, 0);
146  y_filter.setQ(Q_angle*_dt, 0, 0, Q_rate*_dt);
147  y_filter.setR(R_angle);
148  y_filter.setB(_dt, 0);
149  std::cerr << "[" << print_str << "] Q_angle=" << Q_angle << ", Q_rate=" << Q_rate << ", R_angle=" << R_angle << std::endl;
150  };
152  {
153  r_filter.resetStateByObservation();
154  p_filter.resetStateByObservation();
155  y_filter.resetStateByObservation();
156  };
157  void setSensorR (const hrp::Matrix33& sr) { m_sensorR = sr;};
158  double getQangle () const { return Q_angle;};
159  double getQrate () const { return Q_rate;};
160  double getRangle () const { return R_angle;};
161 private:
162  KFilter r_filter, p_filter, y_filter;
163  double Q_angle, Q_rate, R_angle;
165 };
166 
167 #endif /* RPYKALMANFILTER_H */
void resetKalmanFilterState()
hrp::Matrix33 m_sensorR
hrp::Vector2 x
double getQangle() const
OpenHRP::matrix33 Matrix33
Eigen::Matrix< double, 1, 2 > H
void setSensorR(const hrp::Matrix33 &sr)
double getQrate() const
void setB(const double _b0, const double _b1)
Eigen::Vector3d Vector3
Matrix33 rotFromRpy(const Vector3 &rpy)
void resetStateByObservation()
Eigen::Matrix3d Matrix33
void setParam(const double _dt, const double _Q_angle, const double _Q_rate, const double _R_angle, const std::string print_str="")
double z
const hrp::Vector2 & getx()
void setR(const double _R)
void main_one(hrp::Vector3 &rpy, hrp::Vector3 &rpyRaw, hrp::Vector3 &baseRpyCurrent, const hrp::Vector3 &acc, const hrp::Vector3 &gyro, const double &sl_y, const hrp::Matrix33 &BtoS)
void update(const double u, const double _z)
Eigen::Matrix2d Matrix22
HRP_UTIL_EXPORT Vector3 rpyFromRot(const Matrix33 &m)
void setP(const double _p0, const double _p1, const double _p2, const double _p3)
void setF(const double _f0, const double _f1, const double _f2, const double _f3)
void setQ(const double _q0, const double _q1, const double _q2, const double _q3)
hrp::Matrix22 Q
Eigen::Vector2d Vector2
hrp::Vector2 K


hrpsys
Author(s): AIST, Fumio Kanehiro
autogenerated on Thu May 6 2021 02:41:51