Laelaps  2.3.5
RoadNarrows Robotics Small Outdoor Mobile Robot Project
laeImu.cxx
Go to the documentation of this file.
1 ////////////////////////////////////////////////////////////////////////////////
2 //
3 // Package: Laelaps
4 //
5 // File: laeImu.cxx
6 //
7 /*! \file
8  *
9  * \brief Laelaps built-in Inertial Measurement Unit class implementation.
10  *
11  * The current Laelaps uses the open-source CleanFlight firmware loaded
12  * on a Naze32 controller. The interface is serial USB.
13  *
14  * \sa https://github.com/cleanflight
15  *
16  * \author Robin Knight (robin.knight@roadnarrows.com)
17  *
18  * \par Copyright
19  * \h_copy 2015-2017. RoadNarrows LLC.\n
20  * http://www.roadnarrows.com\n
21  * All Rights Reserved
22  */
23 /*
24  * @EulaBegin@
25  *
26  * Unless otherwise stated explicitly, all materials contained are copyrighted
27  * and may not be used without RoadNarrows LLC's written consent,
28  * except as provided in these terms and conditions or in the copyright
29  * notice (documents and software) or other proprietary notice provided with
30  * the relevant materials.
31  *
32  * IN NO EVENT SHALL THE AUTHOR, ROADNARROWS LLC, OR ANY
33  * MEMBERS/EMPLOYEES/CONTRACTORS OF ROADNARROWS OR DISTRIBUTORS OF THIS SOFTWARE
34  * BE LIABLE TO ANY PARTY FOR DIRECT, INDIRECT, SPECIAL, INCIDENTAL, OR
35  * CONSEQUENTIAL DAMAGES ARISING OUT OF THE USE OF THIS SOFTWARE AND ITS
36  * DOCUMENTATION, EVEN IF THE AUTHORS OR ANY OF THE ABOVE PARTIES HAVE BEEN
37  * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
38  *
39  * THE AUTHORS AND ROADNARROWS LLC SPECIFICALLY DISCLAIM ANY WARRANTIES,
40  * INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND
41  * FITNESS FOR A PARTICULAR PURPOSE. THE SOFTWARE PROVIDED HEREUNDER IS ON AN
42  * "AS IS" BASIS, AND THE AUTHORS AND DISTRIBUTORS HAVE NO OBLIGATION TO
43  * PROVIDE MAINTENANCE, SUPPORT, UPDATES, ENHANCEMENTS, OR MODIFICATIONS.
44  *
45  * @EulaEnd@
46  */
47 ////////////////////////////////////////////////////////////////////////////////
48 
49 #include <pthread.h>
50 #include <unistd.h>
51 #include <math.h>
52 
53 #include <string>
54 #include <sstream>
55 
56 #include "rnr/rnrconfig.h"
57 #include "rnr/serdev.h"
58 #include "rnr/log.h"
59 
60 #include "Laelaps/laelaps.h"
61 #include "Laelaps/laeUtils.h"
62 #include "Laelaps/laeDesc.h"
63 #include "Laelaps/laeTune.h"
64 #include "Laelaps/laeImu.h"
65 #include "Laelaps/laeDb.h"
66 
67 using namespace std;
68 using namespace laelaps;
69 using namespace sensor::imu;
70 using namespace sensor::imu::msp;
71 
72 
73 //------------------------------------------------------------------------------
74 // Quaternion Class
75 //------------------------------------------------------------------------------
76 
77 Quaternion Quaternion::operator=(const Quaternion &rhs)
78 {
79  m_x = rhs.m_x;
80  m_y = rhs.m_y;
81  m_z = rhs.m_z;
82  m_w = rhs.m_w;
83 
84  return *this;
85 }
86 
87 void Quaternion::clear()
88 {
89  m_x = 0.0;
90  m_y = 0.0;
91  m_z = 0.0;
92  m_w = 1.0;
93 }
94 
95 void Quaternion::convertEuler(double phi, double theta, double psi)
96 {
97  double half_phi, half_theta, half_psi;
98  double cos_phi, sin_phi;
99  double cos_theta, sin_theta;
100  double cos_psi, sin_psi;
101 
102  half_phi = phi / 2.0;
103  half_theta = theta / 2.0;
104  half_psi = psi / 2.0;
105 
106  cos_phi = cos(half_phi);
107  sin_phi = sin(half_phi);
108  cos_theta = cos(half_theta);
109  sin_theta = sin(half_theta);
110  cos_psi = cos(half_psi);
111  sin_psi = sin(half_psi);
112 
113  m_x = cos_phi*cos_theta*cos_psi + sin_phi*sin_theta*sin_psi;
114  m_y = sin_phi*cos_theta*cos_psi - cos_phi*sin_theta*sin_psi;
115  m_z = cos_phi*sin_theta*cos_psi + sin_phi*cos_theta*sin_psi;
116  m_w = cos_phi*cos_theta*sin_psi - sin_phi*sin_theta*cos_psi;
117 }
118 
119 void Quaternion::convertTaitBryan(double roll, double pitch, double yaw)
120 {
121  double half_roll = 0.5 * roll;
122  double half_pitch = 0.5 * pitch;
123  double half_yaw = 0.5 * yaw;
124 
125  double t0 = cos(half_yaw);
126  double t1 = sin(half_yaw);
127  double t2 = cos(half_roll);
128  double t3 = sin(half_roll);
129  double t4 = cos(half_pitch);
130  double t5 = sin(half_pitch);
131 
132  m_w = t0 * t2 * t4 + t1 * t3 * t5;
133  m_x = t0 * t3 * t4 - t1 * t2 * t5;
134  m_y = t0 * t2 * t5 + t1 * t3 * t4;
135  m_z = t1 * t2 * t4 - t0 * t3 * t5;
136 }
137 
138 
139 //------------------------------------------------------------------------------
140 // LaeImu Virtual Base Class
141 //------------------------------------------------------------------------------
142 
143 LaeImu::LaeImu(string strIdent) : m_strIdent(strIdent)
144 {
145  m_fd = -1;
146  m_bBlackListed = false;
147 
148  clearSensedData();
149 
150  pthread_mutex_init(&m_mutexIo, NULL);
151  pthread_mutex_init(&m_mutexOp, NULL);
152 }
153 
155 {
156  close();
157 
158  pthread_mutex_destroy(&m_mutexOp);
159  pthread_mutex_destroy(&m_mutexIo);
160 }
161 
162 int LaeImu::open(const string &strDevName, int nBaudRate)
163 {
164  string strDevNameReal;
165  int rc;
166 
167  lockIo();
168 
169  // Get the real device name, not any symbolic links.
170  strDevNameReal = getRealDeviceName(strDevName);
171 
172  m_fd = SerDevOpen(strDevNameReal.c_str(), nBaudRate, 8, 'N', 1, false, false);
173 
174  if( m_fd < 0 )
175  {
176  LOGERROR("Failed to open %s@%d.", strDevNameReal.c_str(), nBaudRate);
177  rc = -LAE_ECODE_NO_DEV;
178  }
179 
180  else
181  {
182  m_strDevName = strDevNameReal;
183  m_nBaudRate = nBaudRate;
184  m_bBlackListed = false;
185 
186  RtDb.m_enable.m_bImu = true;
187 
188  clearSensedData();
189 
190  LOGDIAG2("Opened interface to IMU on %s@%d.",
191  strDevNameReal.c_str(), nBaudRate);
192 
193  rc = LAE_OK;
194  }
195 
196  unlockIo();
197 
198  return rc;
199 }
200 
202 {
203  lockIo();
204 
205  if( m_fd >= 0 )
206  {
207  SerDevClose(m_fd);
208  LOGDIAG2("Closed %s interface to IMU.", m_strDevName.c_str());
209  }
210 
211  m_strDevName.clear();
212  m_nBaudRate = 0;
213  m_fd = -1;
214 
215  unlockIo();
216 
217  return LAE_OK;
218 }
219 
221 {
222  if( isOpen() )
223  {
224  close();
225  }
226 
227  m_bBlackListed = true;
228  RtDb.m_enable.m_bImu = false;
229 }
230 
232 {
233  m_bBlackListed = false;
234  RtDb.m_enable.m_bImu = true;
235 }
236 
237 int LaeImu::configure(const LaeDesc &desc)
238 {
239  return LAE_OK;
240 }
241 
242 int LaeImu::configure(const LaeTunes &tunes)
243 {
244  return LAE_OK;
245 }
246 
247 int LaeImu::reload(const LaeTunes &tunes)
248 {
249  return LAE_OK;
250 }
251 
253 {
254  for(int i = 0; i < NumOfAxes; ++i)
255  {
256  m_accelRaw[i] = 0;
257  m_gyroRaw[i] = 0;
258  m_magRaw[i] = 0;
259  m_rpyRaw[i] = 0;
260 
261  m_accel[i] = 0.0;
262  m_gyro[i] = 0.0;
263  m_mag[i] = 0.0;
264  m_rpy[i] = 0.0;
265  }
266 
268 }
269 
271 {
273  computeDynamics();
274 }
275 
277 {
279 }
280 
282 {
283 }
284 
286 {
287  if( isBlackListed() )
288  {
289  return;
290  }
291 
292  lockOp();
293 
294  if( readRawImu() == LAE_OK )
295  {
296  convertRawToSI();
297  compute();
298  }
299 
300  unlockOp();
301 }
302 
303 void LaeImu::getRawInertiaData(int accel[], int gyro[])
304 {
305  for(int i = 0; i < NumOfAxes; ++i)
306  {
307  accel[i] = m_accelRaw[i];
308  gyro[i] = m_gyroRaw[i];
309  }
310 }
311 
312 void LaeImu::getInertiaData(double accel[], double gyro[])
313 {
314  for(int i = 0; i < NumOfAxes; ++i)
315  {
316  accel[i] = m_accel[i];
317  gyro[i] = m_gyro[i];
318  }
319 }
320 
321 void LaeImu::getMagnetometerData(double mag[])
322 {
323  for(int i = 0; i < NumOfAxes; ++i)
324  {
325  mag[i] = m_mag[i];
326  }
327 }
328 
329 void LaeImu::getAttitude(double rpy[])
330 {
331  for(int i = 0; i < NumOfAxes; ++i)
332  {
333  rpy[i] = m_rpy[i];
334  }
335 }
336 
337 void LaeImu::getAttitude(double &roll, double &pitch, double &yaw)
338 {
339  roll = m_rpy[ROLL];
340  pitch = m_rpy[PITCH];
341  yaw = m_rpy[YAW];
342 }
343 
345 {
346  q = m_quaternion;
347 }
348 
349 void LaeImu::getImuData(double accel[], double gyro[], double mag[],
350  double rpy[], Quaternion &q)
351 {
352  lockOp();
353 
354  getInertiaData(accel, gyro);
355  getMagnetometerData(mag);
356  getAttitude(rpy);
357  getQuaternion(q);
358 
359  unlockOp();
360 }
361 
362 
363 //------------------------------------------------------------------------------
364 // LaeImuCleanFlight IMU class with Cleanflight firmware on a supported board.
365 //------------------------------------------------------------------------------
366 
368  LaeImu("CleanFlight Naze32 with MPU-6050 IMU sensor")
369 {
370 }
371 
373 {
374 }
375 
376 int LaeImuCleanFlight::readIdentity(string &strIdent)
377 {
378  MspIdent ident;
379  int rc;
380 
381  if( isBlackListed() )
382  {
383  strIdent = "Unknown - blacklisted";
384  rc = LAE_OK;
385  }
386 
387  else if( (rc = mspReadIdent(ident)) == LAE_OK )
388  {
389  stringstream ss;
390 
391  ss << "CleanFlight v" << ident.m_uFwVersion
392  << " Naze32 with MPU-6050 IMU sensor";
393 
394  m_strIdent = ss.str();
395  strIdent = m_strIdent;
396  }
397 
398  return rc;
399 }
400 
402 {
403  int rc;
404 
405  if( isBlackListed() )
406  {
407  rc = LAE_OK;
408  }
409 
410  else if( (rc = mspReadRawImu()) == LAE_OK )
411  {
412  rc = mspReadAttitude();
413  }
414 
415  return rc;
416 }
417 
419 {
420  int rc;
421 
422  if( isBlackListed() )
423  {
424  rc = LAE_OK;
425  }
426 
427  else
428  {
429  rc = mspReadRawImu();
430  }
431 
432  return rc;
433 }
434 
436 {
437  int rc;
438 
439  if( isBlackListed() )
440  {
441  rc = LAE_OK;
442  }
443 
444  else
445  {
446  rc = mspReadAttitude();
447  }
448 
449  return rc;
450 }
451 
453 {
454  for(int i = 0; i < NumOfAxes; ++i)
455  {
457  RtDb.m_imu.m_accel[i] = m_accel[i];
458 
460  RtDb.m_imu.m_gyro[i] = m_gyro[i];
461 
462  if( i != YAW )
463  {
465  RtDb.m_imu.m_rpy[i] = m_rpy[i];
466  }
467  }
469  RtDb.m_imu.m_rpy[YAW] = m_rpy[YAW];
470 
471  return LAE_OK;
472 }
473 
475 {
476  static const uint_t CmdId = MspCmdIdIdent;
477  static const size_t RspDataLen = 7;
478 
479  byte_t rspData[RspDataLen];
480  int rc;
481 
482  if( !isOpen() )
483  {
484  return -LAE_ECODE_IO;
485  }
486 
487  lockIo();
488 
489  if( (rc = sendCmd(CmdId, NULL, 0)) == LAE_OK )
490  {
491  rc = receiveRsp(CmdId, rspData, RspDataLen);
492  }
493 
494  if( rc == LAE_OK )
495  {
496  ident.m_uFwVersion = (uint_t)rspData[0];
497  ident.m_uMultiType = (uint_t)rspData[1];
498  ident.m_uMspVersion = (uint_t)rspData[2];
499  unpack32(&rspData[3], ident.m_uCaps);
500  }
501 
502  unlockIo();
503 
504  return rc;
505 }
506 
508 {
509  static const uint_t CmdId = MspCmdIdRawImu;
510  static const size_t RspDataLen = 18;
511 
512  byte_t rspData[RspDataLen];
513  int i, n;
514  int rc;
515 
516  if( !isOpen() )
517  {
518  return -LAE_ECODE_IO;
519  }
520 
521  lockIo();
522 
523  if( (rc = sendCmd(CmdId, NULL, 0)) == LAE_OK )
524  {
525  rc = receiveRsp(CmdId, rspData, RspDataLen);
526  }
527 
528  if( rc == LAE_OK )
529  {
530  for(i = 0, n = 0; i < NumOfAxes; ++i, n += 2)
531  {
532  unpack16(&rspData[n], m_accelRaw[i]);
533  }
534  for(i = 0; i < NumOfAxes; ++i, n += 2)
535  {
536  unpack16(&rspData[n], m_gyroRaw[i]);
537  }
538  for(i = 0; i < NumOfAxes; ++i, n += 2)
539  {
540  unpack16(&rspData[n], m_magRaw[i]);
541  }
542  }
543 
544  unlockIo();
545 
546  return rc;
547 }
548 
550 {
551  static const uint_t CmdId = MspCmdIdAttitude;
552  static const size_t RspDataLen = 6;
553 
554  byte_t rspData[RspDataLen];
555  int i, n;
556  int rc;
557 
558  if( !isOpen() )
559  {
560  return -LAE_ECODE_IO;
561  }
562 
563  lockIo();
564 
565  if( (rc = sendCmd(CmdId, NULL, 0)) == LAE_OK )
566  {
567  rc = receiveRsp(CmdId, rspData, RspDataLen);
568  }
569 
570  if( rc == LAE_OK )
571  {
572  for(i = 0, n = 0; i < NumOfAxes; ++i, n += 2)
573  {
574  unpack16(&rspData[n], m_rpyRaw[i]);
575  }
576  }
577 
578  unlockIo();
579 
580  return rc;
581 }
582 
583 
584 int LaeImuCleanFlight::sendCmd(uint_t cmdId, byte_t cmdData[], size_t lenData)
585 {
586  byte_t cmd[MspCmdMaxLen];
587  uint_t chksum;
588  size_t n;
589 
590  for(n = 0; n<strlen(MspCmdPreamble); ++n)
591  {
592  cmd[n] = MspCmdPreamble[n];
593  }
594 
595  chksum = 0;
596 
597  cmd[n++] = (byte_t)lenData;
598  chksum ^= (byte_t)lenData;
599 
600  cmd[n++] = (byte_t)cmdId;
601  chksum ^= (byte_t)cmdId;
602 
603  for(size_t i = 0; i < lenData; ++i)
604  {
605  cmd[n++] = (byte_t)cmdData[i];
606  chksum ^= (byte_t)cmdData[i];
607  }
608 
609  cmd[n++] = (byte_t)chksum;
610 
611  if( SerDevWrite(m_fd, cmd, n, TCmdTimeout) == n )
612  {
613  return LAE_OK;
614  }
615  else
616  {
618  LOGERROR("IMU: Cmd %d: Send failed.", cmdId);
619  return -LAE_ECODE_IO;
620  }
621 }
622 
624  byte_t rspData[],
625  size_t lenData)
626 {
627  byte_t rsp[MspRspMaxLen];
628  uint_t chksum;
629  size_t lenRsp;
630  size_t n;
631  size_t fldSize;
632  uint_t fldCmdId;
633  byte_t fldChkSum;
634  size_t i;
635 
636  lenRsp = MspRspMinLen + lenData;
637 
638  if( (n = SerDevRead(m_fd, rsp, lenRsp, TRspTimeout)) < 0 )
639  {
640  LOGERROR("IMU: Cmd %d response: Receive failed.", cmdId);
642  return -LAE_ECODE_IO;
643  }
644  else if( n < lenRsp )
645  {
646  LOGERROR("IMU: Cmd %d response: Receive partial response: "
647  "rcv'd %zu bytes, expected %zu bytes.", cmdId, n, lenRsp);
649  return -LAE_ECODE_IO;
650  }
651 
652  fldSize = (size_t)rsp[MspFieldPosSize];
653 
654  if( fldSize != lenData )
655  {
656  LOGERROR("IMU: Cmd %d response: Data length mismatch: " \
657  "Received %zu bytes, expected %zu bytes.", cmdId, fldSize, lenData);
658  resyncComm();
659  return -LAE_ECODE_IO;
660  }
661 
662  fldCmdId = (uint_t)rsp[MspFieldPosCmdId];
663 
664  if( fldCmdId != cmdId )
665  {
666  LOGERROR("IMU: Cmd %d response: Command Id mismatch: Received %d.",
667  cmdId, fldCmdId);
668  resyncComm();
669  return -LAE_ECODE_IO;
670  }
671 
672  chksum = rsp[MspFieldPosSize];
673  chksum ^= rsp[MspFieldPosCmdId];
674 
675  for(i = 0, n = MspFieldPosDataStart; i < lenData; ++i, ++n)
676  {
677  chksum ^= rsp[n];
678  rspData[i] = rsp[n];
679  }
680 
681  fldChkSum = rsp[lenRsp-1];
682 
683  if( chksum != fldChkSum )
684  {
685  LOGERROR("IMU: Cmd %d response: Checksum mismatch: " \
686  "Received 0x%02x, calculated 0x%02x.", cmdId, fldChkSum, chksum);
687  resyncComm();
688  return -LAE_ECODE_IO;
689  }
690 
691  return LAE_OK;
692 }
693 
695 {
696  MspIdent ident;
697  int nMaxTries = 3;
698  int nTries;
699  int rc;
700 
701  LOGDIAG3("IMU: Resynchronizing serial communication.");
702 
703  for(nTries = 0; nTries < nMaxTries; ++nTries)
704  {
706  if( (rc = mspReadIdent(ident)) == LAE_OK )
707  {
708  return;
709  }
710  }
711 
712  LOGWARN("IMU: Failed to resynchronize communication in %d tries.", nMaxTries);
713  LOGWARN("IMU: Blacklisting.", nMaxTries);
714 
715  blacklist();
716 }
717 
719 {
720  if( t > 0 )
721  {
722  usleep(t);
723  }
724 
725  SerDevFIFOOutputFlush(m_fd);
726  SerDevFIFOInputFlush(m_fd);
727 }
728 
729 int LaeImuCleanFlight::pack16(uint_t val, byte_t buf[])
730 {
731  buf[0] = (byte_t)(val & 0xff);
732  buf[1] = (byte_t)((val >> 8) & 0xff);
733  return 2;
734 }
735 
736 int LaeImuCleanFlight::unpack16(byte_t buf[], uint_t &val)
737 {
738  val = ((uint_t)(buf[1]) << 8) | (uint_t)buf[0];
739  return 2;
740 }
741 
742 int LaeImuCleanFlight::unpack16(byte_t buf[], int &val)
743 {
744  s16_t v;
745  v = ((s16_t)(buf[1]) << 8) | (s16_t)buf[0];
746  val = (int)v;
747  return 2;
748 }
749 
750 int LaeImuCleanFlight::pack32(uint_t val, byte_t buf[])
751 {
752  buf[0] = (byte_t)(val & 0xff);
753  buf[1] = (byte_t)((val >> 8) & 0xff);
754  buf[2] = (byte_t)((val >> 16) & 0xff);
755  buf[3] = (byte_t)((val >> 24) & 0xff);
756  return 4;
757 }
758 
759 int LaeImuCleanFlight::unpack32(byte_t buf[], uint_t &val)
760 {
761  val = ((uint_t)(buf[3]) << 24) |
762  ((uint_t)(buf[2]) << 16) |
763  ((uint_t)(buf[1]) << 8) |
764  (uint_t)buf[0];
765  return 4;
766 }
767 
768 int LaeImuCleanFlight::unpack32(byte_t buf[], int &val)
769 {
770  s32_t v;
771 
772  v = ((s32_t)(buf[3]) << 24) |
773  ((s32_t)(buf[2]) << 16) |
774  ((s32_t)(buf[1]) << 8) |
775  (s32_t)buf[0];
776  val = (int)v;
777  return 4;
778 }
virtual int configure(const laelaps::LaeDesc &desc)
Configure IMU from product description.
Definition: laeImu.cxx:237
int m_gyroRaw[NumOfAxes]
gyroscope raw values
Definition: laeImu.h:506
static const uint_t TFlushDelay
flush buffer delay (usec)
Definition: laeImu.h:689
static const double MspMpu6050RawToDegPerSec
MPU-6050 rotation raw value to degrees/second.
Definition: laeImu.h:653
void flush(uint_t t)
Flush serial input and output FIFOs, discarding all data.
Definition: laeImu.cxx:718
uint_t m_uCaps
capabilities or&#39;d bits
Definition: laeImu.h:643
uint_t m_uMultiType
multiwii type
Definition: laeImu.h:641
Laelaps tuning data class.
Definition: laeTune.h:566
Laelaps robotic mobile platform full description class.
Definition: laeDesc.h:451
double m_rpy[NumOfAxes]
roll,pitch,yaw (radians)
Definition: laeImu.h:516
void lockIo()
Lock the shared I/O resource.
Definition: laeImu.h:541
double degToRad(double d)
Convert degrees to radians.
Definition: laeUtils.h:124
double m_accel[NumOfAxes]
accelerometer (m/s^2)
Definition: laeImu.h:513
virtual int readRawInertia()
Read sensors inertia data.
Definition: laeImu.cxx:418
virtual int open(const std::string &strDevName, int nBaudRate)
Definition: laeImu.cxx:162
void unlockIo()
Unlock the shared I/O resource.
Definition: laeImu.h:552
virtual int readRawImu()
Read sensor and board raw IMU values.
Definition: laeImu.cxx:401
int sendCmd(uint_t cmdId, byte_t cmdData[], size_t lenData)
Send command to IMU.
Definition: laeImu.cxx:584
std::string m_strIdent
IMU identity.
Definition: laeImu.h:496
int m_fd
opened device file descriptor
Definition: laeImu.h:499
pthread_mutex_t m_mutexIo
low-level I/O mutex
Definition: laeImu.h:530
static const uint_t TRspTimeout
response timeout (usec)
Definition: laeImu.h:688
static const double MspGToMPerSec2
standard g in m/s^2
Definition: laeImu.h:649
int pack16(int val, byte_t buf[])
Pack 16-bit signed value into buffer.
Definition: laeImu.h:859
yaw index
Definition: laeImu.h:107
void resyncComm()
Attempt to resynchronize the serial communication between the host and the IMU.
Definition: laeImu.cxx:694
roll index
Definition: laeImu.h:105
void unlockOp()
Unlock the extended operation.
Definition: laeImu.h:576
static const char *const MspCmdPreamble
command preamble
Definition: laeImu.h:607
virtual void clearSensedData()
Clear IMU sensed data.
Definition: laeImu.cxx:252
static const uint_t MspCmdIdIdent
read board/sensor idents
Definition: laeImu.h:631
int m_nBaudRate
device baudrate
Definition: laeImu.h:498
static const int MspRspMinLen
MspRspHdrLen+1 response min len.
Definition: laeImu.h:625
Multiwii Serial Protocal Interface.
Definition: laeImu.h:598
int unpack16(byte_t buf[], int &val)
Unpack 16-bit signed value from buffer.
Definition: laeImu.cxx:742
LaeImuCleanFlight()
Default constructor.
Definition: laeImu.cxx:367
virtual int convertRawToSI()
Convert last read IMU values to International System of Units.
Definition: laeImu.cxx:452
virtual ~LaeImu()
Destructor.
Definition: laeImu.cxx:154
virtual void getQuaternion(Quaternion &q)
Get the last computed quaternion.
Definition: laeImu.cxx:344
virtual void getImuData(double accel[], double gyro[], double mag[], double rpy[], Quaternion &q)
Get the last sensed, converted, and computed IMU data.
Definition: laeImu.cxx:349
int m_accelRaw[NumOfAxes]
accelerometer raw values
Definition: laeImu.h:505
static const uint_t TCmdTimeout
command timeout (usec)
Definition: laeImu.h:687
int mspReadRawImu()
Read raw IMU data.
Definition: laeImu.cxx:507
virtual bool isOpen()
Check if IMU serial interface is open.
Definition: laeImu.h:222
pitch index
Definition: laeImu.h:106
static const int MspCmdMaxLen
response max len
Definition: laeImu.h:623
int receiveRsp(uint_t cmdId, byte_t rspData[], size_t lenData)
Definition: laeImu.cxx:623
uint_t m_uMspVersion
MSP version.
Definition: laeImu.h:642
virtual void getMagnetometerData(double mag[])
Get the last read magnetometer values.
Definition: laeImu.cxx:321
virtual int reload(const laelaps::LaeTunes &tunes)
Reload with new tuning parameters.
Definition: laeImu.cxx:247
Board identity structure.
Definition: laeImu.h:638
The <b><i>Laelaps</i></b> namespace encapsulates all <b><i>Laelaps</i></b> related constructs...
Definition: laeAlarms.h:64
Laelaps robotic base mobile platform description class interface.
double m_mag[NumOfAxes]
magnetometer (tesla)
Definition: laeImu.h:515
virtual ~LaeImuCleanFlight()
Destructor.
Definition: laeImu.cxx:372
const int NumOfAxes
maximum number of axes per sensor component.
Definition: laeImu.h:98
uint_t m_uFwVersion
firmware version
Definition: laeImu.h:640
Laelaps common utilities.
Laelaps built-in Inertial Measurement Unit class interface.
static const double MspAttitudeRawToDeg
board computed attitude raw value to degreess
Definition: laeImu.h:655
virtual void computeQuaternion()
Compute the quaternion from the IMU data.
Definition: laeImu.cxx:276
static const int MspFieldPosDataStart
data start field position
Definition: laeImu.h:616
void lockOp()
Lock the extended operation.
Definition: laeImu.h:565
virtual int readRawImu()=0
Read sensor raw IMU values.
Laelaps tuning.
static const double MspMpu6050RawToG
MPU-6050 acceleration raw value to g&#39;s.
Definition: laeImu.h:651
int m_magRaw[NumOfAxes]
magnetometer raw values
Definition: laeImu.h:507
virtual void compute()
Compute all IMU values form converted, raw values.
Definition: laeImu.cxx:270
Quaternion class.
Definition: laeImu.h:118
static const int MspFieldPosSize
data size field position
Definition: laeImu.h:614
int pack32(int val, byte_t buf[])
Pack 32-bit signed value into buffer.
Definition: laeImu.h:910
static const uint_t MspCmdIdRawImu
read raw imu data
Definition: laeImu.h:632
pthread_mutex_t m_mutexOp
high-level operation mutex
Definition: laeImu.h:531
Quaternion m_quaternion
imu orientation (and robot)
Definition: laeImu.h:517
virtual void getAttitude(double rpy[])
Get the last read IMU (vehicle) attitude.
Definition: laeImu.cxx:329
bool m_bBlackListed
IMU is [not] black listed.
Definition: laeImu.h:500
virtual void exec()
Exectute one step to read, convert, and compute IMU values.
Definition: laeImu.cxx:285
int unpack32(byte_t buf[], int &val)
Unpack 32-bit signed value from buffer.
Definition: laeImu.cxx:768
virtual int readIdentity(std::string &strIdent)
Read sensor identity values.
Definition: laeImu.cxx:376
int mspReadIdent(msp::MspIdent &ident)
Read CleanFlight board&#39;s identity values.
Definition: laeImu.cxx:474
virtual int close()
Close connection to motor controller.
Definition: laeImu.cxx:201
virtual int readRawRollPitchYaw()
Read board&#39;s calculated roll, pitch, and yaw raw values.
Definition: laeImu.cxx:435
int mspReadAttitude()
MSP command/response.
Definition: laeImu.cxx:549
virtual void getInertiaData(double accel[], double gyro[])
Get the last read and converted inertia data.
Definition: laeImu.cxx:312
static const uint_t MspCmdIdAttitude
read raw attitude data
Definition: laeImu.h:633
Laelaps real-time "database".
virtual void whitelist()
White list IMU sensor.
Definition: laeImu.cxx:231
double m_gyro[NumOfAxes]
gyrscope (radians/s)
Definition: laeImu.h:514
void convertTaitBryan(double roll, double pitch, double yaw)
Convert Tait-Bryan angles to quaternion.
Definition: laeImu.cxx:119
static const int MspRspMaxLen
response max len
Definition: laeImu.h:626
virtual void computeDynamics()
Compute the velocity, position, and any other dynamics from the IMU data.
Definition: laeImu.cxx:281
virtual void blacklist()
Black list IMU from robot sensors.
Definition: laeImu.cxx:220
virtual bool isBlackListed()
Test if IMU is black listed.
Definition: laeImu.h:242
std::string m_strDevName
serial device name
Definition: laeImu.h:497
std::string getRealDeviceName(const std::string &strDevName)
Get real device name.
int m_rpyRaw[NumOfAxes]
roll,pitch,yaw raw values
Definition: laeImu.h:508
Top-level package include file.
static const int MspFieldPosCmdId
command id field position
Definition: laeImu.h:615
virtual void getRawInertiaData(int accel[], int gyro[])
Get the last read raw inertia data.
Definition: laeImu.cxx:303
virtual int convertRawToSI()=0
Convert last read IMU values to International System of Units.
void clear()
Clear quaternion values.
Definition: laeImu.cxx:87