ImuTestUtility.cc
Go to the documentation of this file.
1 
37 #ifdef WIN32
38 #ifndef WIN32_LEAN_AND_MEAN
39 #define WIN32_LEAN_AND_MEAN 1
40 #endif
41 
42 #include <windows.h>
43 #include <winsock2.h>
44 #else
45 #include <unistd.h>
46 #endif
47 
48 #include <stdio.h>
49 #include <stdlib.h>
50 #include <signal.h>
51 #include <string.h>
52 #include <errno.h>
53 #include <iostream>
54 #include <iomanip>
55 
58 
60 
61 using namespace crl::multisense;
62 
63 namespace { // anonymous
64 
65 volatile bool doneG = false;
66 FILE* logFileP = stdout;
67 uint32_t accel_samples = 0;
68 uint32_t gyro_samples = 0;
69 uint32_t mag_samples = 0;
70 int64_t sequence = -1;
71 uint32_t messages = 0;
72 uint32_t dropped = 0;
73 
74 void usage(const char *programNameP)
75 {
76  std::cerr << "USAGE: " << programNameP << " [<options>]" << std::endl;
77  std::cerr << "Where <options> are:" << std::endl;
78  std::cerr << "\t-a <ip_address> : IPV4 address (default=10.66.171.21)" << std::endl;
79  std::cerr << "\t-m <mtu> : default=7200" << std::endl;
80  std::cerr << "\t-f <log_file> : FILE to log IMU data (stdout by default)" << std::endl;
81 
82  exit(1);
83 }
84 
85 #ifdef WIN32
86 BOOL WINAPI signalHandler(DWORD dwCtrlType)
87 {
88  CRL_UNUSED (dwCtrlType);
89  std::cerr << "Shutting down on signal: CTRL-C" << std::endl;
90  doneG = true;
91  return TRUE;
92 }
93 #else
94 void signalHandler(int sig)
95 {
96  std::cerr << "Shutting down on signal: " << strsignal(sig) << std::endl;
97  doneG = true;
98 }
99 #endif
100 
101 void imuCallback(const imu::Header& header,
102  void *userDataP)
103 {
104  (void) userDataP;
105  std::vector<imu::Sample>::const_iterator it = header.samples.begin();
106 
107  for(; it!=header.samples.end(); ++it) {
108 
109  const imu::Sample& s = *it;
110 
111  switch(s.type) {
112  case imu::Sample::Type_Accelerometer: accel_samples ++; break;
113  case imu::Sample::Type_Gyroscope: gyro_samples ++; break;
114  case imu::Sample::Type_Magnetometer: mag_samples ++; break;
115  }
116 
117  if (logFileP)
118  fprintf(logFileP, "%d %.6f %.6f %.6f %.6f\n",
119  s.type,
120  s.timeSeconds + 1e-6 * s.timeMicroSeconds,
121  s.x, s.y, s.z);
122  }
123 
124  if (-1 == sequence)
125  sequence = header.sequence;
126  else if ((sequence + 1) != header.sequence) {
127  const int32_t d = static_cast<int32_t> (header.sequence - (sequence + 1));
128  dropped += d;
129  }
130 
131  sequence = header.sequence;
132  messages ++;
133 }
134 
135 } // anonymous
136 
137 int main(int argc,
138  char **argvPP)
139 {
140  std::string currentAddress = "10.66.171.21";
141  const char *logFileNameP = NULL;
142  uint32_t mtu = 7200;
143 
144 #if WIN32
145  SetConsoleCtrlHandler (signalHandler, TRUE);
146 #else
147  signal(SIGINT, signalHandler);
148 #endif
149 
150  //
151  // Parse args
152 
153  int c;
154 
155  while(-1 != (c = getopt(argc, argvPP, "a:f:m:v")))
156  switch(c) {
157  case 'a': currentAddress = std::string(optarg); break;
158  case 'f': logFileNameP = optarg; break;
159  case 'm': mtu = atoi(optarg); break;
160  default: usage(*argvPP); break;
161  }
162 
163  //
164  // Initialize communications.
165 
166  Channel *channelP = Channel::Create(currentAddress);
167  if (NULL == channelP) {
168  std::cerr << "Failed to establish communications with \"" << currentAddress << "\"" << std::endl;
169  return -1;
170  }
171 
172  //
173  // Query firmware version
174 
176 
177  Status status = channelP->getVersionInfo(v);
178  if (Status_Ok != status) {
179  std::cerr << "Failed to query sensor version: " << Channel::statusString(status) << std::endl;
180  goto clean_out;
181  }
182 
183  //
184  // Make sure firmware supports IMU
185 
186  if (v.sensorFirmwareVersion <= 0x0202) {
187  std::cerr << "IMU support requires sensor firmware version v2.3 or greater, sensor is " <<
188  "running v" << (v.sensorFirmwareVersion >> 8) << "." << (v.sensorFirmwareVersion & 0xff) << std::endl;
189  goto clean_out;
190  }
191 
192  //
193  // Turn off all streams by default
194 
195  status = channelP->stopStreams(Source_All);
196  if (Status_Ok != status) {
197  std::cerr << "Failed to stop streams: " << Channel::statusString(status) << std::endl;
198  goto clean_out;
199  }
200 
201  //
202  // Was logging requested ?
203 
204  if (NULL != logFileNameP) {
205 
206  //
207  // Open the log file
208 
209  logFileP = fopen(logFileNameP, "w+");
210  if (NULL == logFileP) {
211  std::cerr << "Failed to open \"" << logFileNameP << "\" for writing: " << strerror(errno) << std::endl;
212  goto clean_out;
213  }
214 
215  }
216 
217  //
218  // Change MTU
219 
220  status = channelP->setMtu(mtu);
221  if (Status_Ok != status) {
222  std::cerr << "Failed to set MTU to " << mtu << ": " << Channel::statusString(status) << std::endl;
223  goto clean_out;
224  }
225 
226  //
227  // Add callbacks
228 
229  channelP->addIsolatedCallback(imuCallback);
230 
231  //
232  // Start streaming
233 
234  status = channelP->startStreams(Source_Imu);
235  if (Status_Ok != status) {
236  std::cerr << "Failed to start streams: " << Channel::statusString(status) << std::endl;
237  goto clean_out;
238  }
239 
240  while(!doneG)
241  usleep(100000);
242 
243  //
244  // Stop streaming
245 
246  status = channelP->stopStreams(Source_All);
247  if (Status_Ok != status) {
248  std::cerr << "Failed to stop streams: " << Channel::statusString(status) << std::endl;
249  }
250 
251  //
252  // Report simple stats
253 
254  {
255  int64_t imu_total = accel_samples + gyro_samples + mag_samples;
256  if (imu_total > 0) {
257  std::cerr << "IMU samples : " <<
258  "total: " << imu_total << ", " <<
259  "accel: " << std::fixed << std::setprecision(1) << (100.0 * static_cast<double>(accel_samples) / static_cast<double>(imu_total)) << "%, " <<
260  "gyro: " << std::fixed << std::setprecision(1) << (100.0 * static_cast<double>(gyro_samples) / static_cast<double>(imu_total)) << "%, " <<
261  "mag: " << std::fixed << std::setprecision(1) << (100.0 * static_cast<double>(mag_samples) / static_cast<double>(imu_total)) << "%" << std::endl;
262  }
263 
264  if (messages > 0)
265  std::cerr << "IMU messages: total: " << messages << ", " <<
266  "dropped: " << dropped << "(" << std::fixed << std::setprecision(6) << (100* static_cast<double>(dropped) / static_cast<double>(messages+dropped)) << "%)" << std::endl;
267  }
268 
269 clean_out:
270 
271  if (logFileNameP)
272  fclose(logFileP);
273 
274  Channel::Destroy(channelP);
275  return 0;
276 }
virtual Status startStreams(DataSource mask)=0
d
static CRL_CONSTEXPR Type Type_Accelerometer
static const char * statusString(Status status)
Definition: channel.cc:649
std::vector< Sample > samples
virtual Status stopStreams(DataSource mask)=0
static Channel * Create(const std::string &sensorAddress)
Definition: channel.cc:623
int main(int argc, char **argvPP)
static CRL_CONSTEXPR Type Type_Magnetometer
virtual Status getVersionInfo(system::VersionInfo &v)=0
int getopt(int argc, char **argv, char *opts)
Definition: getopt.c:31
virtual Status addIsolatedCallback(image::Callback callback, DataSource imageSourceMask, void *userDataP=NULL)=0
#define CRL_UNUSED(var)
Definition: Portability.hh:44
static CRL_CONSTEXPR DataSource Source_Imu
static CRL_CONSTEXPR Status Status_Ok
virtual Status setMtu(int32_t mtu)=0
def usage(progname)
static void Destroy(Channel *instanceP)
Definition: channel.cc:636
char * optarg
Definition: getopt.c:29
static CRL_CONSTEXPR Type Type_Gyroscope
static CRL_CONSTEXPR DataSource Source_All


multisense_lib
Author(s):
autogenerated on Sun Mar 14 2021 02:34:50