JeVoisBase  1.18
JeVois Smart Embedded Machine Vision Toolkit Base Modules
Share this page:
DemoDMP.C
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 #include <jevois/Core/Module.H>
19 #include <jevois/Core/ICM20948.H>
20 
22 #include <linux/videodev2.h>
23 #include <list>
24 
25 #include <Eigen/Geometry>
26 #include <opencv2/calib3d/calib3d.hpp>
27 #include <opencv2/core/eigen.hpp>
28 
29 // icon by icons8
30 
31 //! Plot results of processing IMU data with the on-chip Digital Motion Processor (DMP)
32 /*! As an optional hardware upgrade, one can install a global shutter sensor into JeVois (an OnSemi AR0135 1.2MP), which
33  also includes on its custom circuit board for JeVois an inertial measurement unit (IMU). The IMU is a
34  9-degrees-of-freedom (9DOF) TDK InvenSense ICM-20948 (with 3-axis accelerometer, 3-axis gyroscope, and 3-axis
35  magnetometer). This IMU also includes a digital motion processing unit (small programmable processor inside the IMU
36  chip), which allows it to compute and filter quaternions directly inside the IMU chip.
37 
38  This module only works with optional JeVois sensors that include an IMU! The base JeVois-A33 smart camera does not
39  have an onboard IMU.
40 
41  \youtube{MFGpN_Vp7mg}
42 
43  This module demonstrates the digital motion processing (DMP) mode of the IMU.
44 
45  The specifications of this chip are quite impressive:
46  - 3-axis 16-bit accelerometer with full-range sensitivity selectable to +/-2g, +/-4g, +/-8g, and +/-16g.
47  - Accelerometer data rate from 4 Hz to 1125 Hz.
48  - 3-axis 16-bit gyroscope with full-range sensitivity selectable to +/-250dps (degrees/s), +/-500dps,
49  +/-1000dps, and +/-2000dps.
50  - Gyroscope data rate from 4 Hz to 1125 Hz.
51  - 3-axis 16-bit magnetometer (compass) with wide range of +/-4900uT (micro Tesla).
52  - Magnetometer data rates 10 Hz, 20 Hz, 50 Hz, or 100 Hz.
53  - 16-bit temperature sensor with readout rate of up to 8 kHz.
54  - RAW data mode (get current sensor values at any time), buffered (FIFO) data mode (sensor values accumulate into
55  a FIFO at a fixed rate), and digital motion processing mode (DMP; raw data is processed on-chip).
56  - On-chip digital motion processor (DMP) can compute, inside the IMU chip itself:
57  + quaternion 6 (uses accel + gyro),
58  + quaternion 9 (uses accel + gyro + compass),
59  + geomag quaternion (uses accel + compass),
60  + flip/pickup detection,
61  + step detection and counting,
62  + basic activity recognition: drive, walk, run, bike, tilt, still.
63 
64  With quaternions computed on-chip, with an algorithm that gets sensor data at a highly accurate, fixed rate, and
65  applies various calibrations, drift corrections, and compensations on the fly, one gets highly accurate real-time
66  estimate of the sensor's pose in the 3D world and of how it is moving.
67 
68  Note that communication with the IMU is over a 400kHz I2C bus, which may limit data readout rate depending on
69  which data is requested from the IMU.
70 
71  This IMU has 3 basic modes of operation (parameter mode, which can only be set in params.cfg):
72 
73  - RAW: One can access the latest raw sensor data at any time using the getRaw() or get() functions. This is the
74  simplest mode of operation. One disadvantage is that if you are not calling get() at a perfectly regular
75  interval, there will be some time jitter in your readouts. The IMU does not provide any time stamps for its
76  data.
77 
78  - FIFO: In this mode, data from the sensor is piled up into a 1 kbyte FIFO buffer at a precise, constant rate
79  (when all three of accelerometer, gyroscope, and magnetometer are on, the gyro rate determines the FIFO
80  buffering rate). Main advantage is that you can then read out the data without having to worry about calling
81  getRaw() or get() at a highly precise interval. But you need to be careful that the FIFO can fill up and
82  overflow very quickly when using high sensor data rates.
83 
84  - DMP: In this mode, data is captured from the sensor at an accurate, fixed rate, and is fed to the on-chip
85  digital motion processor (DMP). The DMP then computes quaternions, activity recognition, etc and pushes data
86  packets into the FIFO as results from these algorithms become available.
87 
88  Low-level tweaking of the IMU and DMP
89  -------------------------------------
90 
91  The ICM-20948 IMU chip is a very sophisticated and complex computer on its own right. There are many settings and
92  modes that are supported. Unfortunately, the full documentation is not open. But you can obtain it after
93  registration with TDK InvenSense. We provide the following user-level functions in the command-line interface of
94  JeVois to allow you to get/set raw registers of the IMU and DMP:
95 
96  - setimureg <reg> <val> - set raw IMU register <reg> to value <val>
97  - getimureg <reg> - get value of raw IMU register <reg>
98  - setimuregs <reg> <num> <val1> ... <valn> - set array of raw IMU register values
99  - getimuregs <reg> <num> - get array of raw IMU register values
100  - setdmpreg <reg> <val> - set raw DMP register <reg> to value <val>
101  - getdmpreg <reg> - get value of raw DMP register <reg>
102  - setdmpregs <reg> <num> <val1> ... <valn> - set array of raw DMP register values
103  - getdmpregs <reg> <num> - get array of raw DMP register values
104 
105  The registers and values can be specified in decimal, hex (with prefix 0x), or octal (with prefix 0 - beware of this
106  and be careful). The values returned are always in hex (with no prefix). Note that the above functions are not
107  activated by default, to prevent mistakes by rookie users. To activate them, issue a `setpar camreg 1` on the JeVois
108  console.
109 
110  For example, to set the output data rate (ODR) of the DMP quaternion-9; this is in DMP register DMP_ODR_QUAT9 = 168
111  (see definitions in file ICM20948_regs.H of the JeVois core software):
112 
113  \verbatim
114  setpar camreg 1
115  getdmpreg 168 # shows default divider value of 5; ODR is DMP engine rate / (1 + divider)
116  setdmpreg 168 2
117  \endverbatim
118 
119  To see the effect, you should first turn on FSYNC as one of the DMP outputs (e.g., set `dmp` parameter to QF). Then
120  turn on parameter `pktdbg` and turn on log messages to USB see how many quaternion packets (long packets that start
121  with 4 0) you get between two FSYNC packets (short packets that start with 0 8 8 0). By default it is about 2 (with
122  camera sensor at 25fps and DMP engine running at 56Hz). Then increase the `arate` and `grate` to 112 Hz. You should
123  still get about 2 quaternion packets between two FSYNC packets. Finally, apply the above DMP register change. You
124  should now see 4 quaternion packets between two FSYNC packets. Note that sometimes quaternion and FSYNC packets get
125  combined.
126 
127  As you experiment, keep in mind that the IMU can easily saturate the 400 kHz bandwidth of the i2c bus that connects
128  it to the JeVois main processor. If you start getting errors in the console from IMUdata::parsePacket() then likely
129  your data rate is too high for the i2c bus. One of the nice things about the DMP is that you can still run the
130  quaternion computation very fast (e.g., at 450 Hz or even 1125 Hz) while maintaining a low output data rate.
131 
132  @author Laurent Itti
133 
134  @videomapping YUYV 640 520 25.0 YUYV 640 480 25.0 JeVois DemoDMP
135  @email itti\@usc.edu
136  @address University of Southern California, HNB-07A, 3641 Watt Way, Los Angeles, CA 90089-2520, USA
137  @copyright Copyright (C) 2018 by Laurent Itti, iLab and the University of Southern California
138  @mainurl http://jevois.org
139  @supporturl http://jevois.org/doc
140  @otherurl http://iLab.usc.edu
141  @license GPL v3
142  @distribution Unrestricted
143  @restrictions None
144  \ingroup modules */
145 class DemoDMP : public jevois::Module
146 {
147  public:
148  //! Constructor
149  DemoDMP(std::string const & instance) : jevois::Module(instance)
150  { itsIMU = addSubComponent<jevois::ICM20948>("imu"); }
151 
152  //! Virtual destructor for safe inheritance
153  virtual ~DemoDMP() { }
154 
155  //! Processing function
156  virtual void process(jevois::InputFrame && inframe, jevois::OutputFrame && outframe) override
157  {
158  // Wait for next available camera image:
159  jevois::RawImage const inimg = inframe.get(true);
160  int const w = inimg.width, h = inimg.height;
161 
162  // Wait for an image from our gadget driver into which we will put our results:
163  jevois::RawImage outimg = outframe.get();
164 
165  // Load camera calibration params if needed (for 3D cube displays):
166  static cv::Mat itsCamMatrix = cv::Mat();
167  static cv::Mat itsDistCoeffs = cv::Mat();
168  if (itsCamMatrix.empty())
169  {
170  std::string const cpf = std::string(JEVOIS_SHARE_PATH) + "/camera/calibration" +
171  std::to_string(w) + 'x' + std::to_string(h) + ".yaml";
172 
173  cv::FileStorage fs(cpf, cv::FileStorage::READ);
174  if (fs.isOpened())
175  {
176  fs["camera_matrix"] >> itsCamMatrix;
177  fs["distortion_coefficients"] >> itsDistCoeffs;
178  LINFO("Loaded camera calibration from " << cpf);
179  }
180  else LERROR("Failed to read camera parameters from file [" << cpf << "] -- IGNORED");
181  }
182 
183  // Enforce that the input and output formats and image sizes match:
184  outimg.require("output", w, h + 40, inimg.fmt);
185 
186  // Just copy the pixel data over:
187  memcpy(outimg.pixelsw<void>(), inimg.pixels<void>(), std::min(inimg.buf->length(), outimg.buf->length()));
188  jevois::rawimage::drawFilledRect(outimg, 0, h, w, outimg.height-h, jevois::yuyv::Black);
189 
190  // Let camera know we are done processing the input image:
191  inframe.done();
192 
193  // Note: we get different packets for steps, activity, and for quaternions. So let's cache the data:
194  static long step_ts = 0;
195  static long steps = 0;
196  static std::vector<std::string> bac;
197  static cv::Vec3d rvec(0.0, 0.0, 0.0); // Euler angles computed from quaternion
198  static cv::Vec3d tvec(0.0, 0.0, 0.5); // Place cube 0.5 meters in front of the camera
199  float const hsz = 0.075F; // half size of cube, in meters
200  static int pickup = 0; // Number of frames remaining to show pickup message
201  long quat[3] = { 0, 0, 0 }; // Our latest quaternion
202  std::string qtype;
204  bool has_accel = false, has_gyro = false, has_cpass = false;
205  float fsync = -1.0F;
206 
207  // Get as many IMU readings as we can so we keep the FIFO empty:
208  jevois::DMPdata d; int npkt = 0;
209  while (itsIMU->dataReady())
210  {
211  d = itsIMU->getDMP(); ++npkt;
212 
213  // ---------- Quaternions using 9 DOF:
214  if (d.header1 & JEVOIS_DMP_QUAT9)
215  {
216  quat[0] = d.quat9[0]; quat[1] = d.quat9[1]; quat[2] = d.quat9[2];
217  qtype = "Quat-9";
218  }
219 
220  // ---------- Quaternions using 6 DOF:
221  if (d.header1 & JEVOIS_DMP_QUAT6)
222  {
223  quat[0] = d.quat6[0]; quat[1] = d.quat6[1]; quat[2] = d.quat6[2];
224  qtype = "Quat-6";
225  }
226 
227  // ---------- Quaternions using GeoMag:
228  if (d.header1 & JEVOIS_DMP_GEOMAG)
229  {
230  quat[0] = d.geomag[0]; quat[1] = d.geomag[1]; quat[2] = d.geomag[2];
231  qtype = "GeoMag";
232  }
233 
234  // ---------- Step detection:
235  if (d.header1 & JEVOIS_DMP_PED_STEPDET) { step_ts = d.stepts; steps += d.steps; }
236 
237  // ---------- Activity recognition:
238  if (d.header2 & JEVOIS_DMP_ACT_RECOG) bac = d.activity2();
239 
240  // ---------- Pickup/flip detection:
241  if (d.header2 & JEVOIS_DMP_FLIP_PICKUP) pickup = 20;
242 
243  // ---------- FSYNC detection:
244  if (d.header2 & JEVOIS_DMP_FSYNC) fsync = d.fsync_us();
245 
246  // ---------- Raw accel, gyro, mag:
247  if (d.header1 & JEVOIS_DMP_ACCEL)
248  { has_accel = true; rd.ax() = d.accel[0]; rd.ay() = d.accel[1]; rd.az() = d.accel[2]; }
249 
250  if (d.header1 & JEVOIS_DMP_GYRO)
251  { has_gyro = true; rd.gx() = d.gyro[0]; rd.gy() = d.gyro[1]; rd.gz() = d.gyro[2]; }
252 
253  if (d.header1 & JEVOIS_DMP_CPASS)
254  { has_cpass = true; rd.mx() = d.cpass[0]; rd.my() = d.cpass[1]; rd.mz() = d.cpass[2]; }
255  }
256 
257  // ---------- Display a cube rotated by our latest quaternion:
258  if (qtype.empty() == false)
259  {
260  Eigen::Quaterniond q(0.0, d.fix2float(quat[0]), d.fix2float(quat[1]), d.fix2float(quat[2]));
261 
262  // Compute the scalar part, which is not returned by the IMU, to get a normalized quaternion:
263  q.w() = std::sqrt(1.0 - q.squaredNorm());
264 
265  // Display it:
266  jevois::rawimage::writeText(outimg, qtype +
267  jevois::sformat(": x=%+09.6f y=%+09.6f z=%+09.6f", q.x(), q.y(), q.z()),
268  3, h + 3, jevois::yuyv::White);
269 
270  // Compute OpenCV rvec for use with projectPoints() below:
271  // You could also compute Euler angles: Eigen::Vector3f eig_rvec = q.toRotationMatrix().eulerAngles(0, 1, 2);
272  Eigen::Matrix3d eig_rmat = q.toRotationMatrix();
273  cv::Mat rmat(3, 3, CV_64FC1); cv::eigen2cv(eig_rmat, rmat);
274  cv::Rodrigues(rmat, rvec);
275 
276  // Project axis points:
277  std::vector<cv::Point3f> axisPoints;
278  axisPoints.push_back(cv::Point3f(0.0F, 0.0F, 0.0F));
279  axisPoints.push_back(cv::Point3f(hsz * 1.5F, 0.0F, 0.0F));
280  axisPoints.push_back(cv::Point3f(0.0F, hsz * 1.5F, 0.0F));
281  axisPoints.push_back(cv::Point3f(0.0F, 0.0F, hsz * 1.5F));
282  axisPoints.push_back(cv::Point3f(hsz * 1.55F, 0.0F, 0.0F));
283  axisPoints.push_back(cv::Point3f(0.0F, hsz * 1.55F, 0.0F));
284  axisPoints.push_back(cv::Point3f(0.0F, 0.0F, hsz * 1.55F));
285 
286  std::vector<cv::Point2f> imagePoints;
287  cv::projectPoints(axisPoints, rvec, tvec, itsCamMatrix, itsDistCoeffs, imagePoints);
288 
289  // Draw axis lines
290  jevois::rawimage::drawLine(outimg, int(imagePoints[0].x + 0.5F), int(imagePoints[0].y + 0.5F),
291  int(imagePoints[1].x + 0.5F), int(imagePoints[1].y + 0.5F),
292  2, jevois::yuyv::MedPurple);
293  jevois::rawimage::writeText(outimg, "X", int(imagePoints[4].x - 4.0F), int(imagePoints[4].y - 9.5F),
294  jevois::yuyv::White, jevois::rawimage::Font10x20);
295 
296  jevois::rawimage::drawLine(outimg, int(imagePoints[0].x + 0.5F), int(imagePoints[0].y + 0.5F),
297  int(imagePoints[2].x + 0.5F), int(imagePoints[2].y + 0.5F),
298  2, jevois::yuyv::MedGreen);
299  jevois::rawimage::writeText(outimg, "Y", int(imagePoints[5].x - 4.0F), int(imagePoints[5].y - 9.5F),
300  jevois::yuyv::White, jevois::rawimage::Font10x20);
301 
302  jevois::rawimage::drawLine(outimg, int(imagePoints[0].x + 0.5F), int(imagePoints[0].y + 0.5F),
303  int(imagePoints[3].x + 0.5F), int(imagePoints[3].y + 0.5F),
304  2, jevois::yuyv::MedGrey);
305  jevois::rawimage::writeText(outimg, "Z", int(imagePoints[6].x - 4.0F), int(imagePoints[6].y - 9.5F),
306  jevois::yuyv::White, jevois::rawimage::Font10x20);
307 
308  // Also draw a cube:
309  std::vector<cv::Point3f> cubePoints;
310  cubePoints.push_back(cv::Point3f(-hsz, -hsz, -hsz));
311  cubePoints.push_back(cv::Point3f(hsz, -hsz, -hsz));
312  cubePoints.push_back(cv::Point3f(hsz, hsz, -hsz));
313  cubePoints.push_back(cv::Point3f(-hsz, hsz, -hsz));
314  cubePoints.push_back(cv::Point3f(-hsz, -hsz, hsz));
315  cubePoints.push_back(cv::Point3f(hsz, -hsz, hsz));
316  cubePoints.push_back(cv::Point3f(hsz, hsz, hsz));
317  cubePoints.push_back(cv::Point3f(-hsz, hsz, hsz));
318 
319  std::vector<cv::Point2f> cuf;
320  cv::projectPoints(cubePoints, rvec, tvec, itsCamMatrix, itsDistCoeffs, cuf);
321 
322  // Round all the coordinates:
323  std::vector<cv::Point> cu;
324  for (auto const & p : cuf) cu.push_back(cv::Point(int(p.x + 0.5F), int(p.y + 0.5F)));
325 
326  // Draw cube lines:
327  jevois::rawimage::drawLine(outimg, cu[0].x, cu[0].y, cu[1].x, cu[1].y, 2, jevois::yuyv::LightGreen);
328  jevois::rawimage::drawLine(outimg, cu[1].x, cu[1].y, cu[2].x, cu[2].y, 2, jevois::yuyv::LightGreen);
329  jevois::rawimage::drawLine(outimg, cu[2].x, cu[2].y, cu[3].x, cu[3].y, 2, jevois::yuyv::LightGreen);
330  jevois::rawimage::drawLine(outimg, cu[3].x, cu[3].y, cu[0].x, cu[0].y, 2, jevois::yuyv::LightGreen);
331  jevois::rawimage::drawLine(outimg, cu[4].x, cu[4].y, cu[5].x, cu[5].y, 2, jevois::yuyv::LightGreen);
332  jevois::rawimage::drawLine(outimg, cu[5].x, cu[5].y, cu[6].x, cu[6].y, 2, jevois::yuyv::LightGreen);
333  jevois::rawimage::drawLine(outimg, cu[6].x, cu[6].y, cu[7].x, cu[7].y, 2, jevois::yuyv::LightGreen);
334  jevois::rawimage::drawLine(outimg, cu[7].x, cu[7].y, cu[4].x, cu[4].y, 2, jevois::yuyv::LightGreen);
335  jevois::rawimage::drawLine(outimg, cu[0].x, cu[0].y, cu[4].x, cu[4].y, 2, jevois::yuyv::LightGreen);
336  jevois::rawimage::drawLine(outimg, cu[1].x, cu[1].y, cu[5].x, cu[5].y, 2, jevois::yuyv::LightGreen);
337  jevois::rawimage::drawLine(outimg, cu[2].x, cu[2].y, cu[6].x, cu[6].y, 2, jevois::yuyv::LightGreen);
338  jevois::rawimage::drawLine(outimg, cu[3].x, cu[3].y, cu[7].x, cu[7].y, 2, jevois::yuyv::LightGreen);
339  }
340 
341  // ---------- Step detection:
342  jevois::rawimage::writeText(outimg, jevois::sformat("Steps: %6u (last at %010u)", steps, step_ts),
343  3, h + 15, jevois::yuyv::White);
344 
345  // ---------- FSYNC detection:
346  if (fsync >= 0.0F) jevois::rawimage::writeText(outimg, jevois::sformat("FSYNC: %4d", int(fsync + 0.499F)),
347  w - 11*6, h + 15, jevois::yuyv::White);
348 
349  // ---------- Activity recognition:
350  if (bac.size()) jevois::rawimage::writeText(outimg, jevois::join(bac, ", "), 290, h + 15, jevois::yuyv::White);
351 
352  // ---------- Pickup/flip detection:
353  if (pickup) jevois::rawimage::writeText(outimg, "pickup/flip", 214, h + 15, jevois::yuyv::White);
354 
355  // ---------- Show raw accel/gyro/compass:
356  if (has_accel || has_gyro || has_cpass)
357  {
358  // Convert from raw data to scaled data:
359  jevois::IMUdata dd(rd, itsIMU->arange::get(), itsIMU->grange::get());
360 
361  // Display the ones that are on:
362  if (has_accel)
364  jevois::sformat("Acc: x=%+06.2fg y=%+06.2fg z=%+06.2fg",
365  dd.ax(), dd.ay(), dd.az()),
366  333, h + 3, jevois::yuyv::White);
367  if (has_gyro)
369  jevois::sformat("Gyr: x=%+07.1fdps y=%+07.1fdps z=%+07.1fdps",
370  dd.gx(), dd.gy(), dd.gz()),
371  3, h + 27, jevois::yuyv::White);
372  if (has_cpass)
374  jevois::sformat("Mag: %+09.2fuT %+09.2fuT %+09.2fuT",
375  dd.mx(), dd.my(), dd.mz()),
376  333, h + 27, jevois::yuyv::White);
377  }
378 
379  // ---------- Show number of IMU packets processed:
380  jevois::rawimage::writeText(outimg, jevois::sformat("%03d pkts", npkt), 592, h + 3, jevois::yuyv::White);
381 
382  // Decay counters for some ephemerous messages:
383  if (pickup > 0) --pickup;
384 
385  // Send the output image with our processing results to the host over USB:
386  outframe.send();
387  }
388 
389  private:
390  std::shared_ptr<jevois::ICM20948> itsIMU;
391 };
392 
393 // Allow the module to be loaded as a shared object (.so) file:
jevois::RawImage::pixels
const T * pixels() const
jevois::OutputFrame
jevois::DMPdata::header2
unsigned short header2
quantize-inc.q
q
Definition: quantize-inc.py:95
jevois::DMPdata::activity2
std::vector< std::string > activity2()
Module.H
jevois::sformat
std::string sformat(char const *fmt,...) __attribute__((format(__printf__
JEVOIS_DMP_QUAT6
#define JEVOIS_DMP_QUAT6
jevois::IMUdata::gy
float & gy()
DemoDMP::DemoDMP
DemoDMP(std::string const &instance)
Constructor.
Definition: DemoDMP.C:149
jevois::DMPdata::gyro
short gyro[3]
jevois::DMPdata::header1
unsigned short header1
JEVOIS_DMP_QUAT9
#define JEVOIS_DMP_QUAT9
DemoDMP::~DemoDMP
virtual ~DemoDMP()
Virtual destructor for safe inheritance.
Definition: DemoDMP.C:153
jevois::DMPdata::accel
short accel[3]
jevois::IMUrawData::ay
short & ay()
jevois::IMUrawData::az
short & az()
JEVOIS_DMP_PED_STEPDET
#define JEVOIS_DMP_PED_STEPDET
jevois::RawImage
jevois::IMUrawData::gz
short & gz()
jevois::DMPdata::fsync_us
float fsync_us() const
JEVOIS_REGISTER_MODULE
JEVOIS_REGISTER_MODULE(DemoDMP)
LERROR
#define LERROR(msg)
jevois::RawImage::require
void require(char const *info, unsigned int w, unsigned int h, unsigned int f) const
jevois::IMUrawData::gy
short & gy()
jevois::DMPdata::quat6
long quat6[3]
jevois::DMPdata::stepts
unsigned long stepts
jevois::DMPdata::geomag
long geomag[3]
jevois::RawImage::width
unsigned int width
jevois::RawImage::pixelsw
T * pixelsw()
jevois::rawimage::writeText
void writeText(RawImage &img, std::string const &txt, int x, int y, unsigned int col, Font font=Font6x10)
JEVOIS_DMP_GEOMAG
#define JEVOIS_DMP_GEOMAG
jevois
F
float F
JEVOIS_DMP_FSYNC
#define JEVOIS_DMP_FSYNC
ICM20948.H
jevois::join
std::string join(std::vector< std::string > const &strings, std::string const &delimiter)
jevois::IMUrawData::mx
short & mx()
jevois::DMPdata::fix2float
static float fix2float(long val)
jevois::rawimage::drawFilledRect
void drawFilledRect(RawImage &img, int x, int y, unsigned int w, unsigned int h, unsigned int col)
jevois::IMUrawData
JEVOIS_DMP_CPASS
#define JEVOIS_DMP_CPASS
jevois::IMUrawData::mz
short & mz()
jevois::IMUdata::my
float & my()
jevois::DMPdata::steps
unsigned short steps
jevois::Module
jevois::DMPdata
RawImageOps.H
jevois::IMUdata::mz
float & mz()
jevois::RawImage::height
unsigned int height
jevois::IMUdata::az
float & az()
JEVOIS_DMP_ACT_RECOG
#define JEVOIS_DMP_ACT_RECOG
to_string
std::string to_string(T const &val)
jevois::InputFrame
jevois::DMPdata::quat9
long quat9[3]
DemoDMP::process
virtual void process(jevois::InputFrame &&inframe, jevois::OutputFrame &&outframe) override
Processing function.
Definition: DemoDMP.C:156
jevois::RawImage::fmt
unsigned int fmt
JEVOIS_DMP_GYRO
#define JEVOIS_DMP_GYRO
jevois::RawImage::buf
std::shared_ptr< VideoBuf > buf
h
int h
jevois::IMUrawData::my
short & my()
jevois::IMUdata::gz
float & gz()
jevois::IMUdata::ax
float & ax()
jevois::DMPdata::cpass
short cpass[3]
jevois::IMUdata::mx
float & mx()
jevois::rawimage::drawLine
void drawLine(RawImage &img, int x1, int y1, int x2, int y2, unsigned int thick, unsigned int col)
jevois::IMUrawData::ax
short & ax()
JEVOIS_DMP_FLIP_PICKUP
#define JEVOIS_DMP_FLIP_PICKUP
DemoDMP
Plot results of processing IMU data with the on-chip Digital Motion Processor (DMP)
Definition: DemoDMP.C:145
jevois::IMUdata::ay
float & ay()
jevois::rawimage::Font10x20
Font10x20
LINFO
#define LINFO(msg)
jevois::IMUdata::gx
float & gx()
demo.w
w
Definition: demo.py:85
jevois::IMUrawData::gx
short & gx()
JEVOIS_DMP_ACCEL
#define JEVOIS_DMP_ACCEL
jevois::IMUdata
jevois::Component::Module
friend friend class Module