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

D435i: start()ing an rs2::pipeline with an rs2::config (only IMU) and a callback reduces IMU frame rate #6426

Closed
rafaelspring opened this issue May 19, 2020 · 1 comment

Comments

@rafaelspring
Copy link

Required Info
Camera Model D435i
Firmware Version 5.11.06.250, 5.12.03.00
Operating System & Version Win10
SDK Version 2.34.0
Language C++

There seems to be a strange link between #6424 and #6425 . When start()ing an rs2::pipeline with an rs2::config and a callback we get reduced frame rates for the IMU if the config does not include depth or IR.

Below is a minimal code example. This is almost exactly the rs-callback example, with the exception of using an rs2::config as described when a flag is set to true.

The expected behavior is to always receive 200 callbacks per second for the Gyro.
However on my D435i I only receive ~30 callbacks per second for the Gyro when using the rs2::config object.

I was able to reproduce this on firmwares 5.11.06.250 and 5.12.03.00. I haven't tried any other FW versions.

The issue seems to only affect the D435i. Things work as expected on the L515!

// License: Apache 2.0. See LICENSE file in root directory.
// Copyright(c) 2017 Intel Corporation. All Rights Reserved.

#include <librealsense2/rs.hpp> // Include RealSense Cross Platform API
#include <iostream>
#include <map>
#include <chrono>
#include <mutex>
#include <thread>

// The callback example demonstrates asynchronous usage of the pipeline
int main(int argc, char * argv[]) try
{
    //rs2::log_to_console(RS2_LOG_SEVERITY_ERROR);

    std::map<int, int> counters;
    std::map<int, std::string> stream_names;
    std::mutex mutex;

    // Define frame callback
    // The callback is executed on a sensor thread and can be called simultaneously from multiple sensors
    // Therefore any modification to common memory should be done under lock
    auto callback = [&](const rs2::frame& frame)
    {
        std::lock_guard<std::mutex> lock(mutex);
        if (rs2::frameset fs = frame.as<rs2::frameset>())
        {
            // With callbacks, all synchronized stream will arrive in a single frameset
            for (const rs2::frame& f : fs)
                counters[f.get_profile().unique_id()]++;
        }
        else
        {
            // Stream that bypass synchronization (such as IMU) will produce single frames
            counters[frame.get_profile().unique_id()]++;
        }
    };

    // Declare RealSense pipeline, encapsulating the actual device and sensors.
    rs2::pipeline pipe;
    rs2::pipeline_profile profiles;

    // Set to false to make the problem disappear.
    constexpr bool useConfig = true;

    if (useConfig) {
      rs2::config cfg;
      cfg.disable_all_streams();
      cfg.enable_stream(RS2_STREAM_GYRO, -1, RS2_FORMAT_MOTION_XYZ32F, 200);

//      cfg.enable_stream(RS2_STREAM_ACCEL);    // <-- Uncomment to even further reduce IMU rate!
//      cfg.enable_stream(RS2_STREAM_DEPTH);    // <-- Uncommenting this line magically fixes things.
//      cfg.enable_stream(RS2_STREAM_INFRARED); // <-- Uncommenting this line magically fixes things.

      profiles = pipe.start(cfg, callback);
    }
    else {
      // Start streaming through the callback with default recommended configuration
      // The default video configuration contains Depth and Color streams
      // If a device is capable to stream IMU data, both Gyro and Accelerometer are enabled by default
      profiles = pipe.start(callback);
    }

    // Collect the enabled streams names
    for (auto p : profiles.get_streams())
        stream_names[p.unique_id()] = p.stream_name();

    std::cout << "RealSense callback sample" << std::endl << std::endl;

    while (true)
    {
        std::this_thread::sleep_for(std::chrono::seconds(1));

        std::lock_guard<std::mutex> lock(mutex);

        for (auto p : counters)
        {
            std::cout << stream_names[p.first] << "[" << p.first << "]: " << p.second << " [frames] || ";
        }
        std::cout << std::endl;
    }

    return EXIT_SUCCESS;
}
catch (const rs2::error & e)
{
    std::cerr << "RealSense error calling " << e.get_failed_function() << "(" << e.get_failed_args() << "):\n    " << e.what() << std::endl;
    return EXIT_FAILURE;
}
catch (const std::exception& e)
{
    std::cerr << e.what() << std::endl;
    return EXIT_FAILURE;
}
@rafaelspring
Copy link
Author

Duplicate of #6424

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

No branches or pull requests

1 participant