JeVois  1.21
JeVois Smart Embedded Machine Vision Toolkit
Share this page:
Loading...
Searching...
No Matches
IMUdata.C
Go to the documentation of this file.
1 // ///////////////////////////////////////////////////////////////////////////////////////////////////////////////////
2//
3// JeVois Smart Embedded Machine Vision Toolkit - Copyright (C) 2018 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#include <jevois/Debug/Log.H>
19#include <jevois/Core/IMUdata.H>
20#include <jevois/Util/Utils.H>
22
23// data packet size reg 1
24#define JEVOIS_DMP_HEADER_SZ 2
25#define JEVOIS_DMP_ACCEL_DATA_SZ 6
26#define JEVOIS_DMP_GYRO_DATA_SZ 6
27#define JEVOIS_DMP_CPASS_DATA_SZ 6
28#define JEVOIS_DMP_ALS_DATA_SZ 8
29#define JEVOIS_DMP_QUAT6_DATA_SZ 12
30#define JEVOIS_DMP_QUAT9_DATA_SZ 14
31#define JEVOIS_DMP_PQUAT6_DATA_SZ 6
32#define JEVOIS_DMP_GEOMAG_DATA_SZ 14
33#define JEVOIS_DMP_PRESSURE_DATA_SZ 6
34#define JEVOIS_DMP_GYRO_BIAS_DATA_SZ 6
35#define JEVOIS_DMP_CPASS_CALIBR_DATA_SZ 12
36#define JEVOIS_DMP_PED_STEPDET_TIMESTAMP_SZ 4
37#define JEVOIS_DMP_FOOTER_SZ 2
38
39// data packet size reg 2
40#define JEVOIS_DMP_HEADER2_SZ 2
41#define JEVOIS_DMP_ACCEL_ACCURACY_SZ 2
42#define JEVOIS_DMP_GYRO_ACCURACY_SZ 2
43#define JEVOIS_DMP_CPASS_ACCURACY_SZ 2
44#define JEVOIS_DMP_FSYNC_SZ 2
45#define JEVOIS_DMP_FLIP_PICKUP_SZ 2
46#define JEVOIS_DMP_ACT_RECOG_SZ 6
47
48// This is always present at end of packet?
49#define JEVOIS_DMP_ODR_CNT_GYRO_SZ 2
50
51// ####################################################################################################
52size_t jevois::DMPpacketSize(unsigned short ctl1, unsigned short ctl2)
53{
54 size_t ret = JEVOIS_DMP_HEADER_SZ;
55
59 if (ctl1 & JEVOIS_DMP_ALS) ret += JEVOIS_DMP_ALS_DATA_SZ;
69
73 if (ctl2 & JEVOIS_DMP_FSYNC) ret += JEVOIS_DMP_FSYNC_SZ;
75 if (ctl2 & JEVOIS_DMP_BATCH_MODE_EN) ret += JEVOIS_DMP_ODR_CNT_GYRO_SZ; // is this correct?
77
79
80 return ret;
81}
82
83// ####################################################################################################
84void jevois::DMPdata::parsePacket(unsigned char const * packet, size_t siz)
85{
86 // Parse the headers:
87 header1 = (packet[0] << 8) | packet[1];
88 size_t off = JEVOIS_DMP_HEADER_SZ; // offset to where we are in parsing the packet so far
89 header2 = 0;
90 if (header1 & JEVOIS_DMP_HEADER2) { header2 = (packet[off] << 8) | packet[off + 1]; off += JEVOIS_DMP_HEADER2_SZ; }
91
92 // Now decode the various data:
94 {
95 accel[0] = (packet[off + 0] << 8) | packet[off + 1];
96 accel[1] = (packet[off + 2] << 8) | packet[off + 3];
97 accel[2] = (packet[off + 4] << 8) | packet[off + 5];
99 }
100
102 {
103 gyro[0] = (packet[off + 0] << 8) | packet[off + 1];
104 gyro[1] = (packet[off + 2] << 8) | packet[off + 3];
105 gyro[2] = (packet[off + 4] << 8) | packet[off + 5];
107 gbias[0] = (packet[off + 0] << 8) | packet[off + 1];
108 gbias[1] = (packet[off + 2] << 8) | packet[off + 3];
109 gbias[2] = (packet[off + 4] << 8) | packet[off + 5];
111 }
112
114 {
115 cpass[0] = (packet[off + 0] << 8) | packet[off + 1];
116 cpass[1] = (packet[off + 2] << 8) | packet[off + 3];
117 cpass[2] = (packet[off + 4] << 8) | packet[off + 5];
119 }
120
122 {
123 // Not supported by InvenSense?
125 }
126
128 {
129 quat6[0] = (packet[off + 0] << 24) | (packet[off + 1] << 16) | (packet[off + 2] << 8) | packet[off + 3];
130 quat6[1] = (packet[off + 4] << 24) | (packet[off + 5] << 16) | (packet[off + 6] << 8) | packet[off + 7];
131 quat6[2] = (packet[off + 8] << 24) | (packet[off + 9] << 16) | (packet[off + 10] << 8) | packet[off + 11];
133 }
134
136 {
137 quat9[0] = (packet[off + 0] << 24) | (packet[off + 1] << 16) | (packet[off + 2] << 8) | packet[off + 3];
138 quat9[1] = (packet[off + 4] << 24) | (packet[off + 5] << 16) | (packet[off + 6] << 8) | packet[off + 7];
139 quat9[2] = (packet[off + 8] << 24) | (packet[off + 9] << 16) | (packet[off + 10] << 8) | packet[off + 11];
140 quat9acc = (packet[off + 12] << 24) | (packet[off + 13] << 16);
142 }
143
145 {
146 stepts = (packet[off + 0] << 24) | (packet[off + 1] << 16) | (packet[off + 2] << 8) | packet[off + 3];
148 if (steps == 0) steps = 1; // FIXME: docs say we should get the number of steps, but it is always 0...
150 }
151
153 {
154 geomag[0] = (packet[off + 0] << 24) | (packet[off + 1] << 16) | (packet[off + 2] << 8) | packet[off + 3];
155 geomag[1] = (packet[off + 4] << 24) | (packet[off + 5] << 16) | (packet[off + 6] << 8) | packet[off + 7];
156 geomag[2] = (packet[off + 8] << 24) | (packet[off + 9] << 16) | (packet[off + 10] << 8) | packet[off + 11];
157 geomagacc = (packet[off + 12] << 24) | (packet[off + 13] << 16);
159 }
160
162 {
163 // Not supported by InvenSense?
165 }
166
168 {
169 gyrobias[0] = (packet[off + 0] << 8) | packet[off + 1];
170 gyrobias[1] = (packet[off + 2] << 8) | packet[off + 3];
171 gyrobias[2] = (packet[off + 4] << 8) | packet[off + 5];
173 }
174
176 {
177 cpasscal[0] = (packet[off + 0] << 24) | (packet[off + 1] << 16) | (packet[off + 2] << 8) | packet[off + 3];
178 cpasscal[1] = (packet[off + 4] << 24) | (packet[off + 5] << 16) | (packet[off + 6] << 8) | packet[off + 7];
179 cpasscal[2] = (packet[off + 8] << 24) | (packet[off + 9] << 16) | (packet[off + 10] << 8) | packet[off + 11];
181 }
182
184 {
185 accelacc = (packet[off + 0] << 8) | packet[off + 1];
187 }
188
190 {
191 gyroacc = (packet[off + 0] << 8) | packet[off + 1];
193 }
194
196 {
197 cpassacc = (packet[off + 0] << 8) | packet[off + 1];
199 }
200
202 {
203 fsync = (packet[off + 0] << 8) | packet[off + 1];
204 off += JEVOIS_DMP_FSYNC_SZ;
205 }
206
208 {
209 pickup = (packet[off + 0] << 8) | packet[off + 1];
211 }
212
214 {
215 bacstate = (packet[off + 0] << 8) | packet[off + 1];
216 bacts = (packet[off + 2] << 24) | (packet[off + 3] << 16) | (packet[off + 4] << 8) | packet[off + 5];
218 }
219
220 odrcnt = (packet[off + 0] << 8) | packet[off + 1];
222
223 if (off != siz) LERROR("Decoded " << off << " bytes from " << siz << " bytes of IMU packet");
224}
225
226// ####################################################################################################
228{
229 return float(fsync) * 0.9645F;
230}
231
232// ####################################################################################################
233std::vector<std::string> jevois::DMPdata::activity()
234{
235 std::vector<std::string> ret;
236
237 // The activity classifier reports start/stop of activities:
238 // bacstate is a set of 2 bytes:
239 // - high byte indicates activity start
240 // - low byte indicates activity end
241 unsigned char bs[2]; bs[0] = bacstate >> 8; bs[1] = bacstate & 0xff;
242 unsigned short const mask = DMP_BAC_DRIVE | DMP_BAC_WALK | DMP_BAC_RUN | DMP_BAC_BIKE | DMP_BAC_TILT | DMP_BAC_STILL;
243 for (int i = 0; i < 2; ++i)
244 {
245 std::string const ss = (i == 0) ? "start " : "stop ";
246 if (bs[i] & DMP_BAC_DRIVE) ret.push_back(ss + "drive");
247 if (bs[i] & DMP_BAC_WALK) ret.push_back(ss + "walk");
248 if (bs[i] & DMP_BAC_RUN) ret.push_back(ss + "run");
249 if (bs[i] & DMP_BAC_BIKE) ret.push_back(ss + "bike");
250 if (bs[i] & DMP_BAC_TILT) ret.push_back(ss + "tilt");
251 if (bs[i] & DMP_BAC_STILL) ret.push_back(ss + "still");
252 if (bs[i] & ~mask) ret.push_back(ss + jevois::sformat("Unk(0x%02x)", bs[i] & ~mask));
253 }
254
255 return ret;
256}
257
258// ####################################################################################################
259std::vector<std::string> jevois::DMPdata::activity2()
260{
261 std::vector<std::string> ret;
262 static unsigned char act = 0; // Activities that currently are ongoing
263
264 // The activity classifier reports start/stop of activities:
265 // - high byte indicates activity start
266 // - low byte indicates activity end
267 unsigned char bs[2]; bs[0] = bacstate >> 8; bs[1] = bacstate & 0xff;
268
269 act |= bs[0]; // Activities that started are turned on
270 act &= ~bs[1]; // Activities that stopped are turned off
271
272 if (act & DMP_BAC_DRIVE) ret.push_back("drive");
273 if (act & DMP_BAC_WALK) ret.push_back("walk");
274 if (act & DMP_BAC_RUN) ret.push_back("run");
275 if (act & DMP_BAC_BIKE) ret.push_back("bike");
276 if (act & DMP_BAC_TILT) ret.push_back("tilt");
277 if (act & DMP_BAC_STILL) ret.push_back("still");
278
279 return ret;
280}
281
282// ####################################################################################################
284{ return float(val * 1.0 / (1<<30)); }
285
286// ####################################################################################################
287jevois::IMUdata::IMUdata(jevois::IMUrawData const & rd, double arange, double grange)
288{
289 double const ar = arange / 32768.0;
290 ax() = rd.ax() * ar;
291 ay() = rd.ay() * ar;
292 az() = rd.az() * ar;
293
294 double const gr = grange / 32768.0;
295 gx() = rd.gx() * gr;
296 gy() = rd.gy() * gr;
297 gz() = rd.gz() * gr;
298
299 temp() = rd.temp() / 333.87F + 21.0F;
300
301 double const mr = 4912.0 / 32752.0; // full range is +/-4912uT for raw values +/-32752
302 mx() = rd.mx() * mr;
303 my() = rd.my() * mr;
304 mz() = rd.mz() * mr;
305
306 magovf = ((rd.mst2() & BIT_AK09916_STATUS2_HOFL) != 0);
307}
308
#define DMP_BAC_TILT
#define DMP_BAC_STILL
#define DMP_BAC_BIKE
#define DMP_BAC_WALK
#define DMP_BAC_DRIVE
#define DMP_BAC_RUN
#define JEVOIS_DMP_ALS_DATA_SZ
Definition IMUdata.C:28
#define JEVOIS_DMP_GYRO_ACCURACY_SZ
Definition IMUdata.C:42
#define JEVOIS_DMP_CPASS_CALIBR_DATA_SZ
Definition IMUdata.C:35
#define JEVOIS_DMP_HEADER2_SZ
Definition IMUdata.C:40
#define JEVOIS_DMP_ODR_CNT_GYRO_SZ
Definition IMUdata.C:49
#define JEVOIS_DMP_GYRO_DATA_SZ
Definition IMUdata.C:26
#define JEVOIS_DMP_PED_STEPDET_TIMESTAMP_SZ
Definition IMUdata.C:36
#define JEVOIS_DMP_HEADER_SZ
Definition IMUdata.C:24
#define JEVOIS_DMP_ACT_RECOG_SZ
Definition IMUdata.C:46
#define JEVOIS_DMP_ACCEL_ACCURACY_SZ
Definition IMUdata.C:41
#define JEVOIS_DMP_PRESSURE_DATA_SZ
Definition IMUdata.C:33
#define JEVOIS_DMP_FSYNC_SZ
Definition IMUdata.C:44
#define JEVOIS_DMP_FLIP_PICKUP_SZ
Definition IMUdata.C:45
#define JEVOIS_DMP_CPASS_ACCURACY_SZ
Definition IMUdata.C:43
#define JEVOIS_DMP_QUAT6_DATA_SZ
Definition IMUdata.C:29
#define JEVOIS_DMP_GEOMAG_DATA_SZ
Definition IMUdata.C:32
#define JEVOIS_DMP_PQUAT6_DATA_SZ
Definition IMUdata.C:31
#define JEVOIS_DMP_CPASS_DATA_SZ
Definition IMUdata.C:27
#define JEVOIS_DMP_FOOTER_SZ
Definition IMUdata.C:37
#define JEVOIS_DMP_ACCEL_DATA_SZ
Definition IMUdata.C:25
#define JEVOIS_DMP_GYRO_BIAS_DATA_SZ
Definition IMUdata.C:34
#define JEVOIS_DMP_QUAT9_DATA_SZ
Definition IMUdata.C:30
#define LERROR(msg)
Convenience macro for users to print out console or syslog messages, ERROR level.
Definition Log.H:211
#define JEVOIS_DMP_GYRO_CALIBR
Definition IMUdata.H:109
#define JEVOIS_DMP_HEADER2
Definition IMUdata.H:112
#define JEVOIS_DMP_ACT_RECOG
Definition IMUdata.H:121
#define JEVOIS_DMP_BATCH_MODE_EN
Definition IMUdata.H:120
#define JEVOIS_DMP_ACCEL
Definition IMUdata.H:100
#define JEVOIS_DMP_ALS
Definition IMUdata.H:103
#define JEVOIS_DMP_QUAT6
Definition IMUdata.H:104
#define JEVOIS_DMP_GEOMAG
Definition IMUdata.H:107
#define JEVOIS_DMP_PED_STEPDET
Definition IMUdata.H:111
#define JEVOIS_DMP_GYRO
Definition IMUdata.H:101
#define JEVOIS_DMP_GYRO_ACCURACY
Definition IMUdata.H:116
#define JEVOIS_DMP_CPASS_ACCURACY
Definition IMUdata.H:117
#define JEVOIS_DMP_CPASS_CALIBR
Definition IMUdata.H:110
#define JEVOIS_DMP_ACCEL_ACCURACY
Definition IMUdata.H:115
#define JEVOIS_DMP_PRESSURE
Definition IMUdata.H:108
#define JEVOIS_DMP_CPASS
Definition IMUdata.H:102
#define JEVOIS_DMP_FLIP_PICKUP
Definition IMUdata.H:119
#define JEVOIS_DMP_PED_STEPIND
Definition IMUdata.H:113
#define JEVOIS_DMP_QUAT9
Definition IMUdata.H:105
#define JEVOIS_DMP_PQUAT6
Definition IMUdata.H:106
#define JEVOIS_DMP_FSYNC
Definition IMUdata.H:118
size_t DMPpacketSize(unsigned short ctl1, unsigned short ctl2)
Helper function to determine DMP packet size depending on options.
Definition IMUdata.C:52
std::string sformat(char const *fmt,...) __attribute__((format(__printf__
Create a string using printf style arguments.
Definition Utils.C:439
short cpassacc
Compass accuracy data (when JEVOIS_DMP_CPASS_ACCURACY in header2)
Definition IMUdata.H:157
unsigned short bacstate
Activity recognition state (when JEVOIS_DMP_ACT_RECOG in header2)
Definition IMUdata.H:164
short gyroacc
Gyro accuracy data (when JEVOIS_DMP_GYRO_ACCURACY in header2)
Definition IMUdata.H:156
unsigned short steps
Number of steps (0..7) detected this cycle (when JEVOIS_DMP_PED_STEPDET)
Definition IMUdata.H:147
long quat9acc
Quaternion9 accuracy (when JEVOIS_DMP_QUAT9 in header1)
Definition IMUdata.H:144
long cpasscal[3]
Compass calibration data (when JEVOIS_DMP_CPASS_CALIBR in header1)
Definition IMUdata.H:153
short gyro[3]
Raw gyro data (when JEVOIS_DMP_GYRO in header1)
Definition IMUdata.H:138
short gyrobias[3]
Gyro bias/calibration data (when JEVOIS_DMP_GYRO_CALIBR in header1)
Definition IMUdata.H:152
std::vector< std::string > activity2()
Definition IMUdata.C:259
unsigned short fsync
Delay between FSYNC received from camera and first subsequent IMU data generated.
Definition IMUdata.H:159
short accel[3]
Raw accelerometer data (when JEVOIS_DMP_ACCEL in header1)
Definition IMUdata.H:137
unsigned short header1
Header 1 fields that indicate what data is valid.
Definition IMUdata.H:134
short accelacc
Accelerometer accuracy data (when JEVOIS_DMP_ACCEL_ACCURACY in header2)
Definition IMUdata.H:155
void parsePacket(unsigned char const *packet, size_t siz)
Populate our fields from a packet received from the DMP.
Definition IMUdata.C:84
short cpass[3]
Raw compass data (when JEVOIS_DMP_CPASS in header1)
Definition IMUdata.H:139
std::vector< std::string > activity()
Decode current ongoing activities into a string.
Definition IMUdata.C:233
unsigned short header2
Header 2 fields that indicate what data is valid.
Definition IMUdata.H:135
unsigned long stepts
Step detection timestamp (when JEVOIS_DMP_PED_STEPDET)
Definition IMUdata.H:146
long quat9[3]
Quaternion9 data (when JEVOIS_DMP_QUAT9 in header1)
Definition IMUdata.H:143
long geomagacc
Geomag accuracy (when JEVOIS_DMP_GEOMAG in header1)
Definition IMUdata.H:150
long quat6[3]
Quaternion6 data (when JEVOIS_DMP_QUAT6 in header1)
Definition IMUdata.H:142
float fsync_us() const
Delay between FSYNC and next IMU data, in microseconds.
Definition IMUdata.C:227
short pickup
Flip/pickup detection (when JEVOIS_DMP_FLIP_PICKUP in header2)
Definition IMUdata.H:162
unsigned short odrcnt
Output data rate counter (always here but unclear what it is)
Definition IMUdata.H:167
long geomag[3]
Geomag data (when JEVOIS_DMP_GEOMAG in header1)
Definition IMUdata.H:149
long bacts
Activity recognition timestamp (when JEVOIS_DMP_ACT_RECOG in header2)
Definition IMUdata.H:165
static float fix2float(long val)
Convert a long fixed-point value to float.
Definition IMUdata.C:283
short gbias[3]
Raw gyro bias data (when JEVOIS_DMP_GYRO in header1)
Definition IMUdata.H:140
IMUdata(IMUrawData const &rd, double arange, double grange)
Construct from a raw data reading.
Definition IMUdata.C:287
Raw IMU data.
Definition IMUdata.H:37
short & gy()
Definition IMUdata.H:48
short & az()
Definition IMUdata.H:44
short & mst2()
Definition IMUdata.H:60
short & mz()
Definition IMUdata.H:58
short & gx()
Definition IMUdata.H:46
short & my()
Definition IMUdata.H:56
short & temp()
Definition IMUdata.H:52
short & ay()
Definition IMUdata.H:42
short & gz()
Definition IMUdata.H:50
short & ax()
Definition IMUdata.H:40
short & mx()
Definition IMUdata.H:54