diff --git a/README.md b/README.md index 15861d4..bc983cf 100644 --- a/README.md +++ b/README.md @@ -6,13 +6,14 @@ This repos is openFrameworks addon fo [IntelĀ® RealSenseā„¢ SDK 2.0](https://git ## Version - Realsense 2.14.1 (released on 2018.7) + - linux : Realsense SDK 2.17.0 - libusb 1.0.22 - openFrameworks 0.10.0 ## TODO - [x] OSX support - [x] Windows support -- [ ] Linux support +- [x] Linux support - v2.17.0 updated - [x] add ci scripts - [ ] add postprocessing example - [ ] add bag file playback example @@ -56,4 +57,4 @@ Unplug and plug camera again if you see strange data. ## Notice ### libusb in osx -- libusb is NOT included in this repo. Should be installed to your system with 'brew install libusb' at first SDK install step. \ No newline at end of file +- libusb is NOT included in this repo. Should be installed to your system with 'brew install libusb' at first SDK install step. diff --git a/addon_config.mk b/addon_config.mk index 97af0a7..baf525a 100755 --- a/addon_config.mk +++ b/addon_config.mk @@ -26,6 +26,8 @@ vs: ADDON_DLLS_TO_COPY = dlls_to_copy linux64: + ADDON_LDFLAGS = ../../../addons/ofxRealsense2/libs/realsense2/lib/linux64/librealsense2.so + linuxarmv6l: linuxarmv7l: msys2: diff --git a/libs/realsense2/include/librealsense2/h/rs_advanced_mode_command.h b/libs/realsense2/include/librealsense2/h/rs_advanced_mode_command.h old mode 100755 new mode 100644 diff --git a/libs/realsense2/include/librealsense2/h/rs_config.h b/libs/realsense2/include/librealsense2/h/rs_config.h new file mode 100644 index 0000000..c365b71 --- /dev/null +++ b/libs/realsense2/include/librealsense2/h/rs_config.h @@ -0,0 +1,198 @@ +/* License: Apache 2.0. See LICENSE file in root directory. +Copyright(c) 2017 Intel Corporation. All Rights Reserved. */ + +/** \file rs_pipeline.h +* \brief +* Exposes RealSense processing-block functionality for C compilers +*/ + + +#ifndef LIBREALSENSE_RS2_CONFIG_H +#define LIBREALSENSE_RS2_CONFIG_H + +#ifdef __cplusplus +extern "C" { +#endif + +#include "rs_types.h" +#include "rs_sensor.h" + + /** + * Create a config instance + * The config allows pipeline users to request filters for the pipeline streams and device selection and configuration. + * This is an optional step in pipeline creation, as the pipeline resolves its streaming device internally. + * Config provides its users a way to set the filters and test if there is no conflict with the pipeline requirements + * from the device. It also allows the user to find a matching device for the config filters and the pipeline, in order to + * select a device explicitly, and modify its controls before streaming starts. + * + * \param[out] error if non-null, receives any error that occurs during this call, otherwise, errors are ignored + * \return rs2_config* A pointer to a new config instance + */ + rs2_config* rs2_create_config(rs2_error** error); + + /** + * Deletes an instance of a config + * + * \param[in] config A pointer to an instance of a config + */ + void rs2_delete_config(rs2_config* config); + + /** + * Enable a device stream explicitly, with selected stream parameters. + * The method allows the application to request a stream with specific configuration. If no stream is explicitly enabled, the pipeline + * configures the device and its streams according to the attached computer vision modules and processing blocks requirements, or + * default configuration for the first available device. + * The application can configure any of the input stream parameters according to its requirement, or set to 0 for don't care value. + * The config accumulates the application calls for enable configuration methods, until the configuration is applied. Multiple enable + * stream calls for the same stream with conflicting parameters override each other, and the last call is maintained. + * Upon calling \c resolve(), the config checks for conflicts between the application configuration requests and the attached computer + * vision modules and processing blocks requirements, and fails if conflicts are found. Before \c resolve() is called, no conflict + * check is done. + * + * \param[in] config A pointer to an instance of a config + * \param[in] stream Stream type to be enabled + * \param[in] index Stream index, used for multiple streams of the same type. -1 indicates any. + * \param[in] width Stream image width - for images streams. 0 indicates any. + * \param[in] height Stream image height - for images streams. 0 indicates any. + * \param[in] format Stream data format - pixel format for images streams, of data type for other streams. RS2_FORMAT_ANY indicates any. + * \param[in] framerate Stream frames per second. 0 indicates any. + * \param[out] error if non-null, receives any error that occurs during this call, otherwise, errors are ignored + */ + void rs2_config_enable_stream(rs2_config* config, + rs2_stream stream, + int index, + int width, + int height, + rs2_format format, + int framerate, + rs2_error** error); + + /** + * Enable all device streams explicitly. + * The conditions and behavior of this method are similar to those of \c enable_stream(). + * This filter enables all raw streams of the selected device. The device is either selected explicitly by the application, + * or by the pipeline requirements or default. The list of streams is device dependent. + * + * \param[in] config A pointer to an instance of a config + * \param[out] error if non-null, receives any error that occurs during this call, otherwise, errors are ignored + */ + void rs2_config_enable_all_stream(rs2_config* config, rs2_error ** error); + + /** + * Select a specific device explicitly by its serial number, to be used by the pipeline. + * The conditions and behavior of this method are similar to those of \c enable_stream(). + * This method is required if the application needs to set device or sensor settings prior to pipeline streaming, to enforce + * the pipeline to use the configured device. + * + * \param[in] config A pointer to an instance of a config + * \param[in] serial device serial number, as returned by RS2_CAMERA_INFO_SERIAL_NUMBER + * \param[out] error if non-null, receives any error that occurs during this call, otherwise, errors are ignored + */ + void rs2_config_enable_device(rs2_config* config, const char* serial, rs2_error ** error); + + /** + * Select a recorded device from a file, to be used by the pipeline through playback. + * The device available streams are as recorded to the file, and \c resolve() considers only this device and configuration + * as available. + * This request cannot be used if enable_record_to_file() is called for the current config, and vise versa + * By default, playback is repeated once the file ends. To control this, see 'rs2_config_enable_device_from_file_repeat_option'. + * + * \param[in] config A pointer to an instance of a config + * \param[in] file The playback file of the device + * \param[out] error if non-null, receives any error that occurs during this call, otherwise, errors are ignored + */ + void rs2_config_enable_device_from_file(rs2_config* config, const char* file, rs2_error ** error); + + /** + * Select a recorded device from a file, to be used by the pipeline through playback. + * The device available streams are as recorded to the file, and \c resolve() considers only this device and configuration + * as available. + * This request cannot be used if enable_record_to_file() is called for the current config, and vise versa + * + * \param[in] config A pointer to an instance of a config + * \param[in] file The playback file of the device + * \param[in] repeat_playback if true, when file ends the playback starts again, in an infinite loop; + if false, when file ends playback does not start again, and should by stopped manually by the user. + * \param[out] error if non-null, receives any error that occurs during this call, otherwise, errors are ignored + */ + void rs2_config_enable_device_from_file_repeat_option(rs2_config* config, const char* file, int repeat_playback, rs2_error ** error); + + /** + * Requires that the resolved device would be recorded to file + * This request cannot be used if enable_device_from_file() is called for the current config, and vise versa + * + * \param[in] config A pointer to an instance of a config + * \param[in] file The desired file for the output record + * \param[out] error if non-null, receives any error that occurs during this call, otherwise, errors are ignored + */ + void rs2_config_enable_record_to_file(rs2_config* config, const char* file, rs2_error ** error); + + + /** + * Disable a device stream explicitly, to remove any requests on this stream type. + * The stream can still be enabled due to pipeline computer vision module request. This call removes any filter on the + * stream configuration. + * + * \param[in] config A pointer to an instance of a config + * \param[in] stream Stream type, for which the filters are cleared + * \param[out] error if non-null, receives any error that occurs during this call, otherwise, errors are ignored + */ + void rs2_config_disable_stream(rs2_config* config, rs2_stream stream, rs2_error ** error); + + /** + * Disable a device stream explicitly, to remove any requests on this stream profile. + * The stream can still be enabled due to pipeline computer vision module request. This call removes any filter on the + * stream configuration. + * + * \param[in] config A pointer to an instance of a config + * \param[in] stream Stream type, for which the filters are cleared + * \param[in] index Stream index, for which the filters are cleared + * \param[out] error if non-null, receives any error that occurs during this call, otherwise, errors are ignored + */ + void rs2_config_disable_indexed_stream(rs2_config* config, rs2_stream stream, int index, rs2_error ** error); + + /** + * Disable all device stream explicitly, to remove any requests on the streams profiles. + * The streams can still be enabled due to pipeline computer vision module request. This call removes any filter on the + * streams configuration. + * + * \param[in] config A pointer to an instance of a config + * \param[out] error if non-null, receives any error that occurs during this call, otherwise, errors are ignored + */ + void rs2_config_disable_all_streams(rs2_config* config, rs2_error ** error); + + /** + * Resolve the configuration filters, to find a matching device and streams profiles. + * The method resolves the user configuration filters for the device and streams, and combines them with the requirements of + * the computer vision modules and processing blocks attached to the pipeline. If there are no conflicts of requests, it looks + * for an available device, which can satisfy all requests, and selects the first matching streams configuration. In the absence + * of any request, the rs2::config selects the first available device and the first color and depth streams configuration. + * The pipeline profile selection during \c start() follows the same method. Thus, the selected profile is the same, if no + * change occurs to the available devices occurs. + * Resolving the pipeline configuration provides the application access to the pipeline selected device for advanced control. + * The returned configuration is not applied to the device, so the application doesn't own the device sensors. However, the + * application can call \c enable_device(), to enforce the device returned by this method is selected by pipeline \c start(), + * and configure the device and sensors options or extensions before streaming starts. + * + * \param[in] config A pointer to an instance of a config + * \param[in] pipe The pipeline for which the selected filters are applied + * \param[out] error if non-null, receives any error that occurs during this call, otherwise, errors are ignored + * \return A matching device and streams profile, which satisfies the filters and pipeline requests. + */ + rs2_pipeline_profile* rs2_config_resolve(rs2_config* config, rs2_pipeline* pipe, rs2_error ** error); + + /** + * Check if the config can resolve the configuration filters, to find a matching device and streams profiles. + * The resolution conditions are as described in \c resolve(). + * + * \param[in] config A pointer to an instance of a config + * \param[in] pipe The pipeline for which the selected filters are applied + * \param[out] error if non-null, receives any error that occurs during this call, otherwise, errors are ignored + * \return True if a valid profile selection exists, false if no selection can be found under the config filters and the available devices. + */ + int rs2_config_can_resolve(rs2_config* config, rs2_pipeline* pipe, rs2_error ** error); + +#ifdef __cplusplus +} +#endif +#endif diff --git a/libs/realsense2/include/librealsense2/h/rs_context.h b/libs/realsense2/include/librealsense2/h/rs_context.h old mode 100755 new mode 100644 index 52718f3..87d375b --- a/libs/realsense2/include/librealsense2/h/rs_context.h +++ b/libs/realsense2/include/librealsense2/h/rs_context.h @@ -71,6 +71,21 @@ void rs2_context_remove_device(rs2_context* ctx, const char* file, rs2_error** e */ rs2_device_list* rs2_query_devices(const rs2_context* context, rs2_error** error); +#define RS2_PRODUCT_LINE_ANY 0xff +#define RS2_PRODUCT_LINE_ANY_INTEL 0xfe +#define RS2_PRODUCT_LINE_NON_INTEL 0x01 +#define RS2_PRODUCT_LINE_D400 0x02 +#define RS2_PRODUCT_LINE_SR300 0x04 + +/** +* create a static snapshot of all connected devices at the time of the call +* \param context Object representing librealsense session +* \param product_mask Controls what kind of devices will be returned +* \param[out] error if non-null, receives any error that occurs during this call, otherwise, errors are ignored +* \return the list of devices, should be released by rs2_delete_device_list +*/ +rs2_device_list* rs2_query_devices_ex(const rs2_context* context, int product_mask, rs2_error** error); + /** * \brief Creates RealSense device_hub . * \param[in] context The context for the device hub @@ -93,7 +108,7 @@ void rs2_delete_device_hub(const rs2_device_hub* hub); * \param[out] error If non-null, receives any error that occurs during this call, otherwise, errors are ignored. * \return device object */ -rs2_device* rs2_device_hub_wait_for_device(rs2_context* ctx, const rs2_device_hub* hub, rs2_error** error); +rs2_device* rs2_device_hub_wait_for_device(const rs2_device_hub* hub, rs2_error** error); /** * Checks if device is still connected diff --git a/libs/realsense2/include/librealsense2/h/rs_device.h b/libs/realsense2/include/librealsense2/h/rs_device.h old mode 100755 new mode 100644 diff --git a/libs/realsense2/include/librealsense2/h/rs_frame.h b/libs/realsense2/include/librealsense2/h/rs_frame.h old mode 100755 new mode 100644 index c346d24..a69d42c --- a/libs/realsense2/include/librealsense2/h/rs_frame.h +++ b/libs/realsense2/include/librealsense2/h/rs_frame.h @@ -40,9 +40,9 @@ typedef enum rs2_frame_metadata_value RS2_FRAME_METADATA_BACKEND_TIMESTAMP , /**< Timestamp get from uvc driver. usec*/ RS2_FRAME_METADATA_ACTUAL_FPS , /**< Actual fps */ RS2_FRAME_METADATA_FRAME_LASER_POWER , /**< Laser power value 0-360. */ - RS2_FRAME_METADATA_FRAME_LASER_POWER_MODE , /**< Laser power mode. Zero corresponds to Laser power switched off and one for switched on. */ + RS2_FRAME_METADATA_FRAME_LASER_POWER_MODE , /**< Laser power mode. Zero corresponds to Laser power switched off and one for switched on. */ RS2_FRAME_METADATA_EXPOSURE_PRIORITY , /**< Exposure priority. */ - RS2_FRAME_METADATA_EXPOSURE_ROI_LEFT , /**< Left region of interest for the auto exposure Algorithm. */ + RS2_FRAME_METADATA_EXPOSURE_ROI_LEFT , /**< Left region of interest for the auto exposure Algorithm. */ RS2_FRAME_METADATA_EXPOSURE_ROI_RIGHT , /**< Right region of interest for the auto exposure Algorithm. */ RS2_FRAME_METADATA_EXPOSURE_ROI_TOP , /**< Top region of interest for the auto exposure Algorithm. */ RS2_FRAME_METADATA_EXPOSURE_ROI_BOTTOM , /**< Bottom region of interest for the auto exposure Algorithm. */ @@ -276,6 +276,17 @@ int rs2_is_frame_extendable_to(const rs2_frame* frame, rs2_extension extension_t rs2_frame* rs2_allocate_synthetic_video_frame(rs2_source* source, const rs2_stream_profile* new_stream, rs2_frame* original, int new_bpp, int new_width, int new_height, int new_stride, rs2_extension frame_type, rs2_error** error); +/** +* Allocate new points frame using a frame-source provided from a processing block +* \param[in] source Frame pool to allocate the frame from +* \param[in] new_stream New stream profile to assign to newly created frame +* \param[in] original A reference frame that can be used to fill in auxilary information like format, width, height, bpp, stride (if applicable) +* \param[out] error If non-null, receives any error that occurs during this call, otherwise, errors are ignored +* \return reference to a newly allocated frame, must be released with release_frame +* memory for the frame is likely to be re-used from previous frame, but in lack of available frames in the pool will be allocated from the free store +*/ +rs2_frame* rs2_allocate_points(rs2_source* source, const rs2_stream_profile* new_stream, rs2_frame* original, rs2_error** error); + /** * Allocate new composite frame, aggregating a set of existing frames * \param[in] source Frame pool to allocate the frame from @@ -323,9 +334,6 @@ void rs2_synthetic_frame_ready(rs2_source* source, rs2_frame* frame, rs2_error** */ void rs2_pose_frame_get_pose_data(const rs2_frame* frame, rs2_pose* pose, rs2_error** error); - - - #ifdef __cplusplus } #endif diff --git a/libs/realsense2/include/librealsense2/h/rs_internal.h b/libs/realsense2/include/librealsense2/h/rs_internal.h old mode 100755 new mode 100644 index d812c99..7081e88 --- a/libs/realsense2/include/librealsense2/h/rs_internal.h +++ b/libs/realsense2/include/librealsense2/h/rs_internal.h @@ -30,7 +30,7 @@ typedef enum rs2_recording_mode RS2_RECORDING_MODE_COUNT } rs2_recording_mode; -/** \brief All the parameters are requaired to defind video stream*/ +/** \brief All the parameters are requaired to define video stream*/ typedef struct rs2_video_stream { rs2_stream type; @@ -44,6 +44,27 @@ typedef struct rs2_video_stream rs2_intrinsics intrinsics; } rs2_video_stream; +/** \brief All the parameters are requaired to define motion stream*/ +typedef struct rs2_motion_stream +{ + rs2_stream type; + int index; + int uid; + int fps; + rs2_format fmt; + rs2_motion_device_intrinsic intrinsics; +} rs2_motion_stream; + +/** \brief All the parameters are requaired to define pose stream*/ +typedef struct rs2_pose_stream +{ + rs2_stream type; + int index; + int uid; + int fps; + rs2_format fmt; +} rs2_pose_stream; + /** \brief All the parameters are requaired to define video frame*/ typedef struct rs2_software_video_frame { @@ -57,6 +78,39 @@ typedef struct rs2_software_video_frame const rs2_stream_profile* profile; } rs2_software_video_frame; +/** \brief All the parameters are requaired to define motion frame*/ +typedef struct rs2_software_motion_frame +{ + void* data; + void(*deleter)(void*); + rs2_time_t timestamp; + rs2_timestamp_domain domain; + int frame_number; + const rs2_stream_profile* profile; +} rs2_software_motion_frame; + +/** \brief All the parameters are requaired to define pose frame*/ +typedef struct rs2_software_pose_frame +{ + struct pose_frame_info + { + float translation[3]; + float velocity[3]; + float acceleration[3]; + float rotation[4]; + float angular_velocity[3]; + float angular_acceleration[3]; + int tracker_confidence; + int mapper_confidence; + }; + void* data; + void(*deleter)(void*); + rs2_time_t timestamp; + rs2_timestamp_domain domain; + int frame_number; + const rs2_stream_profile* profile; +} rs2_software_pose_frame; + /** * Create librealsense context that will try to record all operations over librealsense into a file * \param[in] api_version realsense API version as provided by RS2_API_VERSION macro @@ -108,13 +162,29 @@ rs2_device* rs2_create_software_device(rs2_error** error); rs2_sensor* rs2_software_device_add_sensor(rs2_device* dev, const char* sensor_name, rs2_error** error); /** - * Inject frame to software sonsor + * Inject video frame to software sonsor * \param[in] sensor the software sensor * \param[in] frame all the frame components * \param[out] error if non-null, receives any error that occurs during this call, otherwise, errors are ignored */ void rs2_software_sensor_on_video_frame(rs2_sensor* sensor, rs2_software_video_frame frame, rs2_error** error); +/** +* Inject motion frame to software sonsor +* \param[in] sensor the software sensor +* \param[in] frame all the frame components +* \param[out] error if non-null, receives any error that occurs during this call, otherwise, errors are ignored +*/ +void rs2_software_sensor_on_motion_frame(rs2_sensor* sensor, rs2_software_motion_frame frame, rs2_error** error); + +/** +* Inject pose frame to software sonsor +* \param[in] sensor the software sensor +* \param[in] frame all the frame components +* \param[out] error if non-null, receives any error that occurs during this call, otherwise, errors are ignored +*/ +void rs2_software_sensor_on_pose_frame(rs2_sensor* sensor, rs2_software_pose_frame frame, rs2_error** error); + /** * Set frame metadata for the upcoming frames * \param[in] sensor the software sensor @@ -140,6 +210,22 @@ void rs2_software_device_create_matcher(rs2_device* dev, rs2_matchers matcher, r */ rs2_stream_profile* rs2_software_sensor_add_video_stream(rs2_sensor* sensor, rs2_video_stream video_stream, rs2_error** error); +/** +* Add motion stream to sensor +* \param[in] sensor the software sensor +* \param[in] video_stream all the stream components +* \param[out] error if non-null, receives any error that occurs during this call, otherwise, errors are ignored +*/ +rs2_stream_profile* rs2_software_sensor_add_motion_stream(rs2_sensor* sensor, rs2_motion_stream motion_stream, rs2_error** error); + +/** +* Add pose stream to sensor +* \param[in] sensor the software sensor +* \param[in] video_stream all the stream components +* \param[out] error if non-null, receives any error that occurs during this call, otherwise, errors are ignored +*/ +rs2_stream_profile* rs2_software_sensor_add_pose_stream(rs2_sensor* sensor, rs2_pose_stream pose_stream, rs2_error** error); + /** * Add read only option to sensor * \param[in] sensor the software sensor diff --git a/libs/realsense2/include/librealsense2/h/rs_option.h b/libs/realsense2/include/librealsense2/h/rs_option.h old mode 100755 new mode 100644 index 71be14b..215da93 --- a/libs/realsense2/include/librealsense2/h/rs_option.h +++ b/libs/realsense2/include/librealsense2/h/rs_option.h @@ -1,5 +1,5 @@ /* License: Apache 2.0. See LICENSE file in root directory. - Copyright(c) 2017 Intel Corporation. All Rights Reserved. */ +Copyright(c) 2017 Intel Corporation. All Rights Reserved. */ /** \file rs_option.h * \brief @@ -16,156 +16,159 @@ extern "C" { #include "rs_types.h" -/** \brief Defines general configuration controls. + /** \brief Defines general configuration controls. These can generally be mapped to camera UVC controls, and unless stated otherwise, can be set/queried at any time. */ -typedef enum rs2_option -{ - RS2_OPTION_BACKLIGHT_COMPENSATION , /**< Enable / disable color backlight compensation*/ - RS2_OPTION_BRIGHTNESS , /**< Color image brightness*/ - RS2_OPTION_CONTRAST , /**< Color image contrast*/ - RS2_OPTION_EXPOSURE , /**< Controls exposure time of color camera. Setting any value will disable auto exposure*/ - RS2_OPTION_GAIN , /**< Color image gain*/ - RS2_OPTION_GAMMA , /**< Color image gamma setting*/ - RS2_OPTION_HUE , /**< Color image hue*/ - RS2_OPTION_SATURATION , /**< Color image saturation setting*/ - RS2_OPTION_SHARPNESS , /**< Color image sharpness setting*/ - RS2_OPTION_WHITE_BALANCE , /**< Controls white balance of color image. Setting any value will disable auto white balance*/ - RS2_OPTION_ENABLE_AUTO_EXPOSURE , /**< Enable / disable color image auto-exposure*/ - RS2_OPTION_ENABLE_AUTO_WHITE_BALANCE , /**< Enable / disable color image auto-white-balance*/ - RS2_OPTION_VISUAL_PRESET , /**< Provide access to several recommend sets of option presets for the depth camera */ - RS2_OPTION_LASER_POWER , /**< Power of the F200 / SR300 projector, with 0 meaning projector off*/ - RS2_OPTION_ACCURACY , /**< Set the number of patterns projected per frame. The higher the accuracy value the more patterns projected. Increasing the number of patterns help to achieve better accuracy. Note that this control is affecting the Depth FPS */ - RS2_OPTION_MOTION_RANGE , /**< Motion vs. Range trade-off, with lower values allowing for better motion sensitivity and higher values allowing for better depth range*/ - RS2_OPTION_FILTER_OPTION , /**< Set the filter to apply to each depth frame. Each one of the filter is optimized per the application requirements*/ - RS2_OPTION_CONFIDENCE_THRESHOLD , /**< The confidence level threshold used by the Depth algorithm pipe to set whether a pixel will get a valid range or will be marked with invalid range*/ - RS2_OPTION_EMITTER_ENABLED , /**< Laser Emitter enabled */ - RS2_OPTION_FRAMES_QUEUE_SIZE , /**< Number of frames the user is allowed to keep per stream. Trying to hold-on to more frames will cause frame-drops.*/ - RS2_OPTION_TOTAL_FRAME_DROPS , /**< Total number of detected frame drops from all streams */ - RS2_OPTION_AUTO_EXPOSURE_MODE , /**< Auto-Exposure modes: Static, Anti-Flicker and Hybrid */ - RS2_OPTION_POWER_LINE_FREQUENCY , /**< Power Line Frequency control for anti-flickering Off/50Hz/60Hz/Auto */ - RS2_OPTION_ASIC_TEMPERATURE , /**< Current Asic Temperature */ - RS2_OPTION_ERROR_POLLING_ENABLED , /**< disable error handling */ - RS2_OPTION_PROJECTOR_TEMPERATURE , /**< Current Projector Temperature */ - RS2_OPTION_OUTPUT_TRIGGER_ENABLED , /**< Enable / disable trigger to be outputed from the camera to any external device on every depth frame */ - RS2_OPTION_MOTION_MODULE_TEMPERATURE , /**< Current Motion-Module Temperature */ - RS2_OPTION_DEPTH_UNITS , /**< Number of meters represented by a single depth unit */ - RS2_OPTION_ENABLE_MOTION_CORRECTION , /**< Enable/Disable automatic correction of the motion data */ - RS2_OPTION_AUTO_EXPOSURE_PRIORITY , /**< Allows sensor to dynamically ajust the frame rate depending on lighting conditions */ - RS2_OPTION_COLOR_SCHEME , /**< Color scheme for data visualization */ - RS2_OPTION_HISTOGRAM_EQUALIZATION_ENABLED , /**< Perform histogram equalization post-processing on the depth data */ - RS2_OPTION_MIN_DISTANCE , /**< Minimal distance to the target */ - RS2_OPTION_MAX_DISTANCE , /**< Maximum distance to the target */ - RS2_OPTION_TEXTURE_SOURCE , /**< Texture mapping stream unique ID */ - RS2_OPTION_FILTER_MAGNITUDE , /**< The 2D-filter effect. The specific interpretation is given within the context of the filter */ - RS2_OPTION_FILTER_SMOOTH_ALPHA , /**< 2D-filter parameter controls the weight/radius for smoothing.*/ - RS2_OPTION_FILTER_SMOOTH_DELTA , /**< 2D-filter range/validity threshold*/ - RS2_OPTION_HOLES_FILL , /**< Enhance depth data post-processing with holes filling where appropriate*/ - RS2_OPTION_STEREO_BASELINE , /**< The distance in mm between the first and the second imagers in stereo-based depth cameras*/ - RS2_OPTION_AUTO_EXPOSURE_CONVERGE_STEP , /**< Allows dynamically ajust the converge step value of the target exposure in Auto-Exposure algorithm*/ - RS2_OPTION_INTER_CAM_SYNC_MODE , /**< Impose Inter-camera HW synchronization mode. Applicable for D400/Rolling Shutter SKUs */ - RS2_OPTION_COUNT /**< Number of enumeration values. Not a valid input: intended to be used in for-loops. */ -} rs2_option; -const char* rs2_option_to_string(rs2_option option); - -/** \brief For SR300 devices: provides optimized settings (presets) for specific types of usage. */ -typedef enum rs2_sr300_visual_preset -{ - RS2_SR300_VISUAL_PRESET_SHORT_RANGE , /**< Preset for short range */ - RS2_SR300_VISUAL_PRESET_LONG_RANGE , /**< Preset for long range */ - RS2_SR300_VISUAL_PRESET_BACKGROUND_SEGMENTATION , /**< Preset for background segmentation */ - RS2_SR300_VISUAL_PRESET_GESTURE_RECOGNITION , /**< Preset for gesture recognition */ - RS2_SR300_VISUAL_PRESET_OBJECT_SCANNING , /**< Preset for object scanning */ - RS2_SR300_VISUAL_PRESET_FACE_ANALYTICS , /**< Preset for face analytics */ - RS2_SR300_VISUAL_PRESET_FACE_LOGIN , /**< Preset for face login */ - RS2_SR300_VISUAL_PRESET_GR_CURSOR , /**< Preset for GR cursor */ - RS2_SR300_VISUAL_PRESET_DEFAULT , /**< Camera default settings */ - RS2_SR300_VISUAL_PRESET_MID_RANGE , /**< Preset for mid-range */ - RS2_SR300_VISUAL_PRESET_IR_ONLY , /**< Preset for IR only */ - RS2_SR300_VISUAL_PRESET_COUNT /**< Number of enumeration values. Not a valid input: intended to be used in for-loops. */ -} rs2_sr300_visual_preset; -const char* rs2_sr300_visual_preset_to_string(rs2_sr300_visual_preset preset); - -/** \brief For RS400 devices: provides optimized settings (presets) for specific types of usage. */ -typedef enum rs2_rs400_visual_preset -{ - RS2_RS400_VISUAL_PRESET_CUSTOM, - RS2_RS400_VISUAL_PRESET_DEFAULT, - RS2_RS400_VISUAL_PRESET_HAND, - RS2_RS400_VISUAL_PRESET_HIGH_ACCURACY, - RS2_RS400_VISUAL_PRESET_HIGH_DENSITY, - RS2_RS400_VISUAL_PRESET_MEDIUM_DENSITY, - RS2_RS400_VISUAL_PRESET_REMOVE_IR_PATTERN, - RS2_RS400_VISUAL_PRESET_COUNT -} rs2_rs400_visual_preset; -const char* rs2_rs400_visual_preset_to_string(rs2_rs400_visual_preset preset); - -/** -* check if an option is read-only -* \param[in] sensor the RealSense sensor -* \param[in] option option id to be checked -* \param[out] error if non-null, receives any error that occurs during this call, otherwise, errors are ignored -* \return true if option is read-only -*/ -int rs2_is_option_read_only(const rs2_options* options, rs2_option option, rs2_error** error); - -/** -* read option value from the sensor -* \param[in] sensor the RealSense sensor -* \param[in] option option id to be queried -* \param[out] error if non-null, receives any error that occurs during this call, otherwise, errors are ignored -* \return value of the option -*/ -float rs2_get_option(const rs2_options* options, rs2_option option, rs2_error** error); - -/** -* write new value to sensor option -* \param[in] sensor the RealSense sensor -* \param[in] option option id to be queried -* \param[in] value new value for the option -* \param[out] error if non-null, receives any error that occurs during this call, otherwise, errors are ignored -*/ -void rs2_set_option(const rs2_options* options, rs2_option option, float value, rs2_error** error); - -/** -* check if particular option is supported by a subdevice -* \param[in] sensor the RealSense sensor -* \param[in] option option id to be checked -* \param[out] error if non-null, receives any error that occurs during this call, otherwise, errors are ignored -* \return true if option is supported -*/ -int rs2_supports_option(const rs2_options* options, rs2_option option, rs2_error** error); - -/** -* retrieve the available range of values of a supported option -* \param[in] sensor the RealSense device -* \param[in] option the option whose range should be queried -* \param[out] min the minimum value which will be accepted for this option -* \param[out] max the maximum value which will be accepted for this option -* \param[out] step the granularity of options which accept discrete values, or zero if the option accepts continuous values -* \param[out] def the default value of the option -* \param[out] error if non-null, receives any error that occurs during this call, otherwise, errors are ignored -*/ -void rs2_get_option_range(const rs2_options* sensor, rs2_option option, float* min, float* max, float* step, float* def, rs2_error** error); - -/** -* get option description -* \param[in] sensor the RealSense sensor -* \param[in] option option id to be checked -* \param[out] error if non-null, receives any error that occurs during this call, otherwise, errors are ignored -* \return human-readable option description -*/ -const char* rs2_get_option_description(const rs2_options* options, rs2_option option, rs2_error ** error); - -/** -* get option value description (in case specific option value hold special meaning) -* \param[in] device the RealSense device -* \param[in] option option id to be checked -* \param[in] value value of the option -* \param[out] error if non-null, receives any error that occurs during this call, otherwise, errors are ignored -* \return human-readable description of a specific value of an option or null if no special meaning -*/ -const char* rs2_get_option_value_description(const rs2_options* options, rs2_option option, float value, rs2_error ** error); + typedef enum rs2_option + { + RS2_OPTION_BACKLIGHT_COMPENSATION, /**< Enable / disable color backlight compensation*/ + RS2_OPTION_BRIGHTNESS, /**< Color image brightness*/ + RS2_OPTION_CONTRAST, /**< Color image contrast*/ + RS2_OPTION_EXPOSURE, /**< Controls exposure time of color camera. Setting any value will disable auto exposure*/ + RS2_OPTION_GAIN, /**< Color image gain*/ + RS2_OPTION_GAMMA, /**< Color image gamma setting*/ + RS2_OPTION_HUE, /**< Color image hue*/ + RS2_OPTION_SATURATION, /**< Color image saturation setting*/ + RS2_OPTION_SHARPNESS, /**< Color image sharpness setting*/ + RS2_OPTION_WHITE_BALANCE, /**< Controls white balance of color image. Setting any value will disable auto white balance*/ + RS2_OPTION_ENABLE_AUTO_EXPOSURE, /**< Enable / disable color image auto-exposure*/ + RS2_OPTION_ENABLE_AUTO_WHITE_BALANCE, /**< Enable / disable color image auto-white-balance*/ + RS2_OPTION_VISUAL_PRESET, /**< Provide access to several recommend sets of option presets for the depth camera */ + RS2_OPTION_LASER_POWER, /**< Power of the F200 / SR300 projector, with 0 meaning projector off*/ + RS2_OPTION_ACCURACY, /**< Set the number of patterns projected per frame. The higher the accuracy value the more patterns projected. Increasing the number of patterns help to achieve better accuracy. Note that this control is affecting the Depth FPS */ + RS2_OPTION_MOTION_RANGE, /**< Motion vs. Range trade-off, with lower values allowing for better motion sensitivity and higher values allowing for better depth range*/ + RS2_OPTION_FILTER_OPTION, /**< Set the filter to apply to each depth frame. Each one of the filter is optimized per the application requirements*/ + RS2_OPTION_CONFIDENCE_THRESHOLD, /**< The confidence level threshold used by the Depth algorithm pipe to set whether a pixel will get a valid range or will be marked with invalid range*/ + RS2_OPTION_EMITTER_ENABLED, /**< Laser Emitter enabled */ + RS2_OPTION_FRAMES_QUEUE_SIZE, /**< Number of frames the user is allowed to keep per stream. Trying to hold-on to more frames will cause frame-drops.*/ + RS2_OPTION_TOTAL_FRAME_DROPS, /**< Total number of detected frame drops from all streams */ + RS2_OPTION_AUTO_EXPOSURE_MODE, /**< Auto-Exposure modes: Static, Anti-Flicker and Hybrid */ + RS2_OPTION_POWER_LINE_FREQUENCY, /**< Power Line Frequency control for anti-flickering Off/50Hz/60Hz/Auto */ + RS2_OPTION_ASIC_TEMPERATURE, /**< Current Asic Temperature */ + RS2_OPTION_ERROR_POLLING_ENABLED, /**< disable error handling */ + RS2_OPTION_PROJECTOR_TEMPERATURE, /**< Current Projector Temperature */ + RS2_OPTION_OUTPUT_TRIGGER_ENABLED, /**< Enable / disable trigger to be outputed from the camera to any external device on every depth frame */ + RS2_OPTION_MOTION_MODULE_TEMPERATURE, /**< Current Motion-Module Temperature */ + RS2_OPTION_DEPTH_UNITS, /**< Number of meters represented by a single depth unit */ + RS2_OPTION_ENABLE_MOTION_CORRECTION, /**< Enable/Disable automatic correction of the motion data */ + RS2_OPTION_AUTO_EXPOSURE_PRIORITY, /**< Allows sensor to dynamically ajust the frame rate depending on lighting conditions */ + RS2_OPTION_COLOR_SCHEME, /**< Color scheme for data visualization */ + RS2_OPTION_HISTOGRAM_EQUALIZATION_ENABLED, /**< Perform histogram equalization post-processing on the depth data */ + RS2_OPTION_MIN_DISTANCE, /**< Minimal distance to the target */ + RS2_OPTION_MAX_DISTANCE, /**< Maximum distance to the target */ + RS2_OPTION_TEXTURE_SOURCE, /**< Texture mapping stream unique ID */ + RS2_OPTION_FILTER_MAGNITUDE, /**< The 2D-filter effect. The specific interpretation is given within the context of the filter */ + RS2_OPTION_FILTER_SMOOTH_ALPHA, /**< 2D-filter parameter controls the weight/radius for smoothing.*/ + RS2_OPTION_FILTER_SMOOTH_DELTA, /**< 2D-filter range/validity threshold*/ + RS2_OPTION_HOLES_FILL, /**< Enhance depth data post-processing with holes filling where appropriate*/ + RS2_OPTION_STEREO_BASELINE, /**< The distance in mm between the first and the second imagers in stereo-based depth cameras*/ + RS2_OPTION_AUTO_EXPOSURE_CONVERGE_STEP, /**< Allows dynamically ajust the converge step value of the target exposure in Auto-Exposure algorithm*/ + RS2_OPTION_INTER_CAM_SYNC_MODE, /**< Impose Inter-camera HW synchronization mode. Applicable for D400/Rolling Shutter SKUs */ + RS2_OPTION_STREAM_FILTER, /**< Select a stream to process */ + RS2_OPTION_STREAM_FORMAT_FILTER, /**< Select a stream format to process */ + RS2_OPTION_STREAM_INDEX_FILTER, /**< Select a stream index to process */ + RS2_OPTION_COUNT /**< Number of enumeration values. Not a valid input: intended to be used in for-loops. */ + } rs2_option; + const char* rs2_option_to_string(rs2_option option); + + /** \brief For SR300 devices: provides optimized settings (presets) for specific types of usage. */ + typedef enum rs2_sr300_visual_preset + { + RS2_SR300_VISUAL_PRESET_SHORT_RANGE, /**< Preset for short range */ + RS2_SR300_VISUAL_PRESET_LONG_RANGE, /**< Preset for long range */ + RS2_SR300_VISUAL_PRESET_BACKGROUND_SEGMENTATION, /**< Preset for background segmentation */ + RS2_SR300_VISUAL_PRESET_GESTURE_RECOGNITION, /**< Preset for gesture recognition */ + RS2_SR300_VISUAL_PRESET_OBJECT_SCANNING, /**< Preset for object scanning */ + RS2_SR300_VISUAL_PRESET_FACE_ANALYTICS, /**< Preset for face analytics */ + RS2_SR300_VISUAL_PRESET_FACE_LOGIN, /**< Preset for face login */ + RS2_SR300_VISUAL_PRESET_GR_CURSOR, /**< Preset for GR cursor */ + RS2_SR300_VISUAL_PRESET_DEFAULT, /**< Camera default settings */ + RS2_SR300_VISUAL_PRESET_MID_RANGE, /**< Preset for mid-range */ + RS2_SR300_VISUAL_PRESET_IR_ONLY, /**< Preset for IR only */ + RS2_SR300_VISUAL_PRESET_COUNT /**< Number of enumeration values. Not a valid input: intended to be used in for-loops. */ + } rs2_sr300_visual_preset; + const char* rs2_sr300_visual_preset_to_string(rs2_sr300_visual_preset preset); + + /** \brief For RS400 devices: provides optimized settings (presets) for specific types of usage. */ + typedef enum rs2_rs400_visual_preset + { + RS2_RS400_VISUAL_PRESET_CUSTOM, + RS2_RS400_VISUAL_PRESET_DEFAULT, + RS2_RS400_VISUAL_PRESET_HAND, + RS2_RS400_VISUAL_PRESET_HIGH_ACCURACY, + RS2_RS400_VISUAL_PRESET_HIGH_DENSITY, + RS2_RS400_VISUAL_PRESET_MEDIUM_DENSITY, + RS2_RS400_VISUAL_PRESET_REMOVE_IR_PATTERN, + RS2_RS400_VISUAL_PRESET_COUNT + } rs2_rs400_visual_preset; + const char* rs2_rs400_visual_preset_to_string(rs2_rs400_visual_preset preset); + + /** + * check if an option is read-only + * \param[in] sensor the RealSense sensor + * \param[in] option option id to be checked + * \param[out] error if non-null, receives any error that occurs during this call, otherwise, errors are ignored + * \return true if option is read-only + */ + int rs2_is_option_read_only(const rs2_options* options, rs2_option option, rs2_error** error); + + /** + * read option value from the sensor + * \param[in] sensor the RealSense sensor + * \param[in] option option id to be queried + * \param[out] error if non-null, receives any error that occurs during this call, otherwise, errors are ignored + * \return value of the option + */ + float rs2_get_option(const rs2_options* options, rs2_option option, rs2_error** error); + + /** + * write new value to sensor option + * \param[in] sensor the RealSense sensor + * \param[in] option option id to be queried + * \param[in] value new value for the option + * \param[out] error if non-null, receives any error that occurs during this call, otherwise, errors are ignored + */ + void rs2_set_option(const rs2_options* options, rs2_option option, float value, rs2_error** error); + + /** + * check if particular option is supported by a subdevice + * \param[in] sensor the RealSense sensor + * \param[in] option option id to be checked + * \param[out] error if non-null, receives any error that occurs during this call, otherwise, errors are ignored + * \return true if option is supported + */ + int rs2_supports_option(const rs2_options* options, rs2_option option, rs2_error** error); + + /** + * retrieve the available range of values of a supported option + * \param[in] sensor the RealSense device + * \param[in] option the option whose range should be queried + * \param[out] min the minimum value which will be accepted for this option + * \param[out] max the maximum value which will be accepted for this option + * \param[out] step the granularity of options which accept discrete values, or zero if the option accepts continuous values + * \param[out] def the default value of the option + * \param[out] error if non-null, receives any error that occurs during this call, otherwise, errors are ignored + */ + void rs2_get_option_range(const rs2_options* sensor, rs2_option option, float* min, float* max, float* step, float* def, rs2_error** error); + + /** + * get option description + * \param[in] sensor the RealSense sensor + * \param[in] option option id to be checked + * \param[out] error if non-null, receives any error that occurs during this call, otherwise, errors are ignored + * \return human-readable option description + */ + const char* rs2_get_option_description(const rs2_options* options, rs2_option option, rs2_error ** error); + + /** + * get option value description (in case specific option value hold special meaning) + * \param[in] device the RealSense device + * \param[in] option option id to be checked + * \param[in] value value of the option + * \param[out] error if non-null, receives any error that occurs during this call, otherwise, errors are ignored + * \return human-readable description of a specific value of an option or null if no special meaning + */ + const char* rs2_get_option_value_description(const rs2_options* options, rs2_option option, float value, rs2_error ** error); #ifdef __cplusplus } diff --git a/libs/realsense2/include/librealsense2/h/rs_pipeline.h b/libs/realsense2/include/librealsense2/h/rs_pipeline.h old mode 100755 new mode 100644 index f617236..1018c77 --- a/libs/realsense2/include/librealsense2/h/rs_pipeline.h +++ b/libs/realsense2/include/librealsense2/h/rs_pipeline.h @@ -16,6 +16,7 @@ extern "C" { #include "rs_types.h" #include "rs_sensor.h" +#include "rs_config.h" /** * Create a pipeline instance @@ -111,7 +112,6 @@ extern "C" { */ rs2_pipeline_profile* rs2_pipeline_start(rs2_pipeline* pipe, rs2_error ** error); - /** * Start the pipeline streaming according to the configuraion. * The pipeline streaming loop captures samples from the device, and delivers them to the attached computer vision modules @@ -132,6 +132,72 @@ extern "C" { */ rs2_pipeline_profile* rs2_pipeline_start_with_config(rs2_pipeline* pipe, rs2_config* config, rs2_error ** error); + /** + * Start the pipeline streaming with its default configuration. + * The pipeline captures samples from the device, and delivers them to the through the provided frame callback. + * Starting the pipeline is possible only when it is not started. If the pipeline was started, an exception is raised. + * When starting the pipeline with a callback both \c wait_for_frames() or \c poll_for_frames() will throw exception. + * + * \param[in] pipe A pointer to an instance of the pipeline + * \param[in] on_frame function pointer to register as per-frame callback + * \param[in] user auxiliary data the user wishes to receive together with every frame callback + * \param[out] error If non-null, receives any error that occurs during this call, otherwise, errors are ignored + * \return The actual pipeline device and streams profile, which was successfully configured to the streaming device. + */ + rs2_pipeline_profile* rs2_pipeline_start_with_callback(rs2_pipeline* pipe, rs2_frame_callback_ptr on_frame, void* user, rs2_error ** error); + + /** + * Start the pipeline streaming with its default configuration. + * The pipeline captures samples from the device, and delivers them to the through the provided frame callback. + * Starting the pipeline is possible only when it is not started. If the pipeline was started, an exception is raised. + * When starting the pipeline with a callback both \c wait_for_frames() or \c poll_for_frames() will throw exception. + * + * \param[in] pipe A pointer to an instance of the pipeline + * \param[in] callback callback object created from c++ application. ownership over the callback object is moved into the relevant streaming lock + * \param[out] error If non-null, receives any error that occurs during this call, otherwise, errors are ignored + * \return The actual pipeline device and streams profile, which was successfully configured to the streaming device. + */ + rs2_pipeline_profile* rs2_pipeline_start_with_callback_cpp(rs2_pipeline* pipe, rs2_frame_callback* callback, rs2_error ** error); + + /** + * Start the pipeline streaming according to the configuraion. + * The pipeline captures samples from the device, and delivers them to the through the provided frame callback. + * Starting the pipeline is possible only when it is not started. If the pipeline was started, an exception is raised. + * When starting the pipeline with a callback both \c wait_for_frames() or \c poll_for_frames() will throw exception. + * The pipeline selects and activates the device upon start, according to configuration or a default configuration. + * When the rs2::config is provided to the method, the pipeline tries to activate the config \c resolve() result. If the application + * requests are conflicting with pipeline computer vision modules or no matching device is available on the platform, the method fails. + * Available configurations and devices may change between config \c resolve() call and pipeline start, in case devices are connected + * or disconnected, or another application acquires ownership of a device. + * + * \param[in] pipe A pointer to an instance of the pipeline + * \param[in] config A rs2::config with requested filters on the pipeline configuration. By default no filters are applied. + * \param[in] on_frame function pointer to register as per-frame callback + * \param[in] user auxiliary data the user wishes to receive together with every frame callback + * \param[out] error If non-null, receives any error that occurs during this call, otherwise, errors are ignored + * \return The actual pipeline device and streams profile, which was successfully configured to the streaming device. + */ + rs2_pipeline_profile* rs2_pipeline_start_with_config_and_callback(rs2_pipeline* pipe, rs2_config* config, rs2_frame_callback_ptr on_frame, void* user, rs2_error ** error); + + /** + * Start the pipeline streaming according to the configuraion. + * The pipeline captures samples from the device, and delivers them to the through the provided frame callback. + * Starting the pipeline is possible only when it is not started. If the pipeline was started, an exception is raised. + * When starting the pipeline with a callback both \c wait_for_frames() or \c poll_for_frames() will throw exception. + * The pipeline selects and activates the device upon start, according to configuration or a default configuration. + * When the rs2::config is provided to the method, the pipeline tries to activate the config \c resolve() result. If the application + * requests are conflicting with pipeline computer vision modules or no matching device is available on the platform, the method fails. + * Available configurations and devices may change between config \c resolve() call and pipeline start, in case devices are connected + * or disconnected, or another application acquires ownership of a device. + * + * \param[in] pipe A pointer to an instance of the pipeline + * \param[in] config A rs2::config with requested filters on the pipeline configuration. By default no filters are applied. + * \param[in] callback callback object created from c++ application. ownership over the callback object is moved into the relevant streaming lock + * \param[out] error If non-null, receives any error that occurs during this call, otherwise, errors are ignored + * \return The actual pipeline device and streams profile, which was successfully configured to the streaming device. + */ + rs2_pipeline_profile* rs2_pipeline_start_with_config_and_callback_cpp(rs2_pipeline* pipe, rs2_config* config, rs2_frame_callback* callback, rs2_error ** error); + /** * Return the active device and streams profiles, used by the pipeline. * The pipeline streams profiles are selected during \c start(). The method returns a valid result only when the pipeline is active - @@ -175,181 +241,6 @@ extern "C" { */ void rs2_delete_pipeline_profile(rs2_pipeline_profile* profile); - /** - * Create a config instance - * The config allows pipeline users to request filters for the pipeline streams and device selection and configuration. - * This is an optional step in pipeline creation, as the pipeline resolves its streaming device internally. - * Config provides its users a way to set the filters and test if there is no conflict with the pipeline requirements - * from the device. It also allows the user to find a matching device for the config filters and the pipeline, in order to - * select a device explicitly, and modify its controls before streaming starts. - * - * \param[out] error if non-null, receives any error that occurs during this call, otherwise, errors are ignored - * \return rs2_config* A pointer to a new config instance - */ - rs2_config* rs2_create_config(rs2_error** error); - - /** - * Deletes an instance of a config - * - * \param[in] config A pointer to an instance of a config - */ - void rs2_delete_config(rs2_config* config); - - /** - * Enable a device stream explicitly, with selected stream parameters. - * The method allows the application to request a stream with specific configuration. If no stream is explicitly enabled, the pipeline - * configures the device and its streams according to the attached computer vision modules and processing blocks requirements, or - * default configuration for the first available device. - * The application can configure any of the input stream parameters according to its requirement, or set to 0 for don't care value. - * The config accumulates the application calls for enable configuration methods, until the configuration is applied. Multiple enable - * stream calls for the same stream with conflicting parameters override each other, and the last call is maintained. - * Upon calling \c resolve(), the config checks for conflicts between the application configuration requests and the attached computer - * vision modules and processing blocks requirements, and fails if conflicts are found. Before \c resolve() is called, no conflict - * check is done. - * - * \param[in] config A pointer to an instance of a config - * \param[in] stream Stream type to be enabled - * \param[in] index Stream index, used for multiple streams of the same type. -1 indicates any. - * \param[in] width Stream image width - for images streams. 0 indicates any. - * \param[in] height Stream image height - for images streams. 0 indicates any. - * \param[in] format Stream data format - pixel format for images streams, of data type for other streams. RS2_FORMAT_ANY indicates any. - * \param[in] framerate Stream frames per second. 0 indicates any. - * \param[out] error if non-null, receives any error that occurs during this call, otherwise, errors are ignored - */ - void rs2_config_enable_stream(rs2_config* config, - rs2_stream stream, - int index, - int width, - int height, - rs2_format format, - int framerate, - rs2_error** error); - - /** - * Enable all device streams explicitly. - * The conditions and behavior of this method are similar to those of \c enable_stream(). - * This filter enables all raw streams of the selected device. The device is either selected explicitly by the application, - * or by the pipeline requirements or default. The list of streams is device dependent. - * - * \param[in] config A pointer to an instance of a config - * \param[out] error if non-null, receives any error that occurs during this call, otherwise, errors are ignored - */ - void rs2_config_enable_all_stream(rs2_config* config, rs2_error ** error); - - /** - * Select a specific device explicitly by its serial number, to be used by the pipeline. - * The conditions and behavior of this method are similar to those of \c enable_stream(). - * This method is required if the application needs to set device or sensor settings prior to pipeline streaming, to enforce - * the pipeline to use the configured device. - * - * \param[in] config A pointer to an instance of a config - * \param[in] serial device serial number, as returned by RS2_CAMERA_INFO_SERIAL_NUMBER - * \param[out] error if non-null, receives any error that occurs during this call, otherwise, errors are ignored - */ - void rs2_config_enable_device(rs2_config* config, const char* serial, rs2_error ** error); - - /** - * Select a recorded device from a file, to be used by the pipeline through playback. - * The device available streams are as recorded to the file, and \c resolve() considers only this device and configuration - * as available. - * This request cannot be used if enable_record_to_file() is called for the current config, and vise versa - * By default, playback is repeated once the file ends. To control this, see 'rs2_config_enable_device_from_file_repeat_option'. - * - * \param[in] config A pointer to an instance of a config - * \param[in] file The playback file of the device - * \param[out] error if non-null, receives any error that occurs during this call, otherwise, errors are ignored - */ - void rs2_config_enable_device_from_file(rs2_config* config, const char* file, rs2_error ** error); - - /** - * Select a recorded device from a file, to be used by the pipeline through playback. - * The device available streams are as recorded to the file, and \c resolve() considers only this device and configuration - * as available. - * This request cannot be used if enable_record_to_file() is called for the current config, and vise versa - * - * \param[in] config A pointer to an instance of a config - * \param[in] file The playback file of the device - * \param[in] repeat_playback if true, when file ends the playback starts again, in an infinite loop; - if false, when file ends playback does not start again, and should by stopped manually by the user. - * \param[out] error if non-null, receives any error that occurs during this call, otherwise, errors are ignored - */ - void rs2_config_enable_device_from_file_repeat_option(rs2_config* config, const char* file, int repeat_playback, rs2_error ** error); - - /** - * Requires that the resolved device would be recorded to file - * This request cannot be used if enable_device_from_file() is called for the current config, and vise versa - * - * \param[in] config A pointer to an instance of a config - * \param[in] file The desired file for the output record - * \param[out] error if non-null, receives any error that occurs during this call, otherwise, errors are ignored - */ - void rs2_config_enable_record_to_file(rs2_config* config, const char* file, rs2_error ** error); - - - /** - * Disable a device stream explicitly, to remove any requests on this stream type. - * The stream can still be enabled due to pipeline computer vision module request. This call removes any filter on the - * stream configuration. - * - * \param[in] config A pointer to an instance of a config - * \param[in] stream Stream type, for which the filters are cleared - * \param[out] error if non-null, receives any error that occurs during this call, otherwise, errors are ignored - */ - void rs2_config_disable_stream(rs2_config* config, rs2_stream stream, rs2_error ** error); - - /** - * Disable a device stream explicitly, to remove any requests on this stream profile. - * The stream can still be enabled due to pipeline computer vision module request. This call removes any filter on the - * stream configuration. - * - * \param[in] config A pointer to an instance of a config - * \param[in] stream Stream type, for which the filters are cleared - * \param[in] index Stream index, for which the filters are cleared - * \param[out] error if non-null, receives any error that occurs during this call, otherwise, errors are ignored - */ - void rs2_config_disable_indexed_stream(rs2_config* config, rs2_stream stream, int index, rs2_error ** error); - - /** - * Disable all device stream explicitly, to remove any requests on the streams profiles. - * The streams can still be enabled due to pipeline computer vision module request. This call removes any filter on the - * streams configuration. - * - * \param[in] config A pointer to an instance of a config - * \param[out] error if non-null, receives any error that occurs during this call, otherwise, errors are ignored - */ - void rs2_config_disable_all_streams(rs2_config* config, rs2_error ** error); - - /** - * Resolve the configuration filters, to find a matching device and streams profiles. - * The method resolves the user configuration filters for the device and streams, and combines them with the requirements of - * the computer vision modules and processing blocks attached to the pipeline. If there are no conflicts of requests, it looks - * for an available device, which can satisfy all requests, and selects the first matching streams configuration. In the absence - * of any request, the rs2::config selects the first available device and the first color and depth streams configuration. - * The pipeline profile selection during \c start() follows the same method. Thus, the selected profile is the same, if no - * change occurs to the available devices occurs. - * Resolving the pipeline configuration provides the application access to the pipeline selected device for advanced control. - * The returned configuration is not applied to the device, so the application doesn't own the device sensors. However, the - * application can call \c enable_device(), to enforce the device returned by this method is selected by pipeline \c start(), - * and configure the device and sensors options or extensions before streaming starts. - * - * \param[in] config A pointer to an instance of a config - * \param[in] pipe The pipeline for which the selected filters are applied - * \param[out] error if non-null, receives any error that occurs during this call, otherwise, errors are ignored - * \return A matching device and streams profile, which satisfies the filters and pipeline requests. - */ - rs2_pipeline_profile* rs2_config_resolve(rs2_config* config, rs2_pipeline* pipe, rs2_error ** error); - - /** - * Check if the config can resolve the configuration filters, to find a matching device and streams profiles. - * The resolution conditions are as described in \c resolve(). - * - * \param[in] config A pointer to an instance of a config - * \param[in] pipe The pipeline for which the selected filters are applied - * \param[out] error if non-null, receives any error that occurs during this call, otherwise, errors are ignored - * \return True if a valid profile selection exists, false if no selection can be found under the config filters and the available devices. - */ - int rs2_config_can_resolve(rs2_config* config, rs2_pipeline* pipe, rs2_error ** error); - #ifdef __cplusplus } #endif diff --git a/libs/realsense2/include/librealsense2/h/rs_processing.h b/libs/realsense2/include/librealsense2/h/rs_processing.h old mode 100755 new mode 100644 index 7836470..351f003 --- a/libs/realsense2/include/librealsense2/h/rs_processing.h +++ b/libs/realsense2/include/librealsense2/h/rs_processing.h @@ -187,6 +187,13 @@ rs2_processing_block* rs2_create_disparity_transform_block(unsigned char transfo */ rs2_processing_block* rs2_create_hole_filling_filter_block(rs2_error** error); +/** +* Creates a rates printer block. The printer prints the actual FPS of the invoked frame stream. +* The block ignores reapiting frames and calculats the FPS only if the frame number of the relevant frame was changed. +* \param[out] error if non-null, receives any error that occurs during this call, otherwise, errors are ignored +*/ +rs2_processing_block* rs2_create_rates_printer_block(rs2_error** error); + #ifdef __cplusplus } #endif diff --git a/libs/realsense2/include/librealsense2/h/rs_record_playback.h b/libs/realsense2/include/librealsense2/h/rs_record_playback.h old mode 100755 new mode 100644 index cddec6d..a540e6d --- a/libs/realsense2/include/librealsense2/h/rs_record_playback.h +++ b/libs/realsense2/include/librealsense2/h/rs_record_playback.h @@ -24,6 +24,7 @@ typedef enum rs2_playback_status RS2_PLAYBACK_STATUS_STOPPED, /**< All sensors were stopped, or playback has ended (all data was read). This is the initial playback status*/ RS2_PLAYBACK_STATUS_COUNT } rs2_playback_status; + const char* rs2_playback_status_to_string(rs2_playback_status status); typedef void (*rs2_playback_status_changed_callback_ptr)(rs2_playback_status); @@ -37,6 +38,16 @@ typedef void (*rs2_playback_status_changed_callback_ptr)(rs2_playback_status); */ rs2_device* rs2_create_record_device(const rs2_device* device, const char* file, rs2_error** error); +/** +* Creates a recording device to record the given device and save it to the given file +* \param[in] device The device to record +* \param[in] file The desired path to which the recorder should save the data +* \param[in] compression_enabled Indicates if compression is enabled, 0 means false, otherwise true +* \param[out] error If non-null, receives any error that occurs during this call, otherwise, errors are ignored +* \return A pointer to a device that records its data to file, or null in case of failure +*/ +rs2_device* rs2_create_record_device_ex(const rs2_device* device, const char* file, int compression_enabled, rs2_error** error); + /** * Pause the recording device without stopping the actual device from streaming. * Pausing will cause the device to stop writing new data to the file, in particular, frames and changes to extensions diff --git a/libs/realsense2/include/librealsense2/h/rs_sensor.h b/libs/realsense2/include/librealsense2/h/rs_sensor.h old mode 100755 new mode 100644 index 9120275..cb810d9 --- a/libs/realsense2/include/librealsense2/h/rs_sensor.h +++ b/libs/realsense2/include/librealsense2/h/rs_sensor.h @@ -56,7 +56,7 @@ typedef enum rs2_format { RS2_FORMAT_ANY , /**< When passed to enable stream, librealsense will try to provide best suited format */ RS2_FORMAT_Z16 , /**< 16-bit linear depth values. The depth is meters is equal to depth scale * pixel value. */ - RS2_FORMAT_DISPARITY16 , /**< 16-bit linear disparity values. The depth in meters is equal to depth scale / pixel value. */ + RS2_FORMAT_DISPARITY16 , /**< 16-bit float-point disparity values. Depth->Disparity conversion : Disparity = Baseline*FocalLength/Depth. */ RS2_FORMAT_XYZ32F , /**< 32-bit floating point 3D coordinates. */ RS2_FORMAT_YUYV , /**< 32-bit y0, u, y1, v data for every two pixels. Similar to YUV422 but packed in a different order - https://en.wikipedia.org/wiki/YUV */ RS2_FORMAT_RGB8 , /**< 8-bit red, green and blue channels */ diff --git a/libs/realsense2/include/librealsense2/h/rs_types.h b/libs/realsense2/include/librealsense2/h/rs_types.h old mode 100755 new mode 100644 diff --git a/libs/realsense2/include/librealsense2/hpp/rs_context.hpp b/libs/realsense2/include/librealsense2/hpp/rs_context.hpp old mode 100755 new mode 100644 index 6b383ce..541735d --- a/libs/realsense2/include/librealsense2/hpp/rs_context.hpp +++ b/libs/realsense2/include/librealsense2/hpp/rs_context.hpp @@ -49,7 +49,7 @@ namespace rs2 return res > 0; } - + /** * returns a list of all newly connected devices * \return the list of all new connected devices @@ -128,6 +128,21 @@ namespace rs2 return device_list(list); } + /** + * create a static snapshot of all connected devices at the time of the call + * \return the list of devices connected devices at the time of the call + */ + device_list query_devices(int mask) const + { + rs2_error* e = nullptr; + std::shared_ptr list( + rs2_query_devices_ex(_context.get(), mask, &e), + rs2_delete_device_list); + error::handle(e); + + return device_list(list); + } + /** * @brief Generate a flat list of all available sensors from all RealSense devices * @return List of sensors @@ -192,13 +207,14 @@ namespace rs2 rs2::error::handle(e); } + context(std::shared_ptr ctx) + : _context(ctx) + {} + explicit operator std::shared_ptr() { return _context; }; protected: friend class rs2::pipeline; friend class rs2::device_hub; - context(std::shared_ptr ctx) - : _context(ctx) - {} std::shared_ptr _context; }; @@ -209,11 +225,10 @@ namespace rs2 { public: explicit device_hub(context ctx) - : _ctx(std::move(ctx)) { rs2_error* e = nullptr; _device_hub = std::shared_ptr( - rs2_create_device_hub(_ctx._context.get(), &e), + rs2_create_device_hub(ctx._context.get(), &e), rs2_delete_device_hub); error::handle(e); } @@ -226,7 +241,7 @@ namespace rs2 { rs2_error* e = nullptr; std::shared_ptr dev( - rs2_device_hub_wait_for_device(_ctx._context.get(), _device_hub.get(), &e), + rs2_device_hub_wait_for_device(_device_hub.get(), &e), rs2_delete_device); error::handle(e); @@ -247,8 +262,10 @@ namespace rs2 return res > 0 ? true : false; } + + explicit operator std::shared_ptr() { return _device_hub; } + explicit device_hub(std::shared_ptr hub) : _device_hub(std::move(hub)) {} private: - context _ctx; std::shared_ptr _device_hub; }; diff --git a/libs/realsense2/include/librealsense2/hpp/rs_device.hpp b/libs/realsense2/include/librealsense2/hpp/rs_device.hpp old mode 100755 new mode 100644 index 917450d..8146727 --- a/libs/realsense2/include/librealsense2/hpp/rs_device.hpp +++ b/libs/realsense2/include/librealsense2/hpp/rs_device.hpp @@ -134,6 +134,9 @@ namespace rs2 virtual ~device() { } + + explicit operator std::shared_ptr() { return _dev; }; + explicit device(std::shared_ptr dev) : _dev(dev) {} protected: friend class rs2::context; friend class rs2::device_list; @@ -141,9 +144,7 @@ namespace rs2 friend class rs2::device_hub; std::shared_ptr _dev; - explicit device(std::shared_ptr dev) : _dev(dev) - { - } + }; class debug_protocol : public device @@ -283,6 +284,8 @@ namespace rs2 return _list.get(); } + operator std::shared_ptr() { return _list; }; + private: std::shared_ptr _list; }; diff --git a/libs/realsense2/include/librealsense2/hpp/rs_frame.hpp b/libs/realsense2/include/librealsense2/hpp/rs_frame.hpp old mode 100755 new mode 100644 index 14f8d00..b35ed2c --- a/libs/realsense2/include/librealsense2/hpp/rs_frame.hpp +++ b/libs/realsense2/include/librealsense2/hpp/rs_frame.hpp @@ -77,10 +77,10 @@ namespace rs2 */ bool operator==(const stream_profile& rhs) { - return stream_index() == rhs.stream_index()&& - stream_type() == rhs.stream_type()&& - format() == rhs.format()&& - fps() == rhs.fps(); + return stream_index() == rhs.stream_index() && + stream_type() == rhs.stream_type() && + format() == rhs.format() && + fps() == rhs.fps(); } /** @@ -139,10 +139,6 @@ namespace rs2 Operator implement, return the internal stream profile instance. * \return rs2_stream_profile* - internal instance to communicate with real implementation. */ - operator const rs2_stream_profile*() - { - return _profile; - } /** * Get the extrinsic transformation between two profiles (representing physical sensors) * \param[in] stream_profile to - the stream profile (another sensor) to be based to return the extrinsic @@ -169,12 +165,7 @@ namespace rs2 error::handle(e); } - protected: - friend class rs2::sensor; - friend class rs2::frame; - friend class rs2::pipeline_profile; - friend class software_sensor; - + bool is_cloned() { return bool(_clone); } explicit stream_profile(const rs2_stream_profile* profile) : _profile(profile) { rs2_error* e = nullptr; @@ -185,6 +176,14 @@ namespace rs2 error::handle(e); } + operator const rs2_stream_profile*() { return _profile; } + explicit operator std::shared_ptr() { return _clone; } + + protected: + friend class rs2::sensor; + friend class rs2::frame; + friend class rs2::pipeline_profile; + friend class software_sensor; const rs2_stream_profile* _profile; std::shared_ptr _clone; @@ -283,6 +282,17 @@ namespace rs2 } }; + + /** + Interface for frame filtering functionality + */ + class filter_interface + { + public: + virtual rs2::frame process(rs2::frame frame) const = 0; + virtual ~filter_interface() = default; + }; + class frame { public: @@ -294,16 +304,16 @@ namespace rs2 * Base class for multiple frame extensions with internal frame handle * \param[in] rs2_frame frame_ref - internal frame instance */ - frame(rs2_frame* frame_ref) : frame_ref(frame_ref) + frame(rs2_frame* ref) : frame_ref(ref) { #ifdef _DEBUG - if (frame_ref) + if (ref) { rs2_error* e = nullptr; - auto r = rs2_get_frame_number(frame_ref, &e); + auto r = rs2_get_frame_number(ref, &e); if (!e) frame_number = r; - auto s = rs2_get_frame_stream_profile(frame_ref, &e); + auto s = rs2_get_frame_stream_profile(ref, &e); if (!e) profile = stream_profile(s); } @@ -335,6 +345,7 @@ namespace rs2 swap(other); return *this; } + /** * Set the internal frame handle to the one in parameter, the function create additional reference if internal reference exist. * \param[in] frame other - another frame instance to be pointed to @@ -345,7 +356,7 @@ namespace rs2 if (frame_ref) add_ref(); #ifdef _DEBUG frame_number = other.frame_number; - profile = other.profile; + profile = other.profile; #endif } /** @@ -493,6 +504,12 @@ namespace rs2 * \return rs2_frame - internal frame handle. */ rs2_frame* get() const { return frame_ref; } + explicit operator rs2_frame*() { return frame_ref; } + + frame apply_filter(filter_interface& filter) + { + return filter.process(*this); + } protected: /** @@ -639,7 +656,6 @@ namespace rs2 if (get()) { - rs2_error* e = nullptr; _size = rs2_get_frame_points_count(get(), &e); error::handle(e); } @@ -774,10 +790,10 @@ namespace rs2 * Retrieve back the motion data from IMU sensor * \return rs2_vector - 3D vector in Euclidean coordinate space. */ - rs2_vector get_motion_data() + rs2_vector get_motion_data() const { auto data = reinterpret_cast(get_data()); - return rs2_vector{data[0], data[1], data[2]}; + return rs2_vector{ data[0], data[1], data[2] }; } }; @@ -836,24 +852,24 @@ namespace rs2 if (get()) { - rs2_error* e = nullptr; _size = rs2_embedded_frames_count(get(), &e); error::handle(e); } } /** - * Retrieve back the first frame of specific stream type, if no frame found, return the default one(frame instance) + * Retrieve back the first frame of specific stream and format types, if no frame found, return the default one(frame instance) * \param[in] rs2_stream s - frame to be retrieved from this stream type. + * \param[in] rs2_format f - frame to be retrieved from this format type. * \return frame - first found frame with s stream type. */ - frame first_or_default(rs2_stream s) const + frame first_or_default(rs2_stream s, rs2_format f = RS2_FORMAT_ANY) const { frame result; - foreach([&result, s](frame f) { - if (!result && f.get_profile().stream_type() == s) + foreach([&result, s, f](frame frm) { + if (!result && frm.get_profile().stream_type() == s && (f == RS2_FORMAT_ANY || f == frm.get_profile().format())) { - result = std::move(f); + result = std::move(frm); } }); return result; @@ -861,13 +877,14 @@ namespace rs2 /** * Retrieve back the first frame of specific stream type, if no frame found, error will be thrown * \param[in] rs2_stream s - frame to be retrieved from this stream type. + * \param[in] rs2_format f - frame to be retrieved from this format type. * \return frame - first found frame with s stream type. */ - frame first(rs2_stream s) const + frame first(rs2_stream s, rs2_format f = RS2_FORMAT_ANY) const { - auto f = first_or_default(s); - if (!f) throw error("Frame of requested stream type was not found!"); - return f; + auto frm = first_or_default(s, f); + if (!frm) throw error("Frame of requested stream type was not found!"); + return frm; } /** @@ -876,7 +893,7 @@ namespace rs2 */ depth_frame get_depth_frame() const { - auto f = first_or_default(RS2_STREAM_DEPTH); + auto f = first_or_default(RS2_STREAM_DEPTH, RS2_FORMAT_Z16); return f.as(); } /** @@ -909,9 +926,9 @@ namespace rs2 } else { - foreach([&f, index](const frame& frame) { - if (frame.get_profile().stream_type() == RS2_STREAM_INFRARED && frame.get_profile().stream_index() == index) - f = frame; + foreach([&f, index](const frame& frm) { + if (frm.get_profile().stream_type() == RS2_STREAM_INFRARED && + frm.get_profile().stream_index() == index) f = frm; }); } return f; @@ -979,7 +996,5 @@ namespace rs2 private: size_t _size; }; - - } #endif // LIBREALSENSE_RS2_FRAME_HPP diff --git a/libs/realsense2/include/librealsense2/hpp/rs_internal.hpp b/libs/realsense2/include/librealsense2/hpp/rs_internal.hpp old mode 100755 new mode 100644 index 7cf1048..338b4ce --- a/libs/realsense2/include/librealsense2/hpp/rs_internal.hpp +++ b/libs/realsense2/include/librealsense2/hpp/rs_internal.hpp @@ -89,7 +89,37 @@ namespace rs2 } /** - * Inject frame into the sensor + * Add motion stream to software sensor + * + * \param[in] motion all the parameters that required to defind motion stream + */ + stream_profile add_motion_stream(rs2_motion_stream motion_stream) + { + rs2_error* e = nullptr; + + stream_profile stream(rs2_software_sensor_add_motion_stream(_sensor.get(), motion_stream, &e)); + error::handle(e); + + return stream; + } + + /** + * Add pose stream to software sensor + * + * \param[in] pose all the parameters that required to defind pose stream + */ + stream_profile add_pose_stream(rs2_pose_stream pose_stream) + { + rs2_error* e = nullptr; + + stream_profile stream(rs2_software_sensor_add_pose_stream(_sensor.get(), pose_stream, &e)); + error::handle(e); + + return stream; + } + + /** + * Inject video frame into the sensor * * \param[in] frame all the parameters that required to define video frame */ @@ -100,6 +130,30 @@ namespace rs2 error::handle(e); } + /** + * Inject motion frame into the sensor + * + * \param[in] frame all the parameters that required to define motion frame + */ + void on_motion_frame(rs2_software_motion_frame frame) + { + rs2_error* e = nullptr; + rs2_software_sensor_on_motion_frame(_sensor.get(), frame, &e); + error::handle(e); + } + + /** + * Inject pose frame into the sensor + * + * \param[in] frame all the parameters that required to define pose frame + */ + void on_pose_frame(rs2_software_pose_frame frame) + { + rs2_error* e = nullptr; + rs2_software_sensor_on_pose_frame(_sensor.get(), frame, &e); + error::handle(e); + } + /** * Set frame metadata for the upcoming frames * \param[in] value metadata key to set diff --git a/libs/realsense2/include/librealsense2/hpp/rs_pipeline.hpp b/libs/realsense2/include/librealsense2/hpp/rs_pipeline.hpp old mode 100755 new mode 100644 index 120a80c..433a6f5 --- a/libs/realsense2/include/librealsense2/hpp/rs_pipeline.hpp +++ b/libs/realsense2/include/librealsense2/hpp/rs_pipeline.hpp @@ -102,12 +102,11 @@ namespace rs2 return _pipeline_profile != nullptr; } - private: + explicit operator std::shared_ptr() { return _pipeline_profile; } pipeline_profile(std::shared_ptr profile) : - _pipeline_profile(profile) - { + _pipeline_profile(profile){} + private: - } std::shared_ptr _pipeline_profile; friend class config; friend class pipeline; @@ -316,12 +315,14 @@ namespace rs2 { return _config; } - private: - config(std::shared_ptr config) : _config(config) + explicit operator std::shared_ptr() const { + return _config; } - std::shared_ptr _config; + config(std::shared_ptr cfg) : _config(cfg) {} + private: + std::shared_ptr _config; }; /** @@ -343,7 +344,6 @@ namespace rs2 * \param[in] ctx The context allocated by the application. Using the platform context by default. */ pipeline(context ctx = context()) - : _ctx(ctx) { rs2_error* e = nullptr; _pipeline = std::shared_ptr( @@ -403,6 +403,54 @@ namespace rs2 return pipeline_profile(p); } + /** + * Start the pipeline streaming with its default configuration. + * The pipeline captures samples from the device, and delivers them to the through the provided frame callback. + * Starting the pipeline is possible only when it is not started. If the pipeline was started, an exception is raised. + * When starting the pipeline with a callback both \c wait_for_frames() or \c poll_for_frames() will throw exception. + * + * \param[in] callback Stream callback, can be any callable object accepting rs2::frame + * \return The actual pipeline device and streams profile, which was successfully configured to the streaming device. + */ + template + pipeline_profile start(S callback) + { + rs2_error* e = nullptr; + auto p = std::shared_ptr( + rs2_pipeline_start_with_callback_cpp(_pipeline.get(), new frame_callback(callback), &e), + rs2_delete_pipeline_profile); + + error::handle(e); + return pipeline_profile(p); + } + + /** + * Start the pipeline streaming according to the configuraion. + * The pipeline captures samples from the device, and delivers them to the through the provided frame callback. + * Starting the pipeline is possible only when it is not started. If the pipeline was started, an exception is raised. + * When starting the pipeline with a callback both \c wait_for_frames() or \c poll_for_frames() will throw exception. + * The pipeline selects and activates the device upon start, according to configuration or a default configuration. + * When the rs2::config is provided to the method, the pipeline tries to activate the config \c resolve() result. + * If the application requests are conflicting with pipeline computer vision modules or no matching device is available on + * the platform, the method fails. + * Available configurations and devices may change between config \c resolve() call and pipeline start, in case devices + * are connected or disconnected, or another application acquires ownership of a device. + * + * \param[in] config A rs2::config with requested filters on the pipeline configuration. By default no filters are applied. + * \param[in] callback Stream callback, can be any callable object accepting rs2::frame + * \return The actual pipeline device and streams profile, which was successfully configured to the streaming device. + */ + template + pipeline_profile start(const config& config, S callback) + { + rs2_error* e = nullptr; + auto p = std::shared_ptr( + rs2_pipeline_start_with_config_and_callback_cpp(_pipeline.get(), config.get().get(), new frame_callback(callback), &e), + rs2_delete_pipeline_profile); + + error::handle(e); + return pipeline_profile(p); + } /** * Stop the pipeline streaming. @@ -509,9 +557,9 @@ namespace rs2 { return _pipeline; } + explicit pipeline(std::shared_ptr ptr) : _pipeline(ptr) {} private: - context _ctx; std::shared_ptr _pipeline; friend class config; }; diff --git a/libs/realsense2/include/librealsense2/hpp/rs_processing.hpp b/libs/realsense2/include/librealsense2/hpp/rs_processing.hpp old mode 100755 new mode 100644 index 66f5c8c..127d6fb --- a/libs/realsense2/include/librealsense2/hpp/rs_processing.hpp +++ b/libs/realsense2/include/librealsense2/hpp/rs_processing.hpp @@ -43,6 +43,16 @@ namespace rs2 error::handle(e); return result; } + + frame allocate_points(const stream_profile& profile, + const frame& original) const + { + rs2_error* e = nullptr; + auto result = rs2_allocate_points(_source, profile.get(), original.get(), &e); + error::handle(e); + return result; + } + /** * Allocate composite frame with given params * @@ -101,89 +111,6 @@ namespace rs2 void release() override { delete this; } }; - /** - * Define the processing block flow, inherit this class to generate your own processing_block. Best understanding is to refer to colorizer.h/cpp - */ - class processing_block : public options - { - public: - /** - * Start the processing block with callback function on_frame to inform the application the frame is processed. - * - * \param[in] on_frame callback function for noticing the frame to be processed is ready. - */ - template - void start(S on_frame) - { - rs2_error* e = nullptr; - rs2_start_processing(_block.get(), new frame_callback(on_frame), &e); - error::handle(e); - } - /** - * Does the same thing as "start" function - * - * \param[in] on_frame address of callback function for noticing the frame to be processed is ready. - * \return address of callback function. - */ - template - S& operator>>(S& on_frame) - { - start(on_frame); - return on_frame; - } - /** - * Ask processing block to process the frame - * - * \param[in] on_frame frame to be processed. - */ - void invoke(frame f) const - { - rs2_frame* ptr = nullptr; - std::swap(f.frame_ref, ptr); - - rs2_error* e = nullptr; - rs2_process_frame(_block.get(), ptr, &e); - error::handle(e); - } - /** - * Does the same thing as "invoke" function - */ - void operator()(frame f) const - { - invoke(std::move(f)); - } - /** - * constructor with already created low level processing block assigned. - * - * \param[in] block - low level rs2_processing_block created before. - */ - processing_block(std::shared_ptr block) - : options((rs2_options*)block.get()),_block(block) - { - } - - /** - * constructor with callback function on_frame in rs2_frame_processor_callback structure assigned. - * - * \param[in] processing_function - function pointer of on_frame function in rs2_frame_processor_callback structure, which will be called back by invoke function . - */ - template - processing_block(S processing_function) - { - rs2_error* e = nullptr; - _block = std::shared_ptr( - rs2_create_processing_block(new frame_processor_callback(processing_function),&e), - rs2_delete_processing_block); - options::operator=(_block); - error::handle(e); - } - - operator rs2_options*() const { return (rs2_options*)_block.get(); } - - private: - std::shared_ptr _block; - }; - class frame_queue { public: @@ -192,12 +119,12 @@ namespace rs2 * to help developers who are not using async APIs * param[in] capacity size of the frame queue */ - explicit frame_queue(unsigned int capacity): _capacity(capacity) + explicit frame_queue(unsigned int capacity) : _capacity(capacity) { rs2_error* e = nullptr; _queue = std::shared_ptr( - rs2_create_frame_queue(capacity, &e), - rs2_delete_frame_queue); + rs2_create_frame_queue(capacity, &e), + rs2_delete_frame_queue); error::handle(e); } @@ -272,29 +199,149 @@ namespace rs2 }; /** - * Generating the 3D point cloud base on depth frame also create the mapped texture. + * Define the processing block flow, inherit this class to generate your own processing_block. Best understanding is to refer to the viewer class in examples.hpp */ - class pointcloud : public options + class processing_block : public options { public: /** - * create pointcloud instance + * Start the processing block with callback function on_frame to inform the application the frame is processed. + * + * \param[in] on_frame callback function for noticing the frame to be processed is ready. */ - pointcloud() : _queue(1) + template + void start(S on_frame) { rs2_error* e = nullptr; + rs2_start_processing(get(), new frame_callback(on_frame), &e); + error::handle(e); + } + /** + * Does the same thing as "start" function + * + * \param[in] on_frame address of callback function for noticing the frame to be processed is ready. + * \return address of callback function. + */ + template + S& operator>>(S& on_frame) + { + start(on_frame); + return on_frame; + } + /** + * Ask processing block to process the frame + * + * \param[in] on_frame frame to be processed. + */ + void invoke(frame f) const + { + rs2_frame* ptr = nullptr; + std::swap(f.frame_ref, ptr); - auto pb = std::shared_ptr( - rs2_create_pointcloud(&e), - rs2_delete_processing_block); - _block = std::make_shared(pb); + rs2_error* e = nullptr; + rs2_process_frame(get(), ptr, &e); + error::handle(e); + } + /** + * constructor with already created low level processing block assigned. + * + * \param[in] block - low level rs2_processing_block created before. + */ + processing_block(std::shared_ptr block) + : _block(block), options((rs2_options*)block.get()) + { + } + /** + * constructor with callback function on_frame in rs2_frame_processor_callback structure assigned. + * + * \param[in] processing_function - function pointer of on_frame function in rs2_frame_processor_callback structure, which will be called back by invoke function . + */ + template + processing_block(S processing_function) + { + rs2_error* e = nullptr; + _block = std::shared_ptr( + rs2_create_processing_block(new frame_processor_callback(processing_function), &e), + rs2_delete_processing_block); + options::operator=(_block); error::handle(e); + } - // Redirect options API to the processing block - options::operator=(pb); + operator rs2_options*() const { return (rs2_options*)get(); } + rs2_processing_block* get() const { return _block.get(); } + protected: + std::shared_ptr _block; + }; - _block->start(_queue); + /** + * Define the processing block flow, inherit this class to generate your own processing_block. Best understanding is to refer to the viewer class in examples.hpp + */ + class filter : public processing_block, public filter_interface + { + public: + /** + * Ask processing block to process the frame and poll the processed frame from internal queue + * + * \param[in] on_frame frame to be processed. + * return processed frame + */ + rs2::frame process(rs2::frame frame) const override + { + invoke(frame); + rs2::frame f; + if (!_queue.poll_for_frame(&f)) + throw std::runtime_error("Error occured during execution of the processing block! See the log for more info"); + return f; + } + + /** + * constructor with already created low level processing block assigned. + * + * \param[in] block - low level rs2_processing_block created before. + */ + filter(std::shared_ptr block, int queue_size = 1) + : processing_block(block), + _queue(queue_size) + { + start(_queue); + } + + /** + * constructor with callback function on_frame in rs2_frame_processor_callback structure assigned. + * + * \param[in] processing_function - function pointer of on_frame function in rs2_frame_processor_callback structure, which will be called back by invoke function . + */ + template + filter(S processing_function, int queue_size = 1) : + processing_block(processing_function), + _queue(queue_size) + { + start(_queue); + } + + frame_queue get_queue() { return _queue; } + rs2_processing_block* get() const { return _block.get(); } + + protected: + frame_queue _queue; + }; + + /** + * Generating the 3D point cloud base on depth frame also create the mapped texture. + */ + class pointcloud : public filter + { + public: + /** + * create pointcloud instance + */ + pointcloud() : filter(init(), 1) {} + + pointcloud(rs2_stream stream, int index = 0) : filter(init(), 1) + { + set_option(RS2_OPTION_STREAM_FILTER, float(stream)); + set_option(RS2_OPTION_STREAM_INDEX_FILTER, float(index)); } /** * Generate the pointcloud and texture mappings of depth map. @@ -304,11 +351,19 @@ namespace rs2 */ points calculate(frame depth) { - _block->invoke(std::move(depth)); - rs2::frame f; - if (!_queue.poll_for_frame(&f)) - throw std::runtime_error("Error occured during execution of the processing block! See the log for more info"); - return points(f); + auto res = process(depth); + if (res.as()) + return res; + + if (auto set = res.as ()) + { + for (auto f : set) + { + if(f.as()) + return f; + } + } + throw std::runtime_error("Error occured during execution of the processing block! See the log for more info"); } /** * Map the point cloud to other frame. @@ -317,52 +372,50 @@ namespace rs2 */ void map_to(frame mapped) { - _block->set_option(RS2_OPTION_TEXTURE_SOURCE, float(mapped.get_profile().unique_id())); - _block->invoke(std::move(mapped)); + set_option(RS2_OPTION_STREAM_FILTER, float(mapped.get_profile().stream_type())); + set_option(RS2_OPTION_STREAM_FORMAT_FILTER, float(mapped.get_profile().format())); + set_option(RS2_OPTION_STREAM_INDEX_FILTER, float(mapped.get_profile().stream_index())); + invoke(mapped); } + private: friend class context; - std::shared_ptr _block; - frame_queue _queue; + std::shared_ptr init() + { + rs2_error* e = nullptr; + + auto block = std::shared_ptr( + rs2_create_pointcloud(&e), + rs2_delete_processing_block); + + error::handle(e); + + // Redirect options API to the processing block + //options::operator=(pb); + return block; + } }; - class asynchronous_syncer + class asynchronous_syncer : public processing_block { public: /** * Real asynchronous syncer within syncer class */ - asynchronous_syncer() + asynchronous_syncer() : processing_block(init()) {} + + private: + std::shared_ptr init() { rs2_error* e = nullptr; - _processing_block = std::make_shared( - std::shared_ptr( - rs2_create_sync_processing_block(&e), - rs2_delete_processing_block)); + auto block = std::shared_ptr( + rs2_create_sync_processing_block(&e), + rs2_delete_processing_block); error::handle(e); + return block; } - - /** - * Start and set the callback when the synchronization is done. - * \param[in] on_frame - callback function, will be invoked when synchronization is finished. - */ - template - void start(S on_frame) - { - _processing_block->start(on_frame); - } - /** - * Doing the actual synchronization work for the frame - * \param[in] f - frame to send to processing block to do the synchronization. - */ - void operator()(frame f) const - { - _processing_block->operator()(std::move(f)); - } - private: - std::shared_ptr _processing_block; }; class syncer @@ -375,7 +428,6 @@ namespace rs2 :_results(queue_size) { _sync.start(_results); - } /** @@ -423,7 +475,7 @@ namespace rs2 void operator()(frame f) const { - _sync(std::move(f)); + _sync.invoke(std::move(f)); } private: asynchronous_syncer _sync; @@ -431,83 +483,72 @@ namespace rs2 }; /** - Auxiliary processing block that performs image alignment using depth data and camera calibration + Auxiliary processing block that performs image alignment using depth data and camera calibration */ - class align + class align : public filter { public: /** - Create align processing block - Alignment is performed between a depth image and another image. - To perform alignment of a depth image to the other, set the align_to parameter with the other stream type. - To perform alignment of a non depth image to a depth image, set the align_to parameter to RS2_STREAM_DEPTH - Camera calibration and frame's stream type are determined on the fly, according to the first valid frameset passed to process() + Create align processing block + Alignment is performed between a depth image and another image. + To perform alignment of a depth image to the other, set the align_to parameter with the other stream type. + To perform alignment of a non depth image to a depth image, set the align_to parameter to RS2_STREAM_DEPTH + Camera calibration and frame's stream type are determined on the fly, according to the first valid frameset passed to process() - * \param[in] align_to The stream type to which alignment should be made. + * \param[in] align_to The stream type to which alignment should be made. */ - align(rs2_stream align_to) :_queue(1) - { - rs2_error* e = nullptr; - _block = std::make_shared( - std::shared_ptr( - rs2_create_align(align_to, &e), - rs2_delete_processing_block)); - error::handle(e); - - _block->start(_queue); - } + align(rs2_stream align_to) : filter(init(align_to), 1) {} /** * Run the alignment process on the given frames to get an aligned set of frames * - * \param[in] frame A pair of images, where at least one of which is a depth frame + * \param[in] frames A set of frames, where at least one of which is a depth frame * \return Input frames aligned to one another */ - frameset process(frameset frame) + frameset process(frameset frames) { - (*_block)(frame); - rs2::frame f; - if (!_queue.poll_for_frame(&f)) - throw std::runtime_error("Error occured during execution of the processing block! See the log for more info"); - return frameset(f); - } - /** - * Run the alignment process on the given frame - * - * \param[in] f - A pair of images, where at least one of which is a depth frame - * \return Input frames aligned to one another - */ - void operator()(frame f) const - { - (*_block)(std::move(f)); + return filter::process(frames); } + private: friend class context; + std::shared_ptr init(rs2_stream align_to) + { + rs2_error* e = nullptr; + auto block = std::shared_ptr( + rs2_create_align(align_to, &e), + rs2_delete_processing_block); + error::handle(e); - std::shared_ptr _block; - frame_queue _queue; + return block; + } }; - class colorizer : public options + class colorizer : public filter { public: /** * Create colorizer processing block * Colorizer generate color image base on input depth frame */ - colorizer() : _queue(1) + colorizer() : filter(init(), 1) { } + /** + * Create colorizer processing block + * Colorizer generate color image base on input depth frame + * \param[in] color_scheme - select one of the available color schemes: + * 0 - Jet + * 1 - Classic + * 2 - WhiteToBlack + * 3 - BlackToWhite + * 4 - Bio + * 5 - Cold + * 6 - Warm + * 7 - Quantized + * 8 - Pattern + */ + colorizer(float color_scheme) : filter(init(), 1) { - rs2_error* e = nullptr; - auto pb = std::shared_ptr( - rs2_create_colorizer(&e), - rs2_delete_processing_block); - _block = std::make_shared(pb); - error::handle(e); - - // Redirect options API to the processing block - options::operator=(pb); - - _block->start(_queue); + set_option(RS2_OPTION_COLOR_SCHEME, float(color_scheme)); } /** * Start to generate color image base on depth frame @@ -516,140 +557,114 @@ namespace rs2 */ video_frame colorize(frame depth) const { - if(depth) - { - _block->invoke(std::move(depth)); - rs2::frame f; - if (!_queue.poll_for_frame(&f)) - throw std::runtime_error("Error occured during execution of the processing block! See the log for more info"); - return video_frame(f); - } - return depth; + return process(depth); } - /** - * Same function as colorize(depth) - * \param[in] depth - depth frame to be processed to generate the color image - * \return video_frame - generated color image - */ - video_frame operator()(frame depth) const { return colorize(depth); } - private: - std::shared_ptr _block; - frame_queue _queue; - }; + private: + std::shared_ptr init() + { + rs2_error* e = nullptr; + auto block = std::shared_ptr( + rs2_create_colorizer(&e), + rs2_delete_processing_block); + error::handle(e); + + // Redirect options API to the processing block + //options::operator=(pb); - /** - Interface for frame processing functionality - */ - class process_interface : public options - { - public: - virtual rs2::frame process(rs2::frame frame) = 0; - virtual void operator()(frame f) const = 0; - virtual ~process_interface() = default; + return block; + } }; - class decimation_filter : public process_interface + class decimation_filter : public filter { public: /** * Create decimation filter processing block * decimation filter performing downsampling by using the median with specific kernel size */ - decimation_filter() :_queue(1) + decimation_filter() : filter(init(), 1) {} + /** + * Create decimation filter processing block + * decimation filter performing downsampling by using the median with specific kernel size + * \param[in] magnitude - number of filter iterations. + */ + decimation_filter(float magnitude) : filter(init(), 1) + { + set_option(RS2_OPTION_FILTER_MAGNITUDE, magnitude); + } + + private: + friend class context; + + std::shared_ptr init() { rs2_error* e = nullptr; - auto pb = std::shared_ptr( + auto block = std::shared_ptr( rs2_create_decimation_filter_block(&e), rs2_delete_processing_block); - _block = std::make_shared(pb); error::handle(e); // Redirect options API to the processing block - options::operator=(pb); + //options::operator=(this); - _block->start(_queue); - } - /** - * process the frame AND return the result - * \param[in] frame - depth frame to be processed - * \return rs2::frame - filtered frame - */ - rs2::frame process(rs2::frame frame) override - { - (*_block)(frame); - rs2::frame f; - if (!_queue.poll_for_frame(&f)) - throw std::runtime_error("Error occured during execution of the processing block! See the log for more info"); - return f; + return block; } - /** - * process the frame - * \param[in] frame - depth frame to be processed - */ - void operator()(frame f) const override - { - (*_block)(std::move(f)); - } - private: - friend class context; - - std::shared_ptr _block; - frame_queue _queue; }; - class temporal_filter : public process_interface + class temporal_filter : public filter { public: /** - * Create temporal filter processing block + * Create temporal filter processing block with default settings * temporal filter smooth the image by calculating multiple frames with alpha and delta settings * alpha defines the weight of current frame, delta defines threshold for edge classification and preserving. * For more information, check the temporal-filter.cpp */ - temporal_filter() :_queue(1) + temporal_filter() : filter(init(), 1) {} + /** + * Create temporal filter processing block with user settings + * temporal filter smooth the image by calculating multiple frames with alpha and delta settings + * \param[in] smooth_alpha - defines the weight of current frame. + * \param[in] smooth_delta - delta defines threshold for edge classification and preserving. + * \param[in] persistence_control - A set of predefined rules (masks) that govern when missing pixels will be replace with the last valid value so that the data will remain persistent over time: + * 0 - Disabled - Persistency filter is not activated and no hole filling occurs. + * 1 - Valid in 8/8 - Persistency activated if the pixel was valid in 8 out of the last 8 frames + * 2 - Valid in 2/last 3 - Activated if the pixel was valid in two out of the last 3 frames + * 3 - Valid in 2/last 4 - Activated if the pixel was valid in two out of the last 4 frames + * 4 - Valid in 2/8 - Activated if the pixel was valid in two out of the last 8 frames + * 5 - Valid in 1/last 2 - Activated if the pixel was valid in one of the last two frames + * 6 - Valid in 1/last 5 - Activated if the pixel was valid in one out of the last 5 frames + * 7 - Valid in 1/last 8 - Activated if the pixel was valid in one out of the last 8 frames + * 8 - Persist Indefinitely - Persistency will be imposed regardless of the stored history(most aggressive filtering) + * For more information, check the temporal-filter.cpp + */ + temporal_filter(float smooth_alpha, float smooth_delta, int persistence_control) : filter(init(), 1) + { + set_option(RS2_OPTION_HOLES_FILL, float(persistence_control)); + set_option(RS2_OPTION_FILTER_SMOOTH_ALPHA, float(smooth_alpha)); + set_option(RS2_OPTION_FILTER_SMOOTH_DELTA, float(smooth_delta)); + } + + private: + friend class context; + + std::shared_ptr init() { rs2_error* e = nullptr; - auto pb = std::shared_ptr( + auto block = std::shared_ptr( rs2_create_temporal_filter_block(&e), rs2_delete_processing_block); - _block = std::make_shared(pb); error::handle(e); // Redirect options API to the processing block - options::operator=(pb); + //options::operator=(pb); - _block->start(_queue); - } - /** - * process the frame AND return the result - * \param[in] frame - depth frame to be processed - * \return rs2::frame - filtered frame - */ - rs2::frame process(rs2::frame frame) override - { - (*_block)(frame); - rs2::frame f; - if (!_queue.poll_for_frame(&f)) - throw std::runtime_error("Error occured during execution of the processing block! See the log for more info"); - return f; + return block; } - /** - * process the frame - * \param[in] frame - depth frame to be processed - */ - void operator()(frame f) const override - { - (*_block)(std::move(f)); - } - private: - friend class context; - - std::shared_ptr _block; - frame_queue _queue; }; - class spatial_filter : public process_interface + class spatial_filter : public filter { public: /** @@ -659,148 +674,131 @@ namespace rs2 * delta defines the depth gradient below which the smoothing will occur as number of depth levels * For more information, check the spatial-filter.cpp */ - spatial_filter() :_queue(1) - { - rs2_error* e = nullptr; - auto pb = std::shared_ptr( - rs2_create_spatial_filter_block(&e), - rs2_delete_processing_block); - _block = std::make_shared(pb); - error::handle(e); - - // Redirect options API to the processing block - options::operator=(pb); - - _block->start(_queue); - } + spatial_filter() : filter(init(), 1) { } /** - * process the frame AND return the result - * \param[in] frame - depth frame to be processed - * \return rs2::frame - filtered frame + * Create spatial filter processing block + * spatial filter smooth the image by calculating frame with alpha and delta settings + * \param[in] smooth_alpha - defines the weight of the current pixel for smoothing is bounded within [25..100]% + * \param[in] smooth_delta - defines the depth gradient below which the smoothing will occur as number of depth levels + * \param[in] magnitude - number of filter iterations. + * \param[in] hole_fill - an in-place heuristic symmetric hole-filling mode applied horizontally during the filter passes. + * Intended to rectify minor artefacts with minimal performance impact */ - rs2::frame process(rs2::frame frame) override + spatial_filter(float smooth_alpha, float smooth_delta, float magnitude, float hole_fill) : filter(init(), 1) { - (*_block)(frame); - rs2::frame f; - if (!_queue.poll_for_frame(&f)) - throw std::runtime_error("Error occured during execution of the processing block! See the log for more info"); - return f; + set_option(RS2_OPTION_FILTER_SMOOTH_ALPHA, float(smooth_alpha)); + set_option(RS2_OPTION_FILTER_SMOOTH_DELTA, float(smooth_delta)); + set_option(RS2_OPTION_FILTER_MAGNITUDE, magnitude); + set_option(RS2_OPTION_HOLES_FILL, hole_fill); } - /** - * process the frame - * \param[in] frame - depth frame to be processed - */ - void operator()(frame f) const override - { - (*_block)(std::move(f)); - } private: friend class context; - std::shared_ptr _block; - frame_queue _queue; + std::shared_ptr init() + { + rs2_error* e = nullptr; + auto block = std::shared_ptr( + rs2_create_spatial_filter_block(&e), + rs2_delete_processing_block); + error::handle(e); + + // Redirect options API to the processing block + //options::operator=(pb); + + return block; + } }; - class disparity_transform : public process_interface + class disparity_transform : public filter { public: /** * Create disparity transform processing block * the processing convert the depth and disparity from each pixel */ - disparity_transform(bool transform_to_disparity=true) :_queue(1) + disparity_transform(bool transform_to_disparity = true) : filter(init(transform_to_disparity), 1) { } + + private: + friend class context; + std::shared_ptr init(bool transform_to_disparity) { rs2_error* e = nullptr; - auto pb = std::shared_ptr( - rs2_create_disparity_transform_block(uint8_t(transform_to_disparity),&e), + auto block = std::shared_ptr( + rs2_create_disparity_transform_block(uint8_t(transform_to_disparity), &e), rs2_delete_processing_block); - _block = std::make_shared(pb); error::handle(e); // Redirect options API to the processing block - options::operator=(pb); + //options::operator=(pb); - _block->start(_queue); + return block; } + }; + class hole_filling_filter : public filter + { + public: /** - * process the frame AND return the result - * \param[in] frame - depth frame to be processed - * \return rs2::frame - filtered frame + * Create hole filling processing block + * the processing perform the hole filling base on different hole filling mode. */ - rs2::frame process(rs2::frame frame) override - { - (*_block)(frame); - rs2::frame f; - if (!_queue.poll_for_frame(&f)) - throw std::runtime_error("Error occured during execution of the processing block! See the log for more info"); - return f; - } + hole_filling_filter() : filter(init(), 1) {} /** - * process the frame - * \param[in] frame - depth frame to be processed + * Create hole filling processing block + * the processing perform the hole filling base on different hole filling mode. + * \param[in] mode - select the hole fill mode: + * 0 - fill_from_left - Use the value from the left neighbor pixel to fill the hole + * 1 - farest_from_around - Use the value from the neighboring pixel which is furthest away from the sensor + * 2 - nearest_from_around - - Use the value from the neighboring pixel closest to the sensor */ - void operator()(frame f) const override + hole_filling_filter(int mode) : filter(init(), 1) { - (*_block)(std::move(f)); + set_option(RS2_OPTION_HOLES_FILL, float(mode)); } + private: friend class context; - std::shared_ptr _block; - frame_queue _queue; - }; - - class hole_filling_filter : public process_interface - { - public: - /** - * Create hole filling processing block - * the processing perform the hole filling base on different hole filling mode. - */ - hole_filling_filter() :_queue(1) + std::shared_ptr init() { rs2_error* e = nullptr; - auto pb = std::shared_ptr( + auto block = std::shared_ptr( rs2_create_hole_filling_filter_block(&e), rs2_delete_processing_block); - _block = std::make_shared(pb); error::handle(e); // Redirect options API to the processing block - options::operator=(pb); + //options::operator=(_block); - _block->start(_queue); - } - /** - * process the frame AND return the result - * \param[in] frame - depth frame to be processed - * \return rs2::frame - filtered frame - */ - rs2::frame process(rs2::frame frame) override - { - (*_block)(frame); - rs2::frame f; - if (!_queue.poll_for_frame(&f)) - throw std::runtime_error("Error occured during execution of the processing block! See the log for more info"); - return f; + return block; } + }; + + class rates_printer : public filter + { + public: /** - * process the frame - * \param[in] frame - depth frame to be processed + * Create hole filling processing block + * the processing perform the hole filling base on different hole filling mode. */ - void operator()(frame f) const override - { - (*_block)(std::move(f)); - } + rates_printer() : filter(init(), 1) {} + private: friend class context; - std::shared_ptr _block; - frame_queue _queue; + std::shared_ptr init() + { + rs2_error* e = nullptr; + auto block = std::shared_ptr( + rs2_create_rates_printer_block(&e), + rs2_delete_processing_block); + error::handle(e); + + return block; + } }; } #endif // LIBREALSENSE_RS2_PROCESSING_HPP diff --git a/libs/realsense2/include/librealsense2/hpp/rs_record_playback.hpp b/libs/realsense2/include/librealsense2/hpp/rs_record_playback.hpp old mode 100755 new mode 100644 index 8352023..8f127de --- a/libs/realsense2/include/librealsense2/hpp/rs_record_playback.hpp +++ b/libs/realsense2/include/librealsense2/hpp/rs_record_playback.hpp @@ -210,15 +210,31 @@ namespace rs2 * \param[in] file The desired path to which the recorder should save the data * \param[in] device The device to record */ - recorder(const std::string& file, rs2::device device) + recorder(const std::string& file, rs2::device dev) { rs2_error* e = nullptr; _dev = std::shared_ptr( - rs2_create_record_device(device.get().get(), file.c_str(), &e), + rs2_create_record_device(dev.get().get(), file.c_str(), &e), rs2_delete_device); rs2::error::handle(e); } + /** + * Creates a recording device to record the given device and save it to the given file as rosbag format + * \param[in] file The desired path to which the recorder should save the data + * \param[in] device The device to record + * \param[in] compression_enabled Indicates if compression is enabled + */ + recorder(const std::string& file, rs2::device dev, bool compression_enabled) + { + rs2_error* e = nullptr; + _dev = std::shared_ptr( + rs2_create_record_device_ex(dev.get().get(), file.c_str(), compression_enabled, &e), + rs2_delete_device); + rs2::error::handle(e); + } + + /** * Pause the recording device without stopping the actual device from streaming. */ diff --git a/libs/realsense2/include/librealsense2/hpp/rs_sensor.hpp b/libs/realsense2/include/librealsense2/hpp/rs_sensor.hpp old mode 100755 new mode 100644 index 21e41ec..96172b5 --- a/libs/realsense2/include/librealsense2/hpp/rs_sensor.hpp +++ b/libs/realsense2/include/librealsense2/hpp/rs_sensor.hpp @@ -9,21 +9,22 @@ namespace rs2 { + class notification { public: - notification(rs2_notification* notification) + notification(rs2_notification* nt) { rs2_error* e = nullptr; - _description = rs2_get_notification_description(notification, &e); + _description = rs2_get_notification_description(nt, &e); error::handle(e); - _timestamp = rs2_get_notification_timestamp(notification, &e); + _timestamp = rs2_get_notification_timestamp(nt, &e); error::handle(e); - _severity = rs2_get_notification_severity(notification, &e); + _severity = rs2_get_notification_severity(nt, &e); error::handle(e); - _category = rs2_get_notification_category(notification, &e); + _category = rs2_get_notification_category(nt, &e); error::handle(e); - _serialized_data = rs2_get_notification_serialized_data(notification, &e); + _serialized_data = rs2_get_notification_serialized_data(nt, &e); error::handle(e); } @@ -211,6 +212,8 @@ namespace rs2 _options = other._options; return *this; } + // if operator= is ok, this should be ok too + options(const options& other) : _options(other._options) {} virtual ~options() = default; protected: @@ -223,7 +226,6 @@ namespace rs2 return *this; } - options(const options& other) : _options(other._options) {} private: rs2_options* _options; @@ -349,7 +351,7 @@ namespace rs2 */ std::vector get_stream_profiles() const { - std::vector results; + std::vector results{}; rs2_error* e = nullptr; std::shared_ptr list( @@ -411,6 +413,12 @@ namespace rs2 return extension; } + explicit sensor(std::shared_ptr dev) + :options((rs2_options*)dev.get()), _sensor(dev) + { + } + explicit operator std::shared_ptr() { return _sensor; } + protected: friend context; friend device_list; @@ -420,10 +428,7 @@ namespace rs2 std::shared_ptr _sensor; - explicit sensor(std::shared_ptr dev) - :options((rs2_options*)dev.get()), _sensor(dev) - { - } + }; inline bool operator==(const sensor& lhs, const sensor& rhs) @@ -495,6 +500,7 @@ namespace rs2 } operator bool() const { return _sensor.get() != nullptr; } + explicit depth_sensor(std::shared_ptr dev) : depth_sensor(sensor(dev)) {} }; class depth_stereo_sensor : public depth_sensor diff --git a/libs/realsense2/include/librealsense2/hpp/rs_types.hpp b/libs/realsense2/include/librealsense2/hpp/rs_types.hpp old mode 100755 new mode 100644 diff --git a/libs/realsense2/include/librealsense2/rs.h b/libs/realsense2/include/librealsense2/rs.h old mode 100755 new mode 100644 index 1cebc0d..9907b76 --- a/libs/realsense2/include/librealsense2/rs.h +++ b/libs/realsense2/include/librealsense2/rs.h @@ -23,7 +23,7 @@ extern "C" { #include "h/rs_sensor.h" #define RS2_API_MAJOR_VERSION 2 -#define RS2_API_MINOR_VERSION 14 +#define RS2_API_MINOR_VERSION 17 #define RS2_API_PATCH_VERSION 0 #define RS2_API_BUILD_VERSION 0 diff --git a/libs/realsense2/include/librealsense2/rs.hpp b/libs/realsense2/include/librealsense2/rs.hpp old mode 100755 new mode 100644 diff --git a/libs/realsense2/include/librealsense2/rs_advanced_mode.h b/libs/realsense2/include/librealsense2/rs_advanced_mode.h old mode 100755 new mode 100644 diff --git a/libs/realsense2/include/librealsense2/rs_advanced_mode.hpp b/libs/realsense2/include/librealsense2/rs_advanced_mode.hpp old mode 100755 new mode 100644 diff --git a/libs/realsense2/include/librealsense2/rsutil.h b/libs/realsense2/include/librealsense2/rsutil.h old mode 100755 new mode 100644 index e6218b1..499bff4 --- a/libs/realsense2/include/librealsense2/rsutil.h +++ b/libs/realsense2/include/librealsense2/rsutil.h @@ -6,11 +6,14 @@ #include "h/rs_types.h" #include "h/rs_sensor.h" +#include "h/rs_frame.h" +#include "rs.h" #include "assert.h" - +#include +#include +#include #include - /* Given a point in 3D space, compute the corresponding pixel coordinates in an image with no distortion or forward distortion coefficients produced by the same camera */ static void rs2_project_point_to_pixel(float pixel[2], const struct rs2_intrinsics * intrin, const float point[3]) { @@ -80,4 +83,80 @@ static void rs2_fov(const struct rs2_intrinsics * intrin, float to_fov[2]) to_fov[1] = (atan2f(intrin->ppy + 0.5f, intrin->fy) + atan2f(intrin->height - (intrin->ppy + 0.5f), intrin->fy)) * 57.2957795f; } +static void next_pixel_in_line(float curr[2], const float start[2], const float end[2]) +{ + float line_slope = (end[1] - start[1]) / (end[0] - start[0]); + if (abs(end[0] - curr[0]) > abs(end[1] - curr[1])) + { + curr[0] = end[0] > curr[0] ? curr[0] + 1 : curr[0] - 1; + curr[1] = end[1] - line_slope * (end[0] - curr[0]); + } + else + { + curr[1] = end[1] > curr[1] ? curr[1] + 1 : curr[1] - 1; + curr[0] = end[0] - ((end[1] + curr[1]) / line_slope); + } +} + +static bool is_pixel_in_line(const float curr[2], const float start[2], const float end[2]) +{ + return ((end[0] >= start[0] && end[0] >= curr[0] && curr[0] >= start[0]) || (end[0] <= start[0] && end[0] <= curr[0] && curr[0] <= start[0])) && + ((end[1] >= start[1] && end[1] >= curr[1] && curr[1] >= start[1]) || (end[1] <= start[1] && end[1] <= curr[1] && curr[1] <= start[1])); +} + +static void adjust_2D_point_to_boundary(float p[2], int width, int height) +{ + if (p[0] < 0) p[0] = 0; + if (p[0] > width) p[0] = width; + if (p[1] < 0) p[1] = 0; + if (p[1] > height) p[1] = height; +} + +/* Find projected pixel with unknown depth search along line. */ +static void rs2_project_color_pixel_to_depth_pixel(float to_pixel[2], + const uint16_t* data, float depth_scale, + float depth_min, float depth_max, + const struct rs2_intrinsics* depth_intrin, + const struct rs2_intrinsics* color_intrin, + const struct rs2_extrinsics* color_to_depth, + const struct rs2_extrinsics* depth_to_color, + const float from_pixel[2]) +{ + //Find line start pixel + float start_pixel[2] = { 0 }, min_point[3] = { 0 }, min_transformed_point[3] = { 0 }; + rs2_deproject_pixel_to_point(min_point, color_intrin, from_pixel, depth_min); + rs2_transform_point_to_point(min_transformed_point, color_to_depth, min_point); + rs2_project_point_to_pixel(start_pixel, depth_intrin, min_transformed_point); + adjust_2D_point_to_boundary(start_pixel, depth_intrin->width, depth_intrin->height); + + //Find line end depth pixel + float end_pixel[2] = { 0 }, max_point[3] = { 0 }, max_transformed_point[3] = { 0 }; + rs2_deproject_pixel_to_point(max_point, color_intrin, from_pixel, depth_max); + rs2_transform_point_to_point(max_transformed_point, color_to_depth, max_point); + rs2_project_point_to_pixel(end_pixel, depth_intrin, max_transformed_point); + adjust_2D_point_to_boundary(end_pixel, depth_intrin->width, depth_intrin->height); + + //search along line for the depth pixel that it's projected pixel is the closest to the input pixel + float min_dist = -1; + for (float p[2] = { start_pixel[0], start_pixel[1] }; is_pixel_in_line(p, start_pixel, end_pixel); next_pixel_in_line(p, start_pixel, end_pixel)) + { + float depth = depth_scale * data[(int)p[1] * depth_intrin->width + (int)p[0]]; + if (depth == 0) + continue; + + float projected_pixel[2] = { 0 }, point[3] = { 0 }, transformed_point[3] = { 0 }; + rs2_deproject_pixel_to_point(point, depth_intrin, p, depth); + rs2_transform_point_to_point(transformed_point, depth_to_color, point); + rs2_project_point_to_pixel(projected_pixel, color_intrin, transformed_point); + + float new_dist = pow((projected_pixel[1] - from_pixel[1]), 2) + pow((projected_pixel[0] - from_pixel[0]), 2); + if (new_dist < min_dist || min_dist < 0) + { + min_dist = new_dist; + to_pixel[0] = p[0]; + to_pixel[1] = p[1]; + } + } +} + #endif diff --git a/libs/realsense2/lib/linux64/librealsense2.so.2 b/libs/realsense2/lib/linux64/librealsense2.so.2 new file mode 100755 index 0000000..4630d37 Binary files /dev/null and b/libs/realsense2/lib/linux64/librealsense2.so.2 differ diff --git a/libs/realsense2/lib/linux64/librealsense2.so.2.17.0 b/libs/realsense2/lib/linux64/librealsense2.so.2.17.0 new file mode 100755 index 0000000..4630d37 Binary files /dev/null and b/libs/realsense2/lib/linux64/librealsense2.so.2.17.0 differ