unit-tests-live-zr300.cpp
Go to the documentation of this file.
1 // License: Apache 2.0. See LICENSE file in root directory.
2 // Copyright(c) 2015 Intel Corporation. All Rights Reserved.
3 
5 // This set of tests is valid only for the R200 camera //
7 
8 #if !defined(MAKEFILE) || ( defined(LIVE_TEST) && defined(ZR300_TEST) )
9 
10 #include "catch/catch.hpp"
11 
12 #include "librealsense/rs.hpp"
14 
15 #include <climits>
16 #include <sstream>
17 #include <numeric>
18 
19 static std::vector<rs::motion_data> accel_frames = {};
20 static std::vector<rs::motion_data> gyro_frames = {};
21 static std::vector<rs::timestamp_data> fisheye_timestamp_events = {};
22 static std::vector<rs::timestamp_data> depth_timestamp_events = {};
23 
25 {
26  // Collect data
27  if (rs_event_source::RS_EVENT_IMU_ACCEL == entry.timestamp_data.source_id)
28  {
29  accel_frames.push_back(entry);
30  }
31  if (rs_event_source::RS_EVENT_IMU_GYRO == entry.timestamp_data.source_id)
32  {
33  gyro_frames.push_back(entry);
34  }
35 };
36 
37 // ... and the timestamp packets (DS4.1/FishEye Frame, GPIOS...)
39 {
40  if (rs_event_source::RS_EVENT_IMU_MOTION_CAM == entry.source_id)
41  {
42  fisheye_timestamp_events.push_back(entry);
43  }
44  if (rs_event_source::RS_EVENT_IMU_DEPTH_CAM == entry.source_id)
45  {
46  depth_timestamp_events.push_back(entry);
47  }
48 };
49 
50 TEST_CASE("ZR300 devices support all required options", "[live] [DS-device]")
51 {
52  // Require at least one device to be plugged in
54  const int device_count = rs_get_device_count(ctx, require_no_error());
55  REQUIRE(device_count > 0);
56 
57  // For each device
58  for (int i = 0; i<device_count; ++i)
59  {
61  REQUIRE(dev != nullptr);
63 
65 
66  SECTION("ZR300 supports DS-Line standard UVC controls and ZR300 Motion Module controls, and nothing else")
67  {
68  const int supported_options[] = {
114  };
115 
116  for (int i = 0; i<RS_OPTION_COUNT; ++i)
117  {
118  if (std::find(std::begin(supported_options), std::end(supported_options), i) != std::end(supported_options))
119  {
121  }
122  else
123  {
125  }
126  }
127  }
128  }
129 }
130 
131 TEST_CASE("ZR300 Motion Module Data Streaming Validation", "[live] [DS-device]")
132 {
133  // Require only one device to be plugged in
135  const int device_count = rs_get_device_count(ctx, require_no_error());
136  REQUIRE(device_count == 1);
137 
138  // For each device
140  REQUIRE(dev != nullptr);
141 
143 
145 
146  unsigned int active_period_ms = 5000; // Time for the application to generate and collect data
147  const unsigned int gyro_bandwidth_fps = 200;
148  const unsigned int accel_bandwidth_fps = 250; // Predefined rate
149  const double allowed_deviation = 0.03; // The frame rates can vary within the predefined limit
150  const int video_fps = 60;
151 
152  for (int ii = 0; ii < 2; ii++)
153  {
154  INFO("Iteration num " << ii + 1 << " has started ");
155 
156  accel_frames.clear();
157  gyro_frames.clear();
158  fisheye_timestamp_events.clear();
159  depth_timestamp_events.clear();
160 
161  // Configure motion events callbacks
163 
164  // Configure which video streams need to active
165  rs_enable_stream(dev, RS_STREAM_DEPTH, 640, 480, RS_FORMAT_Z16, video_fps, require_no_error());
166  rs_enable_stream(dev, RS_STREAM_COLOR, 640, 480, RS_FORMAT_RGB8, video_fps, require_no_error());
167  rs_enable_stream(dev, RS_STREAM_INFRARED, 640, 480, RS_FORMAT_Y8, video_fps, require_no_error());
168  rs_enable_stream(dev, RS_STREAM_INFRARED2, 640, 480, RS_FORMAT_Y8, video_fps, require_no_error());
169  rs_enable_stream(dev, RS_STREAM_FISHEYE, 640, 480, RS_FORMAT_RAW8, video_fps, require_no_error());
170 
171  // Activate strobe to enforce timestamp events ( required by spec)
173 
174  // 3. Start generating motion-tracking data
176 
177  // Collect data for a while
178  std::this_thread::sleep_for(std::chrono::milliseconds(active_period_ms));
179 
180  // 4. stop data acquisition
182 
183  // 5. reset previous settings formotion data handlers
185 
186  // i. Sanity Tests
187  REQUIRE(accel_frames.size() > 0);
188  REQUIRE(gyro_frames.size() > 0);
189  REQUIRE(fisheye_timestamp_events.size() > 0);
190  REQUIRE(depth_timestamp_events.size() > 0);
191  INFO(gyro_frames.size() << " Gyro packets received over " << active_period_ms*0.001 << "sec sampling");
192  INFO(accel_frames.size() << " Accelerometer packets received");
193  INFO(fisheye_timestamp_events.size() << " Fisheye timestamp packets received");
194  INFO(depth_timestamp_events.size() << " Depth timestamp packets received");
195 
196  // Verify predefined frame rates
197  REQUIRE(gyro_frames.size() / (double)active_period_ms == Approx(gyro_bandwidth_fps).epsilon(gyro_bandwidth_fps*allowed_deviation));
198  REQUIRE(gyro_frames.size() / (double)active_period_ms == Approx(accel_bandwidth_fps).epsilon(accel_bandwidth_fps*allowed_deviation));
199 
200  REQUIRE(fisheye_timestamp_events.size() / (double)active_period_ms == Approx(video_fps).epsilon(video_fps*allowed_deviation));
201  REQUIRE(depth_timestamp_events.size() / (double)active_period_ms == Approx(video_fps).epsilon(video_fps*allowed_deviation));
202 
203  // ii. Verify that the recorded data
204  REQUIRE(std::all_of(accel_frames.begin(), accel_frames.end(), [](rs::motion_data const& entry) { return entry.timestamp_data.source_id == rs_event_source::RS_EVENT_IMU_ACCEL; }));
205  REQUIRE(std::all_of(gyro_frames.begin(), gyro_frames.end(), [](rs::motion_data const& entry) { return entry.timestamp_data.source_id == rs_event_source::RS_EVENT_IMU_GYRO; }));
206  REQUIRE(std::all_of(fisheye_timestamp_events.begin(), fisheye_timestamp_events.end(), [](rs::timestamp_data const& entry) { return entry.source_id == rs_event_source::RS_EVENT_IMU_MOTION_CAM; }));
207  REQUIRE(std::all_of(depth_timestamp_events.begin(), depth_timestamp_events.end(), [](rs::timestamp_data const& entry) { return entry.source_id == rs_event_source::RS_EVENT_IMU_DEPTH_CAM; }));
208 
209  // iii. Validate data consistency
210  for (size_t i = 0; i < (gyro_frames.size() - 1); i++)
211  REQUIRE(gyro_frames[i].timestamp_data.frame_number <= gyro_frames[i + 1].timestamp_data.frame_number);
212 
213  for (size_t i = 0; i < (accel_frames.size() - 1); i++)
214  REQUIRE(accel_frames[i].timestamp_data.frame_number <= accel_frames[i + 1].timestamp_data.frame_number);
215 
216  for (size_t i = 0; i < (fisheye_timestamp_events.size() - 1); i++)
217  REQUIRE(fisheye_timestamp_events[i].frame_number <= fisheye_timestamp_events[i + 1].frame_number);
218 
219  for (size_t i = 0; i < (depth_timestamp_events.size() - 1); i++)
220  REQUIRE(depth_timestamp_events[i].frame_number <= depth_timestamp_events[i + 1].frame_number);
221 
222  // Frame numbers statistics
223  std::vector<unsigned long long> gyro_frame_numbers, accel_frame_numbers, fisheye_frame_numbers, depth_cam_frame_numbers;
224  std::vector<unsigned long long> gyro_adjacent_diff, accel_adjacent_diff, fisheye_adjacent_diff, depth_adjacent_diff;
225 
226  // Extract the data
227  for (size_t i = 0; i < gyro_frames.size(); i++) gyro_frame_numbers.push_back(gyro_frames[i].timestamp_data.frame_number);
228  for (size_t i = 0; i < accel_frames.size(); i++) accel_frame_numbers.push_back(accel_frames[i].timestamp_data.frame_number);
229  for (size_t i = 0; i < fisheye_timestamp_events.size(); i++) fisheye_frame_numbers.push_back(fisheye_timestamp_events[i].frame_number);
230  for (size_t i = 0; i < depth_timestamp_events.size(); i++) depth_cam_frame_numbers.push_back(depth_timestamp_events[i].frame_number);
231 
232  gyro_adjacent_diff.resize(gyro_frame_numbers.size());
233  accel_adjacent_diff.resize(accel_frame_numbers.size());
234  fisheye_adjacent_diff.resize(fisheye_frame_numbers.size());
235  depth_adjacent_diff.resize(depth_cam_frame_numbers.size());
236 
237  std::adjacent_difference(gyro_frame_numbers.begin(), gyro_frame_numbers.end(), gyro_adjacent_diff.begin());
238  std::adjacent_difference(accel_frame_numbers.begin(), accel_frame_numbers.end(), accel_adjacent_diff.begin());
239  std::adjacent_difference(fisheye_frame_numbers.begin(), fisheye_frame_numbers.end(), fisheye_adjacent_diff.begin());
240  std::adjacent_difference(depth_cam_frame_numbers.begin(), depth_cam_frame_numbers.end(), depth_adjacent_diff.begin());
241  // Fix the value of the first cell
242  accel_adjacent_diff[0] = gyro_adjacent_diff[0] = fisheye_adjacent_diff[0] = depth_adjacent_diff[0] = 1;
243 
244  std::vector<unsigned int> gyro_frame_diff_bins, accel_frame_diff_bins, fisheye_frame_bins, depth_cam_frames_bins;
245  const uint32_t max_frame_diff_allowed = 100;
246  gyro_frame_diff_bins.resize(max_frame_diff_allowed); // Calculate the distribution of the frame number gaps up to 100 frames
247  accel_frame_diff_bins.resize(max_frame_diff_allowed); // Calculate the distribution of the frame number gaps up to 100 frames
248  fisheye_frame_bins.resize(max_frame_diff_allowed); // Calculate the distribution of the frame number gaps up to 100 frames
249  depth_cam_frames_bins.resize(max_frame_diff_allowed); // Calculate the distribution of the frame number gaps up to 100 frames
250 
251  // Calculate distribution
252  std::for_each(gyro_adjacent_diff.begin(), gyro_adjacent_diff.end(), [max_frame_diff_allowed, &gyro_frame_diff_bins](unsigned long n)
253  { REQUIRE(n < max_frame_diff_allowed); gyro_frame_diff_bins[n]++; });
254  std::for_each(accel_adjacent_diff.begin(), accel_adjacent_diff.end(), [max_frame_diff_allowed, &accel_frame_diff_bins](unsigned long n)
255  { REQUIRE(n < max_frame_diff_allowed); accel_frame_diff_bins[n]++; });
256  std::for_each(fisheye_adjacent_diff.begin(), fisheye_adjacent_diff.end(), [max_frame_diff_allowed, &fisheye_frame_bins](unsigned long n)
257  { REQUIRE(n < max_frame_diff_allowed); fisheye_frame_bins[n]++; });
258  std::for_each(depth_adjacent_diff.begin(), depth_adjacent_diff.end(), [max_frame_diff_allowed, &depth_cam_frames_bins](unsigned long n)
259  { REQUIRE(n < max_frame_diff_allowed); depth_cam_frames_bins[n]++; });
260 
261  // display the distributions
262  INFO(" gyro frame num differences: ");
263  for (size_t i = 0; i < gyro_frame_diff_bins.size(); i++) if (gyro_frame_diff_bins[i]) INFO("[" << i << " = " << gyro_frame_diff_bins[i] << "], ");
264  INFO(" accel frame num differences: ");
265  for (size_t i = 0; i < accel_frame_diff_bins.size(); i++) if (accel_frame_diff_bins[i]) INFO("[" << i << " = " << accel_frame_diff_bins[i] << "], ");
266  INFO(" fisheye frame num differences: ");
267  for (size_t i = 0; i < fisheye_frame_bins.size(); i++) if (fisheye_frame_bins[i]) INFO("[" << i << " = " << fisheye_frame_bins[i] << "], ");
268  INFO(" depth frame num differences: ");
269  for (size_t i = 0; i < depth_cam_frames_bins.size(); i++) if (depth_cam_frames_bins[i]) INFO("[" << i << " = " << depth_cam_frames_bins[i] << "], ");
270 
271  //Consecutive frames are those collected in bin 1
272  double gyro_consecutive_frames_percentage = gyro_frame_diff_bins[1] / (double)gyro_frames.size() * 100;
273  double accel_consecutive_frames_percentage = accel_frame_diff_bins[1] / (double)accel_frames.size() * 100;
274  double fisheye_consecutive_frames_percentage = fisheye_frame_bins[1] / (double)fisheye_timestamp_events.size() * 100;
275  double depth_consecutive_frames_percentage = depth_cam_frames_bins[1] / (double)depth_timestamp_events.size() * 100;
276 
277  INFO("Gyro frames- consecutive frames " << gyro_frame_diff_bins[1] << " out of " << gyro_frames.size() << ", consistency rate:" << gyro_consecutive_frames_percentage << "% \n"
278  << "Accel frames- consecutive frames " << accel_frame_diff_bins[1] << " out of " << accel_frames.size() << ", consistency rate:" << accel_consecutive_frames_percentage << "% \n"
279  << "Fisheye frames- consecutive frames " << fisheye_frame_bins[1] << " out of " << fisheye_timestamp_events.size() << ", consistency rate:" << fisheye_consecutive_frames_percentage << "% \n"
280  << "Depth frames- consecutive frames " << depth_cam_frames_bins[1] << " out of " << depth_timestamp_events.size() << ", consistency rate:" << depth_consecutive_frames_percentage << "% \n");
281 
282  }
283 }
284 
285 TEST_CASE("ZR300 correctly recognizes invalid options", "[live] [DS-device]")
286 {
288  REQUIRE(ctx.get_device_count() == 1);
289 
290  rs::device * dev = ctx.get_device(0);
291  REQUIRE(nullptr!=dev);
292 
293  const char * name = dev->get_name();
294  REQUIRE(ds_names[Intel_ZR300] == dev->get_name());
295 
296  int index = 0;
297  double val = 0;
298 
300  {
301  index = i;
302  try
303  {
304  rs::option opt = (rs::option)i;
305  dev->set_options(&opt,1, &val);
306  }
307  catch(...)
308  {
309  REQUIRE(i==index); // Each invoked option must throw exception
310  }
311  }
312 }
313 
314 TEST_CASE( "Test ZR300 streaming mode combinations", "[live] [ZR300] [one-camera]" )
315 {
317 
318  SECTION( "exactly one device is connected" )
319  {
320  int device_count = rs_get_device_count(ctx, require_no_error());
321  REQUIRE(device_count == 1);
322  }
323 
325  REQUIRE(dev != nullptr);
326 
327  SECTION( "device name is Intel RealSense ZR300" )
328  {
329  const char * name = rs_get_device_name(dev, require_no_error());
330  REQUIRE(name == std::string("Intel RealSense ZR300"));
331  }
332 
333  SECTION( "streaming with some configurations" )
334  {
335  test_streaming(dev, {
336  {RS_STREAM_DEPTH, 640, 480, RS_FORMAT_Z16, 60},
337  {RS_STREAM_COLOR, 640, 480, RS_FORMAT_RGB8, 60},
338  {RS_STREAM_INFRARED, 640, 480, RS_FORMAT_Y16, 60},
339  {RS_STREAM_INFRARED2, 640, 480, RS_FORMAT_Y16, 60},
340  {RS_STREAM_FISHEYE, 640, 480, RS_FORMAT_RAW8, 60}
341  });
342 
343  test_streaming(dev, {
344  {RS_STREAM_DEPTH, 640, 480, RS_FORMAT_Z16, 30},
345  {RS_STREAM_COLOR, 640, 480, RS_FORMAT_RGB8, 30},
346  {RS_STREAM_INFRARED, 640, 480, RS_FORMAT_Y16, 30},
347  {RS_STREAM_INFRARED2, 640, 480, RS_FORMAT_Y16, 30},
348  {RS_STREAM_FISHEYE, 640, 480, RS_FORMAT_RAW8, 30}
349  });
350  }
351 }
352 
353 #endif /* !defined(MAKEFILE) || ( defined(LIVE_TEST) && defined(ZR300_TEST) ) */
Provides convenience methods relating to devices.
Definition: rs.hpp:567
TEST_CASE("ZR300 devices support all required options","[live] [DS-device]")
int rs_supports(rs_device *device, rs_capabilities capability, rs_error **error)
Determines device capabilities.
Definition: rs.cpp:442
void rs_start_source(rs_device *device, rs_source source, rs_error **error)
Begins streaming on all enabled streams for this device.
Definition: rs.cpp:390
void rs_disable_motion_tracking(rs_device *device, rs_error **error)
Disables motion-tracking handlers.
Definition: rs.cpp:366
int rs_get_device_count(const rs_context *context, rs_error **error)
Determines number of connected devices.
Definition: rs.cpp:113
static std::vector< rs::motion_data > gyro_frames
GLsizei const GLchar *const * string
Definition: glext.h:683
Motion data from gyroscope and accelerometer from the microcontroller.
Definition: rs.hpp:295
#define REQUIRE(expr)
Definition: catch.hpp:9333
void rs_set_device_option(rs_device *device, rs_option option, double value, rs_error **error)
Sets the current value of a single option.
Definition: rs.cpp:712
Exposes librealsense functionality for C++ compilers.
const char * rs_get_device_name(const rs_device *device, rs_error **error)
Retrieves human-readable device model string.
Definition: rs.cpp:128
rs_option
Defines general configuration controls.
Definition: rs.h:128
GLdouble n
Definition: glext.h:1950
option
Defines general configuration controls.
Definition: rs.hpp:87
GLuint index
Definition: glext.h:655
Context.
Definition: rs.hpp:319
GLuint GLuint end
Definition: glext.h:111
int rs_device_supports_option(const rs_device *device, rs_option option, rs_error **error)
Determines if the device allows a specific option to be queried and set.
Definition: rs.cpp:182
auto timestamp_handler
typedef int(WINAPI *PFNWGLRELEASEPBUFFERDCARBPROC)(HPBUFFERARB hPbuffer
void test_streaming(rs_device *device, std::initializer_list< stream_mode > modes)
auto motion_handler
void rs_enable_stream(rs_device *device, rs_stream stream, int width, int height, rs_format format, int framerate, rs_error **error)
Enables a specific stream and requests specific properties.
Definition: rs.cpp:220
void rs_stop_source(rs_device *device, rs_source source, rs_error **error)
Ends data acquisition for the specified source providers.
Definition: rs.cpp:405
static std::vector< rs::timestamp_data > fisheye_timestamp_events
auto ctx
GLuint const GLchar * name
Definition: glext.h:655
static std::vector< rs::motion_data > accel_frames
rs_device * dev
rs_device * rs_get_device(rs_context *context, int index, rs_error **error)
Retrieves connected device by index.
Definition: rs.cpp:120
#define SECTION(name, description)
Definition: catch.hpp:9370
static std::vector< rs::timestamp_data > depth_timestamp_events
#define INFO(msg)
Definition: catch.hpp:9353
device * get_device(int index)
Definition: rs.hpp:354
Timestamp data from the motion microcontroller.
Definition: rs.hpp:288
int get_device_count() const
Definition: rs.hpp:343
Approx & epsilon(double newEpsilon)
Definition: catch.hpp:2155
GLuint GLfloat * val
Definition: glext.h:1490
static const std::vector< std::string > ds_names
void rs_enable_motion_tracking_cpp(rs_device *device, rs_motion_callback *motion_callback, rs_timestamp_callback *timestamp_callback, rs_error **error)
Enables and configures motion-tracking data handlers.
Definition: rs.cpp:352


librealsense
Author(s): Sergey Dorodnicov , Mark Horn , Reagan Lopez
autogenerated on Fri Mar 13 2020 03:16:18