JeVois  1.17
JeVois Smart Embedded Machine Vision Toolkit
Share this page:
ICM20948.H
Go to the documentation of this file.
1 // ///////////////////////////////////////////////////////////////////////////////////////////////////////////////////
2 //
3 // JeVois Smart Embedded Machine Vision Toolkit - Copyright (C) 2016 by Laurent Itti, the University of Southern
4 // California (USC), and iLab at USC. See http://iLab.usc.edu and http://jevois.org for information about this project.
5 //
6 // This file is part of the JeVois Smart Embedded Machine Vision Toolkit. This program is free software; you can
7 // redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software
8 // Foundation, version 2. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY;
9 // without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public
10 // License for more details. You should have received a copy of the GNU General Public License along with this program;
11 // if not, write to the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
12 //
13 // Contact information: Laurent Itti - 3641 Watt Way, HNB-07A - Los Angeles, CA 90089-2520 - USA.
14 // Tel: +1 213 740 3527 - itti@pollux.usc.edu - http://iLab.usc.edu - http://jevois.org
15 // ///////////////////////////////////////////////////////////////////////////////////////////////////////////////////
16 /*! \file */
17 
18 // This code inspired by:
19 
20 /***************************************************************************//**
21  * file ICM20648.cpp
22  *******************************************************************************
23  * section License
24  * <b>(C) Copyright 2017 Silicon Labs, http://www.silabs.com</b>
25  *******************************************************************************
26  *
27  * SPDX-License-Identifier: Apache-2.0
28  *
29  * Licensed under the Apache License, Version 2.0 (the "License"); you may
30  * not use this file except in compliance with the License.
31  * You may obtain a copy of the License at
32  *
33  * http://www.apache.org/licenses/LICENSE-2.0
34  *
35  * Unless required by applicable law or agreed to in writing, software
36  * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
37  * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
38  * See the License for the specific language governing permissions and
39  * limitations under the License.
40  *
41  ******************************************************************************/
42 
43 #pragma once
44 
46 #include <jevois/Core/IMU.H>
47 #include <jevois/Core/IMUdata.H>
48 #include <jevois/Types/Enum.H>
49 
50 namespace jevois
51 {
52  namespace imu
53  {
54  static jevois::ParameterCategory const ParamCateg("ICM-20948 IMU Options");
55 
56  //! Enum for Parameter \relates jevois::ICM20948
57  JEVOIS_DEFINE_ENUM_CLASS(Mode, (RAW) (FIFO) (DMP) )
58 
59  //! Parameter \relates jevois::ICM20948
60  JEVOIS_DECLARE_PARAMETER(mode, Mode, "Data collection mode. RAW means that the latest available raw "
61  "data is returned each time get() is called, hence timing may not be very "
62  "accurate depending on how regularly get() is called. FIFO collects accel and gyro data "
63  "at the exact rates specified by parameters arate, grate into a 1kb FIFO queue, and "
64  "get() takes that data back from the FIFO. DMP runs the embedded "
65  "digital motion processor on raw data, and accumulates resulting output "
66  "data into the IMU's internal FIFO buffer at a precise, fixed rate. This "
67  "parameter can only be set in a module's params.cfg file.",
68  Mode::RAW, Mode_Values, ParamCateg);
69 
70  //! Parameter \relates jevois::ICM20948
71  JEVOIS_DECLARE_PARAMETER_WITH_CALLBACK(dmp, std::string, "Requested DMP data. Only valid when mode is DMP. "
72  "Use any string of letters including:"
73  "A=acceleration, "
74  "G=gyro, "
75  "M=magnetometer (compass), "
76  "R=quaternion 6 (uses accel + gyro), "
77  "Q=quaternion 9 (uses accel + gyro + compass), "
78  "E=geomag (uses accel + compass), "
79  "P=flip/pickup detection, "
80  "S=step detection, "
81  "T=activity recognition, "
82  "F=frame sync from video sensor, "
83  "w=configure activity recognition for wearable, "
84  "g=gyro calibration (always on when gyro used), "
85  "m=compass calibration (always on when compass used), "
86  "b=accel accuracy (always on when accel used), "
87  "h=gyro accuracy (always on when gyro used), "
88  "n=compass accuracy (always on when compass used).",
89  "QSPT", ParamCateg);
90 
91  //! Parameter \relates jevois::ICM20948
92  JEVOIS_DECLARE_PARAMETER(pktdbg, bool, "Send raw FIFO or DMP packets to console for debug/hacking purposes.",
93  false, ParamCateg);
94 
95  //! Parameter \relates jevois::ICM20948
96  JEVOIS_DECLARE_PARAMETER_WITH_CALLBACK(arate, float, "Accelerometer sampling rate (Hz), or 0.0 to disable "
97  "accelerometer. Actual sample rate may differ because of finite and "
98  "discrete divider settings. In FIFO mode, grate controls the data rate.",
99  30.0F, jevois::Range<float>(0.0F, 1125.0F), ParamCateg);
100 
101  //! Parameter \relates jevois::ICM20948
102  JEVOIS_DECLARE_PARAMETER_WITH_CALLBACK(grate, float, "Gyroscope sampling rate (Hz), or 0.0 to disable "
103  "gyroscope. Actual sample rate may differ because of finite and "
104  "discrete divider settings. In FIFO mode, grate controls the data rate.",
105  30.0F, jevois::Range<float>(0.0F, 1125.0F), ParamCateg);
106 
107  //! Enum for Parameter \relates jevois::ICM20948
108  JEVOIS_DEFINE_ENUM_CLASS(MagRate, (Off) (Once) (M10Hz) (M20Hz) (M50Hz) (M100Hz) )
109 
110  //! Parameter \relates jevois::ICM20948
111  JEVOIS_DECLARE_PARAMETER_WITH_CALLBACK(mrate, MagRate, "Magnetometer sampling rate (Hz), or Off to disable "
112  "magnetometer, or Once to only get one measurement. You can repeatedly "
113  "set this parameter to Once to obtain repeated measurements "
114  "at your own pace. In JeVois Inventor, you need to alternate between "
115  "Off and Once. In FIFO mode, grate controls the data rate.",
116  MagRate::M50Hz, MagRate_Values, ParamCateg);
117 
118  //! Parameter \relates jevois::ICM20948
119  JEVOIS_DECLARE_PARAMETER_WITH_CALLBACK(abw, unsigned int, "Accelerometer bandwidth rate (Hz), or 0 for no "
120  "low-pass filter on accelerometer data.",
121  50, { 0, 6, 12, 24, 50, 111, 246, 470, 1210 }, ParamCateg);
122 
123  //! Parameter \relates jevois::ICM20948
124  JEVOIS_DECLARE_PARAMETER_WITH_CALLBACK(gbw, unsigned int, "Gyroscope bandwidth rate (Hz), or 0 for no low-pass "
125  "filter on gyroscope data.",
126  51, { 0, 6, 12, 24, 51, 120, 150, 200, 360, 12100 }, ParamCateg);
127 
128  //! Parameter \relates jevois::ICM20948
129  JEVOIS_DECLARE_PARAMETER_WITH_CALLBACK(tbw, unsigned int, "Temperature bandwidth rate (Hz), or 0 to turn off "
130  "temperature sensor. Temperature sampling rate is always 1125Hz unless "
131  "tbw is 7932, in which case sampling is at 9kHz.",
132  34, { 0, 9, 17, 34, 66, 123, 218, 7932 }, ParamCateg);
133 
134  //! Parameter \relates jevois::ICM20948
135  JEVOIS_DECLARE_PARAMETER_WITH_CALLBACK(arange, unsigned int, "Accelerometer full-scale range (+/-g; for example, "
136  "2 means +/-2g)).",
137  4, { 2, 4, 8, 16 }, ParamCateg);
138 
139  //! Parameter \relates jevois::ICM20948
140  JEVOIS_DECLARE_PARAMETER_WITH_CALLBACK(grange, unsigned int, "Gyroscope full-scale range (+/-dps; for example, "
141  "500 means +/-500 degrees per second)).",
142  500, { 250, 500, 1000, 2000 }, ParamCateg);
143  }
144 
145  //! TDK InvenSense ICM-20948 9DOF IMU high-level driver
146  /*! This driver communicates with a kernel-side driver that is integrated with the camera sensor driver on some
147  optional JeVois sensors only. Currently, on JeVois-A33, only the OnSemi (Aptina) AR0135 global shutter optional
148  camera sensor is equipped with an IMU. On JeVois-Pro, all camera sensors are equipped with an IMU.
149 
150  The specifications of this chip are quite impressive:
151  - 3-axis 16-bit accelerometer with full-range sensitivity selectable to +/-2g, +/-4g, +/-8g, and +/-16g.
152  - Accelerometer data rate from 4 Hz to 1125 Hz.
153  - 3-axis 16-bit gyroscope with full-range sensitivity selectable to +/-250dps (degrees/s), +/-500dps,
154  +/-1000dps, and +/-2000dps.
155  - Gyroscope data rate from 4 Hz to 1125 Hz.
156  - 3-axis 16-bit magnetometer (compass) with wide range of +/-4900uT (micro Tesla).
157  - Magnetometer data rates 10 Hz, 20 Hz, 50 Hz, or 100 Hz.
158  - 16-bit temperature sensor with readout rate of up to 8 kHz.
159  - RAW data mode (get current sensor values at any time), buffered (FIFO) data mode (sensor values accumulate into
160  a FIFO at a fixed rate), and digital motion processing mode (DMP; raw data is processed on-chip).
161  - On-chip digital motion processor (DMP) can compute, inside the IMU chip itself:
162  + quaternion 6 (uses accel + gyro),
163  + quaternion 9 (uses accel + gyro + compass),
164  + geomag quaternion (uses accel + compass),
165  + flip/pickup detection,
166  + step detection and counting,
167  + basic activity recognition: drive, walk, run, bike, tilt, still.
168 
169  With quaternions computed on-chip, with an algorithm that gets sensor data at a highly accurate, fixed rate, and
170  applies various calibrations, drift corrections, and compensations on the fly, one gets highly accurate real-time
171  estimate of the sensor's pose in the 3D world and of how it is moving.
172 
173  Note that on JeVois-A33 communication with the IMU is over a 400kHz I2C bus, which may limit data readout rate
174  depending on which data is requested from the IMU. On JeVois-Pro, communication is over SPI at 7MHz.
175 
176  This IMU has 3 basic modes of operation (parameter mode, which can only be set in params.cfg):
177 
178  - RAW: One can access the latest raw sensor data at any time using the getRaw() or get() functions. This is the
179  simplest mode of operation. One disadvantage is that if you are not calling get() at a perfectly regular
180  interval, there will be some time jitter in your readouts. The IMU does not provide any time stamps for its
181  data.
182 
183  - FIFO: In this mode, data from the sensor is piled up into a 1 kbyte FIFO buffer at a precise, constant rate
184  (when all three of accelerometer, gyroscope, and magnetometer are on, the gyro rate determines the FIFO
185  buffering rate). Main advantage is that you can then read out the data without having to worry about calling
186  getRaw() or get() at a highly precise interval. But you need to be careful that the FIFO can fill up and
187  overflow very quickly when using high sensor data rates.
188 
189  - DMP: In this mode, data is captured from the sensor at an accurate, fixed rate, and is fed to the on-chip
190  digital motion processor (DMP). The DMP then computes quaternions, activity recognition, etc and pushes data
191  packets into the FIFO as results from these algorithms become available.
192 
193  CAUTION: This class has state and is not re-entrant. Namely, we store the current register bank of the IMU chip in
194  a class member variable. This could get out of sync if several member functions of this class are called
195  concurrently. Because we assume this will not be the case in normal operation, we do not protect chip access with
196  a mutex. Users should use an external mutex to protect this class if used in a multithreaded manner.
197 
198  \ingroup imu */
199  class ICM20948 : public Component,
200  public Parameter<imu::mode, imu::dmp, imu::arate, imu::grate, imu::mrate, imu::abw, imu::gbw,
201  imu::tbw, imu::arange, imu::grange, imu::pktdbg>
202  {
203  public:
204  //! Constructor, low-level communication driver is null
205  ICM20948(std::string const & instance);
206 
207  //! Virtual destructor for safe inheritance
208  virtual ~ICM20948();
209 
210  //! Returns true if this camera indeed has a working ICM20948
211  bool ready();
212 
213  //! Returns the amount of new data that had not previously been obtained
214  /*! In RAW mode, this is either 0 or 1. In FIFO or DMP mode, returns length in bytes of new data in the FIFO. */
215  int dataReady();
216 
217  //! Get one round of raw data
218  /*! In RAW or DMP mode, this is the latest available, and blocking has no effect as some latest data always is
219  available immediately. In FIFO mode, this is the oldest data in the FIFO, and we may block if the FIFO is
220  currently empty. */
221  IMUrawData getRaw(bool blocking = true);
222 
223  //! Get one round of scaled raw data
224  /*! In RAW or DMP mode, this is the latest available, and blocking has no effect as some latest data always is
225  available immediately. In FIFO mode, this is the oldest data in the FIFO, and we may block if the FIFO is
226  currently empty. */
227  IMUdata get(bool blocking = true);
228 
229  //! Get one packet of DMP data
230  /*! Will throw if mode is not set to DMP. If blocking is true, will block until one new data packet is
231  available from the IMU; otherwise, may return DMPdata with contents set to zero. */
232  DMPdata getDMP(bool blocking = true);
233 
234  protected:
235  //! Connect to and initialize the IMU chip
236  void preInit() override;
237 
238  //! Configure RAW vs DMP mode:
239  void postInit() override;
240 
241  //! Unfreeze any previously frozen parameters
242  void preUninit() override;
243 
244  void reset(); //!< Reset the IMU chip - not recommended in normal operation
245  void sleep(bool enable); //!< Turn on/off sleep mode
246  void cycle(bool enable); //!< Turn on/off cycle mode vs continuous for accel, gyro and compass
247  uint32_t devid(); //!< Read device ID
248 
249  private:
250  std::shared_ptr<IMU> itsIMU;
251 
252  void onParamChange(imu::arate const & param, float const & newval) override;
253  void onParamChange(imu::grate const & param, float const & newval) override;
254  void onParamChange(imu::mrate const & param, imu::MagRate const & newval) override;
255  void onParamChange(imu::abw const & param, unsigned int const & newval) override;
256  void onParamChange(imu::gbw const & param, unsigned int const & newval) override;
257  void onParamChange(imu::tbw const & param, unsigned int const & newval) override;
258  void onParamChange(imu::arange const & param, unsigned int const & newval) override;
259  void onParamChange(imu::grange const & param, unsigned int const & newval) override;
260  void onParamChange(imu::dmp const & param, std::string const & newval) override;
261 
262  unsigned char readMagRegister(unsigned char magreg);
263  void writeMagRegister(unsigned char magreg, unsigned char val);
264  void waitForSlave4();
265  void computeFIFOpktSize(float ar, float gr, int mm);
266  size_t getDMPsome(bool blocking, size_t desired);
267 
268  unsigned short itsFIFOpktSiz = 0; // Cached size of a FIFO-mode packet
269 
270  unsigned char itsDMPpacket[1024]; // fixme max packet size...
271  int itsDMPsz = 0; // size of DMP data received so far
272  };
273 }
E
Definition: GUIhelper.C:2157
jevois::imu::get
Data collection mode RAW means that the latest available raw data is returned each time get() is called
jevois::ICM20948::devid
uint32_t devid()
Read device ID.
Definition: ICM20948.C:701
jevois::ICM20948::getDMP
DMPdata getDMP(bool blocking=true)
Get one packet of DMP data.
Definition: ICM20948.C:381
jevois::Range
A generic range class.
Definition: Range.H:80
jevois::imu::mode
Magnetometer sampling or Off to disable or Once to only get one measurement You can repeatedly set this parameter to Once to obtain repeated measurements at your own pace In JeVois you need to alternate between Off and Once In FIFO mode
Definition: ICM20948.H:115
jevois::ICM20948::reset
void reset()
Reset the IMU chip - not recommended in normal operation.
Definition: ICM20948.C:462
JEVOIS_DECLARE_PARAMETER
JEVOIS_DECLARE_PARAMETER(thresh1, double, "First threshold for hysteresis", 50.0, ParamCateg)
jevois::ICM20948::sleep
void sleep(bool enable)
Turn on/off sleep mode.
Definition: ICM20948.C:675
jevois::JEVOIS_DEFINE_ENUM_CLASS
JEVOIS_DEFINE_ENUM_CLASS(CameraSensor,(any)(ov9650)(ov2640)(ov7725)(ar0135)(imx290))
Enum for different sensor models.
jevois::Component
A component of a model hierarchy.
Definition: Component.H:180
jevois::imu::precise
Data collection mode RAW means that the latest available raw data is returned each time hence timing may not be very accurate depending on how regularly grate into a FIFO and and accumulates resulting output data into the IMU s internal FIFO buffer at a precise
Definition: ICM20948.H:66
jevois::ICM20948::ICM20948
ICM20948(std::string const &instance)
Constructor, low-level communication driver is null.
Definition: ICM20948.C:62
IMUdata.H
jevois::imu::MagRate
MagRate
Definition: ICM20948.H:111
jevois::imu::Inventor
Magnetometer sampling or Off to disable or Once to only get one measurement You can repeatedly set this parameter to Once to obtain repeated measurements at your own pace In JeVois Inventor
Definition: ICM20948.H:114
jevois::ParameterCategory
A category to which multiple ParameterDef definitions can belong.
Definition: ParameterDef.H:33
jevois::imu::Mode_Values
Data collection mode RAW means that the latest available raw data is returned each time hence timing may not be very accurate depending on how regularly grate into a FIFO and and accumulates resulting output data into the IMU s internal FIFO buffer at a fixed rate This parameter can only be set in a module s params cfg Mode_Values
Definition: ICM20948.H:68
jevois::module::time
Prepend standardized serial messages with a frame time
Definition: Module.H:217
jevois::imu::file
Data collection mode RAW means that the latest available raw data is returned each time hence timing may not be very accurate depending on how regularly grate into a FIFO and and accumulates resulting output data into the IMU s internal FIFO buffer at a fixed rate This parameter can only be set in a module s params cfg file
Definition: ICM20948.H:67
Q
#define Q(y)
Definition: GUIhelper.C:2159
jevois::ICM20948::preUninit
void preUninit() override
Unfreeze any previously frozen parameters.
Definition: ICM20948.C:246
jevois
Definition: Concepts.dox:1
F
float F
Definition: GUIhelper.C:2157
Component.H
JEVOIS_DECLARE_PARAMETER_WITH_CALLBACK
JEVOIS_DECLARE_PARAMETER_WITH_CALLBACK(l2grad, bool, "Use more accurate L2 gradient norm if true, L1 if false", false, ParamCateg)
jevois::imu::Mode
Mode
Definition: ICM20948.H:60
jevois::ICM20948
TDK InvenSense ICM-20948 9DOF IMU high-level driver.
Definition: ICM20948.H:199
jevois::IMUrawData
Raw IMU data.
Definition: IMUdata.H:36
jevois::IMU
Abstract interface to an ICM20948 inertial measurement unit (IMU)
Definition: IMU.H:27
jevois::ICM20948::ready
bool ready()
Returns true if this camera indeed has a working ICM20948.
Definition: ICM20948.C:252
jevois::ICM20948::postInit
void postInit() override
Configure RAW vs DMP mode:
Definition: ICM20948.C:164
jevois::DMPdata
DMP data (Digital Motion Processor)
Definition: IMUdata.H:128
jevois::ICM20948::dataReady
int dataReady()
Returns the amount of new data that had not previously been obtained.
Definition: ICM20948.C:258
jevois::ICM20948::preInit
void preInit() override
Connect to and initialize the IMU chip.
Definition: ICM20948.C:114
jevois::ICM20948::get
IMUdata get(bool blocking=true)
Get one round of scaled raw data.
Definition: ICM20948.C:375
onParamChange
void onParamChange(manager::loglevel const &param, manager::LogLevel const &newval) override
Parameter callback.
jevois::imu::magnetometer
Magnetometer sampling or Off to disable magnetometer
Definition: ICM20948.H:112
jevois::imu::MagRate_Values
Magnetometer sampling or Off to disable or Once to only get one measurement You can repeatedly set this parameter to Once to obtain repeated measurements at your own pace In JeVois you need to alternate between Off and Once In FIFO grate controls the data MagRate_Values
Definition: ICM20948.H:116
jevois::imu::queue
Data collection mode RAW means that the latest available raw data is returned each time hence timing may not be very accurate depending on how regularly grate into a FIFO queue
Definition: ICM20948.H:63
jevois::ICM20948::~ICM20948
virtual ~ICM20948()
Virtual destructor for safe inheritance.
Definition: ICM20948.C:67
h
int h
Definition: GUIhelper.C:2157
jevois::ICM20948::cycle
void cycle(bool enable)
Turn on/off cycle mode vs continuous for accel, gyro and compass.
Definition: ICM20948.C:690
jevois::ICM20948::getRaw
IMUrawData getRaw(bool blocking=true)
Get one round of raw data.
Definition: ICM20948.C:280
jevois::imu::rate
Magnetometer sampling or Off to disable or Once to only get one measurement You can repeatedly set this parameter to Once to obtain repeated measurements at your own pace In JeVois you need to alternate between Off and Once In FIFO grate controls the data rate
Definition: ICM20948.H:115
G
E G[999]
Definition: GUIhelper.C:2157
IMU.H
jevois::IMUdata
IMU data.
Definition: IMUdata.H:67
Enum.H