imunano33  0.1.1
filter.hpp
Go to the documentation of this file.
1 
6 #ifndef INCLUDE_IMUNANO33_FILTER_HPP_
7 #define INCLUDE_IMUNANO33_FILTER_HPP_
8 
9 #ifdef IMUNANO33_EMBED
10 #include <math.h>
11 #else
12 #include <cmath>
13 #endif
14 
15 #include "imunano33/mathutil.hpp"
16 #include "imunano33/quaternion.hpp"
17 #ifdef IMUNANO33_EMBED
18 #include "imunano33/sv_embed.hpp"
19 #else
21 #endif
22 #include "imunano33/unit.hpp"
23 
24 namespace imunano33 {
25 #ifdef IMUNANO33_EMBED
26 using Vector3D =
28 #else
29 using svector::Vector3D;
30 #endif
31 
44 class Filter {
45 public:
53  Filter() : m_gyroFavoring{0.98}, m_qRot{1, Vector3D{}} {}
54 
68  Filter(const num_t gyroFavoring) : m_qRot{1, Vector3D{}} {
69 #ifdef IMUNANO33_EMBED
70  m_gyroFavoring = MathUtil::clamp(gyroFavoring, 0.0F, 1.0F);
71 #else
72  m_gyroFavoring = MathUtil::clamp(gyroFavoring, 0.0, 1.0);
73 #endif
74  }
75 
92  Filter(const num_t gyroFavoring, const Quaternion &initialQ)
93  : m_qRot{initialQ.unit()} {
94 #ifdef IMUNANO33_EMBED
95  m_gyroFavoring = MathUtil::clamp(gyroFavoring, 0.0F, 1.0F);
96 #else
97  m_gyroFavoring = MathUtil::clamp(gyroFavoring, 0.0, 1.0);
98 #endif
99  }
100 
104  Filter(const Filter &other) = default;
105 
109  Filter &operator=(const Filter &other) = default;
110 
114  ~Filter() = default;
115 
119  Filter(Filter &&) = default;
120 
124  Filter &operator=(Filter &&) = default;
125 
136  void updateGyro(const Vector3D &gyro, const num_t time) {
137  if (MathUtil::nearZero(gyro)) {
138  // if gyro reading is 0, then don't correct
139  return;
140  }
141 
142  // otherwise integrate quaternion reading
143  const Quaternion qGyroDelta{normalize(gyro), time * magn(gyro)};
144  m_qRot *= qGyroDelta;
145  }
146 
158  void updateAccel(const Vector3D &accel) {
159  // don't bother with acceleration correction if acceleration is basically
160  // 0
161  if (MathUtil::nearZero(accel)) {
162  return;
163  }
164 
165  // gravity vector rotation
166  const Quaternion qAccelBody{0, accel};
167  const Quaternion qAccelWorld =
168  m_qRot * qAccelBody *
169  m_qRot.conj(); // rotates body acceleration by gyro measurements
170 
171  // correcting gyro drift with accelerometer
172  const Vector3D vecAccelWorldNorm = normalize(qAccelWorld.vec());
173  const Vector3D vecAccelGravity{0, 0, -1};
174  const Vector3D vecRotAxis =
175  cross(vecAccelWorldNorm,
176  vecAccelGravity); // rotation axis for correction rotation from
177  // estimated gravity vector (from gyro
178  // readings) to true gravity vector
179 
180 #ifdef IMUNANO33_EMBED
181  const num_t rotAngle = acosf(MathUtil::clamp(
182  dot(vecAccelGravity, vecAccelWorldNorm) /
183  (magn(vecAccelGravity) * magn(vecAccelWorldNorm)),
184  -1.0F,
185  1.0F)); // angle to rotate to correct acceleration vector
186 #else
187  const num_t rotAngle = std::acos(
188  MathUtil::clamp(dot(vecAccelGravity, vecAccelWorldNorm) /
189  (magn(vecAccelGravity) * magn(vecAccelWorldNorm)),
190  -1.0,
191  1.0)); // angle to rotate to correct acceleration vector
192 #endif
193 
194  // if the axis to rotate around is 0, then don't bother correcting
195  if (MathUtil::nearZero(vecRotAxis)) {
196  return;
197  }
198 
199  // complementary filter
200  const Quaternion qAccelCur{normalize(vecRotAxis),
201  (1 - m_gyroFavoring) * rotAngle};
202  m_qRot = qAccelCur * m_qRot;
203  }
204 
222  void update(const Vector3D &accel, const Vector3D &gyro, const num_t time) {
223  // math from:
224  // https://stanford.edu/class/ee267/lectures/lecture10.pdf
225  // https://stanford.edu/class/ee267/notes/ee267_notes_imu.pdf
226 
227  updateGyro(gyro, time);
228  updateAccel(accel);
229  }
230 
235  void reset() { setRotQ({1, {0, 0, 0}}); }
236 
242  Quaternion getRotQ() const { return m_qRot; }
243 
249  num_t getGyroFavoring() const { return m_gyroFavoring; }
250 
259  void setRotQ(const Quaternion &q) { m_qRot = q.unit(); }
260 
269  void setGyroFavoring(const num_t favoring) {
270 #ifdef IMUNANO33_EMBED
271  m_gyroFavoring = MathUtil::clamp(favoring, 0.0F, 1.0F);
272 #else
273  m_gyroFavoring = MathUtil::clamp(favoring, 0.0, 1.0);
274 #endif
275  }
276 
277 private:
278  num_t m_gyroFavoring;
279 
280  Quaternion m_qRot;
281 };
282 
283 } // namespace imunano33
284 
285 #endif
File containing the imunano33::MathUtil class.
File containing the imunano33::Quaternion class.
A minimized version of vectors for embedded devices without access to the STL (such as on an Arduino,...
Contains imunano33::TempUnit and imunano33::PressureUnit enums, in addition to number type.
double num_t
Alias to number type depending on embed.
Definition: unit.hpp:34
A complementary filter for a 6 axis IMU using quaternions.
Definition: filter.hpp:44
void updateAccel(const Vector3D &accel)
Updates filter with accelerometer data.
Definition: filter.hpp:158
Filter & operator=(Filter &&)=default
Move assignment.
num_t getGyroFavoring() const
Gets gyroscope favoring.
Definition: filter.hpp:249
Filter & operator=(const Filter &other)=default
Assignment operator.
void reset()
Resets quaternion to [1, 0, 0, 0], or facing towards position x direction.
Definition: filter.hpp:235
Filter()
Default Constructor.
Definition: filter.hpp:53
void update(const Vector3D &accel, const Vector3D &gyro, const num_t time)
Updates filter with both gyro and accel data.
Definition: filter.hpp:222
void setGyroFavoring(const num_t favoring)
Sets gyro favoring.
Definition: filter.hpp:269
~Filter()=default
Destructor.
Filter(const num_t gyroFavoring)
Constructor.
Definition: filter.hpp:68
Filter(const Filter &other)=default
Copy constructor.
void updateGyro(const Vector3D &gyro, const num_t time)
Updates filter with gyro data.
Definition: filter.hpp:136
void setRotQ(const Quaternion &q)
Sets rotation quaternion for the filter.
Definition: filter.hpp:259
Filter(Filter &&)=default
Move constructor.
Filter(const num_t gyroFavoring, const Quaternion &initialQ)
Constructor.
Definition: filter.hpp:92
Quaternion getRotQ() const
Gets rotation quaternion of the complementary filter.
Definition: filter.hpp:242
static T clamp(const T &num, const T &lo, const T &hi)
Restricts num between lo and hi.
Definition: mathutil.hpp:141
static bool nearZero(const num_t num)
Determines if number is near zero with given precision.
Definition: mathutil.hpp:48
A simple quaternion class for rotations.
Definition: quaternion.hpp:40
Quaternion unit() const
Gets equivalent unit quaternion.
Definition: quaternion.hpp:161
Quaternion conj() const
Gets the quaternion conjugate.
Definition: quaternion.hpp:124
Vector3D vec() const
Gets the vector component of the quaternion.
Definition: quaternion.hpp:117
A simple 3D vector representation.
Definition: simplevectors.hpp:844
A minimal 3D vector representation.
Definition: sv_embed.hpp:168