Visual Servoing Platform  version 3.6.1 under development (2024-12-17)
tutorial-grabber-multiple-realsense.cpp
1 
2 #include <visp3/core/vpConfig.h>
3 #include <visp3/core/vpImage.h>
4 #include <visp3/gui/vpDisplayGDI.h>
5 #include <visp3/gui/vpDisplayOpenCV.h>
6 #include <visp3/gui/vpDisplayX.h>
7 #include <visp3/sensor/vpRealSense.h>
8 #include <visp3/sensor/vpRealSense2.h>
9 
14 int main(int argc, char **argv)
15 {
16 #if defined(VISP_HAVE_REALSENSE2) && (RS2_API_VERSION > ((2 * 10000) + (31 * 100) + 0)) \
17  && (VISP_CXX_STANDARD >= VISP_CXX_STANDARD_11)
18 #ifdef ENABLE_VISP_NAMESPACE
19  using namespace VISP_NAMESPACE_NAME;
20 #endif
21  std::vector<std::pair<std::string, std::string> > type_serial_nb;
22  std::vector<bool> cam_found;
23 
24  for (int i = 0; i < argc; i++) {
25  if (std::string(argv[i]) == "--T265") {
26  type_serial_nb.push_back(std::make_pair("T265", std::string(argv[i + 1])));
27  }
28  else if (std::string(argv[i]) == "--D435") {
29  type_serial_nb.push_back(std::make_pair("D435", std::string(argv[i + 1])));
30  }
31  else if (std::string(argv[i]) == "--SR300") {
32  type_serial_nb.push_back(std::make_pair("SR300", std::string(argv[i + 1])));
33  }
34  else if (std::string(argv[i]) == "--help" || std::string(argv[i]) == "-h") {
35  std::cout << "\nUsage: " << argv[0]
36  << " [--T265 <serial number>] [--D435 <serial number>] [--SR300 <serial number>]\n"
37  << "\nExample to use 2 T265 cameras:\n"
38  << " " << argv[0] << " --T265 11622110511 --T265 11622110433 \n"
39  << "\nExample to use 1 T265 and 1 D435 cameras:\n"
40  << " " << argv[0] << " --T265 11622110511 --D435 752112077408 \n"
41  << "\nExample to use 2 T265 and 1 D435 cameras:\n"
42  << " " << argv[0] << " --T265 11622110511 --T265 11622110433 --D435 752112070408 \n"
43  << std::endl;
44  return EXIT_SUCCESS;
45  }
46  }
47 
48  rs2::config T265_cfg, D435_cfg;
49  std::vector<vpRealSense2> g(type_serial_nb.size());
50  std::vector<vpImage<unsigned char> > I(type_serial_nb.size());
51 
52 #ifdef VISP_HAVE_X11
53  std::vector<vpDisplayX> d(type_serial_nb.size());
54 #elif defined(VISP_HAVE_GDI)
55  std::vector<vpDisplayGDI> d(type_serial_nb.size());
56 #elif defined(HAVE_OPENCV_HIGHGUI)
57  std::vector<vpDisplayOpenCV> d(type_serial_nb.size());
58 #else
59  std::cout << "No image viewer is available..." << std::endl;
60 #endif
61 
62  bool clicked = false;
63 
64  for (size_t i = 0; i < type_serial_nb.size(); i++) {
65  std::cout << "Opening " << type_serial_nb[i].first << " with ID: " << type_serial_nb[i].second << "." << std::endl;
66  if (type_serial_nb[i].first == "T265") { // T265.
67  T265_cfg.enable_device(type_serial_nb[i].second);
68  T265_cfg.enable_stream(RS2_STREAM_FISHEYE, 1, RS2_FORMAT_Y8);
69  T265_cfg.enable_stream(RS2_STREAM_FISHEYE, 2, RS2_FORMAT_Y8);
70  cam_found.push_back(g[i].open(T265_cfg));
71  if (!cam_found.back()) {
72  std::cout << "Device with ID: " << type_serial_nb[i].second << " not found." << std::endl;
73  }
74  }
75  else { // D435 or SR300
76  D435_cfg.enable_device(type_serial_nb[i].second);
77  D435_cfg.disable_stream(RS2_STREAM_DEPTH);
78  D435_cfg.disable_stream(RS2_STREAM_INFRARED);
79  D435_cfg.enable_stream(RS2_STREAM_COLOR, 640, 480, RS2_FORMAT_RGBA8, 30);
80  cam_found.push_back(g[i].open(D435_cfg));
81  if (!cam_found.back()) {
82  std::cout << "Device with ID: " << type_serial_nb[i].second << " not found." << std::endl;
83  }
84  }
85  }
86 
87  while (true) {
88  for (size_t i = 0; i < type_serial_nb.size(); i++) {
89  if (cam_found[i]) {
90  if (type_serial_nb[i].first == "T265") { // T265.
91  g[i].acquire(&I[i], nullptr, nullptr);
92 
93 #if defined(VISP_HAVE_X11) || defined(VISP_HAVE_GDI) || defined(VISP_HAVE_OPENCV)
94  if (!d[i].isInitialised()) {
95  d[i].init(I[i], static_cast<int>(100 * i), static_cast<int>(100 * i), "T265 left image");
96  }
97 #endif
98  }
99 
100  else { // D435.
101  g[i].acquire(I[i]);
102 
103 #if defined(VISP_HAVE_X11) || defined(VISP_HAVE_GDI) || defined(VISP_HAVE_OPENCV)
104  if (!d[i].isInitialised()) {
105  d[i].init(I[i], static_cast<int>(100 * i), static_cast<int>(100 * i), type_serial_nb[i].first.c_str());
106  }
107 #endif
108  }
109 
110  vpDisplay::display(I[i]);
111  vpDisplay::flush(I[i]);
112  clicked = vpDisplay::getClick(I[i], false);
113  }
114 
115  if (clicked) {
116  break;
117  }
118  }
119 
120  if (clicked) {
121  break;
122  }
123 }
124 #else
125  (void)argc;
126  (void)argv;
127 #if !(defined(VISP_HAVE_REALSENSE2))
128  std::cout << "Install librealsense version > 2.31.0, configure and build ViSP again to use this example" << std::endl;
129 #endif
130 #if !(RS2_API_VERSION > ((2 * 10000) + (31 * 100) + 0))
131  std::cout << "librealsense is detected but its version is too old. Install librealsense version > 2.31.0, configure "
132  "and build ViSP again to use this example"
133  << std::endl;
134 #endif
135 #if (VISP_CXX_STANDARD < VISP_CXX_STANDARD_11)
136  std::cout << "This tutorial should be built with c++11 support" << std::endl;
137 #endif
138 #endif
139  return EXIT_SUCCESS;
140 }
void init(vpImage< unsigned char > &I, int winx=-1, int winy=-1, const std::string &title="") VP_OVERRIDE
static bool getClick(const vpImage< unsigned char > &I, bool blocking=true)
static void display(const vpImage< unsigned char > &I)
static void flush(const vpImage< unsigned char > &I)