rs-terminal.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 
4 #include <librealsense2/rs.hpp>
5 #include <iostream>
6 #include <fstream>
7 
8 #include "tclap/CmdLine.h"
9 #include "parser.hpp"
10 #include "auto-complete.h"
11 
12 #include <string>
13 
14 
15 using namespace std;
16 using namespace TCLAP;
17 
18 
19 vector<uint8_t> build_raw_command_data(const command& command, const vector<string>& params)
20 {
21  if (params.size() > command.parameters.size() && !command.is_cmd_write_data)
22  throw runtime_error("Input string was not in a correct format!");
23 
24  vector<parameter> vec_parameters;
25  for (auto param_index = 0; param_index < params.size(); ++param_index)
26  {
27  auto is_there_write_data = param_index >= int(command.parameters.size());
28  auto name = (is_there_write_data) ? "" : command.parameters[param_index].name;
29  auto is_reverse_bytes = (is_there_write_data) ? false : command.parameters[param_index].is_reverse_bytes;
30  auto is_decimal = (is_there_write_data) ? false : command.parameters[param_index].is_decimal;
31  auto format_length = (is_there_write_data) ? -1 : command.parameters[param_index].format_length;
32  vec_parameters.push_back(parameter(name, params[param_index], is_decimal, is_reverse_bytes, format_length));
33  }
34 
35  vector<uint8_t> raw_data;
36  encode_raw_data_command(command, vec_parameters, raw_data);
37  return raw_data;
38 }
39 
40 void xml_mode(const string& line, const commands_xml& cmd_xml, rs2::device& dev, map<string, xml_parser_function>& format_type_to_lambda)
41 {
42  vector<string> tokens;
43  stringstream ss(line);
44  string word;
45  while (ss >> word)
46  {
47  stringstream converter;
48  converter << hex << word;
49  tokens.push_back(word);
50  }
51 
52  if (tokens.empty())
53  throw runtime_error("Wrong input!");
54 
55  auto command_str = tokens.front();
56  auto it = cmd_xml.commands.find(command_str);
57  if (it == cmd_xml.commands.end())
58  throw runtime_error("Command not found!");
59 
60  auto command = it->second;
61  vector<string> params;
62  for (auto i = 1; i < tokens.size(); ++i)
63  params.push_back(tokens[i]);
64 
65  auto raw_data = build_raw_command_data(command, params);
66 
67  for (auto b : raw_data)
68  {
69  cout << hex << fixed << setfill('0') << setw(2) << (int)b << " ";
70  }
71  cout << endl;
72 
73  auto result = dev.as<rs2::debug_protocol>().send_and_receive_raw_data(raw_data);
74 
75  unsigned returned_opcode = *result.data();
76  // check returned opcode
77  if (command.op_code != returned_opcode)
78  {
79  stringstream msg;
80  msg << "OpCodes do not match! Sent 0x" << hex << command.op_code << " but received 0x" << hex << (returned_opcode) << "!";
81  throw runtime_error(msg.str());
82  }
83 
85  {
86  string data;
87  decode_string_from_raw_data(command, cmd_xml.custom_formatters, result.data(), result.size(), data, format_type_to_lambda);
88  cout << endl << data << endl;
89  }
90  else
91  {
92  cout << endl << "Done!" << endl;
93  }
94 }
95 
96 void hex_mode(const string& line, rs2::device& dev)
97 {
98  vector<uint8_t> raw_data;
99  stringstream ss(line);
100  string word;
101  while (ss >> word)
102  {
103  stringstream converter;
104  int temp;
105  converter << hex << word;
106  converter >> temp;
107  raw_data.push_back(temp);
108  }
109  if (raw_data.empty())
110  throw runtime_error("Wrong input!");
111 
112  auto result = dev.as<rs2::debug_protocol>().send_and_receive_raw_data(raw_data);
113 
114  cout << endl;
115  for (auto& elem : result)
116  cout << setfill('0') << setw(2) << hex << static_cast<int>(elem) << " ";
117 }
118 
119 auto_complete get_auto_complete_obj(bool is_application_in_hex_mode, const map<string, command>& commands_map)
120 {
121  set<string> commands;
122  if (!is_application_in_hex_mode)
123  {
124  for (auto& elem : commands_map)
125  commands.insert(elem.first);
126  }
127  return auto_complete(commands, is_application_in_hex_mode);
128 }
129 
130 void read_script_file(const string& full_file_path, vector<string>& hex_lines)
131 {
132  ifstream myfile(full_file_path);
133  if (myfile.is_open())
134  {
135  string line;
136  while (getline(myfile, line))
137  hex_lines.push_back(line);
138 
139  myfile.close();
140  return;
141  }
142  throw runtime_error("Script file not found!");
143 }
144 
146 {
147  if (print_info)
148  cout << "\nWaiting for RealSense device to connect...\n";
149 
150  auto dev = hub.wait_for_device();
151 
152  if (print_info)
153  cout << "RealSense device has connected...\n";
154 
155  return dev;
156 }
157 
158 int main(int argc, char** argv)
159 {
160  CmdLine cmd("librealsense rs-terminal example tool", ' ', RS2_API_VERSION_STR);
161  ValueArg<string> xml_arg("l", "load", "Full file path of commands XML file", false, "", "Load commands XML file");
162  ValueArg<int> device_id_arg("d", "deviceId", "Device ID could be obtain from rs-enumerate-devices example", false, 0, "Select a device to work with");
163  ValueArg<string> specific_SN_arg("n", "serialNum", "Serial Number can be obtain from rs-enumerate-devices example", false, "", "Select a device serial number to work with");
164  SwitchArg all_devices_arg("a", "allDevices", "Do this command to all attached Realsense Devices", false);
165  ValueArg<string> hex_cmd_arg("s", "send", "Hexadecimal raw data", false, "", "Send hexadecimal raw data to device");
166  ValueArg<string> hex_script_arg("r", "raw", "Full file path of hexadecimal raw data script", false, "", "Send raw data line by line from script file");
167  ValueArg<string> commands_script_arg("c", "cmd", "Full file path of commands script", false, "", "Send commands line by line from script file");
168  cmd.add(xml_arg);
169  cmd.add(device_id_arg);
170  cmd.add(specific_SN_arg);
171  cmd.add(all_devices_arg);
172  cmd.add(hex_cmd_arg);
173  cmd.add(hex_script_arg);
174  cmd.add(commands_script_arg);
175  cmd.parse(argc, argv);
176 
177  // parse command.xml
178  rs2::log_to_file(RS2_LOG_SEVERITY_WARN, "librealsense.log");
179  // Obtain a list of devices currently present on the system
181  rs2::device_hub hub(ctx);
182  rs2::device_list all_device_list = ctx.query_devices();
183  if (all_device_list.size() == 0) {
184  std::cout << "\nLibrealsense is not detecting any devices" << std::endl;
185  return EXIT_FAILURE;
186  };
187 
188  std::vector<rs2::device> rs_device_list;
189  //Ensure that diviceList only has realsense devices in it. tmpList contains webcams as well
190  for (size_t i = 0; i < all_device_list.size(); i++) {
191  try {
192  all_device_list[i].get_info(RS2_CAMERA_INFO_FIRMWARE_VERSION);
193  rs_device_list.push_back(all_device_list[i]);
194  }
195  catch (...) {
196  continue;
197  }
198 
199  }
200  auto num_rs_devices = rs_device_list.size();
201  if (rs_device_list.size() == 0) {
202  std::cout << "\nLibrealsense is not detecting any Realsense cameras" << std::endl;
203  return EXIT_FAILURE;
204  };
205 
206  auto xml_full_file_path = xml_arg.getValue();
207  map<string, xml_parser_function> format_type_to_lambda;
208  commands_xml cmd_xml;
209  auto is_application_in_hex_mode = true;
210 
211  if (!xml_full_file_path.empty())
212  {
213  auto sts = parse_xml_from_file(xml_full_file_path, cmd_xml);
214  if (!sts)
215  {
216  cout << "Provided XML not found!\n";
217  return EXIT_FAILURE;
218  }
219 
220  update_format_type_to_lambda(format_type_to_lambda);
221  is_application_in_hex_mode = false;
222  cout << "Commands XML file - " << xml_full_file_path << " was loaded successfully. Type commands by name (e.g.'gvd'`).\n";
223  }
224  else
225  {
226  cout << "Commands XML file not provided.\nyou still can send raw data to device in hexadecimal\nseparated by spaces.\n";
227  cout << "Example GVD command for the SR300:\n14 00 ab cd 3b 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00\n";
228  cout << "Example GVD command for the RS4xx:\n14 00 ab cd 10 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00\n";
229  }
230  auto auto_comp = get_auto_complete_obj(is_application_in_hex_mode, cmd_xml.commands);
231 
232 
233  std::vector<rs2::device> selected_rs_devices;
234  while (true)
235  {
236  if (all_devices_arg.isSet()) {
237  for (size_t i = 0; i < num_rs_devices; i++) {
239  selected_rs_devices.push_back(rs_device_list[i]);
240  std::cout << "\nDevice with Serial Number: " << rs_device_list[i].get_info(RS2_CAMERA_INFO_SERIAL_NUMBER) << " has loaded.\n";
241  }
242  }
243  else if (specific_SN_arg.isSet()) {
244  auto desired_sn = specific_SN_arg.getValue();
245  bool device_not_found = true;
246  for (size_t i = 0; i < num_rs_devices; i++) {
247  std::string device_sn = std::string(rs_device_list[i].get_info(RS2_CAMERA_INFO_SERIAL_NUMBER));
248  if (device_sn.compare(desired_sn) == 0) { //std::compare returns 0 if the strings are the same
249  selected_rs_devices.push_back(rs_device_list[i]);
250  device_not_found = false;
251  std::cout << "\nDevice with SN: " << device_sn << " has loaded.\n";
252  break;
253  }
254  }
255  if (device_not_found) {
256  std::cout << "\nGiven device serial number doesn't exist! desired serial number=" << desired_sn << std::endl;
257  return EXIT_FAILURE;
258  }
259 
260  }
261  else if (device_id_arg.isSet())
262  {
263  auto dev_id = device_id_arg.getValue();
264  if (num_rs_devices < (dev_id + 1))
265  {
266  std::cout << "\nGiven device_id doesn't exist! device_id=" <<
267  dev_id << " ; connected devices=" << num_rs_devices << std::endl;
268  return EXIT_FAILURE;
269  }
270 
271  for (int i = 0; i < (num_rs_devices - 1); ++i)
272  {
273  wait_for_device(hub, true);
274  }
275  selected_rs_devices.push_back(rs_device_list[dev_id]);
276  std::cout << "\nDevice ID " << dev_id << " has loaded.\n";
277  }
278  else if (rs_device_list.size() == 1)
279  {
280  selected_rs_devices.push_back(rs_device_list[0]);
281  }
282  else
283  {
284  std::cout << "\nEnter a command line option:" << std::endl;
285  std::cout << "-d to choose by device number" << std::endl;
286  std::cout << "-n to choose by serial number" << std::endl;
287  std::cout << "-a to send to all devices" << std::endl;
288  return EXIT_FAILURE;
289  }
290 
291  if (selected_rs_devices.empty()) {
292  std::cout << "\nNo devices were selected. Recheck input arguments" << std::endl;
293  return EXIT_FAILURE;
294  }
295  fflush(nullptr);
296  if (hex_cmd_arg.isSet())
297  {
298  for (auto dev : selected_rs_devices) {
299  auto line = hex_cmd_arg.getValue();
300  try
301  {
302  hex_mode(line, dev);
303  }
304  catch (const exception& ex)
305  {
306  cout << endl << ex.what() << endl;
307  continue;
308  }
309  }
310  return EXIT_SUCCESS;
311 
312  }
313 
314  std::string script_file("");
315  vector<string> script_lines;
316  if (hex_script_arg.isSet())
317  {
318  script_file = hex_script_arg.getValue();
319  }
320  else if (commands_script_arg.isSet())
321  {
322  script_file = commands_script_arg.getValue();
323  }
324 
325  if (!script_file.empty())
326  read_script_file(script_file, script_lines);
327 
328  if (hex_script_arg.isSet())
329  {
330  for (auto dev : selected_rs_devices) {
331  try
332  {
333  for (auto& elem : script_lines)
334  hex_mode(elem, dev);
335  }
336  catch (const exception& ex)
337  {
338  cout << endl << ex.what() << endl;
339  continue;
340  }
341  }
342  return EXIT_SUCCESS;
343  }
344 
345 
346 
347 
348  if (commands_script_arg.isSet())
349  {
350  for (auto dev : selected_rs_devices) {
351  try
352  {
353  for (auto& elem : script_lines)
354  xml_mode(elem, cmd_xml, dev, format_type_to_lambda);
355  }
356  catch (const exception& ex)
357  {
358  cout << endl << ex.what() << endl;
359  continue;
360  }
361  }
362  return EXIT_SUCCESS;
363  }
364 
365  auto dev = selected_rs_devices[0];
366  while (hub.is_connected(dev))
367  {
368  try
369  {
370  cout << "\n\n#>";
371  fflush(nullptr);
372  string line = "";
373  line = auto_comp.get_line([&]() {return !hub.is_connected(dev); });
374  if (!hub.is_connected(dev))
375  continue;
376 
377 
378  if (line == "next")
379  {
380  dev = wait_for_device(hub);
381  continue;
382  }
383  if (line == "exit")
384  {
385  return EXIT_SUCCESS;
386  }
387 
388  for (auto&& dev : selected_rs_devices)
389  {
390  if (!hub.is_connected(dev))
391  continue;
392 
393  if (is_application_in_hex_mode)
394  {
395  hex_mode(line, dev);
396  }
397  else
398  {
399  xml_mode(line, cmd_xml, dev, format_type_to_lambda);
400  }
401  cout << endl;
402  }
403  }
404  catch (const rs2::error & e)
405  {
406  cerr << "RealSense error calling " << e.get_failed_function() << "(" << e.get_failed_args() << "):\n " << e.what() << endl;
407  }
408  catch (const exception & e)
409  {
410  cerr << e.what() << endl;
411  }
412  }
413 
414  }
415 }
416 
GLboolean GLboolean GLboolean b
void read_script_file(const string &full_file_path, vector< string > &hex_lines)
bool is_connected(const device &dev) const
Definition: rs_context.hpp:256
GLuint const GLchar * name
bool parse_xml_from_file(const std::string &xml_full_file_path, commands_xml &cmd_xml)
Definition: parser.hpp:361
void hex_mode(const string &line, rs2::device &dev)
Definition: rs-terminal.cpp:96
device_list query_devices() const
Definition: rs_context.hpp:112
bool is_cmd_write_data
Definition: parser.hpp:173
rs2::device wait_for_device(const rs2::device_hub &hub, bool print_info=true)
uint32_t size() const
Definition: rs_device.hpp:711
void decode_string_from_raw_data(const command_from_xml &command, const std::map< std::string, custom_formatter > &custom_formatters, const uint8_t *raw_data_offset, size_t data_size, std::string &output, const std::map< std::string, xml_parser_function > &format_type_to_lambda)
Definition: parser.hpp:541
auto_complete get_auto_complete_obj(bool is_application_in_hex_mode, const map< string, command > &commands_map)
unsigned int op_code
Definition: parser.hpp:166
GLsizei const GLchar *const * string
int main(int argc, char **argv)
e
Definition: rmse.py:177
GLsizei const GLubyte * commands
Definition: glext.h:10525
vector< uint8_t > build_raw_command_data(const command &command, const vector< string > &params)
Definition: rs-terminal.cpp:19
const std::string & get_failed_args() const
Definition: rs_types.hpp:117
std::ostream & cout()
usb_device_info get_info(const std::wstring device_wstr)
std::vector< parameter > parameters
Definition: parser.hpp:181
bool isSet() const
Definition: Arg.h:575
void update_format_type_to_lambda(std::map< std::string, xml_parser_function > &format_type_to_lambda)
Definition: parser.hpp:387
GLenum const GLfloat * params
def print_info()
Definition: test.py:330
std::map< std::string, command_from_xml > commands
Definition: parser.hpp:193
void log_to_file(rs2_log_severity min_severity, const char *file_path=nullptr)
Definition: rs.hpp:26
T & getValue()
Definition: ValueArg.h:322
void parse(int argc, const char *const *argv)
Definition: CmdLine.h:433
static auto it
#define RS2_API_VERSION_STR
Definition: rs.h:43
std::ostream & cerr()
void add(Arg &a)
Definition: CmdLine.h:413
int i
Definition: Arg.h:57
GLboolean * data
device wait_for_device() const
Definition: rs_context.hpp:240
std::map< std::string, custom_formatter > custom_formatters
Definition: parser.hpp:194
GLuint64EXT * result
Definition: glext.h:10921
void xml_mode(const string &line, const commands_xml &cmd_xml, rs2::device &dev, map< string, xml_parser_function > &format_type_to_lambda)
Definition: rs-terminal.cpp:40
const std::string & get_failed_function() const
Definition: rs_types.hpp:112
bool is_read_command
Definition: parser.hpp:169
T as() const
Definition: rs_device.hpp:129
void encode_raw_data_command(const command_from_xml &xml_cmd_info, const std::vector< parameter > &params, std::vector< uint8_t > &raw_data)
Definition: parser.hpp:678


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