JeVois  1.21
JeVois Smart Embedded Machine Vision Toolkit
Share this page:
Loading...
Searching...
No Matches
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
50namespace 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}
A component of a model hierarchy.
Definition Component.H:182
TDK InvenSense ICM-20948 9DOF IMU high-level driver.
Definition ICM20948.H:202
JEVOIS_DECLARE_PARAMETER_WITH_CALLBACK(gbw, unsigned int, "Gyroscope bandwidth rate (Hz), or 0 for no low-pass " "filter on gyroscope data.", 51, { 0, 6, 12, 24, 51, 120, 150, 200, 360, 12100 }, ParamCateg)
Parameter.
void sleep(bool enable)
Turn on/off sleep mode.
Definition ICM20948.C:669
DMPdata getDMP(bool blocking=true)
Get one packet of DMP data.
Definition ICM20948.C:381
JEVOIS_DECLARE_PARAMETER_WITH_CALLBACK(tbw, unsigned int, "Temperature bandwidth rate (Hz), or 0 to turn off " "temperature sensor. Temperature sampling rate is always 1125Hz unless " "tbw is 7932, in which case sampling is at 9kHz.", 34, { 0, 9, 17, 34, 66, 123, 218, 7932 }, ParamCateg)
Parameter.
void cycle(bool enable)
Turn on/off cycle mode vs continuous for accel, gyro and compass.
Definition ICM20948.C:684
JEVOIS_DECLARE_PARAMETER_WITH_CALLBACK(grange, unsigned int, "Gyroscope full-scale range (+/-dps for example, " "500 means +/-500 degrees per second)).", 500, { 250, 500, 1000, 2000 }, ParamCateg)
Parameter.
JEVOIS_DECLARE_PARAMETER_WITH_CALLBACK(grate, float, "Gyroscope sampling rate (Hz), or 0.0 to disable " "gyroscope. Actual sample rate may differ because of finite and " "discrete divider settings. In FIFO mode, grate controls the data rate.", 30.0F, jevois::Range< float >(0.0F, 1125.0F), ParamCateg)
Parameter.
void reset()
Reset the IMU chip - not recommended in normal operation.
Definition ICM20948.C:462
virtual ~ICM20948()
Virtual destructor for safe inheritance.
Definition ICM20948.C:67
JEVOIS_DEFINE_ENUM_CLASS(MagRate,(Off)(Once)(M10Hz)(M20Hz)(M50Hz)(M100Hz))
Enum for Parameter.
JEVOIS_DECLARE_PARAMETER_WITH_CALLBACK(arange, unsigned int, "Accelerometer full-scale range (+/-g for example, " "2 means +/-2g)).", 4, { 2, 4, 8, 16 }, ParamCateg)
Parameter.
bool ready()
Returns true if this camera indeed has a working ICM20948.
Definition ICM20948.C:252
JEVOIS_DEFINE_ENUM_CLASS(Mode,(RAW)(FIFO)(DMP))
Enum for Parameter.
JEVOIS_DECLARE_PARAMETER_WITH_CALLBACK(dmp, std::string, "Requested DMP data. Only valid when mode is DMP. " "Use any string of letters including:" "A=acceleration, " "G=gyro, " "M=magnetometer (compass), " "R=quaternion 6 (uses accel + gyro), " "Q=quaternion 9 (uses accel + gyro + compass), " "E=geomag (uses accel + compass), " "P=flip/pickup detection, " "S=step detection, " "T=activity recognition, " "F=frame sync from video sensor, " "w=configure activity recognition for wearable, " "g=gyro calibration (always on when gyro used), " "m=compass calibration (always on when compass used), " "b=accel accuracy (always on when accel used), " "h=gyro accuracy (always on when gyro used), " "n=compass accuracy (always on when compass used).", "QSPT", ParamCateg)
Parameter.
void preInit() override
Connect to and initialize the IMU chip.
Definition ICM20948.C:114
void postInit() override
Configure RAW vs DMP mode:
Definition ICM20948.C:164
JEVOIS_DECLARE_PARAMETER(mode, Mode, "Data collection mode. RAW means that the latest available raw " "data is returned each time get() is called, hence timing may not be very " "accurate depending on how regularly get() is called. FIFO collects accel and gyro data " "at the exact rates specified by parameters arate, grate into a 1kb FIFO queue, and " "get() takes that data back from the FIFO. DMP runs the embedded " "digital motion processor on raw data, and accumulates resulting output " "data into the IMU's internal FIFO buffer at a precise, fixed rate. This " "parameter can only be set in a module's params.cfg file.", Mode::RAW, Mode_Values, ParamCateg)
Parameter.
IMUdata get(bool blocking=true)
Get one round of scaled raw data.
Definition ICM20948.C:375
uint32_t devid()
Read device ID.
Definition ICM20948.C:695
IMUrawData getRaw(bool blocking=true)
Get one round of raw data.
Definition ICM20948.C:280
void preUninit() override
Unfreeze any previously frozen parameters.
Definition ICM20948.C:246
JEVOIS_DECLARE_PARAMETER(pktdbg, bool, "Send raw FIFO or DMP packets to console for debug/hacking purposes.", false, ParamCateg)
Parameter.
JEVOIS_DECLARE_PARAMETER_WITH_CALLBACK(abw, unsigned int, "Accelerometer bandwidth rate (Hz), or 0 for no " "low-pass filter on accelerometer data.", 50, { 0, 6, 12, 24, 50, 111, 246, 470, 1210 }, ParamCateg)
Parameter.
int dataReady()
Returns the amount of new data that had not previously been obtained.
Definition ICM20948.C:258
JEVOIS_DECLARE_PARAMETER_WITH_CALLBACK(arate, float, "Accelerometer sampling rate (Hz), or 0.0 to disable " "accelerometer. Actual sample rate may differ because of finite and " "discrete divider settings. In FIFO mode, grate controls the data rate.", 30.0F, jevois::Range< float >(0.0F, 1125.0F), ParamCateg)
Parameter.
JEVOIS_DECLARE_PARAMETER_WITH_CALLBACK(mrate, MagRate, "Magnetometer sampling rate (Hz), or Off to disable " "magnetometer, 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, you need to alternate between " "Off and Once. In FIFO mode, grate controls the data rate.", MagRate::M50Hz, MagRate_Values, ParamCateg)
Parameter.
A generic range class.
Definition Range.H:81
Main namespace for all JeVois classes and functions.
Definition Concepts.dox:2
DMP data (Digital Motion Processor)
Definition IMUdata.H:130
IMU data.
Definition IMUdata.H:68
Raw IMU data.
Definition IMUdata.H:37
A category to which multiple ParameterDef definitions can belong.