IntelRealSense / librealsense

Intel® RealSense™ SDK
https://www.intelrealsense.com/
Apache License 2.0
7.61k stars 4.83k forks source link

Issue of Depth stream start failure when using pipeline #9002

Closed victorll998 closed 3 years ago

victorll998 commented 3 years ago

Required Info
Camera Model D400 }
Firmware Version v2.45.0
Operating System & Version ubuntu 20.04
Kernel Version (Linux Only) 5.8.0-50
Platform Intel NUC
SDK Version 2.45.0
Language C/C++
Segment other

Issue Description

Hi there,

I use rs2::pipeline to record two D455 with USB3.2 connection. I encountered Depth stream start failure one of five takes. The failure is fatal to me because depth stream start failure will cause an empty depth stream which makes the collected data useless.

To record the d455 stream, I followed the example of rs-record and adapted it to fit for two D455. The cables I use are 5A USB C that is directly connected to thunderbolt3 on the back of Intel NUC. The resolution and fps is limited to 848x480 and 5, which should not cause any blocks in USB. I would like to know what causes this issue and the possible solutions to it.

Few things I noticed that saved rosbag files need reindex from time to time though I think I reset pipelines after they close.

rs2::context                          ctx;        
std::vector<rs2::pipeline>            pipelines;

auto list = ctx.query_devices(); 
    if (list.size() == 0) 
        throw std::runtime_error("No device detected. Is it plugged in?");
    else
    {
        for (auto&& dev : list)
        {   
            rs2::pipeline pipe(ctx);
            rs2::config cfg;
            std::string serial = dev.get_info(RS2_CAMERA_INFO_SERIAL_NUMBER);

            if (serial.compare(d455_left_serial) == 0 || serial.compare(d455_right_serial) == 0)
            {
                auto advanced_mode_dev = dev.as<rs400::advanced_mode>();

                if (!advanced_mode_dev.is_enabled())
                {
                    // If not, enable advanced-mode
                    advanced_mode_dev.toggle_advanced_mode(true);      
                }

                std::ifstream t(json_file_name);
                std::string preset_json((std::istreambuf_iterator<char>(t)), std::istreambuf_iterator<char>());
                advanced_mode_dev.load_json(preset_json);

                cfg.enable_device(serial);   
                cfg.enable_record_to_file(filepath);
                pipe.start(cfg);  
                pipelines.emplace_back(pipe);      
          }
      }
   }
....

while(true)
  { 
      auto t = std::chrono::system_clock::now();   
      if(t - t0 > std::chrono::seconds(time_sec))
      {
            for (auto &&pipe : pipelines)
            { 
               pipe.stop();
                //pipe.reset();
               pipe = rs2::pipeline();
               exit(0);
            }
      }
   }
MartyG-RealSense commented 3 years ago

Hi @victorll998 If a rosbag requires reindexing then this can indicate that the pipeline was not properly closed.

https://github.com/IntelRealSense/librealsense/issues/1857#issuecomment-395870781

You could try putting a wait time-period inbetween the pipeline stop and the pipe = rs2::pipeline(); instructions in order to help ensure that the pipeline has time to close fully.

In regard to the 1 in 5 failure to start the pipeline: I would think that the 5 FPS speed is not a factor in this case, since the failure is happening when the pipeline is attempted to be started rather than after it has activated and frame delivery has commenced.

A way to deal with the start failure may be to insert a try-catch mechanism that catches the error of a failed start and repeats the start request instead of exiting the program with an error.

https://github.com/IntelRealSense/librealsense/issues/6347

MartyG-RealSense commented 3 years ago

Hi @victorll998 Do you require further assistance with this case, please? Thanks!

victorll998 commented 3 years ago

@MartyG-RealSense Thank you for your responses and I think it is useful to me.

There is one thing I am not for sure about your mentioning solution of try-catch mechanism. Since ``depth stream start failure``` is displayed as rs notification, does that mean it would never reach the global handler of the process and gives a rs2::error object? If so, do you have any suggestions on how to handling the rs2::notifcation object?

MartyG-RealSense commented 3 years ago

I researched your question about depth stream start failure carefully. If a Depth Stream Start Failure does not generate a catchable error message, another approach may be to check whether the camera is already streaming (busy). In this case though, you would be checking if the camera is not busy (i.e if it failed to start).

The subject is discussed in the link below, with C++ scripting provided.

https://github.com/IntelRealSense/librealsense/issues/2240

MartyG-RealSense commented 3 years ago

Hi @victorll998 Do you require further assistance with this case, please? Thanks!

victorll998 commented 3 years ago

@MartyG-RealSense I was looking into it the other day. I think what you suggest is to add a checker to capture pipe start failure(not busy). In this way, rs2::pipe should give an active profile if it starts streaming (busy). My question is I can still get an active profile (busy) though one of the streams fails (i.e depth stream failure). Do you have suggestions/ideaas on that?

MartyG-RealSense commented 3 years ago

Perhaps you could adapt the SDK's beginner Ready to Hack C++ script, which prints the distance of a depth coordinate at the center of the camera view.

https://github.com/IntelRealSense/librealsense#ready-to-hack

If you initially set dist_to_center to a value of '0' and then query the distance in the next line:

float dist_to_center = depth.get_distance(width / 2, height / 2);

you could then insert an If statement after that line to check if the value of dist_to_center is still '0' (meaning that it has not been updated from its original setting, perhaps because of depth stream start failure). If dist_to_center = 0 then you could perform an action, such as initiating a hardware_reset() instruction to reset that particular camera.

MartyG-RealSense commented 3 years ago

Hi @victorll998 Do you require further assistance with this case, please? Thanks!

MartyG-RealSense commented 3 years ago

Case closed due to no further comments received.