M5Unified
IMU_Class.hpp
Go to the documentation of this file.
1 // Copyright (c) M5Stack. All rights reserved.
2 // Licensed under the MIT license. See LICENSE file in the project root for full license information.
3 
4 #ifndef __M5_IMU_CLASS_H__
5 #define __M5_IMU_CLASS_H__
6 
7 #include "I2C_Class.hpp"
8 #include "imu/IMU_Base.hpp"
9 #include <memory>
10 
11 namespace m5
12 {
13  enum imu_t
21  };
22 
23  class IMU_Class
24  {
25  public:
26 
27  struct imu_3d_t
28  {
29  union
30  {
31  float value[3];
32  struct
33  {
34  float x;
35  float y;
36  float z;
37  };
38  };
39  };
40 
41  struct imu_data_t
42  {
43  uint32_t usec;
44  union
45  {
46  float value[9];
48  struct
49  {
53  };
54  };
55  };
56 
57  enum axis_t
58  {
65  };
66 
68  {
72  };
73 
75  {
80  };
81 
82  bool begin(I2C_Class* i2c = nullptr, board_t board = board_t::board_unknown);
83  bool init(I2C_Class* i2c = nullptr) { return begin(i2c); }
84 
85  sensor_mask_t update(void);
86 
87  void getImuData(imu_data_t* imu_data);
88 
89  const imu_data_t& getImuData(void) { getImuData(&_last_data); return _last_data; }
90 
91  // 軸の順序を指定する。デフォルトはX+,Y+,Z+
92  bool setAxisOrder(axis_t axis0, axis_t axis1, axis_t axis2);
93 
94  // 軸の順序を右手系で指定する。最初の2軸のみ指定し、3軸目は省略
95  bool setAxisOrderRightHanded(axis_t axis0, axis_t axis1);
96 
97  // 軸の順序を左手系で指定する。最初の2軸のみ指定し、3軸目は省略
98  bool setAxisOrderLeftHanded(axis_t axis0, axis_t axis1);
99 
100  bool getAccel(float* ax, float* ay, float* az);
101  bool getGyro(float* gx, float* gy, float* gz);
102  bool getMag(float* mx, float* my, float* mz);
103  bool getAccelData(float* ax, float* ay, float* az) { return getAccel(ax, ay, az); }
104  bool getGyroData(float* gx, float* gy, float* gz) { return getGyro(gx, gy, gz); }
105  bool getGyroMag(float* mx, float* my, float* mz) { return getMag(mx, my, mz); }
106  bool getTemp(float *t);
107 
108  bool isEnabled(void) const { return _imu != imu_none; }
109 
110  imu_t getType(void) const { return _imu; }
111 
112  // 実装予定
113  // void getAhrsData(float *pitch, float *roll, float *yaw);
114 
115  // 廃止
116  // void setRotation(uint_fast8_t rotation) { _rotation = rotation & 3; };
117 
118  bool setINTPinActiveLogic(bool level);
119 
120  // 各センサの自動オフセット調整機能の強さを指定する。 0=自動調整なし 1~255=自動調整あり
121  void setCalibration(uint8_t accel_strength, uint8_t gyro_strength, uint8_t mag_strength);
122 
123  // 現在のオフセット調整値をNVSに保存する
124  bool saveOffsetToNVS(void);
125 
126  // NVSからオフセット調整値を読み込む
127  bool loadOffsetFromNVS(void);
128 
129  // オフセットデータをクリアする
130  void clearOffsetData(void);
131 
132  // OffsetData は RawData<<16 スケール(16bit固定小数扱い)
133  void setOffsetData(size_t index, int32_t value);
134 
135  int32_t getOffsetData(size_t index);
136 
137  int16_t getRawData(size_t index);
138 
139  private:
140 
141  struct offset_point_t
142  {
143  union
144  {
145  int32_t value[3];
146  struct
147  {
148  int32_t x;
149  int32_t y;
150  int32_t z;
151  };
152  };
153  union
154  {
155  int32_t prev_value[3];
156  struct
157  {
158  int32_t prev_x;
159  int32_t prev_y;
160  int32_t prev_z;
161  };
162  };
163  union
164  {
165  int32_t avg_value[3];
166  struct
167  {
168  int32_t avg_x;
169  int32_t avg_y;
170  int32_t avg_z;
171  };
172  };
173  float radius;
174  float tolerance;
175  uint16_t noise_level;
176  uint8_t average_shifter; // 前回値への移動平均設定
177  uint8_t stillness; // 移動量の少なさ(変動が大きい時0になり、静止時に255に近付く)
178  uint8_t strength; // キャリブレーションの強さ(ユーザー指定)
179 
180  std::uint_fast8_t updateStillness(const IMU_Base::point3d_i16_t& dst);
181  void calibration(void);
182  inline void setValue16(size_t index, int16_t val) { value[index] = val << 16; }
183  inline int32_t getValue16(size_t index) const { return value[index] >> 16; }
184  } __attribute__((__packed__));
185 
186  struct imu_offset_data_t
187  {
188  union
189  {
190  offset_point_t sensor[3];
191  struct
192  {
193  offset_point_t accel;
194  offset_point_t gyro;
195  offset_point_t mag;
196  };
197  };
198  };
199 
200  void _update_convert_param(void);
201  void _update_axis_order(void);
202  void _proc_calibration(void);
203 
204  // update成功時のマイクロ秒情報
205  uint32_t _latest_micros;
206 
207  // センサのインスタンス保持用 ([0]=加速度+ジャイロ / [1]=地磁気)
208  std::unique_ptr<IMU_Base> _imu_instance[2];
209 
210  // 生の値を測定値に変換するための補正値
211  IMU_Base::imu_convert_param_t _convert_param;
212 
213  // updateで得た最新の生値
214  IMU_Base::imu_raw_data_t _raw_data;
215 
216  // オフセット補正用の値
217  imu_offset_data_t _offset_data;
218 
219  // 最後に得たセンサ値
220  imu_data_t _last_data;
221 
222  // 最後に動きがあった時のusec
223  uint32_t _moving_micros;
224 
225  // ユーザ側で任意の軸割当を行うための設定項目
226  uint8_t _assign_axis_x;
227  uint8_t _assign_axis_y;
228  uint8_t _assign_axis_z;
229 
230  sensor_mask_t _calibration_flg;
231 
232  sensor_mask_t _has_sensor_mask;
233 
234  imu_t _imu = imu_t::imu_unknown;
235 
236  // 機種別設定とユーザー設定の両方を反映した後のデータ取得順の値
237  uint32_t _axis_order_3bit_x9;
238 
239  enum internal_axisorder_t : uint8_t
240  {
241  axis_invert_x = 1,
242  axis_invert_y = 2,
243  axis_invert_z = 4,
244  axis_order_shift = 3,
245  axis_order_xyz = 0 << axis_order_shift,
246  axis_order_xzy = 1 << axis_order_shift,
247  axis_order_yxz = 2 << axis_order_shift,
248  axis_order_yzx = 3 << axis_order_shift,
249  axis_order_zxy = 4 << axis_order_shift,
250  axis_order_zyx = 5 << axis_order_shift,
251  };
252 
253  // 機種別の軸の不一致を統一するための設定項目(システム自動設定)
254  internal_axisorder_t _internal_axisorder_fixed[3] = { (internal_axisorder_t)0, (internal_axisorder_t)0, (internal_axisorder_t)0 };
255 
256  // ユーザーによる設定値
257  internal_axisorder_t _internal_axisorder_user = (internal_axisorder_t)0;
258  };
259 
262 }
263 #endif
point3d_i16_t accel
Definition: IMU_Base.hpp:0
point3d_i16_t mag
Definition: IMU_Base.hpp:2
point3d_i16_t gyro
Definition: IMU_Base.hpp:1
int32_t prev_x
Definition: IMU_Class.hpp:15
uint16_t noise_level
Definition: IMU_Class.hpp:32
int32_t avg_x
Definition: IMU_Class.hpp:25
int32_t avg_y
Definition: IMU_Class.hpp:26
uint8_t average_shifter
Definition: IMU_Class.hpp:33
int32_t value[3]
Definition: IMU_Class.hpp:2
float radius
Definition: IMU_Class.hpp:30
uint8_t stillness
Definition: IMU_Class.hpp:34
int32_t avg_value[3]
Definition: IMU_Class.hpp:22
int32_t prev_z
Definition: IMU_Class.hpp:17
void calibration(void)
int32_t getValue16(size_t index) const
Definition: IMU_Class.hpp:40
uint8_t strength
Definition: IMU_Class.hpp:35
float tolerance
Definition: IMU_Class.hpp:31
int32_t z
Definition: IMU_Class.hpp:7
std::uint_fast8_t updateStillness(const IMU_Base::point3d_i16_t &dst)
int32_t prev_y
Definition: IMU_Class.hpp:16
void setValue16(size_t index, int16_t val)
Definition: IMU_Class.hpp:39
int32_t avg_z
Definition: IMU_Class.hpp:27
int32_t y
Definition: IMU_Class.hpp:6
int32_t x
Definition: IMU_Class.hpp:5
int32_t prev_value[3]
Definition: IMU_Class.hpp:12
bool getMag(float *mx, float *my, float *mz)
Definition: IMU_Class.cpp:444
bool getGyroMag(float *mx, float *my, float *mz)
Definition: IMU_Class.hpp:105
bool begin(I2C_Class *i2c=nullptr, board_t board=board_t::board_unknown)
Definition: IMU_Class.cpp:28
bool setAxisOrderRightHanded(axis_t axis0, axis_t axis1)
Definition: IMU_Class.cpp:260
bool saveOffsetToNVS(void)
Definition: IMU_Class.cpp:272
bool isEnabled(void) const
Definition: IMU_Class.hpp:108
bool getGyroData(float *gx, float *gy, float *gz)
Definition: IMU_Class.hpp:104
int16_t getRawData(size_t index)
Definition: IMU_Class.cpp:343
sensor_mask_t update(void)
Definition: IMU_Class.cpp:348
bool loadOffsetFromNVS(void)
Definition: IMU_Class.cpp:295
bool getTemp(float *t)
Definition: IMU_Class.cpp:460
bool init(I2C_Class *i2c=nullptr)
Definition: IMU_Class.hpp:83
bool setAxisOrderLeftHanded(axis_t axis0, axis_t axis1)
Definition: IMU_Class.cpp:265
bool getAccelData(float *ax, float *ay, float *az)
Definition: IMU_Class.hpp:103
void clearOffsetData(void)
Definition: IMU_Class.cpp:319
void setCalibration(uint8_t accel_strength, uint8_t gyro_strength, uint8_t mag_strength)
Definition: IMU_Class.cpp:183
bool getGyro(float *gx, float *gy, float *gz)
Definition: IMU_Class.cpp:428
bool setINTPinActiveLogic(bool level)
Definition: IMU_Class.cpp:472
bool getAccel(float *ax, float *ay, float *az)
Definition: IMU_Class.cpp:412
const imu_data_t & getImuData(void)
Definition: IMU_Class.hpp:89
void setOffsetData(size_t index, int32_t value)
Definition: IMU_Class.cpp:331
bool setAxisOrder(axis_t axis0, axis_t axis1, axis_t axis2)
Definition: IMU_Class.cpp:193
imu_t getType(void) const
Definition: IMU_Class.hpp:110
int32_t getOffsetData(size_t index)
Definition: IMU_Class.cpp:338
Definition: M5Unified.cpp:48
m5gfx::board_t board_t
Definition: M5Unified.hpp:23
imu_t
Definition: IMU_Class.hpp:14
@ imu_none
Definition: IMU_Class.hpp:14
@ imu_bmi270
Definition: IMU_Class.hpp:20
@ imu_mpu6886
Definition: IMU_Class.hpp:18
@ imu_sh200q
Definition: IMU_Class.hpp:16
@ imu_unknown
Definition: IMU_Class.hpp:15
@ imu_mpu6050
Definition: IMU_Class.hpp:17
@ imu_mpu9250
Definition: IMU_Class.hpp:19
IMU_Class::imu_3d_t imu_3d_t
Definition: IMU_Class.hpp:260
IMU_Class::imu_data_t imu_data_t
Definition: IMU_Class.hpp:261