Laelaps  2.3.5
RoadNarrows Robotics Small Outdoor Mobile Robot Project
diagImu.cxx
Go to the documentation of this file.
1 ////////////////////////////////////////////////////////////////////////////////
2 //
3 // Package: Laelaps
4 //
5 // Program: laelaps_diag
6 //
7 // File: diagImu.cxx
8 //
9 /*! \file
10  *
11  * \brief Perform Laelaps IMU diagnostics.
12  *
13  * \author Robin Knight (robin.knight@roadnarrows.com)
14  *
15  * \par Copyright
16  * \h_copy 2015-2017. RoadNarrows LLC.\n
17  * http://www.roadnarrows.com\n
18  * All Rights Reserved
19  */
20 /*
21  * @EulaBegin@
22  *
23  * Unless otherwise stated explicitly, all materials contained are copyrighted
24  * and may not be used without RoadNarrows LLC's written consent,
25  * except as provided in these terms and conditions or in the copyright
26  * notice (documents and software) or other proprietary notice provided with
27  * the relevant materials.
28  *
29  * IN NO EVENT SHALL THE AUTHOR, ROADNARROWS LLC, OR ANY
30  * MEMBERS/EMPLOYEES/CONTRACTORS OF ROADNARROWS OR DISTRIBUTORS OF THIS SOFTWARE
31  * BE LIABLE TO ANY PARTY FOR DIRECT, INDIRECT, SPECIAL, INCIDENTAL, OR
32  * CONSEQUENTIAL DAMAGES ARISING OUT OF THE USE OF THIS SOFTWARE AND ITS
33  * DOCUMENTATION, EVEN IF THE AUTHORS OR ANY OF THE ABOVE PARTIES HAVE BEEN
34  * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
35  *
36  * THE AUTHORS AND ROADNARROWS LLC SPECIFICALLY DISCLAIM ANY WARRANTIES,
37  * INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND
38  * FITNESS FOR A PARTICULAR PURPOSE. THE SOFTWARE PROVIDED HEREUNDER IS ON AN
39  * "AS IS" BASIS, AND THE AUTHORS AND DISTRIBUTORS HAVE NO OBLIGATION TO
40  * PROVIDE MAINTENANCE, SUPPORT, UPDATES, ENHANCEMENTS, OR MODIFICATIONS.
41  *
42  * @EulaEnd@
43  */
44 ////////////////////////////////////////////////////////////////////////////////
45 
46 #include <unistd.h>
47 #include <termios.h>
48 #include <string.h>
49 #include <stdio.h>
50 #include <stdlib.h>
51 #include <stdarg.h>
52 
53 #include <iostream>
54 #include <fstream>
55 #include <string>
56 #include <vector>
57 
58 #include "rnr/rnrconfig.h"
59 #include "rnr/log.h"
60 #include "rnr/opts.h"
61 #include "rnr/pkg.h"
62 
63 // common
64 #include "Laelaps/laelaps.h"
65 #include "Laelaps/laeUtils.h"
66 
67 // hardware
68 #include "Laelaps/laeSysDev.h"
69 #include "Laelaps/laeImu.h"
70 
71 #include "laelaps_diag.h"
72 
73 using namespace std;
74 using namespace laelaps;
75 using namespace sensor::imu;
76 using namespace sensor::imu::msp;
77 
78 static const char *SubSysName = "IMU";
79 static const char *ProdName = "CleanFlight Naze32";
80 
81 static DiagStats initImu(LaeImuCleanFlight &imu)
82 {
83  const char *sTag;
84  DiagStats stats;
85 
86  printSubHdr("Initialize IMU");
87 
88  ++stats.testCnt;
89 
90  if( imu.open(LaeDevIMU, LaeBaudRateIMU) == LAE_OK )
91  {
92  sTag = PassTag;
93  ++stats.passCnt;
94  }
95  else
96  {
97  sTag = FailTag;
98  stats.fatal = true;
99  }
100 
101  printTestResult(sTag, "Open IMU serial device %s.", LaeDevIMU);
102 
103  return stats;
104 }
105 
106 static DiagStats readInfo(LaeImuCleanFlight &imu)
107 {
108  string strIdent;
109 
110  const char *sTag;
111  DiagStats stats;
112 
113  printSubHdr("Read IMU Information and Configuration");
114 
115  ++stats.testCnt;
116 
117  if( imu.readIdentity(strIdent) == LAE_OK )
118  {
119  sTag = PassTag;
120  ++stats.passCnt;
121  }
122  else
123  {
124  sTag = FailTag;
125  strIdent = imu.getIdentity(); // default
126  }
127 
128  printTestResult(sTag, "Read IMU identity.", LaeDevIMU);
129 
130  ++stats.testCnt;
131 
132  if( imu.readRawImu() == LAE_OK )
133  {
134  sTag = PassTag;
135  ++stats.passCnt;
136  }
137  else
138  {
139  sTag = FailTag;
140  }
141 
142  printTestResult(sTag, "Read raw IMU data");
143 
144  printf("\n");
145  printf(" %s\n", strIdent.c_str());
146  printf("\n");
147 
148  return stats;
149 }
150 
151 static DiagStats readImu(LaeImuCleanFlight &imu, int cnt)
152 {
153  double accel[NumOfAxes];
154  double gyro[NumOfAxes];
155  double mag[NumOfAxes];
156  double rpy[NumOfAxes];
157  Quaternion q;
158  bool showLabel;
159 
160  DiagStats stats;
161 
162  showLabel = cnt == 0;
163 
164  ++stats.testCnt;
165 
166  imu.getImuData(accel, gyro, mag, rpy, q);
167 
168  ++stats.passCnt;
169 
170  if( showLabel )
171  {
172  printf("%7s %34s | %34s | %34s\n",
173  "",
174  // 1234567890123456789012345678901234 567890
175  " accel[x,y,z] (meters/s^2) ",
176  " gyro[x,y,z] (radians/s) ",
177  " rpy[roll,pitch,yaw] (radians) ");
178  }
179 
180  printf("%6d. "
181  "%10.4lf, %10.4lf, %10.4lf | "
182  "%10.4lf, %10.4lf, %10.4lf | "
183  "%10.4lf, %10.4lf, %10.4lf\r",
184  cnt,
185  accel[X], accel[Y], accel[Z],
186  gyro[X], gyro[Y], gyro[Z],
187  rpy[ROLL], rpy[PITCH], rpy[YAW]);
188 
189  fflush(stdout);
190 
191  return stats;
192 }
193 
194 DiagStats runImuDiagnostics(bool bAnyKey)
195 {
196  LaeImuCleanFlight imu;
197  int cnt;
198  bool bQuit;
199  DiagStats statsTest;
200  DiagStats statsTotal;
201 
202  printHdr("Inertia Measurement Unit Diagnostics");
203 
204  //
205  // Init Tests
206  //
207  statsTest = initImu(imu);
208 
209  printSubTotals(statsTest);
210 
211  statsTotal += statsTest;
212 
213  //
214  // Read Information Tests
215  //
216  if( !statsTotal.fatal )
217  {
218  statsTest = readInfo(imu);
219 
220  printSubTotals(statsTest);
221 
222  statsTotal += statsTest;
223  }
224 
225  //
226  // Read Sensor Data Tests
227  //
228  statsTest.zero();
229  bQuit = statsTotal.fatal;
230  cnt = 0;
231 
232  printSubHdr("Read IMU Sensor Data");
233 
234  while( !bQuit )
235  {
236  imu.exec();
237 
238  statsTest += readImu(imu, cnt++);
239 
240  if( !bAnyKey || kbhit() || statsTest.fatal )
241  {
242  printf("\n");
243  printSubTotals(statsTest);
244  bQuit = true;
245  }
246  else
247  {
248  usleep(100000);
249  }
250  }
251 
252  statsTotal += statsTest;
253 
254  //
255  // Summary
256  //
257  printTotals(statsTotal);
258 
259  return statsTotal;
260 }
Diagnotics header file.
virtual int open(const std::string &strDevName, int nBaudRate)
Definition: laeImu.cxx:162
virtual int readRawImu()
Read sensor and board raw IMU values.
Definition: laeImu.cxx:401
Multiwii Serial Protocal Interface.
Definition: laeImu.h:598
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
void zero()
Zero statistics.
Definition: laelaps_diag.h:131
The <b><i>Laelaps</i></b> namespace encapsulates all <b><i>Laelaps</i></b> related constructs...
Definition: laeAlarms.h:64
Simple diagnostics statistics class.
Definition: laelaps_diag.h:106
const int NumOfAxes
maximum number of axes per sensor component.
Definition: laeImu.h:98
Laelaps common utilities.
Laelaps built-in Inertial Measurement Unit class interface.
std::string getIdentity()
Get IMU identity.
Definition: laeImu.h:387
Laelaps system devices.
Quaternion class.
Definition: laeImu.h:118
virtual void exec()
Exectute one step to read, convert, and compute IMU values.
Definition: laeImu.cxx:285
virtual int readIdentity(std::string &strIdent)
Read sensor identity values.
Definition: laeImu.cxx:376
Top-level package include file.