-
Notifications
You must be signed in to change notification settings - Fork 4.8k
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
Pipeline callback api #2773
Merged
dorodnic
merged 6 commits into
IntelRealSense:development
from
matkatz:pipeline_callback_api
Nov 28, 2018
Merged
Pipeline callback api #2773
Changes from all commits
Commits
Show all changes
6 commits
Select commit
Hold shift + click to select a range
3abefc2
callback api added to the pipeline
matkatz 4592fd4
fix osx compilation error
matkatz d18ec87
fix pipeline wait for device
matkatz cf1faa0
fix playback example
matkatz 87fe921
pipeline callback - CR fixes
matkatz a2406a5
Update readme.md
dorodnic File filter
Filter by extension
Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,25 @@ | ||
# minimum required cmake version: 3.1.0 | ||
cmake_minimum_required(VERSION 3.1.0) | ||
|
||
project(rs-callback) | ||
|
||
# Save the command line compile commands in the build output | ||
set(CMAKE_EXPORT_COMPILE_COMMANDS 1) | ||
|
||
include(CheckCXXCompilerFlag) | ||
CHECK_CXX_COMPILER_FLAG("-std=c++11" COMPILER_SUPPORTS_CXX11) | ||
CHECK_CXX_COMPILER_FLAG("-std=c++0x" COMPILER_SUPPORTS_CXX0X) | ||
if(COMPILER_SUPPORTS_CXX11) | ||
set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -std=c++11") | ||
elseif(COMPILER_SUPPORTS_CXX0X) | ||
set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -std=c++0x") | ||
endif() | ||
|
||
if(BUILD_GRAPHICAL_EXAMPLES) | ||
add_executable(${PROJECT_NAME} ${PROJECT_NAME}.cpp) | ||
target_link_libraries(${PROJECT_NAME} ${DEPENDENCIES}) | ||
include_directories(${PROJECT_NAME} ../ ../../third-party/tclap/include) | ||
set_target_properties (${PROJECT_NAME} PROPERTIES FOLDER "Examples") | ||
|
||
install(TARGETS ${PROJECT_NAME} RUNTIME DESTINATION ${CMAKE_INSTALL_BINDIR}) | ||
endif() |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,90 @@ | ||
# rs-callback Sample | ||
|
||
## Overview | ||
|
||
This sample demonstrates how to configure the camera for streaming frames using the pipeline's callback API. | ||
This API is recommended when streaming high frequency data such as IMU ([Inertial measurement unit](https://en.wikipedia.org/wiki/Inertial_measurement_unit)) since the callback is invoked immediately once the a frame is ready. | ||
This sample prints a frame counter for each stream, the code demonstrates how it can be done correctly by synchronizing the callbacks. | ||
|
||
## Expected Output | ||
![rs-callback](https://user-images.githubusercontent.com/18511514/48921401-37a0c680-eea8-11e8-9ab4-18e566d69a8a.PNG) | ||
|
||
## Code Overview | ||
|
||
First, we include the Intel® RealSense™ Cross-Platform API. | ||
All but advanced functionality is provided through a single header: | ||
```cpp | ||
#include <librealsense2/rs.hpp> // Include RealSense Cross Platform API | ||
``` | ||
|
||
We define frame counters that will be updated every time a frame arrives. | ||
This counters will be used in the application main loop to print how many frames arrived from each stream. | ||
```cpp | ||
std::map<int, int> counters; | ||
std::map<int, std::string> stream_names; | ||
``` | ||
|
||
The mutex object is a synchronization primitive that will be used to protect our frame counters from being simultaneously accessed by multiple threads. | ||
```cpp | ||
std::mutex mutex; | ||
``` | ||
|
||
Define the frame callback which will be invoked by the pipeline on the sensors thread once a frame (or synchronised frameset) is ready. | ||
```cpp | ||
// Define frame callback | ||
// The callback is executed on a sensor thread and can be called simultaneously from multiple sensors. | ||
// Therefore any modification to shared data 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 (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()]++; | ||
} | ||
}; | ||
``` | ||
|
||
The SDK API entry point is the `pipeline` class: | ||
```cpp | ||
// Declare the RealSense pipeline, encapsulating the actual device and sensors | ||
rs2::pipeline pipe; | ||
|
||
// 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 | ||
rs2::pipeline_profile profiles = pipe.start(callback); | ||
``` | ||
|
||
Collect the stream names from the returned `pipeline_profile` object: | ||
```cpp | ||
// Collect the enabled streams names | ||
for (auto p : profiles.get_streams()) | ||
stream_names[p.unique_id()] = p.stream_name(); | ||
``` | ||
|
||
Finally, print the frame counters once every second. | ||
After calling `start`, the main thread will continue to execute work, so even when no other action is required, we need to keep the application alive. | ||
In order to protect our counters from being accessed simultaneously, access the counters using the mutex. | ||
```cpp | ||
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); | ||
|
||
std::cout << "\r"; | ||
for (auto p : counters) | ||
{ | ||
std::cout << stream_names[p.first] << "[" << p.first << "]: " << p.second << " [frames] || "; | ||
} | ||
} | ||
``` |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,78 @@ | ||
// 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; | ||
|
||
// 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 | ||
// | ||
rs2::pipeline_profile 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); | ||
|
||
std::cout << "\r"; | ||
for (auto p : counters) | ||
{ | ||
std::cout << stream_names[p.first] << "[" << p.first << "]: " << p.second << " [frames] || "; | ||
} | ||
} | ||
|
||
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; | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,50 @@ | ||
# CMake Sample | ||
|
||
## Overview | ||
|
||
This sample demonstrates how to create a basic librealsense application using CMake. | ||
Currently this sample is supported only by Linux OS. | ||
|
||
## Prerequisite | ||
Install the SDK or build it from source ([Linux](https://github.com/IntelRealSense/librealsense/blob/master/doc/distribution_linux.md)) | ||
|
||
## Expected Output | ||
![cmake_example](https://user-images.githubusercontent.com/18511514/48919868-06bb9400-ee9e-11e8-9c93-5bca41d5954c.PNG) | ||
|
||
## Code Overview | ||
|
||
Set minimum required CMake version | ||
``` | ||
cmake_minimum_required(VERSION 3.1.0) | ||
``` | ||
|
||
Name the project, in this sample the project name will be also the executable name | ||
``` | ||
project(hello_librealsense2) | ||
``` | ||
|
||
Find librealsense installation, this feature is currently available only for Linux | ||
``` | ||
# Find librealsense2 installed package | ||
find_package(realsense2 REQUIRED) | ||
``` | ||
|
||
Enable C++ 11 standard in the applicatoin | ||
``` | ||
# Enable C++11 | ||
set(CMAKE_CXX_STANDARD 11) | ||
set(CMAKE_CXX_STANDARD_REQUIRED TRUE) | ||
``` | ||
|
||
Point to the source files, in this simple example we have only one cpp file | ||
``` | ||
# Add the application sources to the target | ||
add_executable(${PROJECT_NAME} hello_librealsense2.cpp) | ||
``` | ||
|
||
Link librealsense, the variable ${realsense2_LIBRARY} is set by "find_package" | ||
``` | ||
# Link librealsense2 to the target | ||
target_link_libraries(${PROJECT_NAME} ${realsense2_LIBRARY}) | ||
``` | ||
|
Oops, something went wrong.
Add this suggestion to a batch that can be applied as a single commit.
This suggestion is invalid because no changes were made to the code.
Suggestions cannot be applied while the pull request is closed.
Suggestions cannot be applied while viewing a subset of changes.
Only one suggestion per line can be applied in a batch.
Add this suggestion to a batch that can be applied as a single commit.
Applying suggestions on deleted lines is not supported.
You must change the existing code in this line in order to create a valid suggestion.
Outdated suggestions cannot be applied.
This suggestion has been applied or marked resolved.
Suggestions cannot be applied from pending reviews.
Suggestions cannot be applied on multi-line comments.
Suggestions cannot be applied while the pull request is queued to merge.
Suggestion cannot be applied right now. Please check back later.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Comment on the lock