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  std::cerr << "Shutting down on signal: CTRL-C" << std::endl;
89  doneG = true;
90  return TRUE;
91 }
92 #else
93 void signalHandler(int sig)
94 {
95  std::cerr << "Shutting down on signal: " << strsignal(sig) << std::endl;
96  doneG = true;
97 }
98 #endif
99 
100 void imuCallback(const imu::Header& header,
101  void *userDataP)
102 {
103  std::vector<imu::Sample>::const_iterator it = header.samples.begin();
104 
105  for(; it!=header.samples.end(); ++it) {
106 
107  const imu::Sample& s = *it;
108 
109  switch(s.type) {
110  case imu::Sample::Type_Accelerometer: accel_samples ++; break;
111  case imu::Sample::Type_Gyroscope: gyro_samples ++; break;
112  case imu::Sample::Type_Magnetometer: mag_samples ++; break;
113  }
114 
115  if (logFileP)
116  fprintf(logFileP, "%d %.6f %.6f %.6f %.6f\n",
117  s.type,
118  s.timeSeconds + 1e-6 * s.timeMicroSeconds,
119  s.x, s.y, s.z);
120  }
121 
122  if (-1 == sequence)
123  sequence = header.sequence;
124  else if ((sequence + 1) != header.sequence) {
125  const int32_t d = static_cast<int32_t> (header.sequence - (sequence + 1));
126  dropped += d;
127  }
128 
129  sequence = header.sequence;
130  messages ++;
131 }
132 
133 }; // anonymous
134 
135 int main(int argc,
136  char **argvPP)
137 {
138  std::string currentAddress = "10.66.171.21";
139  const char *logFileNameP = NULL;
140  uint32_t mtu = 7200;
141 
142 #if WIN32
143  SetConsoleCtrlHandler (signalHandler, TRUE);
144 #else
145  signal(SIGINT, signalHandler);
146 #endif
147 
148  //
149  // Parse args
150 
151  int c;
152 
153  while(-1 != (c = getopt(argc, argvPP, "a:f:m:v")))
154  switch(c) {
155  case 'a': currentAddress = std::string(optarg); break;
156  case 'f': logFileNameP = optarg; break;
157  case 'm': mtu = atoi(optarg); break;
158  default: usage(*argvPP); break;
159  }
160 
161  //
162  // Initialize communications.
163 
164  Channel *channelP = Channel::Create(currentAddress);
165  if (NULL == channelP) {
166  std::cerr << "Failed to establish communications with \"" << currentAddress << "\"" << std::endl;
167  return -1;
168  }
169 
170  //
171  // Query firmware version
172 
174 
175  Status status = channelP->getVersionInfo(v);
176  if (Status_Ok != status) {
177  std::cerr << "Failed to query sensor version: " << Channel::statusString(status) << std::endl;
178  goto clean_out;
179  }
180 
181  //
182  // Make sure firmware supports IMU
183 
184  if (v.sensorFirmwareVersion <= 0x0202) {
185  std::cerr << "IMU support requires sensor firmware version v2.3 or greater, sensor is " <<
186  "running v" << (v.sensorFirmwareVersion >> 8) << "." << (v.sensorFirmwareVersion & 0xff) << std::endl;
187  goto clean_out;
188  }
189 
190  //
191  // Turn off all streams by default
192 
193  status = channelP->stopStreams(Source_All);
194  if (Status_Ok != status) {
195  std::cerr << "Failed to stop streams: " << Channel::statusString(status) << std::endl;
196  goto clean_out;
197  }
198 
199  //
200  // Was logging requested ?
201 
202  if (NULL != logFileNameP) {
203 
204  //
205  // Open the log file
206 
207  logFileP = fopen(logFileNameP, "w+");
208  if (NULL == logFileP) {
209  std::cerr << "Failed to open \"" << logFileNameP << "\" for writing: " << strerror(errno) << std::endl;
210  goto clean_out;
211  }
212 
213  }
214 
215  //
216  // Change MTU
217 
218  status = channelP->setMtu(mtu);
219  if (Status_Ok != status) {
220  std::cerr << "Failed to set MTU to " << mtu << ": " << Channel::statusString(status) << std::endl;
221  goto clean_out;
222  }
223 
224  //
225  // Add callbacks
226 
227  channelP->addIsolatedCallback(imuCallback);
228 
229  //
230  // Start streaming
231 
232  status = channelP->startStreams(Source_Imu);
233  if (Status_Ok != status) {
234  std::cerr << "Failed to start streams: " << Channel::statusString(status) << std::endl;
235  goto clean_out;
236  }
237 
238  while(!doneG)
239  usleep(100000);
240 
241  //
242  // Stop streaming
243 
244  status = channelP->stopStreams(Source_All);
245  if (Status_Ok != status) {
246  std::cerr << "Failed to stop streams: " << Channel::statusString(status) << std::endl;
247  }
248 
249  //
250  // Report simple stats
251 
252  {
253  int64_t imu_total = accel_samples + gyro_samples + mag_samples;
254  if (imu_total > 0) {
255  std::cerr << "IMU samples : " <<
256  "total: " << imu_total << ", " <<
257  "accel: " << std::fixed << std::setprecision(1) << (100.0 * static_cast<double>(accel_samples) / static_cast<double>(imu_total)) << "%, " <<
258  "gyro: " << std::fixed << std::setprecision(1) << (100.0 * static_cast<double>(gyro_samples) / static_cast<double>(imu_total)) << "%, " <<
259  "mag: " << std::fixed << std::setprecision(1) << (100.0 * static_cast<double>(mag_samples) / static_cast<double>(imu_total)) << "%" << std::endl;
260  }
261 
262  if (messages > 0)
263  std::cerr << "IMU messages: total: " << messages << ", " <<
264  "dropped: " << dropped << "(" << std::fixed << std::setprecision(6) << (100* static_cast<double>(dropped) / static_cast<double>(messages+dropped)) << "%)" << std::endl;
265  }
266 
267 clean_out:
268 
269  if (logFileNameP)
270  fclose(logFileP);
271 
272  Channel::Destroy(channelP);
273  return 0;
274 }
virtual Status startStreams(DataSource mask)=0
d
static CRL_CONSTEXPR Type Type_Accelerometer
static const char * statusString(Status status)
Definition: channel.cc:609
std::vector< Sample > samples
virtual Status stopStreams(DataSource mask)=0
static Channel * Create(const std::string &sensorAddress)
Definition: channel.cc:583
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:34
virtual Status addIsolatedCallback(image::Callback callback, DataSource imageSourceMask, void *userDataP=NULL)=0
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:596
char * optarg
Definition: getopt.c:32
static CRL_CONSTEXPR Type Type_Gyroscope
static CRL_CONSTEXPR DataSource Source_All


multisense_lib
Author(s):
autogenerated on Sat Apr 6 2019 02:16:46