rs-data-collect.h
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 // The utility shall be used to collect and analyze Realsense Cameras performance.
4 // Therefore no UI is provided, and the data is gathered and serialized in csv-compatible format for offline analysis.
5 // The utility is configured via command-line parameters and requires user-provided configuration file to run
6 // The following lines provide examples of the configurations available
7 /*
8 //Defines the order at which the params (comma-separated) should appear in configuration file
9 //#rs2_stream, width, height, fps, rs2_format, stream_index (optional, put zero or leave empty if you're not sure)
10 //# Examples (note that all lines starting with non-alpha character (#@!...) will be skipped:
11 #D435/415
12 DEPTH,640,480,30,Z16,0
13 INFRARED,640,480,30,Y8,1
14 INFRARED,640,480,30,Y8,2
15 COLOR,640,480,30,RGB8,0
16 ##D435i-specific
17 ACCEL,1,1,63,MOTION_XYZ32F
18 GYRO,1,1,200,MOTION_XYZ32F
19 #T265
20 #FISHEYE,848,800,30,Y8,1
21 #FISHEYE,848,800,30,Y8,2
22 #ACCEL,1,1,62,MOTION_XYZ32F,0
23 #GYRO,1,1,200,MOTION_XYZ32F,0
24 #POSE,0,0,262,6DOF,0
25 */
26 
27 #include <librealsense2/rs.hpp>
28 #include "tclap/CmdLine.h"
29 #include <fstream>
30 #include <sstream>
31 #include <map>
32 
33 
34 using namespace std;
35 using namespace TCLAP;
36 
37 namespace rs_data_collect
38 {
40  const std::string DEF_OUTPUT_FILE_NAME("frames_data.csv");
41 
42  // Split string into token, trim unreadable characters
43  inline std::vector<std::string> tokenize(std::string line, char separator)
44  {
45  std::vector<std::string> tokens;
46 
47  // Remove trailing characters
48  line.erase(line.find_last_not_of("\t\n\v\r ") + 1);
49 
50  stringstream ss(line);
51  while (ss.good())
52  {
53  string substr;
54  getline(ss, substr, separator);
55  tokens.push_back(substr);
56  }
57 
58  return tokens;
59  }
60 
61  struct stringify
62  {
63  std::ostringstream ss;
64  template<class T> stringify & operator << (const T & val) { ss << val; return *this; }
65  operator std::string() const { return ss.str(); }
66  };
67 
68  template <typename T>
69  inline bool val_in_range(const T& val, const std::initializer_list<T>& list)
70  {
71  for (const auto& i : list) {
72  if (val == i) {
73  return true;
74  }
75  }
76  return false;
77  }
78 
79  inline int parse_number(char const *s, int base = 0)
80  {
81  char c;
82  stringstream ss(s);
83  int i;
84  ss >> i;
85 
86  if (ss.fail() || ss.get(c))
87  {
88  throw runtime_error(string(string("Invalid numeric input - ") + s + string("\n")));
89  }
90  return i;
91  }
92 
94  {
95  auto copy = s;
96  std::transform(copy.begin(), copy.end(), copy.begin(), ::tolower);
97  return copy;
98  }
99 
100  inline rs2_format parse_format(const string str)
101  {
102  for (int i = RS2_FORMAT_ANY; i < RS2_FORMAT_COUNT; i++)
103  {
105  {
106  return (rs2_format)i;
107  }
108  }
109  throw runtime_error((string("Invalid format - ") + str + string("\n")).c_str());
110  }
111 
112  inline rs2_stream parse_stream_type(const string str)
113  {
114  for (int i = RS2_STREAM_ANY; i < RS2_STREAM_COUNT; i++)
115  {
117  {
118  return static_cast<rs2_stream>(i);
119  }
120  }
121  throw runtime_error((string("Invalid stream type - ") + str + string("\n")).c_str());
122  }
123 
124  inline int parse_fps(const string str)
125  {
126  return parse_number(str.c_str());
127  }
128 
130  {
131  std::stringstream ss;
132 
133  ss << profile.stream_name() << ","
134  << profile.stream_type() << ","
135  << profile.format() << ","
136  << profile.fps();
137 
138  if (auto vp = profile.as<rs2::video_stream_profile>())
139  ss << "," << vp.width() << "," << vp.height();
140 
141  ss << std::endl;
142  return ss.str().c_str();
143  }
144 
146  {
149  int _width;
150  int _height;
151  int _fps;
153  };
154 
155  inline std::ostream& operator<<(std::ostream& os, const stream_request& req)
156  {
157  return os << "Type: " << req._stream_type << ", Idx: " << req._stream_idx << ", "
158  << req._stream_format << ", [" << req._width << "x" << req._height << "], " << req._fps << "fps" << std::endl;
159  }
160 
168  };
169 
175  };
176 
178  {
179  public:
180  data_collector(std::shared_ptr<rs2::device> dev,
181  ValueArg<int>& timeout, ValueArg<int>& max_frames);
184 
185  void parse_and_configure(ValueArg<string>& config_file);
186  void save_data_to_file(const string& out_filename);
187  void collect_frame_attributes(rs2::frame f, std::chrono::time_point<std::chrono::high_resolution_clock> start_time);
188  bool collecting(std::chrono::time_point<std::chrono::high_resolution_clock> start_time);
189 
190  const std::vector<rs2::sensor>& selected_sensors() const { return active_sensors; };
191 
193  {
194  frame_record(unsigned long long frame_number, double frame_ts, double host_ts,
195  rs2_timestamp_domain domain, rs2_stream stream_type,int stream_index,
196  double _p1=0., double _p2=0., double _p3=0.,
197  double _p4=0., double _p5=0., double _p6=0., double _p7=0.):
198  _frame_number(frame_number),
199  _ts(frame_ts),
200  _arrival_time(host_ts),
201  _domain(domain),
202  _stream_type(stream_type),
203  _stream_idx(stream_index),
204  _params({_p1,_p2,_p3,_p4,_p5,_p6,_p7})
205  {};
206 
208  {
209  std::stringstream ss;
210  ss << std::endl
211  << rs2_stream_to_string(_stream_type) << ","
212  << _stream_idx << "," << _frame_number << ","
213  << std::fixed << std::setprecision(3) << _ts << "," << _arrival_time;
214 
215  // IMU and Pose frame hold the sample data in addition to the frame's header attributes
216  size_t specific_attributes = 0;
217  if (val_in_range(_stream_type,{RS2_STREAM_GYRO,RS2_STREAM_ACCEL}))
218  specific_attributes = 3;
219  if (val_in_range(_stream_type,{RS2_STREAM_POSE}))
220  specific_attributes = 7;
221 
222  for (auto i=0; i<specific_attributes; i++)
223  ss << "," << _params[i];
224 
225  return ss.str().c_str();
226  }
227 
228  unsigned long long _frame_number;
229  double _ts; // Device-based timestamp. (msec).
230  double _arrival_time; // Host arrival timestamp, relative to start streaming (msec)
231  rs2_timestamp_domain _domain; // The origin of device-based timestamp. Note that Device timestamps may require kernel patches
234  std::array<double,7> _params; // |The parameters are optional and sensor specific
235  };
236 
237  private:
238 
239  std::shared_ptr<rs2::device> _dev;
240  std::map<std::pair<rs2_stream, int>, std::vector<frame_record>> data_collection;
241  std::vector<stream_request> requests_to_go, user_requests;
242  std::vector<rs2::sensor> active_sensors;
243  std::vector<rs2::stream_profile> selected_stream_profiles;
247 
248  bool parse_configuration(const std::string& line, const std::vector<std::string>& tokens,
249  rs2_stream& type, int& width, int& height, rs2_format& format, int& fps, int& index);
250 
251  // Assign the user configuration to the selected device
252  bool configure_sensors();
253  };
254 }
const char * rs2_format_to_string(rs2_format format)
Definition: rs.cpp:1263
int parse_number(char const *s, int base=0)
std::string to_lower(std::string x)
Definition: parser.hpp:217
GLdouble s
std::vector< std::string > tokenize(std::string line, char separator)
std::vector< rs2::sensor > active_sensors
std::ostream & operator<<(std::ostream &os, const stream_request &req)
std::string stream_name() const
Definition: rs_frame.hpp:113
GLsizei const GLchar *const * string
unsigned char uint8_t
Definition: stdint.h:78
std::string get_profile_description(const rs2::stream_profile &profile)
GLuint index
GLuint GLfloat * val
frame_record(unsigned long long frame_number, double frame_ts, double host_ts, rs2_timestamp_domain domain, rs2_stream stream_type, int stream_index, double _p1=0., double _p2=0., double _p3=0., double _p4=0., double _p5=0., double _p6=0., double _p7=0.)
GLdouble f
rs2_stream parse_stream_type(const string str)
const GLubyte * c
Definition: glext.h:12690
std::vector< rs2::stream_profile > selected_stream_profiles
std::map< std::pair< rs2_stream, int >, std::vector< frame_record > > data_collection
GLint GLsizei GLsizei height
int parse_fps(const string str)
GLint GLint GLsizei GLint GLenum format
unsigned __int64 uint64_t
Definition: stdint.h:90
rs2_format
A stream&#39;s format identifies how binary data is encoded within a frame.
Definition: rs_sensor.h:59
rs2_format parse_format(const string str)
rs2_stream
Streams are different types of data provided by RealSense devices.
Definition: rs_sensor.h:42
rs2_format format() const
Definition: rs_frame.hpp:44
const char * rs2_stream_to_string(rs2_stream stream)
Definition: rs.cpp:1262
GLbitfield GLuint64 timeout
GLenum type
signed __int64 int64_t
Definition: stdint.h:89
const std::string DEF_OUTPUT_FILE_NAME("frames_data.csv")
bool val_in_range(const T &val, const std::initializer_list< T > &list)
std::shared_ptr< rs2::device > _dev
int i
std::vector< stream_request > user_requests
GLuint GLenum GLenum transform
Definition: glext.h:11553
const uint64_t DEF_FRAMES_NUMBER
Definition: Arg.h:57
const std::vector< rs2::sensor > & selected_sensors() const
rs2_stream stream_type() const
Definition: rs_frame.hpp:39
int fps() const
Definition: rs_frame.hpp:49
GLint GLsizei width
void copy(void *dst, void const *src, size_t size)
Definition: types.cpp:836
rs2_timestamp_domain
Specifies the clock in relation to which the frame timestamp was measured.
Definition: rs_frame.h:19


librealsense2
Author(s): Sergey Dorodnicov , Doron Hirshberg , Mark Horn , Reagan Lopez , Itay Carpis
autogenerated on Mon May 3 2021 02:47:40