Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

set_devices_changed_callback seems to trigger inconstantly after hardware_reset #9287

Closed
stfuchs opened this issue Jun 24, 2021 · 12 comments
Closed

Comments

@stfuchs
Copy link

stfuchs commented Jun 24, 2021


Required Info
Camera Model D400
Firmware Version 05.12.14.50
Operating System & Version Linux (Ubuntu 18)
Kernel Version (Linux Only) 5.4.0-73
Platform PC
SDK Version 2.47.0
Language C++
Segment Development / Robot

Issue Description

I have a similar issue as #6921 with the main difference that I'm on linux instead of win10.

I am trying to add hardware_reset to the start of my program and wanted to use the set_devices_changed_callback to receive feedback when a camera is available again. My test setup consists of 3x D435 cameras connected via usb hub. The issue that I'm seeing is that the registered callback gets called only occasionally if I try to reset all 3 cameras.

Here is an example to reproduce this:

#include <atomic>
#include <chrono>
#include <iostream>
#include <iomanip>
#include <thread>

#include <librealsense2/rs.hpp>
#include <librealsense2/rs_advanced_mode.hpp>

#define LOG(name, msg) { \
    using namespace std::chrono; \
    duration<double> tnow = high_resolution_clock::now().time_since_epoch(); \
    std::cout << "[" << std::setprecision(std::numeric_limits<double>::digits10 + 1) << tnow.count() \
              << "] [" << name << "] " << msg << std::endl; \
  }


int main(int argc, char** argv)
{
  rs2::context ctx;
  std::atomic<bool> reconnected;
  std::string serial;

  auto _device_changed_cb = [&serial, &reconnected](rs2::event_information& info) {
    LOG(serial, "Callback thread id: " << std::this_thread::get_id());
    LOG(serial, "Device change triggered!");
    for (auto dev_new : info.get_new_devices())
    {
      std::string new_id = dev_new.get_info(RS2_CAMERA_INFO_SERIAL_NUMBER);
      LOG(serial, "Device connected: " << new_id);
      if (new_id == serial)
      {
        reconnected = true;
      }
    }
  };
  ctx.set_devices_changed_callback(_device_changed_cb);

  for (auto&& dev : ctx.query_devices())
  {
    reconnected = false;
    serial = dev.get_info(RS2_CAMERA_INFO_SERIAL_NUMBER);
    LOG(serial, "Thread ID: " << std::this_thread::get_id());

    LOG(serial, "Before hardware_reset.");
    dev.hardware_reset();
    LOG(serial, "After hardware_reset.");

    auto wait_until = std::chrono::system_clock::now() + std::chrono::seconds(30);
    while (std::chrono::system_clock::now() < wait_until)
    {
      std::this_thread::sleep_for(std::chrono::milliseconds(100));
      if (reconnected)
      {
        LOG(serial, "Reset complete.");
        break;
      }
    }
    if (!reconnected)
    {
      LOG(serial, "Reset timeout.");
    }
  }
}

This is the output when I run it (first number in [] is the timestamp, second is the serial number):

[1624551703.266312] [026322071124] Thread ID: 139651490211136
[1624551703.266343] [026322071124] Before hardware_reset.
[1624551703.266588] [026322071124] After hardware_reset.
[1624551733.318992] [026322071124] Reset timeout.

[1624551733.817505] [939622074720] Thread ID: 139651490211136
[1624551733.817518] [939622074720] Before hardware_reset.
[1624551733.817719] [939622074720] After hardware_reset.
[1624551763.885547] [939622074720] Reset timeout.

[1624551763.900465] [814412071622] Thread ID: 139651490211136
[1624551763.900477] [814412071622] Before hardware_reset.
[1624551763.900774] [814412071622] After hardware_reset.
[1624551768.379427] [814412071622] Callback thread id: 139651481790208
[1624551768.379453] [814412071622] Device change triggered!
[1624551768.40303] [814412071622] Device connected: 814412071622
[1624551768.408365] [814412071622] Reset complete.

And here are the dmesg logs for that time:

[242010.325817] usb 2-1.3.2: reset SuperSpeed Gen 1 USB device number 77 using xhci_hcd
[242010.347762] uvcvideo: Found UVC 1.50 device Intel(R) RealSense(TM) Depth Camera 435  (8086:0b07)
[242010.351166] uvcvideo 2-1.3.2:1.0: Entity type for entity Intel(R) RealSense(TM) Depth Ca was not initialized!
[242010.351171] uvcvideo 2-1.3.2:1.0: Entity type for entity Processing 2 was not initialized!
[242010.351175] uvcvideo 2-1.3.2:1.0: Entity type for entity Camera 1 was not initialized!
[242010.351409] input: Intel(R) RealSense(TM) Depth Ca as /devices/pci0000:00/0000:00:14.0/usb2/2-1/2-1.3/2-1.3.2/2-1.3.2:1.0/input/input201
[242010.351905] uvcvideo: Found UVC 1.50 device Intel(R) RealSense(TM) Depth Camera 435  (8086:0b07)
[242010.355312] uvcvideo 2-1.3.2:1.3: Entity type for entity Processing 7 was not initialized!
[242010.355314] uvcvideo 2-1.3.2:1.3: Entity type for entity Extension 8 was not initialized!
[242010.355314] uvcvideo 2-1.3.2:1.3: Entity type for entity Camera 6 was not initialized!

[242040.882208] usb 2-1.3.3: reset SuperSpeed Gen 1 USB device number 78 using xhci_hcd
[242040.903914] uvcvideo: Found UVC 1.50 device Intel(R) RealSense(TM) Depth Camera 435  (8086:0b07)
[242040.907228] uvcvideo 2-1.3.3:1.0: Entity type for entity Intel(R) RealSense(TM) Depth Ca was not initialized!
[242040.907233] uvcvideo 2-1.3.3:1.0: Entity type for entity Processing 2 was not initialized!
[242040.907237] uvcvideo 2-1.3.3:1.0: Entity type for entity Camera 1 was not initialized!
[242040.907480] input: Intel(R) RealSense(TM) Depth Ca as /devices/pci0000:00/0000:00:14.0/usb2/2-1/2-1.3/2-1.3.3/2-1.3.3:1.0/input/input202
[242040.907844] uvcvideo: Found UVC 1.50 device Intel(R) RealSense(TM) Depth Camera 435  (8086:0b07)
[242040.910469] uvcvideo 2-1.3.3:1.3: Entity type for entity Processing 7 was not initialized!
[242040.910471] uvcvideo 2-1.3.3:1.3: Entity type for entity Extension 8 was not initialized!
[242040.910472] uvcvideo 2-1.3.3:1.3: Entity type for entity Camera 6 was not initialized!

[242070.361312] usb 2-1.3.4: USB disconnect, device number 79
[242071.089822] usb 2-1.3.4: new SuperSpeed Gen 1 USB device number 80 using xhci_hcd
[242071.110641] usb 2-1.3.4: New USB device found, idVendor=8086, idProduct=0b07, bcdDevice=50.ce
[242071.110647] usb 2-1.3.4: New USB device strings: Mfr=1, Product=2, SerialNumber=3
[242071.110651] usb 2-1.3.4: Product: Intel(R) RealSense(TM) Depth Camera 435 
[242071.110654] usb 2-1.3.4: Manufacturer: Intel(R) RealSense(TM) Depth Camera 435 
[242071.110657] usb 2-1.3.4: SerialNumber: 811313020107
[242071.120122] uvcvideo: Found UVC 1.50 device Intel(R) RealSense(TM) Depth Camera 435  (8086:0b07)
[242071.123510] uvcvideo 2-1.3.4:1.0: Entity type for entity Intel(R) RealSense(TM) Depth Ca was not initialized!
[242071.123515] uvcvideo 2-1.3.4:1.0: Entity type for entity Processing 2 was not initialized!
[242071.123519] uvcvideo 2-1.3.4:1.0: Entity type for entity Camera 1 was not initialized!
[242071.123695] input: Intel(R) RealSense(TM) Depth Ca as /devices/pci0000:00/0000:00:14.0/usb2/2-1/2-1.3/2-1.3.4/2-1.3.4:1.0/input/input203
[242071.124498] uvcvideo: Found UVC 1.50 device Intel(R) RealSense(TM) Depth Camera 435  (8086:0b07)
[242071.126680] uvcvideo 2-1.3.4:1.3: Entity type for entity Processing 7 was not initialized!
[242071.126683] uvcvideo 2-1.3.4:1.3: Entity type for entity Extension 8 was not initialized!
[242071.126686] uvcvideo 2-1.3.4:1.3: Entity type for entity Camera 6 was not initialized!

I'm built librealsense 2.47 from source with the following flags:

-DCMAKE_BUILD_TYPE=Release
-DBUILD_EXAMPLES=true 
-DBUILD_GRAPHICAL_EXAMPLES=false 
-DBUILD_GLSL_EXTENSIONS=false 
-DBUILD_WITH_TM2=false 
-DIMPORT_DEPTH_CAM_FW=false

UDEV and kernel patch are installed via debian packages:

ii  librealsense2-dkms                                    1.3.18-0ubuntu1                                  all          Modified kernel modules for librealsense2
ii  librealsense2-udev-rules:amd64                        2.47.0-0~realsense0.4805                         amd64        Intel(R) RealSense(tm) Camera Capture API - udev rules

From the example output above you can see that the callback gets triggered only once. For that camera the kernel log also shows an actual disconnect event. Note that it's not always the same camera. Sometimes one of other cameras triggers the callback, sometimes none of them trigger at all, and very few times more than one camera triggered the callback.

So my questions are:

  • Am I missing something in my implementation or is there a bug in the reset + device_changed code?
  • Does the device_list provided by rs2::context::query_devices() become invalid once I call rs2::device::hardware_reset()?
  • Is the hardware_reset successful even if no callback was triggered and no USB disconnect kernel event happened? So is falling back on a timeout reasonable?
@MartyG-RealSense
Copy link
Collaborator

MartyG-RealSense commented Jun 24, 2021

Hi @stfuchs The hardware_reset() scripts on this GitHub support forum are typically suited for single-camera projects. A RealSense user called Westa contributed a C++ multiple-camera hardware reset script that makes use of callbacks to iterate through all attached cameras.

Westa stated that "it explains how the realsense context works - and how to iterate over all the current devices. It also shows a mechanism for resetting a found Intel device - and a mechanism to wait for the hardware to finishing resetting before continuing".

https://community.intel.com/t5/Items-with-no-label/D435-streams-work-once-then-crash/m-p/499732#M6053

I have posted the full C++ script below. Would it be possible to adapt this script for your callback-equipped project to test whether it makes a positive difference, please? Thanks!


// define a realsense context

std::cout << "Initialising realsense context" << std::endl;

rs2::context rs2Ctx;

rs2::device rs2Dev;

resettingIntelRealsense = 0;

resetCompleteIntelRealsense = 0;

int gotDev = 0;

// Define a callback mechanism - to detect when the sensor has been reset

rs2Ctx.set_devices_changed_callback([&](rs2::event_information& info)

{

// loop thru all new devices - that is one that has been reset effectively

for (auto&& dev : info.get_new_devices())

{

std::string devName = "";

std::string devSerialNumber = "";

std::string devFirmware = "";

std::string devProdId = "";

devProdId = dev.get_info(RS2_CAMERA_INFO_PRODUCT_ID);

devSerialNumber = dev.get_info(RS2_CAMERA_INFO_SERIAL_NUMBER);

devName = dev.get_info(RS2_CAMERA_INFO_NAME);

if (devName == "Intel RealSense D415")

{

devFirmware = dev.get_info(RS2_CAMERA_INFO_FIRMWARE_VERSION);

}

if (devName == "Intel RealSense D435")

{

devFirmware = dev.get_info(RS2_CAMERA_INFO_FIRMWARE_VERSION);

}

std::cout << "RESET Dev: " << devName << " Ser: " << devSerialNumber << " Firmware: " << devFirmware << " ProdID " << devProdId << std::endl;

resetCompleteIntelRealsense = 1;

}

});

// interate thru the intel device context looking for intel sensors

// note that other devices like webcams can appear here too depending on their device type

for (auto&& dev : rs2Ctx.query_devices()) // Query the list of connected RealSense devices

{

std::string devName = "";

std::string devSerialNumber = "";

std::string devFirmware = "";

std::string devProdId = "";

devProdId = dev.get_info(RS2_CAMERA_INFO_PRODUCT_ID);

devSerialNumber = dev.get_info(RS2_CAMERA_INFO_SERIAL_NUMBER);

devName = dev.get_info(RS2_CAMERA_INFO_NAME);

if (gotDev == 0 && (devName == "Intel RealSense D415" || devName == "Intel RealSense D435"))

{

devFirmware = dev.get_info(RS2_CAMERA_INFO_FIRMWARE_VERSION);

// assume there is only one intel camera for now

// save the device for future use

rs2Dev = dev;

gotDev = 1;

}

std::cout << "System Dev: " << devName << " Ser: " << devSerialNumber << " Firmware: " << devFirmware << " ProdID " << devProdId << std::endl;

}

////////////////////////////////////////////////////////////////

// if we have found a realsense sensor - force initialise it if required

if (gotDev == 1)

{

// reset the hardware device found during initial iteration thru context

rs2Dev.hardware_reset();

// wait for hardware to reset reset

resetCompleteIntelRealsense = 0;

int rs2WaitForReset = 1;

// pause until device is reset - not elegant but will do for testing

while (resetCompleteIntelRealsense == 0 && rs2WaitForReset < 9999999999)

{

rs2WaitForReset++;

}

}

if (gotDev == 0)

{

std::cout << "No Intel Realsense devices detected" << std::endl;

}

@stfuchs
Copy link
Author

stfuchs commented Jun 24, 2021

Hi Marty,

thanks for getting back to me so quickly. Unfortunately I can't access your link to the Intel Community. It keeps asking me to register even though I already did and even confirmed my email address.

The example you posted is almost the same as mine, except that it actually only resets the first camera it finds and stops there:

  if (gotDev == 0 && (devName == "Intel RealSense D415" || devName == "Intel RealSense D435"))
  {
    devFirmware = dev.get_info(RS2_CAMERA_INFO_FIRMWARE_VERSION);
    // assume there is only one intel camera for now
    // save the device for future use
    rs2Dev = dev;
    gotDev = 1;
  }

It even says it in the comment.

@MartyG-RealSense
Copy link
Collaborator

The link just goes to a comment with the same script, so don't worry. The reason for pasting the script here was that links to that different forum do not always work.

My personal interpretation of the script is that it is not saying that it only detects one camera, but is establishing that there is at least one camera connected. It sets gotdev to '1' to acknowledge this. If gotdev = 0 then the message "No Intel Realsense devices detected" is printed.

@stfuchs
Copy link
Author

stfuchs commented Jun 24, 2021

Maybe I'm missing something but the way I understand this part:

for (auto&& dev : rs2Ctx.query_devices()) // Query the list of connected RealSense devices
{
  std::string devName = "";
  std::string devSerialNumber = "";
  std::string devFirmware = "";
  std::string devProdId = "";

  devProdId = dev.get_info(RS2_CAMERA_INFO_PRODUCT_ID);
  devSerialNumber = dev.get_info(RS2_CAMERA_INFO_SERIAL_NUMBER);
  devName = dev.get_info(RS2_CAMERA_INFO_NAME);

  if (gotDev == 0 && (devName == "Intel RealSense D415" || devName == "Intel RealSense D435"))
  {
    devFirmware = dev.get_info(RS2_CAMERA_INFO_FIRMWARE_VERSION);
    // assume there is only one intel camera for now
    // save the device for future use
    rs2Dev = dev;
    gotDev = 1;
  }

  std::cout << "System Dev: " << devName << " Ser: " << devSerialNumber << " Firmware: " << devFirmware << " ProdID " << devProdId << std::endl;
}

It uses the context to iterate over all available devices. Then if gotDev is still 0 and device name is either D415 or D435 it saves the device object to rs2Dev and sets gotDev to 1 (which essentially stops from collecting more devices, but the loop still iterates and prints their info).

Then the device loop is done it moves to the next part:

////////////////////////////////////////////////////////////////
// if we have found a realsense sensor - force initialise it if required
if (gotDev == 1)
{
  // reset the hardware device found during initial iteration thru context
  rs2Dev.hardware_reset();
  // wait for hardware to reset reset
  resetCompleteIntelRealsense = 0;
  int rs2WaitForReset = 1;
  // pause until device is reset - not elegant but will do for testing

  while (resetCompleteIntelRealsense == 0 && rs2WaitForReset < 9999999999)
  {
    rs2WaitForReset++;
  }
}

where it resets the previously sorted device if it was found. The last while loop blocks execution until either the callback from set_devices_changed_callback gets triggered by a new device or until a timeout of 9999999999 ticks is reached. That block does not get repeated, so no other camera is reset.

@stfuchs
Copy link
Author

stfuchs commented Jun 24, 2021

To be fair, the original formatting doesn't really help, so here is it with fixed indentation:

// define a realsense context
std::cout << "Initialising realsense context" << std::endl;
rs2::context rs2Ctx;
rs2::device rs2Dev;
resettingIntelRealsense = 0;
resetCompleteIntelRealsense = 0;

int gotDev = 0;

// Define a callback mechanism - to detect when the sensor has been reset
rs2Ctx.set_devices_changed_callback(
  [&](rs2::event_information& info)
  {
    // loop thru all new devices - that is one that has been reset effectively
    for (auto&& dev : info.get_new_devices())
    {
      std::string devName = "";
      std::string devSerialNumber = "";
      std::string devFirmware = "";
      std::string devProdId = "";

      devProdId = dev.get_info(RS2_CAMERA_INFO_PRODUCT_ID);
      devSerialNumber = dev.get_info(RS2_CAMERA_INFO_SERIAL_NUMBER);
      devName = dev.get_info(RS2_CAMERA_INFO_NAME);

      if (devName == "Intel RealSense D415")
      {
        devFirmware = dev.get_info(RS2_CAMERA_INFO_FIRMWARE_VERSION);
      }

      if (devName == "Intel RealSense D435")
      {
        devFirmware = dev.get_info(RS2_CAMERA_INFO_FIRMWARE_VERSION);
      }

      std::cout << "RESET Dev: " << devName << " Ser: " << devSerialNumber << " Firmware: " << devFirmware << " ProdID " << devProdId << std::endl;
      resetCompleteIntelRealsense = 1;
    }
  });

// interate thru the intel device context looking for intel sensors
// note that other devices like webcams can appear here too depending on their device type

for (auto&& dev : rs2Ctx.query_devices()) // Query the list of connected RealSense devices
{
  std::string devName = "";
  std::string devSerialNumber = "";
  std::string devFirmware = "";
  std::string devProdId = "";

  devProdId = dev.get_info(RS2_CAMERA_INFO_PRODUCT_ID);
  devSerialNumber = dev.get_info(RS2_CAMERA_INFO_SERIAL_NUMBER);
  devName = dev.get_info(RS2_CAMERA_INFO_NAME);

  if (gotDev == 0 && (devName == "Intel RealSense D415" || devName == "Intel RealSense D435"))
  {
    devFirmware = dev.get_info(RS2_CAMERA_INFO_FIRMWARE_VERSION);
    // assume there is only one intel camera for now
    // save the device for future use
    rs2Dev = dev;
    gotDev = 1;
  }

  std::cout << "System Dev: " << devName << " Ser: " << devSerialNumber << " Firmware: " << devFirmware << " ProdID " << devProdId << std::endl;
}

////////////////////////////////////////////////////////////////
// if we have found a realsense sensor - force initialise it if required
if (gotDev == 1)
{
  // reset the hardware device found during initial iteration thru context
  rs2Dev.hardware_reset();
  // wait for hardware to reset reset
  resetCompleteIntelRealsense = 0;
  int rs2WaitForReset = 1;
  // pause until device is reset - not elegant but will do for testing

  while (resetCompleteIntelRealsense == 0 && rs2WaitForReset < 9999999999)
  {
    rs2WaitForReset++;
  }
}

if (gotDev == 0)
{
  std::cout << "No Intel Realsense devices detected" << std::endl;
}

@MartyG-RealSense
Copy link
Collaborator

MartyG-RealSense commented Jun 24, 2021

I'm reminded of a C++ case where a RealSense user tried to use callback to access multiple cameras to capture an image from every camera simultaneously but could only access one camera at a time, looping through the cameras.

#2219 (comment)

The solution they arrived at was to instead create multiple threads.

#2219 (comment)

Note that if you try the above script, it is looking for D415 cameras and so you should edit the script to look for D435, as that is the model that you have.

@stfuchs
Copy link
Author

stfuchs commented Jun 24, 2021

@MartyG-RealSense thanks for the links. I looked through all the comments but I don't think my problem has to do with threading. In fact I don't even think it has to do with my multi cam setup. I disconnect all other cameras and change the test to this:

int main(int argc, char** argv)
{
  rs2::context ctx;

  bool reconnected = false;
  ctx.set_devices_changed_callback(
    [&reconnected](rs2::event_information& info) {
      std::cout << "Device change triggered!" << std::endl;
      for (auto&& dev_new : info.get_new_devices())
      {
        std::string new_id = dev_new.get_info(RS2_CAMERA_INFO_SERIAL_NUMBER);
        std::cout << "Device connected: " << new_id << std::endl;
        reconnected = true;
      }
    });

  rs2::device_list device_list = ctx.query_devices();
  std::cout << "Devices found: " << device_list.size() << std::endl;

  rs2::device device = device_list.front();
  std::cout << "Before hardware_reset" << std::endl;
  device.hardware_reset();
  std::cout << "After hardware_reset" << std::endl;

  auto wait_until = std::chrono::system_clock::now() + std::chrono::seconds(30);
  while (std::chrono::system_clock::now() < wait_until)
  {
    std::this_thread::sleep_for(std::chrono::milliseconds(100));
    if (reconnected)
    {
      std::cout << "Reset complete" << std::endl;
      break;
    }
  }
  if (!reconnected)
  {
    std::cout << "Reached timeout instead of callback" << std::endl;
  }
}

Only on the first time I run it the callback was triggered. Here is the output of the script running it 5 times in a row:

root@FR-1604:~/ws/src/carl# camera_hardware_reset 
Devices found: 1
Before hardware_reset
After hardware_reset
Device change triggered!
Device connected: 814412071622
Reset complete

root@FR-1604:~/ws/src/carl# camera_hardware_reset 
Devices found: 1
Before hardware_reset
After hardware_reset
Reached timeout instead of callback

root@FR-1604:~/ws/src/carl# camera_hardware_reset 
Devices found: 1
Before hardware_reset
After hardware_reset
Reached timeout instead of callback

root@FR-1604:~/ws/src/carl# camera_hardware_reset 
Devices found: 1
Before hardware_reset
After hardware_reset
Reached timeout instead of callback

root@FR-1604:~/ws/src/carl# camera_hardware_reset 
Devices found: 1
Before hardware_reset
After hardware_reset
Reached timeout instead of callback

@stfuchs
Copy link
Author

stfuchs commented Jun 25, 2021

I started looking into the source code a bit. My understanding so far is that the responsible function, that calls my callback, actively polls for changed devices and does that only every 5 seconds or so:

https://github.com/IntelRealSense/librealsense/blob/master/src/types.h#L1595-L1612
https://github.com/IntelRealSense/librealsense/blob/master/src/backend.h#L33

Based on the dmesg output it seems as if the reset completes within 3 seconds on my machine. So I guess the disconnect just slips through the polling interval most of the time. Is that accurate?

Oddly enough I tried calling query_devices every 5ms to see if I can quickly poll myself:

  rs2::device device = device_list.front();
  std::cout << "Before hardware_reset" << std::endl;
  device.hardware_reset();
  std::cout << "After hardware_reset" << std::endl;

  auto wait_until = std::chrono::system_clock::now() + std::chrono::seconds(30);
  while (std::chrono::system_clock::now() < wait_until)
  {
    std::cout << "Devices connected: " << ctx.query_devices().size() << std::endl;

    if (reconnected)
    {
      std::cout << "Reset complete" << std::endl;
      break;
    }
    std::this_thread::sleep_for(std::chrono::milliseconds(5));
  }

but the device list did not change at all.

@MartyG-RealSense
Copy link
Collaborator

MartyG-RealSense commented Jun 25, 2021

That is indeed my understanding that devices are checked for changes every 5 seconds, as per the advice in #6921 (comment) about editing the time period in files.h to reduce this timer.

Some advice on improving hardware reset is also given in the comment linked to below and the comments below it.

#1086 (comment)

@MartyG-RealSense
Copy link
Collaborator

Hi @stfuchs Do you have an update about this case that you can provide, please? Thanks!

@stfuchs
Copy link
Author

stfuchs commented Jul 1, 2021

I simply came to the conclusion that set_devices_changed_callback can not be used with hardware_reset because it's not reliable enough. I decided to simply wait 10 seconds before I attempt to start the device. I think the answers in most of the other tickets are very misleading and the documentation should be updated. The callback should probably only be used in cases when a user physically plugs/unplugs a device.

@MartyG-RealSense
Copy link
Collaborator

Thanks very much @stfuchs for your feedback. I do not have advice to offer on that subject. As you developed a solution for your particular project, I will close the case. Thanks again!

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

No branches or pull requests

2 participants